Quality RTOS & Embedded Software

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




Loading

FreeRTOS on Concerto F28M35H52C1 problems

Posted by Patrick Harris on May 11, 2012
Is anyone using FreeRTOS on the TI Concerto chip? I'm having problems with tasks and queues. Anyone having any success?

RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Richard on May 11, 2012
There is no official code for the Concerto, but I know that FreeRTOS is used by a number of people on the CM3 side, and all the standard FreeRTOS Cortex-M3 ports (for the various compilers) should not give any problems. There is no official code for the C2000 side though.

Can you explain the problem you are having?

RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Patrick Harris on May 11, 2012
Thanks for your response, Richard.
I started my development by using a limited example program from TI that sends messages from one node to another. In doing this, TI used their own RTOS for the C28 DSP side and FreeRTOS to implement the message handling on the CM3 side. They provided 2 sets of tasks to serrvice the IPC ram and to handle the data received and to prepare data for transmission. The IPC handler uses a software interrupt to communicate intent / alert to the other side.
As this demo did not include any actual interaction with the outside world, I added tasks to handle the UART Tx and Rx along with ring buffers to accumulate serial data. The procedure is pretty basic - collect serial data, convert it to the proper format and pass it to a PLC (power line communication) network. My original intent was to use an interrupt to receive all UART input, but when I added that interrupt to the program, the operation hangs (the uart demo program works fine when run by itself). So, to work around for the time being, I just use the UART tasks to collect and send serial data. This should work, I believe, as I am only running at 38400 baud.
There are several general uncertainties in this system, those being the new chip, the stability of CCSv4 (I have been advised not to use CCSv5 for this chip), and my inexperience with FreeRTOS. I am simply trying to eliminate uncertainties in order to narrow down the problem.
Using FreeRTOS, I set up queues to transfer messages from one task to another. I have tested this transfer and have found that the data placed onto the queue is not the same as the data taken off the queue - usually just zeros. I assume this is just a bug on my part, but I modeled my implementation of the queues according to those in the example that appeared to be working.
Here is the initialization code for all tasks and queues. You might take a look and see if anything appears irregular? Thanks:

// tasks to pass data through the IPC
void IPC_Task_init(void)
{
portBASE_TYPE rtn_code;

// init IPC driver - init interrupt in cm3_ipc_driver.c
CM3_IPC_init();

// create the semaphore for RX HCT sync
vSemaphoreCreateBinary(xBinaryIPCRxSema4);

// create the IPC HCT TX queue
xQueueIPCHctTx = xQueueCreate(CM3_IPC_HCT_TX_QUEUE_SIZE,sizeof(CM3_IPC_HCT_MSG_s));

if (xQueueIPCHctTx == NULL)
{ // can not create the queue, increase the heap size
CM3_IPC_hnd.err_create_queue++;
return;
}

// create the CM3 IPC TX task
rtn_code = xTaskCreate( vCM3_IPC_tx_task, ( signed portCHAR * ) "CM3_IPC_TX",
CM3_IPC_TX_TASK_STACK_SIZE, NULL, CM3_IPC_TX_TASK_PRIORITY + 3, NULL );
if (rtn_code !=pdPASS)
{
SysCall_Error();
}

// create the CM3 IPC RX task
rtn_code = xTaskCreate( vCM3_IPC_rx_task, ( signed portCHAR * ) "CM3_IPC_RX",
CM3_IPC_RX_TASK_STACK_SIZE, NULL, CM3_IPC_RX_TASK_PRIORITY + 3, NULL );
if (rtn_code !=pdPASS)
{
SysCall_Error();
}
}

// tasks to handle data for HTC
void HCT_Task_init(void)
{
portBASE_TYPE rtn_code;
memset(&Uart0_data,0,sizeof(Uart0_data));
Uart0_ptr=0;
// create the HCT TX queue to post msgs from COM / other to IPC
xQueueHCT_Example_TX = xQueueCreate(HCT_EXAMPLE_TX_QUEUE_SIZE,sizeof(CM3_IPC_HCT_MSG_s));
if (xQueueHCT_Example_TX == NULL)
{
UARTSend("xQueueHCT_Example_TX fail",25);
return ;
}

rtn_code=xTaskCreate( vHCT_Example_TX_task, ( signed portCHAR * ) "HCT_tx",
CM3_HCT_Example_TASK_STACK_SIZE, NULL,
CM3_HCT_Example_TASK_PRIORITY + 3, NULL );
if (rtn_code !=pdPASS)
{
SysCall_Error();
}
// create the msg queue for example RX task
// create the IPC HCT TX queue
xQueueHCT_Example_RX = xQueueCreate(HCT_EXAMPLE_RX_QUEUE_SIZE,sizeof(CM3_IPC_HCT_MSG_s));
if (xQueueHCT_Example_RX == NULL)
{
UARTSend("xQueueHCT_Example_RX fail",25);
return ;
}

rtn_code=xTaskCreate( vHCT_Example_RX_task, ( signed portCHAR * ) "HCT_rx",
CM3_HCT_Example_TASK_STACK_SIZE, NULL,
CM3_HCT_Example_TASK_PRIORITY + 3, NULL );

if (rtn_code !=pdPASS)
{
SysCall_Error();
}
}

