Học FreeRTOS, p1

 

Tôi bắt đầu series này với tư cách là người hoàn toàn mới về RTOS nói chung và FreeRTOS nói riêng. Tôi sẽ liệt kê các bình luận và code khi đọc các chương của cuốn Using The FreeRTOS Realtime Kernel.

Tại sao FreeRTOS? Sau một thời gian làm trong lĩnh vực hệ thống nhúng, và IOT, tôi nghĩ nếu một phần cứng không chạy được Linux nhúng, nó nên chạy với FreeRTOS và lwIP? Bạn có thể đưa luận điểm có những nơi mà FreeRTOS+lwIP không phù hợp, Contiki hay RIOT phù hợp hơn. Nhưng qủa thật khả năng kết nối trực tiếp và bảo mật cao từ node đến cloud mang lại sự tiện lợi vô cùng lớn so với việc sử dụng border router.

Do tôi không muốn phụ thuộc vào phần cứng khi làm quen với RTOS này, nên đã setup một môi trường mô phỏng trên Linux, ở https://github.com/nqd/freertos_linux_devl. Trong môi trường này v8.2.3 được sử dụng, lwIP v1.4.1 về sau cũng được tích hợp vào.

Môi trường này không tồn tại nếu không có bản port tuyệt vời của William Davy và fork của megakilo.

Những dòng lệnh sau sẽ chuẩn bị môi trường cho phần này và những phần sau.


git clone --recursive https://github.com/nqd/learn_freertos.git

cd freertos_linux_devl

make -f Makefile.tools

Nếu bạn tò mò, Makefile.tools để lấy freertos v8.2.3 xuống.

Bài đầu tiên, tạo task.


cd ../chapter1

make

./create_task.out

Bình luận

Nếu thay phần vTaskDelay(1000 / portTICK_RATE_MS); bằng vòng lặp for.

Với For delay

Cho mainDELAY_LOOP_COUNT gía trị 10000, kế qủa là task 1 được in ra liên tiếp, rồi đến task 2 và ngược lại.


Task 1 is running
Task 1 is running
...
Task 1 is running
Task 1 is running
Task 1 is running
Task 2 is running
Task 2 is running
...
Task 2 is running

Sau đó tăng mainDELAY_LOOP_COUNT lên 1000000 (tùy thuộc vào tốc độ của PC đang chạy chương trình), kết qủa Task 1/2 được in ra luân phiên nhau.

Task 1 is running
Task 2 is running
Task 1 is running
Task 2 is running
Task 2 is running
Task 1 is running

...

Nguyên nhân? Xem hình dưới. Mỗi task chạy một khoảng delta(T) = t2-t1, ứng với thời gian giữa các tick của kernel. mainDELAY_LOOP_COUNT càng nhỏ thì càng nhiều vòng lặp được thực hiện trong khoảng delta(T) này, dẫn đến Task x is running xuất hiện liên tục nhiều hơn.

freertos-task1-task2-same-priority-delay

Nếu cho task 2 có priority cao hơn, ví dụ bằng cách #define mainTASK2_PRIORITY (tskIDLE_PRIORITY + 2). Lúc này task 1 không có cơ hội được thực thi.


Task 2 is running
Task 2 is running
Task 2 is running
Task 2 is running

freertos-task-priorities

Việc delay bằng vòng lặp for dẫn đến các task có mức độ ưu tiên thấp hơn không có điều khiện thực thi. Đều này nên tránh khi viết chương trình.

vTaskDelay, không For

Quay trở lại với delay bằng vTaskDelay. Chương trình cho kết qủa


Task 2 is running
Task 1 is running
Task 2 is running
Task 1 is running

một cách tuần tự dù Task 2 có độ ưu tiên cao hơn Task 1. Vì sao?

Lúc này xuất hiện khái niệm Blocked/Ready state.

freertos-tasks

Mỗi task nằm trong một trong các trạng thái

  • Blocked là một tráng thái “Not Running”. Lúc này task đang chờ một trong hai sự kiện: Time hoặc Synchronization. Liên quan đến thời gian như Task X sẽ chuyển đến trạng thái Block trong 100 ms. Synchronization khi nó đang tương tác với các Task khác (semaphore, queue, …) hoặc interrupt.
  • Suspended là một trạng thái “Not Running”. Một Task vào trạng thái này khi được gọi với vTaskSuspend(), và thoát ra với vTaskResume() hoặc xTaskResumeFromISR(). Task với trạng thái này sẽ được được schedule bởi kernel.
  • Ready cũng là một trạng thái “Not Running”. Task này sẵng sàng để chạy, nhưng chưa chuyển sang Running.
  • Running là trạng thái Task được CPU thực thi.

Quay trở lại chương trình, Task 2 với ưu tiên cao hơn, được thực thi trước. Khi nó được chuyển sang trạng thái Blocked với hàm vTaskDelay, Task 1 được kernel gọi thực thi. Sau đó Task 1 cũng được chuyển sang trạng thái Blocked này.

Kernel sang trạng thái idle, và vApplicationIdleHook được gọi. Chương trình có thể đặt cpu sang chế độ ngủ nếu năng lượng là vấn đề của hệ thống.

Sau khoảng thời gian delay, Task 2 chuyển sang trạng thái Running, in ra terminal, rồi lại chuyển sang Blocked. Tương tự như vậy với Task 1.

Xác nhận: Các hình ở trên được lấy từ sách Using The FreeRTOS Realtime Kernel của Richard Barry.

2 thoughts on “Học FreeRTOS, p1”

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s