9.1 xMessageBufferCreate() #include “FreeRTOS.h” #include “message_buffer.h” MessageBufferHandle_t xMessageBufferCreate(size_t xBufferSizeBytes); Listing 264: Nguyên mẫu hàm xMessageBufferCreate() Tóm tắt Hàm xMessageBufferCreate() (xMessageBufferCreate()) được sử dụng để tạo một bộ đệm tin nhắn mới bằng cách sử dụng bộ nhớ được cấp phát động. Xem xMessageBufferCreateStatic() để sử dụng phiên bản sử dụng bộ nhớ cấp phát tĩnh (bộ nhớ được cấp phát tại thời điểm biên dịch). configSUPPORT_DYNAMIC_ALLOCATION phải được đặt thành 1 hoặc không được định nghĩa trong FreeRTOSConfig.h để xMessageBufferCreate() có sẵn. Chức năng bộ đệm tin nhắn được kích hoạt bằng cách bao gồm tệp nguồn FreeRTOS/source/stream_buffer.c trong quá trình xây dựng (vì bộ đệm tin nhắn sử dụng bộ đệm luồng). Tham số xBufferSizeBytes: Tổng số byte (không phải số tin nhắn) mà bộ đệm tin nhắn sẽ có thể chứa tại bất kỳ thời điểm nào. Khi một tin nhắn được ghi vào bộ đệm tin nhắn, một số byte sizeof( size_t ) khác cũng được ghi để lưu trữ độ dài của tin nhắn. sizeof( size_t ) thường là 4 byte trên kiến trúc 32-bit, vì vậy trên hầu hết các kiến trúc 32-bit, một tin nhắn 10 byte sẽ chiếm 14 byte trong không gian bộ đệm tin nhắn. Giá trị trả về Nếu trả về NULL, tức là không thể tạo bộ đệm tin nhắn vì không có đủ bộ nhớ heap cho FreeRTOS cấp phát cấu trúc dữ liệu và khu vực lưu trữ của bộ đệm tin nhắn. Một giá trị không phải NULL được trả về cho thấy bộ đệm tin nhắn đã được tạo thành công - giá trị trả về này nên được lưu trữ như handle cho bộ đệm tin nhắn đã tạo. Ví dụ: void vAFunction( void ) { MessageBufferHandle_t xMessageBuffer; const size_t xMessageBufferSizeBytes = 100; /* Create a message buffer that can hold 100 bytes. The memory used to hold both the message buffer structure and the data in the message buffer is allocated dynamically. */ xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes ); if( xMessageBuffer == NULL ) { /* There was not enough heap memory space available to create the message buffer. */ } else { /* The message buffer was created successfully and can now be used. */ } } Listing 265: Ví dụ sử dụng của xMessageBufferCreate() 9.2 xMessageBufferCreateStatic() #include “FreeRTOS.h” #include “message_buffer.h” MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes, uint8_t *pucMessageBufferStorageArea, StaticMessageBuffer_t *pxStaticMessageBuffer ); Listing 266: Nguyên mẫu hàm xMessageBufferCreateStatic() Tóm tắt Hàm xMessageBufferCreateStatic() được sử dụng để tạo một bộ đệm tin nhắn mới bằng cách sử dụng bộ nhớ được cấp phát tĩnh. Xem xMessageBufferCreate() để sử dụng phiên bản sử dụng bộ nhớ cấp phát động. configSUPPORT_STATIC_ALLOCATION phải được đặt thành 1 trong FreeRTOSConfig.h để xMessageBufferCreateStatic() có sẵn. Chức năng bộ đệm tin nhắn được kích hoạt bằng cách bao gồm tệp nguồn FreeRTOS/source/stream_buffer.c trong quá trình xây dựng (vì bộ đệm tin nhắn sử dụng bộ đệm luồng). Tham số xBufferSizeBytes: Kích thước, tính bằng byte, của bộ đệm được trỏ đến bởi tham số pucMessageBufferStorageArea. Khi một tin nhắn được ghi vào bộ đệm tin nhắn, một số byte sizeof( size_t ) khác cũng được ghi để lưu trữ độ dài của tin nhắn. sizeof( size_t ) thường là 4 byte trên kiến trúc 32-bit, vì vậy trên hầu hết các kiến trúc 32-bit, một tin nhắn 10 byte sẽ chiếm 14 byte trong không gian bộ đệm tin nhắn. Số byte tối đa có thể được lưu trữ trong bộ đệm tin nhắn là (xBufferSizeBytes - 1). pucMessageBufferStorageArea: Phải trỏ đến một mảng uint8_t có ít nhất kích thước xBufferSizeBytes + 1. Đây là mảng mà các tin nhắn được sao chép vào khi chúng được ghi vào bộ đệm tin nhắn. pxStaticMessageBuffer: Phải trỏ đến một mảng uint8_t có ít nhất kích thước xBufferSizeBytes + 1. Đây là mảng mà các tin nhắn được sao chép vào khi chúng được ghi vào bộ đệm tin nhắn. Giá trị trả về Nếu bộ đệm tin nhắn được tạo thành công, thì một handle đến bộ đệm tin nhắn đã tạo được trả về. Nếu pucMessageBufferStorageArea hoặc pxStaticMessageBuffer là NULL, thì NULL được trả về. Ví dụ: /* Used to dimension the array used to hold the messages. The available space will actually be one less than this, so 999. */ #define STORAGE_SIZE_BYTES 1000 /* Defines the memory that will actually hold the messages within the message buffer. Should be one more than the value passed in the xBufferSizeBytes parameter. */ static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ]; /* The variable used to hold the message buffer structure. */ StaticMessageBuffer_t xMessageBufferStruct; void MyFunction( void ) { MessageBufferHandle_t xMessageBuffer; xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucStoragegBuffer ), ucBufferStorage, &xMessageBufferStruct ); /* As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer parameters were NULL, xMessageBuffer will not be NULL, and can be used to reference the created message buffer in other message buffer API calls. */ /* Other code that uses the message buffer can go here. */ } Listing 267: Ví dụ sử dụng hàm xMessageBufferCreateStatic() 9.3 vMessageBufferDelete() #include “FreeRTOS.h” #include “message_buffer.h” void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer ); Listing 268: Nguyên mẫu của hàm vMessageBufferDelete() Tóm tắt: Hàm vMessageBufferDelete() được sử dụng để xóa một message buffer đã được tạo trước đó bằng cách sử dụng hàm xMessageBufferCreate() hoặc x Message Buffer CreateStatic(). Nếu message buffer được tạo bằng cách sử dụng bộ nhớ động (tức là bằng xMessageBufferCreate()), thì bộ nhớ đã được cấp phát sẽ được giải phóng. Một message buffer handle không được sử dụng sau khi message buffer đã bị xóa. Chức năng của message buffer được bật bằng cách bao gồm tệp nguồn FreeRTOS/source/stream_buffer.c trong quá trình biên dịch (vì message buffers sử dụng stream buffers). Tham số: xMessageBuffer: Handle của message buffer cần xóa. 9.4 xMessageBufferIsEmpty() #include “FreeRTOS.h” #include “message_buffer.h” BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ); Listing 269: Nguyên mẫu của hàm xMessageBufferIsEmpty() Tóm tắt: Hàm xMessageBufferIsEmpty() được sử dụng để kiểm tra xem một message buffer có trống không. Một message buffer được coi là trống nếu nó không chứa bất kỳ tin nhắn nào. Chức năng của message buffer được kích hoạt bằng cách bao gồm tệp nguồn FreeRTOS/source/stream_buffer.c trong quá trình biên dịch (vì message buffers sử dụng stream buffers). Tham số: xMessageBuffer: Handle của message buffer được kiểm tra. Giá trị trả về: Nếu message buffer trống, thì hàm trả về pdTRUE. Ngược lại, hàm trả về pdFALSE. 9.5 xMessageBufferIsFull() #include “FreeRTOS.h” #include “message_buffer.h” BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ); Listing 270: Nguyên mẫu của hàm xMessageBufferIsFull() Tóm tắt: Hàm xMessageBufferIsFull() được sử dụng để kiểm tra xem một message buffer có đầy không. Một message buffer được coi là đầy nếu nó không thể chứa thêm bất kỳ tin nhắn nào, bất kể kích thước của chúng, cho đến khi có không gian trống được tạo ra bằng cách xóa một tin nhắn khỏi message buffer. Chức năng của message buffer được kích hoạt bằng cách bao gồm tệp nguồn FreeRTOS/source/stream_buffer.c trong quá trình biên dịch (vì message buffers sử dụng stream buffers). Tham số: xMessageBuffer: Handle của message buffer được kiểm tra. Giá trị trả về: Nếu message buffer đầy, thì hàm trả về pdTRUE. Ngược lại, hàm trả về pdFALSE. 9.6 xMessageBufferReceive() #include “FreeRTOS.h” #include “message_buffer.h” size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ); Listing 271: Nguyên mẫu của hàm xMessageBufferReceive() Tóm tắt: Hàm xMessageBufferReceive() được sử dụng để nhận một tin nhắn từ message buffer của hệ điều hành thời gian thực (RTOS). Tin nhắn có thể có độ dài thay đổi và được sao chép ra khỏi buffer. Tham số: xMessageBuffer: Handle của message buffer từ đó tin nhắn đang được nhận. pvRxData: Con trỏ đến buffer mà tin nhắn nhận được sẽ được sao chép vào. xBufferLengthBytes: Độ dài của buffer được chỉ định bởi tham số pvRxData. Tham số này đặt độ dài tối đa của tin nhắn có thể được nhận. Nếu xBufferLengthBytes quá nhỏ để chứa tin nhắn tiếp theo, thì tin nhắn sẽ được giữ lại trong message buffer và hàm sẽ trả về 0. xTicksToWait: Thời gian tối đa mà tác vụ phải ở trạng thái Blocked để chờ một tin nhắn, nếu message buffer trống khi gọi xMessage Buffer Receive(). Hàm x Message Buffer Receive() sẽ trả về ngay lập tức nếu xTicksToWait là 0 và message buffer trống. Thời gian chờ được xác định theo đơn vị tick, do đó thời gian tuyệt đối tương ứng phụ thuộc vào tần số tick. Macro pdMS_TO_TICKS() có thể được sử dụng để chuyển đổi thời gian từ millisecond sang tick. Đặt xTicksToWait thành portMAX_DELAY sẽ khiến tác vụ chờ mãi mãi (mà không bị timeout), miễn là INCLUDE_vTaskSuspend được đặt thành 1 trong FreeRTOSConfig.h. Các tác vụ không sử dụng bất kỳ thời gian CPU nào khi chúng đang ở trạng thái Blocked. Giá trị trả về: Độ dài, tính bằng byte, của tin nhắn được đọc từ message buffer, nếu có. Nếu xMessageBufferReceive() hết thời gian chờ trước khi có tin nhắn sẵn có, thì hàm trả về 0. Nếu độ dài của tin nhắn lớn hơn xBufferLengthBytes, thì tin nhắn sẽ được giữ lại trong message buffer và hàm trả về 0. Ghi chú: Độc đáo trong các đối tượng FreeRTOS, việc triển khai stream buffer (do đó cũng bao gồm việc triển khai message buffer, vì message buffer được xây dựng trên cơ sở stream buffer) cho rằng chỉ có một tác vụ hoặc ngắt sẽ ghi dữ liệu vào buffer (người viết), và chỉ có một tác vụ hoặc ngắt sẽ đọc dữ liệu từ buffer (người đọc). Việc người viết và người đọc khác nhau có thể an toàn, nhưng, khác với các đối tượng FreeRTOS khác, không an toàn khi có nhiều người viết khác nhau hoặc nhiều người đọc khác nhau. Nếu có nhiều người viết khác nhau, người viết ứng dụng phải đặt mỗi cuộc gọi đến hàm API ghi (như xMessageBufferSend()) trong một phần critical section và phải sử dụng thời gian chờ gửi là 0. Tương tự, nếu có nhiều người đọc khác nhau, người viết ứng dụng phải đặt mỗi cuộc gọi đến hàm API đọc (như xMessageBufferRead()) trong một phần critical section và phải sử dụng thời gian chờ nhận là 0. Sử dụng xMessageBufferReceive() để đọc từ message buffer từ một tác vụ. Sử dụng xMessageBufferReceiveFromISR() để đọc từ message buffer từ một hàm ngắt (ISR). Chức năng message buffer được kích hoạt bằng cách bao gồm tệp nguồn FreeRTOS/source/stream_buffer.c trong quá trình biên dịch (vì message buffer sử dụng stream buffer). Ví dụ: void vAFunction( MessageBuffer_t xMessageBuffer ) { uint8_t ucRxData[ 20 ]; size_t xReceivedBytes; const TickType_t xBlockTime = pdMS_TO_TICKS( 20 ); /* Receive the next message from the message buffer. Wait in the Blocked state (so not using any CPU processing time) for a maximum of 100ms for a message to become available. */ xReceivedBytes = xMessageBufferReceive( xMessageBuffer, ( void * ) ucRxData, sizeof( ucRxData ), xBlockTime ); if( xReceivedBytes > 0 ) { /* A ucRxData contains a message that is xReceivedBytes long. Process the message here.... */ } } Listing 272: Ví dụ về việc sử dụng hàm xMessageBufferReceive().