// initialize COM tasks to service uart0 input from interrupt and output data from queue
void COM_Task_init(void)
{
portBASE_TYPE rtn_code;

RingBufInit((tRingBufObject *)&uart0_rb_rx, UART_RX_buffer,UART_BUF_SIZE);
RingBufInit((tRingBufObject *)&uart0_rb_tx, UART_TX_buffer,UART_BUF_SIZE);
// RX task to create message from uart input and send to HCT
rtn_code=xTaskCreate( vCOM_RX_task, ( signed portCHAR * ) "COM_rx",
COM_RX_TASK_STACK_SIZE, NULL,
COM_RX_TASK_PRIORITY + 3, NULL );
if (rtn_code !=pdPASS)
{
SysCall_Error();
}

// TX task to output from circ buf to uart port until finished
rtn_code=xTaskCreate( vCOM_TX_task, ( signed portCHAR * ) "COM_tx",
COM_TX_TASK_STACK_SIZE, NULL,
COM_TX_TASK_PRIORITY + 3, NULL );
if (rtn_code !=pdPASS)
{
SysCall_Error();
}

}

RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Patrick Harris on May 11, 2012
Added note: As you can see, all of the priorities are the same. I have added vTaskDelay times of 20ms to all tasks except the UART tasks as I believe the delay will prevent the task from re-running until that time has passed and I want UART data to serviced as fast as possible. Is that logic correct?
Thanks,
Pat

RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Richard on May 11, 2012
Looking at the init code there is nothing obviously wrong - although I cannot see what the task stack sizes are. Maybe you could post the interrupt code? Or the code writing to and reading form the queues (please use the "codify" tags when you post code so the formatting is maintained) as it would not be easy to get different data out of a queue to that put in, unless you had complete RAM corruption somewhere.

Generically, I can tell you the most likely cause of any interrupt related problem is going to be, because the majority of problems on Cortex-M class microcontrollers turns out to be this, and that is interrupt priorities.

You must ensure that your UART interrupt priority is equal to or lower than configMAX_SYSCALL_INTERRUPT_PRIORITY, which is defined in FreeRTOSConfig.h. When you do that, remember that Cortex-M devices are arse backwards, in that the lower the number you assign to an interrupt priority the higher priority of the interruptis. So 1 is a very high priority, despite being a very low number. Absolutely never leave interrupt priorities unassigned if the interrupt handler uses FreeRTOS calls because by default it will definitely be above configMAX_SYSCALL_INTERRUPT_PRIORITY.

Then also check out http://www.FreeRTOS.org/FAQHelp.html for information on other common problems, like calling API functions that don't end in FromISR from the interrupt handler, and checking for stack overflow, etc.

Regards.


RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Patrick Harris on May 11, 2012
Richard,
I tried setting uart and ipc priorities lower, higher, and finally equal to FreeRTOS, but it still hangs

// from echo demo
// Enable processor interrupts.
IntMasterEnable();

// Set GPIO E4 and E5 as UART pins.
GPIOPinTypeUART(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5);
GPIOPinConfigure(GPIO_PE4_U0RX);
GPIOPinConfigure(GPIO_PE5_U0TX);

// Configure the UART for 115,200, 8-N-1 operation.
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(SYSTEM_CLOCK_SPEED), 38400,
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));

// Enable the UART interrupt.
IntRegister(INT_UART0, UARTIntHandler);
// set the priority lower than FreeRTOS
//! The hardware priority mechanism will only look at the upper N bits of the
//! priority level (where N is 3 for the Concerto family), so any
//! prioritization must be performed in those bits. The remaining bits can be
IntPrioritySet(INT_UART0,160);

IntEnable(INT_UART0);
UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);


Here is the init stuff for the tasks:

// COM tasks config data
#define COM_RX_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + 80 )
#define COM_TX_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + 80)

/* Task priorities. */
#define COM_RX_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define COM_TX_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )

//#define COM_RX_QUEUE_SIZE(4)
#define COM_TX_QUEUE_SIZE(4)

hct:
/* The OLED task uses the sprintf function so requires a little more stack too. */
#define CM3_HCT_Example_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + 80 )

/* Task priorities. */
#define CM3_HCT_Example_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define HCT_EXAMPLE_RX_QUEUE_SIZE (4)
#define HCT_EXAMPLE_TX_QUEUE_SIZE (4)


uart:
// COM tasks config data
#define COM_RX_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + 80 )
#define COM_TX_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE + 80)

/* Task priorities. */
#define COM_RX_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
#define COM_TX_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )

//#define COM_RX_QUEUE_SIZE(4)
#define COM_TX_QUEUE_SIZE(4)


config file:
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/

#define configUSE_PREEMPTION1
#define configUSE_IDLE_HOOK0
#define configUSE_TICK_HOOK1
#define configCPU_CLOCK_HZ( ( unsigned long ) 75000000 )
#define configTICK_RATE_HZ( ( portTickType ) 1000 )
#define configMINIMAL_STACK_SIZE( ( unsigned short ) 80 )
#define configTOTAL_HEAP_SIZE( ( size_t ) ( 6000 ) )
#define configMAX_TASK_NAME_LEN( 12 )
#define configUSE_TRACE_FACILITY0
#define configUSE_16_BIT_TICKS0
#define configIDLE_SHOULD_YIELD0
#define configUSE_CO_ROUTINES 0
#define configUSE_MUTEXES1
#define configCHECK_FOR_STACK_OVERFLOW2
#define configUSE_RECURSIVE_MUTEXES1
#define configQUEUE_REGISTRY_SIZE10
#define configGENERATE_RUN_TIME_STATS0

