Dear sirs
We have some problems working with vision SDK. Let me explain it.
We are working with vision SDK on TDA3MV. We changed SDK a little bit to make it handle several CAN messages IDs. There are the changes we made:
in utils_dcan.c:
static Void Utils_dcanRxProcessMailbox(dcanRxMsgObj_t * dcanRxMsg,
UInt postedEvents)
{
Int i;
dcanMsg_t *rxMsg = NULL;
struct dcanQueMsgs_s * queMsg = NULL;
for (i = 0; i < dcanConfig.rxMsgIdCnt/*UTILS_ARRAYSIZE(dcanRxMbxId)*/; i++) // changes
{
if (postedEvents & (0x1U << i))
{
while (Utils_queGetQueuedCount(&dcanRxMsg->rxMsgQ[i].handle))
{
Utils_dcanQueGet(&dcanRxMsg->rxMsgQ[i].handle,
&queMsg,
&rxMsg,
DCAN_MSG_STATE_IN_RX_QUE,
DCAN_MSG_STATE_MSG_RX);
dcanRxMsg->state = DCAN_RX_TSK_STATE_RXMSGCALLBACK;
Utils_dcanRxMsgProcess(rxMsg);
Utils_dcanQuePut(&dcanRxMsg->freeQ.handle,
queMsg,
DCAN_MSG_STATE_IN_FREEQ);
Utils_dcanConfigRxMsgObj(dcanRxMbxId[i]);
}
}
}
}
in system_dcan.c
static Void System_dcanInitCfgStruct(dcanConfig_t * dcanConfig)
{
Int i;
UInt8 msgData[] = {0xAA,0xEE,0xBB,0xFF,0xCC,0xDD,0x55,0xAA};
dcanConfig->enableLoopback = FALSE;
dcanConfig->enablePeriodicTx = FALSE;
dcanConfig->rxMsgId[0] = 0xC1;
dcanConfig->rxMsgId[1] = 0xC2;
dcanConfig->rxMsgId[2] = SPEED_ID;
dcanConfig->rxMsgId[3] = TURN_ID;
dcanConfig->rxMsgId[4] = WHEEL_ID;
dcanConfig->rxMsgId[5] = 0x7D4;
dcanConfig->rxMsgId[6] = 0x7D5;
dcanConfig->rxMsgIdCnt = 7;
dcanConfig->txMsgId = 0x7C4;
dcanConfig->enableSendRxAck = FALSE;
dcanConfig->enableReceiveRxAck = FALSE;
dcanConfig->txAckMsgId = 0xC4;
dcanConfig->rxAckMsgId = 0xC5;
dcanConfig->rxMsgCb = System_dcanRxMsgHandler;
dcanConfig->rxAckMsgCb = System_dcanRxAckMsgHandler;
dcanConfig->txMsgPeriod_ms = SYSTEM_DCAN_TX_PRD_MS;
dcanConfig->dcanCntrlIntrId = SYSTEM_DCAN_INTR_ID;
dcanConfig->dcanTxTskPri = SYSTEM_DCAN_TX_TSK_PRI;
dcanConfig->dcanRxTskPri = SYSTEM_DCAN_RX_TSK_PRI;
dcanConfig->dcanInputClk_hz = SYSTEM_DCAN_INPUT_CLK;
dcanConfig->dcanBaudRate_hz = SYSTEM_DCAN_BIT_RATE;
dcanConfig->enableTxMsgCycle = FALSE;
dcanConfig->dcanTxPrdMsg.dataLength = UTILS_ARRAYSIZE(msgData);
for ( i = 0 ; i < UTILS_ARRAYSIZE(msgData); i++)
{
dcanConfig->dcanTxPrdMsg.msgData[i] = msgData[i];
}
}
static Void System_dcanRxMsgHandler(dcanMsg_t *rxMsg)
{
if (rxMsg->appMsgPrms.dataLength)
{
canCall(rxMsg->msgId,(char*)rxMsg->appMsgPrms.msgData, rxMsg->appMsgPrms.dataLength);
}
}
Now we are using use-cases on ipu-1.0 kernel, and receiving and processing CAN messages on ipu-1.1 kernel. Purpose is to create separete task on ipu-1.1 and process CAN mesages from queue which we are filling in the interrupt handler:
void Ipu11Init(void) // Task_1 creation
{
Task_Params_init(¶ms);
params.stackSize = 10 * 1024;
params.priority = 5U;
params.affinity = 0x1;
params.stack = &gSwUserBuffer[0];
Task1 = Task_create(Task_1, ¶ms, NULL);
}
void CanRx(UInt32 id, char* data, int len) // interrupt handler function
{
if (id == certain ID)
{
Msg* msg = Utils_memAlloc(UTILS_HEAPID_DDR_CACHED_SR, sizeof(Msg_1), 32); // memory allocation for queue element
memcpy(&msg->data[0], data, len);
msg->len = len;
msg->id = id;
Queue_put(Queue_1, &msg->_elem);
}
}
void Task_1(UArg arg0, UArg arg1) // task to process CAN messages with certain ID
{
while (1)
{
Queue_1 = Queue_create(NULL, NULL);
System_dcanStart(CanRx);
start();
}
}
In start() function there is infinity cicle were we use Queue_empty() and Queue_put() to get and process messages form Queue_1. After receiving we procrssing it and send recponce to CAN. The problem is: if we send messages with only one ID, regardless how hight messages rate is (for example 2 messages per second) everething is OK, but if during that time we also send a messages with some other ID (even with lower rate), task stops to respond, despite the fact that interrupts is still working and continue to put messages at the Queue_1. So we receive messages but we doesnt process them and doesnt responce on them at all, so we have to restart the device if we want back to normal.
Does it have any connection with changes we made in DCAN or there could be another reason?
P.S. We are also trying to check task stats in the interrupt handler function, will it work? There is how it looks like
void CanRx(UInt32 id, char* data, int len) // interrupt handler function
{
if (id == certain ID)
{
Msg* msg = Utils_memAlloc(UTILS_HEAPID_DDR_CACHED_SR, sizeof(Msg_1), 32);
memcpy(&msg->data[0], data, len);
msg->len = len;
msg->id = id;
Queue_put(Queue_1, &msg->_elem);
}
Task_stat(Task_self(), &statbuf);
Vps_printf("task mode %d", statbuf.mode);
}
As we understand, Task_stats() should show us stats of the task interrupted by Hwi, doesnt it?
P.P.S. Also we have checked, there are no any DeInits we went throught during the runtime if you are interested.
Best regards, D.K. Tovmachenko.