Title Image

Blog Logo

Core 19. RTOS - Race Condition

🌱 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.
Race Condition
   
    Như vậy, có thể thấy task main thông thường và chương trình ngắt systick đang sử dụng chung một thanh ghi, đó là thanh ghi GPIOB_ODR
    👉👉👉 Xét về mặt ngôn ngữ ASM, các bạn có thể hiểu đơn giản như sau, thực hiện thao tác trên một thanh ghi (GPIOB_ODR), CPU sẽ không thao tác trực tiếp trên thanh ghi đó, mà thực hiện một quy trình "Load>>Modify>>Store". Tức là CPU sẽ load giá trị của thanh ghi đó, sau đó chỉnh sửa (Modify), và cuối cùng cùng là Store giá trị trở lại các thanh ghi đó. 

Race Condition

    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.

RTOS

    ➤ 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().
    👉 Trên đây chính là ví dụ tiêu biểu nhất của Race Condition, đối với việc chỉ có task main và một chương trình ngắt, việc này cũng có thể xảy ra. Như vậy, trong RTOS, với nhiều task và nhiều ngắt systick liên tiếp, thì Race Condition xảy ra là việc không thể tránh khỏi. Điều này gây "hỗn loạn" chương trình, và có thể gây sai lệch chương trình khi mà các task sử dụng chung các tài nguyên. 

    👉 Vì vậy, có một số cách để tránh được Race Condition:

    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 😊

                                        

Đăng nhận xét

0 Nhận xét