Xu Hướng 11/2022 ❤️ Ý Nghĩa Của Từ Khóa Volatile Trong Lập Trình Nhúng C. ❣️ Top View | 2atlantic.edu.vn

Bạn đang xem bài viết Ý Nghĩa Của Từ Khóa Volatile Trong Lập Trình Nhúng C. được cập nhật mới nhất trên website 2atlantic.edu.vn. Hy vọng những thông tin mà chúng tôi đã chia sẻ là hữu ích với bạn. Nếu nội dung hay, ý nghĩa bạn hãy chia sẻ với bạn bè của mình và luôn theo dõi, ủng hộ chúng tôi để cập nhật những thông tin mới nhất.

Trong lập trình nhúng (embedded system), ta rất thường hay gặp khai báo biến với từ khóa volatile. Việc khai báo biến volatile là rất cần thiết để tránh những lỗi sai khó phát hiện do tính năng optimization của compiler. Trong bài viết này, ta sẽ tìm hiểu ý nghĩa của từ khóa này, cách sử dụng nó và giải thích tại sao nó quan trọng trong một số trường hợp lập trình với hệ thống nhúng và lập trình ứng dụng đa luồng.

Tại sao cần phải có biến volatile

Cách khai báo biến với từ khóa volatile:

volatile int foo;//both this way…

int volatile foo;//… and this way is OK! Define a volatile integer variable

volatile uint8_t *pReg;//both this way…

uint8_t volatile *pReg;//… and this way is OK! Define a pointer to a volatile unsigned 8-bit integer

Một biến cần được khai báo dưới dạng biến volatile khi nào? Khi mà giá trị của nó có thể thay đổi một cách không báo trước. Trong thực tế, có 3 loại biến mà giá trị có thể bị thay đổi như vậy:

Memory-mapped peripheral registers (thanh ghi ngoại vi có ánh xạ đến ô nhớ)

Biến toàn cục được truy xuất từ các tiến trình con xử lý ngắt (interrupt service routine)

Biến toàn cục được truy xuất từ nhiều tác vụ trong một ứng dụng đa luồng.

Thanh ghi ngoại vi

Trong các hệ thống nhúng thường có các thiết bị ngoại vi (ví dụ như cổng vào ra đa chức năng GPIO, cổng UART, cổng SPI, …), và các thiết bị ngoại vi này chứa các thanh ghi mà giá trị của nó có thể thay đổi ngoài ý muốn của dòng chương trình (program flow). Ví dụ một thanh ghi trạng thái pStatReg, ta cần phải thực hiện polling thanh ghi trạng thái này đến khi nó khác 0 (Đoạn code minh họa với Keil ARM compiler, trên vi điều khiển ARM LPC2368)

mappedIOi_nonvolatile.c

unsigned long * pStatReg = (unsigned long*) 0xE002C004;

//Wait for the status register to become non-zero

while(*pStatReg == 0) { }

mappedIO_nonvolatile.s Đoạn code này có gì không ổn? Nó sẽ chạy sai khi ta bật chức năng tối ưu (optimization) của compiler. Quan sát mã assembly mà compiler xuất ra của đoạn code trên như sau:

mappedIO_volatile.c

volatile unsigned long * pStatReg = (unsigned long*) 0xE002C004;

//Wait for the status register to become non-zero

while(*pStatReg == 0) { }

mappedIO_volatile.s Mã assembly mà compiler xuất ra sẽ như sau:

Tiến trình con xử lý ngắt (Interrupt Service Routine)

Ngắt là một khái niệm quan trọng trong hệ thống nhúng. Có nhiều loại ngắt khác nhau như ngắt vào ra (I/O), ngắt SPI, ngắt UART… Mỗi khi xảy ra ngắt, stack pointer sẽ nhảy đến chương trình con xử lý ngắt (ISR). Thường thì các chương trình con xử lý ngắt này sẽ thay đổi giá trị của biến toàn cục và trong chương trình chính sẽ đọc những giá trị này để xử lý.

Để dễ hiểu, lấy ví dụ ngắt cổng serial (UART) kiểm tra các kí tự nhận được xem có phải là 0xFF không. Nếu là kí tự 0xFF, ISR sẽ set một biến cờ toàn cục. Nếu không có volatile, code như sau:

interrupt void rx_isr(void)

Giải pháp là đặt biến ext_rcvd là biến volatile. compiler sẽ biết đó là biến có thể bị thay đổi theo một cách nào đó ngoài ý muốn (ở đây là do ISR). Compiler sẽ bị buộc phải check giá trị của biến ext_rcvd.Ta để ý trong main(): compiler không thể biết được là biến ext_rcvd có thể bị thay đổi trong ISR. Compiler dò đoạn code, thấy rằng biểu thức !ext_rcvd luôn đúng, vì thế không thể thoát được vòng lặp while. Nếu compiler được bật optimization lên, tất cả đoạn code sau vòng lặp while sẽ bị loại bỏ. Nếu không có warning cẩn thận, chương trình của ta có thể bị lỗi mà phát hiện rất khó.

Ứng dụng đa luồng

Trong các ứng dụng đa luồng, thường xảy ra trường hợp các tác vụ trao đổi thông tin với nhau thông qua một biến toàn cục. Như vậy, một tác vụ thay đổi giá trị của biến toàn cục cũng sẽ giống như trường hợp ISR ở trên. Nếu compiler mà bật tính năng optimization thì sẽ xảy ra vấn đề.

Ví dụ đoạn code

multithreaded.c

Cách khắc phục vấn như cũ: đặt biến cntr thành biến volatile !

Sưu tầm và chia sẻ. Nhật Thương

Ý nghĩa của từ khóa Volatile trong lập trình nhúng C.

Cập nhật thông tin chi tiết về Ý Nghĩa Của Từ Khóa Volatile Trong Lập Trình Nhúng C. trên website 2atlantic.edu.vn. Hy vọng nội dung bài viết sẽ đáp ứng được nhu cầu của bạn, chúng tôi sẽ thường xuyên cập nhật mới nội dung để bạn nhận được thông tin nhanh chóng và chính xác nhất. Chúc bạn một ngày tốt lành!