#define configMAX_PRIORITIES( ( unsigned portBASE_TYPE ) 5 )
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */

#define INCLUDE_vTaskPrioritySet1
#define INCLUDE_uxTaskPriorityGet1
#define INCLUDE_vTaskDelete1
#define INCLUDE_vTaskCleanUpResources0
#define INCLUDE_vTaskSuspend0
#define INCLUDE_vTaskDelayUntil1
#define INCLUDE_vTaskDelay1
#define INCLUDE_uxTaskGetStackHighWaterMark1



#define configKERNEL_INTERRUPT_PRIORITY ( ( unsigned char ) 7 << ( unsigned char ) 5 )/* Priority 7, or 255 as only the top three bits are implemented. This is the lowest priority. */
//#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( ( unsigned char ) 5 << ( unsigned char ) 5 ) /* Priority 5, or 160 as only the top three bits are implemented. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 160

#if (0)
extern volatile unsigned long ulHighFrequencyTimerTicks;
/* There is already a high frequency timer running - just reset its count back
to zero. */
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() ( ulHighFrequencyTimerTicks = 0UL )
#define portGET_RUN_TIME_COUNTER_VALUE()ulHighFrequencyTimerTicks
#endif





RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Patrick Harris on May 12, 2012
And here's task code with posts and semaphore


UINT16 HCT_Example_TX_Task_Post(UINT16 msg_type, UINT16 msg_tag, UINT16 msg_len, UINT8 *pbuf)
{
// portTickType xDelay = 20/ portTICK_RATE_MS;

CM3_IPC_HCT_MSG_s ipcMsg; // condense HCT_MSG_HD_s to shorter structure
portBASE_TYPE rtn_code;
ipcMsg.pbuffer = pbuf;
// combine upper 4 bits of type and lower 8 bits of tag. type = 0 is IPC message, IPC tag = 0
ipcMsg.msg_type_tag = (msg_type & HCT_MSG_TYPE_MASK) | (msg_tag & HCT_MSG_TAG_MASK); //0x00ff,0xf000
ipcMsg.msg_len = msg_len;

// post message without wait
rtn_code = xQueueSendToBack(xQueueHCT_Example_TX,&ipcMsg, 0); //xDelay);
if (rtn_code == errQUEUE_FULL)
{ // error to post message, free
UARTSend("HCT_TX_Queue_full",17);
return 1;
}

return 0;

}

// TX HCT data to IPC then WL
void vHCT_Example_TX_task( void *pvParameters )
{
//#ifdef IPC_PHY_TX_TEST
portTickType xDelay = 20/ portTICK_RATE_MS;
//#endif
portBASE_TYPE rtn_code;
CM3_IPC_HCT_MSG_s ipcMsg; //ipcMsg; //

// Loop forever
while(1)
{
// wireline message queue, sends type_tag, len, and pbuf
rtn_code = xQueueReceive(xQueueHCT_Example_TX,(void *)&ipcMsg,portMAX_DELAY);

if ((rtn_code == errQUEUE_EMPTY))//&&(!PSG_set))
{
continue;
}

if (ipcMsg.msg_len > 0) //(PSG_set)
{
hct_cnt.tx_msg++;
// send message to wireline - replace with input message
HCT_Data_Transfer((UINT8*) ipcMsg.pbuffer, (UINT16) ipcMsg.msg_len);
}

// IPC PHY TX test is a compiler pre-define for TX build only
#ifdef IPC_PHY_TX_TEST

Toggle_LED(LED_3);
Toggle_LED(LED_AFE_1);

#endif

// wait the message queue
vTaskDelay( xDelay );

hct_cnt.tx_msg++;

}

}




// Example usage:msgs rcvd from IPC are placed on the HCT queue
UINT16 HCT_Example_RX_Task_Post(UINT16 msg_type, UINT16 msg_tag, UINT16 msg_len, UINT8 *pbuf)
{
CM3_IPC_HCT_MSG_s hctMsg; // condense HCT_MSG_HD_s to shorter structure
portBASE_TYPE rtn_code;
hctMsg.pbuffer = pbuf;
// combine upper 4 bits of type and lower 8 bits of tag. type = 0 is IPC message, IPC tag = 0
hctMsg.msg_type_tag = (msg_type & HCT_MSG_TYPE_MASK) | (msg_tag & HCT_MSG_TAG_MASK); //0x00ff,0xf000
hctMsg.msg_len = msg_len;
// memcpy(hctMsg.pbuffer,pbuf,hctMsg.msg_len);

// post message without wait
rtn_code = xQueueSendToBack(xQueueHCT_Example_RX,&hctMsg, 0);

if (rtn_code == errQUEUE_FULL)
{ // error to post message, free

return 1;
}

return 0;

}

