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 TR
Trace(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);
System
EventsSend
toTask(SYSTEM
TASKTR
TraceTask,
TR
EVSEND
TRACEMSG,
&msg_location, sizeof(char *));
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The “System
EventsSend
toTask” 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 System
EventsSend
toTask(System
TasksT dest
task,
SystemEvents
IDsT event
id,
void *data, sizet size)
{
bool event
sent = false;
portBASETYPE send
status;
SystemEvent_T event;
if(NULL != System
QueueHandles
Array[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 TR
TraceTask(void *pvParameters)
{
System_Event_T bb_event; /**< Variable to read the events received by the task */
char* temp_ptr;
…
while(1)
{
xQueueReceive(TraceMessageQueue, &bb
event, 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.