🌱 OS Event trong Hệ thống Nhúng RTOS: Sử dụng với FreeRTOS

🌱 OS Event trong Hệ thống Nhúng RTOS: Sử dụng với FreeRTOS

    Trong hệ thống nhúng sử dụng RTOS, các task thường phải chờ đợi hoặc phản hồi các sự kiện cụ thể, như dữ liệu từ cảm biến, tín hiệu từ nút bấm, hoặc hoàn thành một giao dịch I/O. Nếu không có cơ chế quản lý sự kiện hiệu quả, các task có thể phải liên tục kiểm tra trạng thái (polling), gây lãng phí CPU, hoặc không phản hồi kịp thời với các sự kiện quan trọng.

    Ví dụ thực tế: Trong một hệ thống điều khiển xe trên STM32, một task cần chờ tín hiệu từ cảm biến siêu âm để tránh vật cản, trong khi task khác chờ lệnh từ người dùng qua UART. Nếu không có OS Event, việc đồng bộ hóa các task này sẽ phức tạp và không tối ưu.

    OS Event giải quyết vấn đề này bằng cách cung cấp một cách linh hoạt để thông báo và chờ sự kiện. Bài viết này sẽ cùng bạn tìm hiểu về cơ chế Event trong RTOS nói chung và sử dụng trong freeRTOS nói riêng!


OS Event là gì?

    OS Event là một cơ chế trong RTOS để thông báo hoặc chờ đợi các sự kiện xảy ra trong hệ thống. Nó cho phép các task phản hồi tức thì với các điều kiện cụ thể (như ngắt phần cứng, tín hiệu từ task khác) mà không cần polling liên tục.

    Ví dụ trong FreeRTOS, OS Event thường được triển khai qua Event Group (Nhóm sự kiện), một tập hợp các cờ (flags) mà các task có thể set hoặc chờ wait để đồng bộ hóa.

OS Event Group


Cách OS Event hoạt động trong RTOS

    OS Event hoạt động dựa trên nguyên tắc sau:

  • Đặt sự kiện (Set): Một task hoặc ISR đặt một hoặc nhiều cờ sự kiện khi điều kiện xảy ra (ví dụ: dữ liệu sẵn sàng).
  • Chờ sự kiện (Wait): Task khác chờ một tập hợp Flags cụ thể, chuyển sang trạng thái ngủ (blocked) cho đến khi Flags được set. Lúc này, OS có thể nhường quyền cho Task khác hoạt động.
  • Xóa sự kiện (Clear): Sau khi xử lý, cờ có thể được xóa để chuẩn bị cho sự kiện tiếp theo.

    OS Event giúp giảm thiểu lãng phí CPU và tăng tính real-time của hệ thống nhúng.

    ➤ OS Event được ứng dụng rộng rãi trong các trường hợp sau:

  • Đồng bộ hóa đa task: Chờ nhiều sự kiện từ các nguồn khác nhau (cảm biến, I/O). Ví dụ một Task xử lý lỗi (chẳng hạn lỗi UART Parity Error) sẽ chỉ cần đợi một Event lỗi. Trong ngắt UART Parity Error sẽ set Event lỗi này để Task xử lý lỗi hoạt động.
  • Xử lý ngắt: ISR thông báo sự kiện cho task qua các Flags, giống trường hợp kể trên.
  • Quản lý trạng thái: Điều khiển trạng thái hệ thống dựa trên các điều kiện cụ thể.

OS Event trong FreeRTOS: Event Group

    FreeRTOS sử dụng Event Group để triển khai OS Event. Event Group là một tập hợp bit (thường 24 bit), mỗi bit đại diện cho một sự kiện. Các hàm chính bao gồm:

  • xEventGroupCreate: Tạo một Event Group.
  • xEventGroupSetBits: Đặt một hoặc nhiều bit sự kiện.
  • xEventGroupWaitBits: Chờ một tập hợp bit cụ thể.
  • xEventGroupClearBits: Xóa bit sau khi xử lý.

    Event Group linh hoạt hơn Semaphore vì nó cho phép chờ nhiều sự kiện cùng lúc.


Ví dụ thực tế trên FreeRTOS với STM32

    Dưới đây là ví dụ sử dụng OS Event trong hệ thống điều khiển xe trên STM32:

Kịch bản: Điều khiển robot với cảm biến và nút bấm

  • Task Sensor: Đọc cảm biến siêu âm, đặt cờ khi phát hiện vật cản.
  • Task Button: Đọc nút bấm, đặt cờ khi người dùng nhấn.
  • Task Control: Chờ cả hai sự kiện để dừng xe.
  1. #include "stm32f4xx_hal.h"
  2. #include "FreeRTOS.h"
  3. #include "task.h"
  4. #include "event_groups.h"
  5. #define SENSOR_EVENT (1 << 0) // Bit 0: Obstacle
  6. #define BUTTON_EVENT (1 << 1) // Bit 1: Push button
  7. EventGroupHandle_t xEventGroup;
  8. UART_HandleTypeDef huart1;
  9. void TaskSensor(void *pvParameters) {
  10. while (1) {
  11. // Simulate reading ultrasonic sensor
  12. if (/* Nearest obstacle < 10cm */) {
  13. xEventGroupSetBits(xEventGroup, SENSOR_EVENT);
  14. }
  15. vTaskDelay(pdMS_TO_TICKS(100));
  16. }
  17. }
  18. void TaskButton(void *pvParameters) {
  19. while (1) {
  20. if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET) { // Button
  21. xEventGroupSetBits(xEventGroup, BUTTON_EVENT);
  22. }
  23. vTaskDelay(pdMS_TO_TICKS(50));
  24. }
  25. }
  26. void TaskControl(void *pvParameters) {
  27. while (1) {
  28. // Wait for both events (AND logic)
  29. EventBits_t bits = xEventGroupWaitBits(xEventGroup,
  30. SENSOR_EVENT | BUTTON_EVENT,
  31. pdTRUE, // Clear bit after processing
  32. pdTRUE, // Wait for both bits
  33. portMAX_DELAY);
  34. if ((bits & (SENSOR_EVENT | BUTTON_EVENT)) == (SENSOR_EVENT | BUTTON_EVENT)) {
  35. HAL_UART_Transmit(&huart1, (uint8_t*)"Stop Robot\n", 11, 100);
  36. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // Stop the motor
  37. }
  38. }
  39. }
  40. void app_main() {
  41. HAL_UART_Init(&huart1);
  42. xEventGroup = xEventGroupCreate(); // Create OS Event
  43. // Create Task
  44. xTaskCreate(TaskSensor, "Sensor", 128, NULL, 1, NULL);
  45. xTaskCreate(TaskButton, "Button", 128, NULL, 1, NULL);
  46. xTaskCreate(TaskControl, "Control", 128, NULL, 2, NULL);
  47. vTaskStartScheduler();
  48. }

Giải thích:

  • Task Sensor và Task Button đặt cờ khi phát hiện sự kiện.
  • Task Control chờ cả hai cờ (SENSOR_EVENT và BUTTON_EVENT) để dừng xe, tránh polling.


Kết luận

    OS Event, đặc biệt qua Event Group trong FreeRTOS, là một công cụ mạnh mẽ để đồng bộ hóa task trong hệ thống nhúng. Nó giúp tiết kiệm năng lượng và tối ưu hiệu suất của CPU, tăng tính real-time, và xử lý hiệu quả các sự kiện phức tạp.

    Bạn đã từng sử dụng OS Event trong dự án của mình chưa? Hãy chia sẻ kinh nghiệm hoặc đặt câu hỏi nhé!

>>>>>> Follow ngay <<<<<<<

Để nhận được những bài học miễn phí mới nhất nhé 😊
Chúc các bạn học tập tốt 😊

Nguyễn Văn Nghĩa

Mình là một người thích học hỏi và chia sẻ các kiến thức về Nhúng IOT.

Đăng nhận xét

Mới hơn Cũ hơn
//