Passing struct to a FreeRTOS task

zazas321
Posts: 231
Joined: Mon Feb 01, 2021 9:41 am

Passing struct to a FreeRTOS task

Postby zazas321 » Tue Jan 25, 2022 6:59 am

Hello. I need to pass struct to FreeRTOS task and I have a question. My struct is declared:

Code: Select all

struct __attribute__((__packed__))long_packet_s
{
    uint8_t* payload;
    uint8_t length;
    uint16_t conn_id;
    uint8_t op_code;
    uint8_t message_id;
    esp_gatt_if_t gatt_if;
    interface_select_e interface;
    bool heap_allocation;
};

In my BLE message parser, I parse a message and then depending on the message I start a one shot task. For example:

Code: Select all

        case(GET_EVENTS):
        {
            printf("get events \n");
            if(payload_length != 0){
                printf("payload length invalid \n");
                break;
            }
            
            long_packet_s message_struct;
            message_struct.conn_id = conn_id;
            message_struct.gatt_if = gatts_if;
            message_struct.message_id = message_id;
            message_struct.op_code = op_code;
            message_struct.heap_allocation = false;
            message_struct.interface = BLE;

            printf("message_struct.conn_id before task =%u \n",message_struct.conn_id);
            printf("message_struct.gatt_if before task =%u \n",message_struct.gatt_if);

                if(xSemaphoreTake(spi_mutex,100)==pdTRUE){
                    uint16_t alarms_written_since_last_read = EEPROM_get_alarms_written_since_last_read(external_eeprom);
                    printf("events written since last read = %u \n",alarms_written_since_last_read);
                    if(alarms_written_since_last_read>=1){
                        xTaskCreate(BLE_long_packet_task_alarms,"ALARM TASK",10000,&message_struct,1,&BLE_long_alarms_handle);
                    }
                    else{
                        printf("no alarms registered \n");
                        xSemaphoreGive(spi_mutex);
                    }  
                }
                else{
                    printf("semaphore is busy alarms \n");
                }
        break;
        }
       
However, inside the task, the conn_id and gatt_if are different. Is this because I have created my long_packet_s message_struct on the ble parser and it is no longer available inside my task?

1. What is the correct way of accesing the structure from the task. I have seen 2 methods:

Code: Select all

void BLE_long_packet_task_alarms(void* param){
            long_packet_s* packet = (long_packet_s*)param;
            ..
            ..
            ..
and

Code: Select all

void BLE_long_packet_task_alarms(void* param){
    long_packet_s packet = *(long_packet_s*)param;
    ..
    ..
    ..
Could someone help me understand what is the difference of the above two and which one should I use?


2. If I cannot pass the structure with the method described above. What are the other ways to pass a structure? Should I declare it as global?
Last edited by zazas321 on Tue Jan 25, 2022 12:12 pm, edited 1 time in total.

limpens
Posts: 13
Joined: Tue Jan 25, 2022 9:14 am

Re: Passing struct to a FreeRTOS task

Postby limpens » Tue Jan 25, 2022 9:23 am

Hi,

the syntax you are referring to:

Code: Select all

long_packet_s* packet = (long_packet_s*)param;
is my normal way of passing structures.

You do know you are printf'ing from a different variable than the variable object you are passing to the xTaskCreate call?
It looks like you are inspecting the

Code: Select all

global_message
and passing

Code: Select all

message_struct
My variables passed to different/multiple tasks always live in the context of my main function, you are sure the message_struct is not created in another function?

FWIW: this shouldn't be resolved by (evil) global variables.

zazas321
Posts: 231
Joined: Mon Feb 01, 2021 9:41 am

Re: Passing struct to a FreeRTOS task

Postby zazas321 » Tue Jan 25, 2022 12:14 pm

Hey. Thank you for the response. There was a typo regarding global_message.
How can I ensure that my long_packet_s message_struct does not get cleared from stack? I think this is what happens what I create the struct and pass it to the task because what I print inside the task and what I print before creating a task is different.

Who is online

Users browsing this forum: Bing [Bot] and 88 guests