ThreadX — message queue of IPC application

Time:2021-6-7

1、 Application Introduction

Message queuingIt is a common way of data communication in RTOS, which is often used for data transmission between tasks or between interrupts and tasks. In bare metal systems, we usually use global variables to transfer data. For example, after an event occurs, we change the data and set flags in the interrupt, and then we poll the main loop to see if different flags are effective to perform different operations on the global data. After the execution, we clear the relevant flags. However, this method needs to constantly poll the flag state, so that the CPU utilization is not high. The message queue using RTOS has the task blocking mechanism. When there is no message to be processed, the task will hang and wait for the message. At this time, other tasks will occupy the CPU to perform other operations. When there is a message put into the queue, the task will resume to receive and process the message. Compared with bare metal, this message processing mechanism greatly improves CPU utilization.

  • ThreadXThe message queue of RT thread supports the function of “message top notification”, that is, the message can be placed at the top of the queue, so that the task can process some urgent messages in time (RT thread message queue also has this function)
  • ThreadXThe message queue of UCOS can deliver data of any length, because it uses the way of passing data pointer (UCOS also uses this way of reference delivery, while FreeRTOS and RT thread support the delivery of the whole data content. These two methods have their own advantages and disadvantages. Pointer transfer method has the advantage of high efficiency, but the disadvantage is that if the memory area where the data is stored is not processed in time, it will cause problems; The advantage of the overall data transfer method is that it is safe and does not need to worry about data rewriting errors. The disadvantage is that if the data volume is large, the execution time of the data transfer process is long, resulting in low efficiency.)

2、 API introduction

Here’s how to use itThreadXSeveral API functions commonly used in message queuing.

1. Create message queue

  • describe
    • This service is used to create message queues. The total number of messages is calculated based on the specified message size and the total number of bytes in the queue
    • If the total number of bytes specified in the memory area of the queue cannot be evenly divided by the specified message size, the remaining bytes in that memory area are not used
  • parameter
    • queue_ptrPointer to the message queuing control block
    • name_ptrPointer to the name of the message queue
    • message_sizeSpecifies the size of each message in the queue. The message size option is between 1 32-bit word and 16 32-bit words (inclusive)
    • queue_startThe starting address of the message queue. The starting address must be aligned with the size of the ulong data type
    • queue_sizeThe total number of bytes available for message queuing
  • Return value
    • TX_SUCCESS(0x00) created successfully
    • TX_QUEUE_ERROR(0x09) invalid message queue pointer, null pointer or queue created
    • TX_PTR_ERROR(0x03) the starting address of message queue is invalid
    • TX_SIZE_ERROR(0x05) invalid message queue size
    • TX_CALLER_ERROR(0x13) the caller of the service is invalid
UINT tx_queue_create(
    TX_QUEUE *queue_ptr, 
    CHAR *name_ptr,
    UINT message_size,
    VOID *queue_start, 
    ULONG queue_size);

2. Delete message queue

  • describe
    • This service removes the specified message queue. All threads suspended waiting for this queue message will resume and TX will be given_ Deleted return status
    • Before deleting a queue, the application must ensure that all send for this queue has been completed (or disabled)_ Notify callback. In addition, the application must prevent future use of deleted queues
    • The application is also responsible for managing the memory area associated with the queue, which is available after the service completes
  • parameter
    • queue_ptrPointer to a previously created message queue
  • Return value
    • TX_SUCCESS(0x00) deleted successfully
    • TX_QUEUE_ERROR(0x09) invalid message queue pointer
    • TX_CALLER_ERROR(0x13) the caller of the service is invalid
UINT tx_queue_delete(TX_QUEUE *queue_ptr);

3. Clear message queue

  • describe
    • This service removes all messages stored in the specified message queue
    • If the queue is full, the messages of all suspended threads are discarded, and then each suspended thread is restored with a return state indicating that the message was sent successfully. If the queue is empty, the service does nothing.
  • parameter
    • queue_ptrPointer to a previously created message queue
  • Return value
    • TX_SUCCESS(0x00) operation successful
    • TX_QUEUE_ERROR(0x09) invalid message queue pointer
UINT tx_queue_flush(TX_QUEUE *queue_ptr);

4. Top news

  • describe
    • The service sends messages to the front of the specified message queue. The message is copied from the storage area specified by the source pointer to the front of the queue
  • parameter
    • queue_ptrPointer to the message queuing control block
    • source_ptrPointer to the message to be stored
    • wait_optionDefines the behavior of the service when the message queue is full
      • TX_NO_WAIT(0x00000000) – returns immediately regardless of success (for non threaded calls, such as interrupts)
      • TX_WAIT_FOREVER(0xFFFFFF) – wait until the message queue is free
  • Return value
    • TX_SUCCESS(0x00) operation successful
    • TX_DELETED(0x01) the message queue is deleted when the thread is suspended
    • TX_QUEUE_FULL(0x0b) the service cannot send the message because the queue is full within the specified waiting time
    • TX_WAIT_ABORTED(0x1a) interrupted by another thread, timer or ISR
    • TX_QUEUE_ERROR(0x09) invalid message queue pointer
    • TX_PTR_ERROR(0x03) invalid source pointer for message
    • TX_WAIT_ERROR(0x04) TX is specified in a non threaded call_ NO_ Waiting options other than wait
UINT tx_queue_front_send(
    TX_QUEUE *queue_ptr,
    VOID *source_ptr, 
    ULONG wait_option);