void vHCT_Example_RX_task( void *pvParameters )
{
portBASE_TYPE rtn_code;
CM3_IPC_HCT_MSG_s hctMsg; // tag,len,pbuf
// init the task
portTickType xDelay = 20/ portTICK_RATE_MS;
// data from C28 -> IPC queue -> IPC-RX -> HCT queue -> HCT RX -> here
// or from uart

// Loop forever
while(1)
{

// clear temp buffer
memset(&hctMsg,0,sizeof(hctMsg));
rtn_code = errQUEUE_EMPTY;
#ifndef IPC_PHY_TX_TEST //RX task

// wireline message queue, returns tag, len, and pbuf
rtn_code = xQueueReceive(xQueueHCT_Example_RX,(void *)&hctMsg,portMAX_DELAY);
if ((rtn_code != errQUEUE_EMPTY) && (hctMsg.msg_len > 2)) // process queue with WL input data
{
// process WL input msg here
// send complete message to wireline as echo test
// post onto HCT TX to IPC TX to WL TX
HCT_Example_TX_Task_Post(HCT_MSG_TYPE_DATA_TRANSFER, 0, (UINT16)hctMsg.msg_len, (UINT8*)hctMsg.pbuffer);

if ((hct_cnt.rx_msg & 0xf) == 8)
{
// test output

Toggle_LED(LED_2);
Toggle_LED(LED_AFE_2);
Toggle_LED(LED_PLCD_4);
}
}
#endif
// else there may be uart input
if (rtn_code == errQUEUE_EMPTY)
{

// if no WL data, then OK to TX UART data to WL
if (!RingBufEmpty((tRingBufObject *) &uart0_rb_rx))
{
while (!RingBufEmpty((tRingBufObject *) &uart0_rb_rx))
{
Uart0_data[Uart0_ptr++] = RingBufReadOne(&uart0_rb_rx);
}
}

// verify PLUS or GPS msg from uart input
int rslt;
if (Uart0_ptr > 0)
{
rslt = Verify_msg(Uart0_data,&Uart0_ptr);
if ( (rslt == PLUS) || (rslt == GPS))
{
// send complete message to wireline
// post onto TX for WL
HCT_Example_TX_Task_Post(HCT_MSG_TYPE_DATA_TRANSFER, 0, (UINT16)Uart0_ptr, (UINT8*)Uart0_data);

// msg complete, reset buffer
Uart0_ptr=0;
memset(Uart0_data,0,sizeof(Uart0_data));
#ifndef IPC_PHY_TX_TEST //RX task getting uart input - rare

// test output

Toggle_LED(LED_2);
Toggle_LED(LED_AFE_3);
Toggle_LED(LED_PLCD_5);

#endif
}
else if (rslt == 0)
{
Uart0_ptr = 0; // bad msg, restart
memset(Uart0_data,0,sizeof(Uart0_data));
}
// else only partial msg, keep collecting data


}
}// end of test for errQue

Toggle_LED(LED_AFE_3);
hct_cnt.rx_msg++;
vTaskDelay( xDelay );
} // end while
}

//
// Define the COM_Rx task to input data from the com port and send to the HCT_RX task.
void vCOM_RX_task( void *pvParameters )
{
// init the task
UINT8 dat;
// portTickType xDelay = 20/ portTICK_RATE_MS;
// Loop forever
while(1)
{
// Read the next character from the UART
dat = (UINT8)UARTCharGetNonBlocking(UART0_BASE);
// put on ring buffer
RingBufWriteOne(&uart0_rb_rx,dat);
// or just echo directly

Toggle_LED(LED_AFE_2);
// UARTSendByte(RingBufUsed(&uart0_rb_rx));
com_cnt.rx_msg++;
// vTaskDelay( xDelay );
}
}

//
// define COM TX task to output msg from TX ring buffer to com0 port
void vCOM_TX_task( void *pvParameters)
{
// init the task
//portTickType xDelay = 20/ portTICK_RATE_MS;
// Loop forever
while(1)
{
while (!RingBufEmpty((tRingBufObject *) &uart0_rb_tx))
{
UARTSendByte(RingBufReadOne(&uart0_rb_tx));
}
// vTaskDelay( xDelay );
com_cnt.tx_msg++;
}
}


void CM3_Post_HCT_RX_Semaphore(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
portBASE_TYPE rtn_code;

rtn_code = xSemaphoreGiveFromISR(xBinaryIPCRxSema4,&xHigherPriorityTaskWoken);

if (rtn_code == pdFAIL)
{
CM3_IPC_hnd.err_post_sema4++;
}
}


void vCM3_IPC_rx_task( void *pvParameters )
{
portBASE_TYPE rtn_code;
portTickType xDelay = 20/ portTICK_RATE_MS;

// init the task
// fake take the semaphore because it is available when created
xSemaphoreTake(xBinaryIPCRxSema4,0);

// Loop forever
while(1)
{
// wait the semaphore from interrupt
rtn_code = xSemaphoreTake(xBinaryIPCRxSema4,portMAX_DELAY);

if (rtn_code == pdFALSE)
{
CM3_IPC_hnd.err_get_sema4++;
continue;
}
vTaskDelay( xDelay );

// get the message from IPC RAM
CM3_IPC_HCT_Receive_Packet();

// CM3 is ready to receive
CM3_IPC_setStat(1);
}

}


