Similarities and differences between FreeRTOS message queue delivery structure pointer and structure

Original link: https://blog.csdn.net/weixin_44333597/article/details/107523343

1 similarities and differences between message queue delivery structure pointer and structure

1.1 using queues to deliver composite data types

When receiving a message sent from multiple sending sources to the queue, the receiver needs to judge the source of the data. The usage method: use the queue to transfer the structure, which contains the data value and data source information.

typedef struct
{
    int  iValue;  //Data value
    int iMeaning; //Data source information
}xData;

1.2 pointer of data passing through queue (faster processing speed)

1. The ownership of the memory space pointed to by the pointer must be clear

Before the pointer of the shared memory is sent to the queue, its contents are only allowed to be accessed by the sent task;

After the shared memory pointer is read from the queue, its contents are only allowed to be accessed by the receiving task

2. The memory space pointed to by the pointer must be valid

The memory space pointed to by the pointer is dynamically allocated. Only one task should release the memory. When this memory space is released, no other task should access this space again.

//Pass pointer to structure
/* Create 10 message queues for storing pointer variables. Since the CM3/CM4 kernel is a 32-bit machine, one pointer variable occupies 4 bytes */
xQueue2 = xQueueCreate(10, sizeof(struct Msg *));    //The cell size is the size of a pointer variable

//Send message to realize the transmission of structure pointer 
MSG_T   *ptMsg;        //MSG_T is the structure declaration
ptMsg = &g_tMsg;   /* Initialize structure pointer */
// Initialize array 
    ptMsg->ucMessageID = 0;
    ptMsg->ulData[0] = 0;
    ptMsg->usData[0] = 0;
//Using message queue to transfer pointer variables 
 if(xQueueSend(xQueue2,                  /* Message queue handle */
               (void *) &ptMsg,           // Send the address "&" of the structure pointer variable ptMsg, take the address of the structure pointer, and pass the pointer
               (TickType_t)10) != pdPASS )
     
//Receive the message and receive the pointer of the structure
MSG_T *ptMsg; //Define a structure pointer
xResult = xQueueReceive(xQueue2,            /* Message queue handle */
                       (void *)&ptMsg,      // The address of the structure is obtained here, similar to char *a="stm";char *b;b=a pointer assignment, a and B point to the same address
                       (TickType_t)xMaxBlockTime);/* Set blocking time */
if(xResult == pdPASS)
            {
                /* Successfully received and printed the data through the serial port */
                printf("Message queue data received ptMsg->ucMessageID = %d\r\n",ptMsg->ucMessageID);
                printf("Message queue data received ptMsg->ulData[0] = %d\r\n", ptMsg->ulData[0]);
                printf("Message queue data received ptMsg->usData[0] = %d\r\n", ptMsg->usData[0]);
            }     

//Transfer structure itself
//Create a message queue
xQueue2 = xQueueCreate(10, sizeof(struct Msg));  //The unit size is the size of the structure  

//Send message to realize the transmission of structure 
MSG_T   ptMsg;       //MSG_T is the structure declaration
//Initialize array
    ptMsg.ucMessageID = 0;
    ptMsg.ulData[0] = 0;
    ptMsg.usData[0] = 0;
 //Using message queue to transfer pointer variables
 if(xQueueSend(xQueue2,                  /* Message queue handle */
               (void *) &ptMsg,           // Send the value of structure ptMsg and copy the value to the queue
               (TickType_t)10) != pdPASS )
     
//Receive the message and receive the value of the structure
MSG_T ptMsg; //Define a structure pointer
xResult = xQueueReceive(xQueue2,            
                       (void *)&ptMsg,      // What you get here is the value of the structure
                       (TickType_t)xMaxBlockTime);/* Set blocking time */

if(xResult == pdPASS)
            {
                /* Successfully received and printed the data through the serial port */
                printf("Message queue data received ptMsg.ucMessageID = %d\r\n",ptMsg.ucMessageID);
                printf("Message queue data received ptMsg.ulData[0] = %d\r\n", ptMsg.ulData[0]);
                printf("Message queue data received ptMsg.usData[0] = %d\r\n", ptMsg.usData[0]);
            }     

1.3 similarities and differences between transfer structure pointer and structure itself

  1. When creating a message queue, the cell size declaration is different

  2. Variable initialization is different. One is to define the pointer and the structure entity assigned is global, and the other is to define the structure

  3. The data output is different. The former uses the pointer member operator "- >", and the latter uses the structure member operator

  4. When sending a message and a request message, the format is the same, but the meaning is different. The former passes the address of the structure pointer, and the latter passes the value of the structure

Vtask delay() relative delay function
Macro PDMS_ TO_ Tips() can be used to convert the time specified in milliseconds to the time specified in ticks. For example, calling vtask delay (pdms_to_tips (100)) will keep the task blocked for 100 milliseconds.

Macro definition#define     pdMS_TO_TICKS( xTimeInMs )     
  ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )

When a task is blocked, it does not use CPU.
Definition: each delay starts when the task executes the vtask delay() function and ends after a certain delay.

vTaskDelay( pdMS_TO_TICKS( 100 ) );  //Delay 100ms

Tags: C data structure IoT FreeRTOS MCU

Posted on Wed, 03 Nov 2021 02:31:15 -0400 by tzikis