5. Get message queue information

  • describe
    • The service retrieves information about the specified message queue
  • parameter(TX_ Null indicates that the information represented by this parameter does not need to be obtained.)
    • queue_ptrPointer to a previously created message queue
    • namePointer to the target, which is used to point to the queue name
    • enqueuedPointer to the target, which represents the number of messages in the current queue
    • available_storagePointer to the target, indicating the number of messages that the queue currently has space to hold
    • first_suspendedPointer to the target, which points to the first thread in the queue’s pending list
    • suspended_countPointer to the target that indicates the number of threads currently suspended on this queue
    • next_queuePointer to the next target to create a pointer to the queue
  • Return value
    • TX_SUCCESS(0x00) operation successful
    • TX_QUEUE_ERROR(0x09) invalid message queue pointer
UINT tx_queue_info_get(
    TX_QUEUE *queue_ptr, 
    CHAR **name,
    ULONG *enqueued, 
    ULONG *available_storage
    TX_THREAD **first_suspended, 
    ULONG *suspended_count,
    TX_QUEUE **next_queue);

6. Get message from queue

  • describe
    • The service retrieves messages from the specified message queue. The retrieved message is copied from the queue to the storage area specified by the destination pointer. The message is then removed from the queue
    • The specified destination store must be large enough to hold messages. In other words, bydestination_ptrThe message destination pointed to must be at least as large as the message size of this queue. Otherwise, if the target is not large enough, illegal memory address errors will occur in the storage area
  • parameter
    • queue_ptrPointer to a previously created message queue
    • destination_ptrPoints to the address where the message is stored
    • wait_optionDefines the behavior of a message queue as a space-time service
      • TX_NO_WAIT(0x00000000) – returns immediately regardless of success (for non threaded calls, such as interrupts)
      • TX_WAIT_FOREVER(0xFFFFFF) – wait until a message is available
      • 0x00000001 ~ 0xFFFFFFFE-Specify the specific number of waiting heartbeat beats (if the heartbeat rate is 1kHz, the unit is MS)
  • Return value
    • TX_SUCCESS(0x00) operation successful
    • TX_DELETED(0x01) the message queue was deleted when the thread was suspended
    • TX_QUEUE_EMPTYThe (0x0a) service could not retrieve the message because the queue was empty for the specified waiting period
    • TX_WAIT_ABORTED(0x1a) interrupted by another thread, timer or ISR
    • TX_QUEUE_ERROR(0x09) invalid message queue pointer
    • TX_PTR_ERROR(0x03) invalid destination pointer for message
    • TX_WAIT_ERROR(0x04) TX is specified in a non threaded call_ NO_ Waiting options other than wait
UINT tx_queue_receive(
    TX_QUEUE *queue_ptr,
    VOID *destination_ptr, 
    ULONG wait_option);

7. Send message to queue

  • describe
    • This service sends messages to the specified message queue. The sent message is copied from the memory area specified by the source pointer to the queue.
  • parameter
    • queue_ptrPointer to a previously created message queue
    • source_ptrPointer to message
    • wait_optionDefines the behavior of the service when the message queue is full
      • TX_NO_WAIT(0x00000000) – returns immediately regardless of success (for non threaded calls, such as interrupts)
      • TX_WAIT_FOREVER(0xFFFFFF) – wait until there is a space in the queue for the message
      • 0x00000001 ~ 0xFFFFFFFE-Specify the specific number of waiting heartbeat beats (if the heartbeat rate is 1kHz, the unit is MS)
  • Return value
    • TX_SUCCESS(0x00) operation successful
    • TX_DELETED(0x01) the message queue was deleted when the thread was suspended
    • TX_QUEUE_FULL(0x0b) the service cannot send the message because the queue is full within the specified waiting time
    • TX_WAIT_ABORTED(0x1a) interrupted by another thread, timer or ISR
    • TX_QUEUE_ERROR(0x09) invalid message queue pointer
    • TX_PTR_ERROR(0x03) invalid destination pointer for message
    • TX_WAIT_ERROR(0x04) TX is specified in a non threaded call_ NO_ Waiting options other than wait
UINT tx_queue_send(
    TX_QUEUE *queue_ptr,
    VOID *source_ptr, 
    ULONG wait_option);

8. Register send notification callback function

  • describe
    • This service registers a notification callback function that is called whenever a message is sent to a specified queue. The processing of notification callbacks is defined by the application
    • It is not allowed to call the ThreadX API with a pause option in the notification sending callback function of the application queue.
  • parameter
    • queue_ptrPointer to a previously created queue
    • queue_send_notifyPointer to the send notification function of the application queue. If this value is TX_ Null, the notification is disabled
  • Return value
    • TX_SUCCESS(0x00) operation successful
    • TX_QUEUE_ERROR(0x09) invalid queue pointer
    • TX_FEATURE_NOT_ENABLED(0xff) the notification function is disabled
UINT tx_queue_send_notify(
    TX_QUEUE *queue_ptr,
    VOID (*queue_send_notify)(TX_QUEUE *));

3、 Example demonstration

  • The application instance creates three tasks and a queue message sending notification callback
  • Task 1: press key 1 once to send a message (single variable message) to message queue 1
  • Task 2: press key 2 once to send a message (structure pointer message) to message queue 2
  • Task 3: send messages to message queue 3; Receive the message of task 1 and task 2 and print out the message content
  • Callback function: output message queue 3 related information

Create message queue

#define DEMO_ STACK_ SIZE         (2 * 1024)
void tx_ application_ define(void *first_ unused_ memory)

Task 1

void    thread_ 0_ entry(ULONG thread_ input)

Task 2

void    thread_ 1_ entry(ULONG thread_ input)

Task 3

void    thread_ 2_ entry(ULONG thread_ input)

Send queue message callback function

void    queue3_ send_ notify(TX_ QUEUE *input)

Task 1 presentation results

Task 2 presentation results

Task 3 presentation results

Note: about using segger_ For RTT printing function, please refer to this note:https://www.cnblogs.com/zzssdd2/p/14162382.html