//msg from HCT is posted onto the IPC queue for TX to C28
UINT16 CM3_IPC_HCT_TX_Task_Post(UINT16 msg_type, UINT16 msg_tag, UINT16 msg_len, UINT8 *pbuf)
{
CM3_IPC_HCT_MSG_s hctMsg;
portBASE_TYPE rtn_code;

CM3_IPC_hnd.tx_post_msg++;

hctMsg.pbuffer = pbuf;
hctMsg.msg_type_tag = (msg_type & HCT_MSG_TYPE_MASK) | (msg_tag & HCT_MSG_TAG_MASK);
hctMsg.msg_len = msg_len;

// post message without wait
rtn_code = xQueueSendToBack(xQueueIPCHctTx,&hctMsg, 0);

if (rtn_code == errQUEUE_FULL)
{ // error to post message, free
CM3_IPC_hnd.err_send_queue_full++;
UARTSend("IPC_ERR",7);
return 1;
}

return 0;
}


// task to send HCT to IPC and C28
void vCM3_IPC_tx_task( void *pvParameters )
{
portBASE_TYPE rtn_code;
CM3_IPC_HCT_MSG_s hctMsg;
// init the task
portTickType xDelay = 20/ portTICK_RATE_MS;

// Loop forever
while(1)
{
// wait the message queue -
rtn_code = xQueueReceive(xQueueIPCHctTx,(void *)&hctMsg,portMAX_DELAY);

if (rtn_code == errQUEUE_EMPTY)
{
CM3_IPC_hnd.err_receive_queue_empty++;
// how long to wait??
continue;
}

// send the HCT message to C28 and set the interrupt for service
CM3_IPC_Send_HCT_Msg(&hctMsg);

vTaskDelay( xDelay );


}

}

void CM3_IPC_HCT_RX_ISR(void)
{
// stat
CM3_IPC_hnd.rx_isr++;

// mark CM3 is busy
CM3_IPC_setStat(0);

// post semaphore to task
CM3_Post_HCT_RX_Semaphore();

// Acknowledge IPC INT3 from C28 to ACK
HWREG(MTOCIPC_BASE + IPC_O_CTOMIPCACK) |= IPC_CTOMIPCACK_IPC3;
}




RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Richard on May 12, 2012
Not sure, again from my skimming of the code there does not appear to be anything obviously wrong.

Regards.

RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Patrick Harris on May 12, 2012
Passing a structure to a queue should not cause a problem, then?

RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Richard on May 13, 2012
“Passing a structure to a queue should not cause a problem, then?”

That should not be a problem. The queue sends in your code are sending the same size of structure used to dimension each queue when the queue is created, as far as I can see.

You have to be careful though. For example, you have the following line:

“ipcMsg.pbuffer = pbuf;”


and then post ipcMsg to a queue, with the message pbuffer member containing a pointer to pbuf, and pbuf is a parameter being passed in to the function. Where is pbuf defined, and does it still exist when you get the message out the other end of the queue? You have only copied a pointer to a buffer into your structure, not the contents of the buffer, so if the buffer being pointed to no longer exists (maybe it was on a task stack?) or if the contents of the buffer have been modified since the structure was sent to the queue, then what you read out of the buffer will differ to what the buffer contained when the message was created.

Regards.

RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Patrick Harris on May 14, 2012
Richard,
Thanks for the advice, but the buffer in question is defined as a global buffer, so I don't think that is the problem. Here is a detailed example of the issue:
Notice in the post that I output the message length anf then the final character of the message (in this case 0x0f and 0xd0) as a test. Then, in the task, I output again. The first and second outputs give me 0f 0d and 0f 0d. The third gives me 0f 00.


// msgs from COM or other are posted to the IPC TX task
UINT16 HCT_Example_TX_Task_Post(UINT16 msg_type, UINT16 msg_tag, UINT16 msg_len, UINT8 *pbuf)
{
// portTickType xDelay = 20/ portTICK_RATE_MS;

CM3_IPC_HCT_MSG_s ipcMsg, ipcMsg2; // condense HCT_MSG_HD_s to shorter structure
portBASE_TYPE rtn_code;
ipcMsg.pbuffer = pbuf;
// combine upper 4 bits of type and lower 8 bits of tag. type = 0 is IPC message, IPC tag = 0
ipcMsg.msg_type_tag = (msg_type & HCT_MSG_TYPE_MASK) | (msg_tag & HCT_MSG_TAG_MASK); //0x00ff,0xf000
ipcMsg.msg_len = msg_len;
// post message without wait
rtn_code = xQueueSendToBack(xQueueHCT_Example_TX,&ipcMsg, 0); //xDelay);
xQueuePeek( xQueueHCT_Example_TX, (void*)&ipcMsg2, 0 ) ;
COM_TX_byte(ipcMsg.msg_len);
COM_TX_byte(ipcMsg.pbuffer[msg_len-1]);
COM_TX_byte(ipcMsg2.msg_len);
COM_TX_byte(ipcMsg2.pbuffer[msg_len-1]);
//COM_TX(ipcMsg.pbuffer, (UINT8) ipcMsg.msg_len);
if (rtn_code == errQUEUE_FULL)
{ // error to post message, free
// UARTSend("HCT_TX_Queue_full",17);
return 1;
}
return 0;

}

