Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

How to send a pointer to a character string to a task queue?

Posted by m4l490n on February 16, 2015

Hello everybody.

I need to send some ascii character strings from one task to another.

I need to send not the string but the address of the first character (as a reference to the string) to another task. The reason I want to send "a reference" to the string and not the string is because I may have a string as long as 250 characters, or maybe more, and I don't want the queue send routine to be copying all the 250+ characters every time a message has to be sent.

As I'm dealing with shared memory then there is no problem about sending pointers and this is a more efficient approach since the FreeRTOS queue send routine just copies 4 bytes (the size of the pointer to the first characters from the string to be sent) instead the n characters in the string.

The function for sending this messages is as follows:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

static char* msg_location = NULL; /* global memory so its contents doesn't corrupt */

void TRTrace(const char *const string) { sizet stringSize = 0;

/* Get the string size to create the dinamyc memory storage */ stringSize = strlen(string);

msg_location = pvPortMalloc(stringSize + 1);

/* Now copy the text to the newly created buffer */ strcpy(msg_location, string);

SystemEventsSendtoTask(SYSTEMTASKTRTraceTask, TREVSENDTRACEMSG, &msg_location, sizeof(char *)); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The "SystemEventsSendtoTask" is a system task I created and I use it to send events to any task. Since the events may have data then this routine helps to abstract the process. Don't pay attention to everything as I just put this for you to see this "intermediate" step in the character string sending.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bool SystemEventsSendtoTask(SystemTasksT desttask, SystemEventsIDsT eventid, void *data, sizet size) { bool eventsent = false; portBASETYPE sendstatus; SystemEvent_T event;

if(NULL != SystemQueueHandlesArray[desttask]) { /* Fill the system event struct with the data from the parameters */ event.eventid = eventid; event.data = data; event.data_size = size;

  /* Send the event to the selected Events Queue */
  send_status = xQueueSend(System_Queue_Handles_Array[dest_task],
                           &event,
                           (QUEUE_SEND_WAIT_TIME / portTICK_RATE_MS));

  /* Check if the event was sent */
  if (pdPASS == send_status)
  {
     event_sent = true;
  }
  else
  {
     event_sent = false;
  }

} else { /* If the queue is not created yet then the transfer is signaled as failed */ event_sent = false; }

return event_sent; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Ok then, the problem I'm facing is that in the receiving task I'm getting an "Invalid Address" when triyng to get the address sent in the "TR_Trace" routine. I get this Invalid address error when single stepping in the debug session.

Here is the way I'm trying to recover the address.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void TRTraceTask(void pvParameters) { SystemEventT bb_event; /**< Variable to read the events received by the task */ char temp_ptr;

...

while(1) { xQueueReceive(TraceMessageQueue, &bbevent, portMAXDELAY);

 switch (bb_event.event_id)
 {
    case TR_EV_SEND_TRACE_MSG:
    {
       temp_ptr = (char*)bb_event.data; /* THE PROBLEM IS HERE! */

       strcpy(DMATxBuffer, (const char *)temp_ptr);

       DmaChnStartTxfer(TRACE_TX_DMA_CHANNEL, DMA_WAIT_NOT, TX_TRANSMISSION_RETRIES);

       /* The memory allocated and being pointed to by the var "temp_ptr"
        * is freed */
       vPortFree((void *)temp_ptr);

       break;
    }

    default:
    {
       break;
    }
 }

}

...

} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Maybe I'm not dereferencing properly or I don't know what is happening.

Any Ideas?

Regards.


How to send a pointer to a character string to a task queue?

Posted by bowerymarc on February 16, 2015

You probably want to do this:

SystemEventsSendtoTask(SYSTEMTASKTRTraceTask,
TREVSENDTRACEMSG, msg_location, sizeof(char *));

the value of msg_location is the address of the string.

also you are creating a local variable ‘event’ that then disappears off the stack once the function exits, but you’re queueing the address of it, which will probably be garbage once it’s dequeued.

M

On Feb 16, 2015, at 5:16 PMEST, Manuel Malagon m4l490n@users.sf.net wrote:

Hello everybody.

I need to send some ascii character strings from one task to another.

