I. Quá trình thực thi chương trình của Arduino IDE
1. Hàm setup()
và loop()
.
Trong arduino IDE, hàm setup()
và loop()
là 2 hàm thường được sử dụng để người dùng có thể cấu hình, và chạy chức năng của chương trình. Hai hàm này liên quan mật thiết với hàm main.cpp
theo link.
#include <Arduino.h> // Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; } // Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { } void setupUSB() __attribute__((weak));
void setupUSB() { } int main(void)
{ init(); initVariant(); #if defined(USBCON) USBDevice.attach();
#endif setup(); for (;;) { loop(); if (serialEventRun) serialEventRun(); } return 0;
}
Giải thích:
-
ini t()
: hàm khởi tạo phần cứng cơ bản (vd GPIO, UART, ...) được định nghĩa trong wiring.c -
if defined(USBCON)
-> Nếu board hỗ trợ usb -
setup()
: Chỉ chạy 1 lần duy nhất.- Gọi hàm
setup()
trong Arduino IDE.
- Gọi hàm
-
for (;;)
: Vòng lặp vô hạn.- Gọi hàm
loop()
trong Arduino IDE. serialEventRun
: xử lí dữ liệu serial nếu có
- Gọi hàm
Trong main()
có initVariant()
được định nghĩa là
void initVariant() __attribute__((weak)); void initVariant() { }
__attribute__((weak))
: Đây là một hàm mặc định rất "yếu", sẽ được ghi đề nếu trong code có hàm initVariant()
cùng tên.
👉 Vậy:
- ➡ Nếu ta không làm gì,
initVariant()
mặc định (hàm rỗng) sẽ chạy. - ➡ Nếu ta viết lại
initVariant()
trong code của mình, chương trình sẽ ghi đè hàminitVariant()
. Và ta có thể viết những gì mình muốn trong hàminitVariant()
trước khi chạysetup()
vàloop()
trong Arduino IDE.
Hàm setupUSB()
thì có tính chất tương tự như hàm initVariant()
.
2. Chỉnh sửa initVariant()
để chạy freeRTOS
Tham khảo trong freeRTOS có 1 file variantHooks.cpp
, chứa hàm initVariant()
đã được định nghĩa lại.
void initVariant(void) __attribute__ ((OS_main)); void initVariant(void)
{ // As the Task stacks are on heap before Task allocated heap variables, // the library default __malloc_heap_end = 0 doesn't work. __malloc_heap_end = (char *)(RAMEND - __malloc_margin); setup(); // the normal Arduino setup() function is run here. vTaskStartScheduler(); // initialise and run the freeRTOS scheduler. Execution should never return here.
}
Hàm void initVariant(void)
trong file variantHooks.cpp
sẽ ghi đè hàm initVariant()
trong main.cpp
của Arduino Core.
⚙️ Uses:
- Gọi
setup()
, hàm này ta dùng để khởi tạo các "Task". - Sau đó gọi
vTaskStartScheduler()
để bắt đầu chạy Real-time OS.
📌 Lưu ý: Khi vTaskStartScheduler()
được thực thi thì nó sẽ chạy mãi mãi từ khi ta bắt đầu chương trình cho đến khi kết thúc. Nên hàm loop()
trong for()
sẽ không được thực thi. => Khi dùng Arduino IDE, ta sử dụng freeRTOS thì không cần dùng loop()
Tham khảo bài viết này để đính chính lưu ý trên: http://arduino.vn/bai-viet/1673-chay-da-nhiem-tren-arduino-voi-freertos