// TX HCT data to IPC then WL
void vHCT_Example_TX_task( void *pvParameters )
{
//#ifdef IPC_PHY_TX_TEST
portTickType xDelay = 10/ portTICK_RATE_MS;
//#endif
// memset(&hct_cnt,0,sizeof(hct_cnt));
portBASE_TYPE rtn_code;
CM3_IPC_HCT_MSG_s ipcMsg; //ipcMsg; //
// Loop forever
while(1)
{
// wireline message queue, sends type_tag, len, and pbuf
rtn_code = xQueueReceive(xQueueHCT_Example_TX,(void *)&ipcMsg,portMAX_DELAY);

if ((rtn_code != errQUEUE_EMPTY))//&&(!PSG_set))
{
COM_TX_byte((UINT8)ipcMsg.msg_len);
COM_TX_byte((UINT8)ipcMsg.pbuffer[ipcMsg.msg_len - 1]);
//continue;
// }
// IPC PHY TX test is a compiler pre-define for TX build only
//#ifdef IPC_PHY_TX_TEST
// process plus cmd : test broadcast or verify ID, service IO, response
// if update, then respond with data
//WL_msg_format((UINT8*)ipcMsg.pbuffer, (UINT8) ipcMsg.msg_len);
// if this node is PSG, then send msg to CCUs. If node is CCU, then send responses to PSG
// use WL_cmd_format
if (ipcMsg.msg_len > 2) //(PSG_set)
{
hct_cnt.tx_msg++;
// send message to wireline - replace with input message
HCT_Data_Transfer((UINT8*) ipcMsg.pbuffer, (UINT16) ipcMsg.msg_len);
}

// IPC PHY TX test is a compiler pre-define for TX build only
#ifdef IPC_PHY_TX_TEST

Toggle_LED(LED_3);
Toggle_LED(LED_AFE_1);
// Toggle_LED(LED_AFE_3);
// Toggle_LED(LED_PLCD_4);

#endif
}
// wait the message queue
vTaskDelay( xDelay );

hct_cnt.tx_msg++;

}

}


RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Patrick Harris on May 14, 2012
Caveat:
I may have two problems:
When I output the full message as a test, I only receive 17 chars total. My buffers are set to 200. a count of 17 is reached, I receive no more characters until the next test input. I've tried adjusting blocking delays, task priorities .. but can't seem to get any more chars at a time. Plus, when I extract the chars from the queue, all the values except the length are set to zero (to do this, I turn off the pre-queue msg output and turn on the post-queue msg output). All the data has been zeroed. There are no other accesses to this queue.
Any insight here would be most helpful.
Thanks,
Pat

RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Richard on May 15, 2012
I'm not sure I'm following your explanation exactly, but I can look at the code, which is not complex and does not contain apparent errors. Although obviously there is an error somewhere, it could be external to these code snippets (memory allocation problem, heap crashing into stack, something overwriting your global buffer, etc.).

In the code you just posted, you set up a message that contains a length value, and a pointer to something you previously stated was a global buffer. This message is then sent to a queue, and received by another task. The receiving task then looks at the message length field - ignoring the characters in the buffer (which were never sent down the queue, only a pointer to them was) when the receiving task reads the length field, is that correct? When it reads the pointer to the global buffer, does the pointer actually point to the global buffer as expected?

Regards.

RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Patrick Harris on May 15, 2012

Three screen shots with the code used and variations in the code. Without loading the queue, the test output of data is correct. The queue call was commented out. See comments between each example. What am I doing wrong?
Thanks




CM3_IPC_HCT_MSG_s htxMsg;
// msgs from COM or other are posted to the IPC TX task
UINT16 HCT_Example_TX_Task_Post(UINT16 msg_type, UINT16 msg_tag, UINT16 msg_len, UINT8 *pbuf)
{

portBASE_TYPE rtn_code;
htxMsg.pbuffer = pbuf;
// combine upper 4 bits of type and lower 8 bits of tag. type = 0 is IPC message, IPC tag = 0
htxMsg.msg_type_tag = (msg_type & HCT_MSG_TYPE_MASK) | (msg_tag & HCT_MSG_TAG_MASK); //0x00ff,0xf000
htxMsg.msg_len = msg_len;
// post message without wait
COM_TX(htxMsg.pbuffer, (UINT8) htxMsg.msg_len);
// rtn_code = xQueueSendToBack(xQueueHCT_Example_TX,&htxMsg, 0); //xDelay);
// xQueuePeek( xQueueHCT_Example_TX, (void*)&ipcMsg2, portMAX_DELAY ) ;



Adding the queue call following the test output corrupts the data, in many cases shortening to 17 bytes. I thought this was a uart problem originally, but it now appears to be related to the queue.





CM3_IPC_HCT_MSG_s htxMsg;
// msgs from COM or other are posted to the IPC TX task
UINT16 HCT_Example_TX_Task_Post(UINT16 msg_type, UINT16 msg_tag, UINT16 msg_len, UINT8 *pbuf)
{
portBASE_TYPE rtn_code;
htxMsg.pbuffer = pbuf;
// combine upper 4 bits of type and lower 8 bits of tag. type = 0 is IPC message, IPC tag = 0
htxMsg.msg_type_tag = (msg_type & HCT_MSG_TYPE_MASK) | (msg_tag & HCT_MSG_TAG_MASK); //0x00ff,0xf000
htxMsg.msg_len = msg_len;
// post message without wait
COM_TX(htxMsg.pbuffer, (UINT8) htxMsg.msg_len);
rtn_code = xQueueSendToBack(xQueueHCT_Example_TX,&htxMsg, 0);
// xQueuePeek( xQueueHCT_Example_TX, (void*)&ipcMsg2, portMAX_DELAY ) ;



I then “peeked” at the queue data to see what was there and found it to be essentially the same as the one above. The send to queue buffer is global and the peek buffer is local. Why is the data corrupted??? I’m obviously missing something here.





CM3_IPC_HCT_MSG_s htxMsg;
// msgs from COM or other are posted to the IPC TX task
UINT16 HCT_Example_TX_Task_Post(UINT16 msg_type, UINT16 msg_tag, UINT16 msg_len, UINT8 *pbuf)
{

CM3_IPC_HCT_MSG_s ipcMsg2;
portBASE_TYPE rtn_code;
htxMsg.pbuffer = pbuf;
// combine upper 4 bits of type and lower 8 bits of tag. type = 0 is IPC message, IPC tag = 0
htxMsg.msg_type_tag = (msg_type & HCT_MSG_TYPE_MASK) | (msg_tag & HCT_MSG_TAG_MASK); //0x00ff,0xf000
htxMsg.msg_len = msg_len;
// post message without wait
//COM_TX(htxMsg.pbuffer, (UINT8) htxMsg.msg_len);
rtn_code = xQueueSendToBack(xQueueHCT_Example_TX,&htxMsg, 0); //xDelay);
xQueuePeek( xQueueHCT_Example_TX, (void*)&ipcMsg2, portMAX_DELAY ) ;
COM_TX(ipcMsg2.pbuffer, (UINT8) ipcMsg2.msg_len);


RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Patrick Harris on May 15, 2012
Sorry about the images. Is there a code for images from a file / word document?


RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Richard on May 16, 2012
There is a lot to look through here, and I am not following it well. Maybe it will be clearer with the screen shots.

Some people have managed to get images included in the text, I have never tried myself, but am experimenting here using the "Add Image" button above the text intput. Lets see what happens...



it looks like you have to put a URL between tags, so the image has to be available online.

Regards.

RE: FreeRTOS on Concerto F28M35H52C1 problems

Posted by Patrick Harris on May 17, 2012
NOTE: The initialiation code for the tasks is at the bottom of this message.


// to summarize, this task shows the problem I am having. I can post to the TX task by loading the queue. After doing this, I output the data and it is correct.
But, when I instead, output the data after unloading the queue, the data is all zeros (however the message length (ipcMsg.msg_len) is correct. Just the ipcMsg.pbuffer data outputs as all zeros. As you can see, the posting function uses a global structure and the task uses an local version.
This has confounded me for too long. What am I doing wrong??? I am programming the Concerto chip, TI's F28M35H52C1 using CCSv4.2.5 on a WinXP machine.
Thanks for any help.


CM3_IPC_HCT_MSG_s ipcMsg;
// msgs from COM or other are posted to the IPC TX task
UINT16 HCT_Example_TX_Task_Post(UINT16 msg_type, UINT16 msg_tag, UINT16 msg_len, UINT8 *pbuf)
{
// portTickType xDelay = 20/ portTICK_RATE_MS;
// CM3_IPC_HCT_MSG_s ipcMsg; // condense HCT_MSG_HD_s to shorter structure
portBASE_TYPE rtn_code;
ipcMsg.pbuffer = pbuf;
// combine upper 4 bits of type and lower 8 bits of tag. type = 0 is IPC message, IPC tag = 0
ipcMsg.msg_type_tag = (msg_type & HCT_MSG_TYPE_MASK) | (msg_tag & HCT_MSG_TAG_MASK); //0x00ff,0xf000
ipcMsg.msg_len = msg_len;
// post message without wait
rtn_code = xQueueSendToBack(xQueueHCT_Example_TX,&ipcMsg, 0); //xDelay);
// xQueuePeek( xQueueHCT_Example_TX, &ipcMsg, ( portTickType ) 10 ) ;
//COM_TX_byte((UINT8)msg_len);
//COM_TX(ipcMsg.pbuffer, (UINT8) ipcMsg.msg_len);
if (rtn_code == errQUEUE_FULL)
{ // error to post message, free
UARTSend("HCT_TX_Queue_full",17);
return 1;
}
return 0;

}

// TX HCT data to IPC then WL
void vHCT_Example_TX_task( void *pvParameters )
{
//#ifdef IPC_PHY_TX_TEST
portTickType xDelay = 10/ portTICK_RATE_MS;
//#endif
// memset(&hct_cnt,0,sizeof(hct_cnt));
portBASE_TYPE rtn_code;
CM3_IPC_HCT_MSG_s htxMsg; //ipcMsg; //
// Loop forever
while(1)
{
// wireline message queue, sends type_tag, len, and pbuf
rtn_code = xQueueReceive(xQueueHCT_Example_TX,(void *)&htxMsg,portMAX_DELAY);

if ((rtn_code == errQUEUE_EMPTY))//&&(!PSG_set))
{
continue;
}
// IPC PHY TX test is a compiler pre-define for TX build only
//#ifdef IPC_PHY_TX_TEST
// process plus cmd : test broadcast or verify ID, service IO, response
// if update, then respond with data
//WL_msg_format((UINT8*)htxMsg.pbuffer, (UINT8) htxMsg.msg_len);
// if this node is PSG, then send msg to CCUs. If node is CCU, then send responses to PSG
// use WL_cmd_format
if (htxMsg.msg_len > 2) //(PSG_set)
{
hct_cnt.tx_msg++;
COM_TX_byte((UINT8)htxMsg.msg_len);
COM_TX((UINT8*)htxMsg.pbuffer,(UINT8)htxMsg.msg_len);
// send message to wireline - replace with input message
HCT_Data_Transfer((UINT8*) &htxMsg, (UINT16) htxMsg.msg_len);
}

// IPC PHY TX test is a compiler pre-define for TX build only
#ifdef IPC_PHY_TX_TEST

Toggle_LED(LED_3);
// Toggle_LED(LED_AFE_1);
// Toggle_LED(LED_AFE_3);
// Toggle_LED(LED_PLCD_4);

#endif

// wait the message queue
vTaskDelay( xDelay );

hct_cnt.tx_msg++;

}

}

// here are the initializations for all three sets of tasks. The one of particular interest is the HCT task, but it utilizes the ring buffer that is initialized in the COM task. Also, the COM task is used to output all test data.


// tasks to pass data through the IPC
void IPC_Task_init(void)
{
portBASE_TYPE rtn_code;

// init IPC driver - init interrupt in cm3_ipc_driver.c
CM3_IPC_init();

// create the semaphore for RX HCT sync
vSemaphoreCreateBinary(xBinaryIPCRxSema4);

// create the IPC HCT TX queue
xQueueIPCHctTx = xQueueCreate(CM3_IPC_HCT_TX_QUEUE_SIZE,sizeof(CM3_IPC_HCT_MSG_s));

if (xQueueIPCHctTx == NULL)
{ // can not create the queue, increase the heap size
CM3_IPC_hnd.err_create_queue++;
return;
}

// create the CM3 IPC TX task
rtn_code = xTaskCreate( vCM3_IPC_tx_task, ( signed portCHAR * ) "CM3_IPC_TX",
CM3_IPC_TX_TASK_STACK_SIZE, NULL, CM3_IPC_TX_TASK_PRIORITY + 3, NULL );
if (rtn_code !=pdPASS)
{
SysCall_Error();
}

// create the CM3 IPC RX task
rtn_code = xTaskCreate( vCM3_IPC_rx_task, ( signed portCHAR * ) "CM3_IPC_RX",
CM3_IPC_RX_TASK_STACK_SIZE, NULL, CM3_IPC_RX_TASK_PRIORITY + 3, NULL );
if (rtn_code !=pdPASS)
{
SysCall_Error();
}
}

// tasks to handle data for HTC
void HCT_Task_init(void)
{
portBASE_TYPE rtn_code;
memset(&Uart0_data,0,sizeof(Uart0_data));
Uart0_ptr=0;
// create the HCT TX queue to post msgs from COM / other to IPC
xQueueHCT_Example_TX = xQueueCreate(HCT_EXAMPLE_TX_QUEUE_SIZE,sizeof(CM3_IPC_HCT_MSG_s));
if (xQueueHCT_Example_TX == NULL)
{
UARTSend("xQueueHCT_Example_TX fail",25);
return ;
}

rtn_code=xTaskCreate( vHCT_Example_TX_task, ( signed portCHAR * ) "HCT_tx",
CM3_HCT_Example_TASK_STACK_SIZE, NULL,
CM3_HCT_Example_TASK_PRIORITY + 3, NULL );
if (rtn_code !=pdPASS)
{
SysCall_Error();
}
// create the msg queue for example RX task
// create the IPC HCT TX queue
xQueueHCT_Example_RX = xQueueCreate(HCT_EXAMPLE_RX_QUEUE_SIZE,sizeof(CM3_IPC_HCT_MSG_s));
if (xQueueHCT_Example_RX == NULL)
{
UARTSend("xQueueHCT_Example_RX fail",25);
return ;
}

rtn_code=xTaskCreate( vHCT_Example_RX_task, ( signed portCHAR * ) "HCT_rx",
CM3_HCT_Example_TASK_STACK_SIZE, NULL,
CM3_HCT_Example_TASK_PRIORITY + 3, NULL );

if (rtn_code !=pdPASS)
{
SysCall_Error();
}
}

// initialize COM tasks to service uart0 input from interrupt and output data from queue
void COM_Task_init(void)
{
portBASE_TYPE rtn_code;

RingBufInit((tRingBufObject *)&uart0_rb_rx, UART_RX_buffer,UART_BUF_SIZE);
RingBufInit((tRingBufObject *)&uart0_rb_tx, UART_TX_buffer,UART_BUF_SIZE);
// RX task to create message from uart input and send to HCT
rtn_code=xTaskCreate( vCOM_RX_task, ( signed portCHAR * ) "COM_rx",
COM_RX_TASK_STACK_SIZE, NULL,
COM_RX_TASK_PRIORITY + 3, NULL );
if (rtn_code !=pdPASS)
{
SysCall_Error();
}

// TX task to output from circ buf to uart port until finished
rtn_code=xTaskCreate( vCOM_TX_task, ( signed portCHAR * ) "COM_tx",
COM_TX_TASK_STACK_SIZE, NULL,
COM_TX_TASK_PRIORITY + 3, NULL );
if (rtn_code !=pdPASS)
{
SysCall_Error();
}

}







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




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

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

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

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

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists