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

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.event_id = event_id; 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) { System_Event_T 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?

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.event_id = event_id; 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) { System_Event_T 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?

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?

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.