🌱 Core 19. RTOS - Race Condition
Một khái niệm thường xuyên gặp phải trong RTOS hay cả multi-thread đó là Race Condition, dịch nghĩa ra thì là điều kiện cuộc đua 😂😂. Nó xảy ra khi các task đồng thời truy cập vào một tài nguyên, và các câu lệnh đan xen lẫn nhau, khiến cho chương trình không diễn ra đúng như quy trình đã được thiết kế.
Các tài nguyên có thể sử dụng chung giữa các task, có thể là biến global, có thể là một cổng usb, hay đơn giản hơn là các thanh ghi.👉 Để hiểu về Race Condition, các bạn hãy xem ví dụ sau:
Mình sẽ xét một chương trình nháy led như sau:
- Trong while(1) chúng ta sẽ cho nháy LED ở chân PB3.
- Cứ sau 0.5s, chương trình sẽ nhảy vào ngắt systick và nháy LED ở chân PB2.
Như chương trình C, chúng ta sẽ không thấy sự khác biệt khi ngắt Systick xảy ra, chúng ta đang hiểu theo hướng, LED PB3 đảo sau đó nó mới nhảy đến chương trình ngắt để đảo LED PB2.
💣 Tuy nhiên, đúng như quy ước "một câu lệnh C bằng 3 câu lệnh ASM", thì việc ngắt systick xảy ra khi mà quá trình thực hiện lệnh Toggle LED PB3 là hoàn toàn có thể xảy ra (xảy ra giữa 3 lệnh ASM trên).
Ở những trường hợp khác, chương trình main và ngắt không sử dụng chung tài nguyên thì không sao cả, nhưng đối với bài toán trên, việc chúng ta đang sử dụng chung thanh ghi GPIOB_ODR, có thể dẫn đến việc chương trình chạy không được như ý muốn, đó chính xác là định nghĩa của Race Condition.
➤ Có thể thấy trong hình trên:
- Thanh ghi GPIOB_ODR được lưu trữ vào trong thanh ghi R2, và thanh ghi này sẽ được sử dụng chung cho cả main và Systick_Handler.
- Khi mà việc Toggle LED PB3 mới chạy đến câu lệnh ASM thứ 2 - Modify, thì ngắt systick xảy ra, lúc này bit số 3 đã được chỉnh sửa ở thanh ghi R3 (R3 = 0x0000.0008). Và chương trình nhảy đến Systick_Handler() để Toggler LED PB2.
- Sau khi thực hiện xong Systick_Handler, PB2 = 1, PB3 vẫn đang bằng 0.
- Chương trình quay trở lại với lệnh Store trong main, load giá trị thanh ghi R3 vào thanh ghi GPIOB_ODR, tức là ODR = 0x0000.0008. Tức là bit số 2 (PB2) đã bị buộc về 0, PB2 = 0. Rõ ràng điều này đã gây ra sai luồng chương trình vì LED PB2 đã bị đảo trạng thái ở ngoài Systick_Handler().
👉 Vì vậy, có một số cách để tránh được Race Condition:
- Sử dụng Mutex.
- Sử dụng Critical Section ở mỗi task.
Các cách trên sẽ được giới thiệu ở những bài viết sau.
>>>= Follow ngay =<<<
Để theo dõi 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 😊
0 Nhận xét