I need to send not the string but the address of the first character (as a reference to the string) to another task. The reason I want to send "a reference" to the string and not the string is because I may have a string as long as 250 characters, or maybe more, and I don't want the queue send routine to be copying all the 250+ characters every time a message has to be sent.

As I'm dealing with shared memory then there is no problem about sending pointers and this is a more efficient approach since the FreeRTOS queue send routine just copies 4 bytes (the size of the pointer to the first characters from the string to be sent) instead the n characters in the string.

The function for sending this messages is as follows:

static char* msg_location = NULL; /* global memory so its contents doesn't corrupt */

void TRTrace(const char *const string) { sizet stringSize = 0;

/* Get the string size to create the dinamyc memory storage */ stringSize = strlen(string);

msg_location = pvPortMalloc(stringSize + 1);

/* Now copy the text to the newly created buffer */ strcpy(msg_location, string);

SystemEventsSendtoTask(SYSTEMTASKTRTraceTask, TREVSENDTRACEMSG, &msglocation, sizeof(char *)); } The "SystemEventsSendto_Task" is a system task I created and I use it to send events to any task. Since the events may have data then this routine helps to abstract the process. Don't pay attention to everything as I just put this for you to see this "intermediate" step in the character string sending.

bool SystemEventsSendtoTask(SystemTasksT desttask, SystemEventsIDsT eventid, void *data, sizet size) { bool eventsent = false; portBASETYPE sendstatus; SystemEvent_T event;

if(NULL != SystemQueueHandlesArray[desttask]) { /* Fill the system event struct with the data from the parameters */ event.eventid = eventid; event.data = data; event.data_size = size;

  /* Send the event to the selected Events Queue */
  send_status = xQueueSend(System_Queue_Handles_Array[dest_task],
                           &event,
                           (QUEUE_SEND_WAIT_TIME / portTICK_RATE_MS));

  /* Check if the event was sent */
  if (pdPASS == send_status)
  {
     event_sent = true;
  }
  else
  {
     event_sent = false;
  }

} else { /* If the queue is not created yet then the transfer is signaled as failed */ event_sent = false; }

return eventsent; } Ok then, the problem I'm facing is that in the receiving task I'm getting an "Invalid Address" when triyng to get the address sent in the "TRTrace" routine. I get this Invalid address error when single stepping in the debug session.

Here is the way I'm trying to recover the address.

void TRTraceTask(void pvParameters) { SystemEventT bb_event; /**< Variable to read the events received by the task */ char temp_ptr;

...

while(1) { xQueueReceive(TraceMessageQueue, &bbevent, portMAXDELAY);

 switch (bb_event.event_id)
 {
    case TR_EV_SEND_TRACE_MSG:
    {
       temp_ptr = (char*)bb_event.data; /* THE PROBLEM IS HERE! */

       strcpy(DMATxBuffer, (const char *)temp_ptr);

       DmaChnStartTxfer(TRACE_TX_DMA_CHANNEL, DMA_WAIT_NOT, TX_TRANSMISSION_RETRIES);

       /* The memory allocated and being pointed to by the var "temp_ptr"
        * is freed */
       vPortFree((void *)temp_ptr);

       break;
    }

    default:
    {
       break;
    }
 }

}

...

} Maybe I'm not dereferencing properly or I don't know what is happening.

Any Ideas?

Regards.

How to send a pointer to a character string to a task queue?

Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/freertos/discussion/382005/

To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/


How to send a pointer to a character string to a task queue?

Posted by m4l490n on February 17, 2015

also you are creating a local variable ‘event’ that then disappears off the stack once the function exits, but you’re queueing the address of it, which will probably be garbage once it’s dequeued.

This is not the case because the "event.eventid" is never corrupted. When dequeueing I always have the ".eventid" right but I don't know why the ".data" is always 0.

And the freertos queue routine is supposed to copy the contents of this local variable so that is another reason why that may not be the problem.


How to send a pointer to a character string to a task queue?

Posted by davedoors on February 17, 2015

Is it because of this line -

SystemEventsSendtoTask(SYSTEMTASKTRTraceTask, TREVSENDTRACEMSG, &msg_location, sizeof(char *));

msglocation is a pointer that points to a string. You are passing the address of the variable (&msglocation), not the address the pointer is pointing to.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS