文章
Create thread to receive all incoming messages with NTCAN
example code
threads.c :此example code仅适用于Linux系统。主线程创建两个handles,一个用于发送txhandle,一个用于接收rxhandle,然后主线程用pthread_create()创建一个子线程同时将rxhandle作为参数传递给子线程程序,然后使用pthread_detach()分离这个子线程,使之在后台运行。子线程的主要目的为接收net0上所有11-bit ID的CAN消息并打印出来,若接收到来自同样是net0发送的CAN消息,则在消息打印时会提示。创建完毕子线程后,主线程继续运行,它每隔1秒发送一条CAN消息,ID为11-bit的001,data在前100秒内显示为"American"的8字节ASCII数据,后100秒更新为"Canadian"的8字节ASCII数据。计数器使用了一个字节,递增方式(NTCAN_SCHED_FLAG_INC8),占据了data域内的第6个字节位置(从第0个字节开始算起)(NTCAN_SCHED_FLAG_OFS6)。计数器初始值为0xA0,结束值为0x20。可以参考scheduling transmit CAN message with NTCAN 。
举例说明
- 在threads.c中有如下代码片段。
/* background thread receive all CAN messages with 11-bit ID */
void* background_thread(void* arg) {
int i,j; /* Loop counter */
int32_t count=8;
CMSG rxcmsg[8];
NTCAN_HANDLE rxhandle = * (NTCAN_HANDLE*) arg; /* can txhandle returned by canOpen() */
NTCAN_RESULT retvalue; /* return values of NTCAN API calls */
while (1) {
count=(int32_t)(sizeof(rxcmsg) / sizeof(rxcmsg[0]));
retvalue = canRead(rxhandle, &rxcmsg[0], &count, NULL);
if (retvalue == NTCAN_RX_TIMEOUT)
{
printf("canRead() returned timeout\n");
continue;
}
else if (retvalue != NTCAN_SUCCESS)
{
printf("canRead() failed with error %d!\n", retvalue);
}
else
{
printf("canRead() received %d message(s) !\n", count);
for (j = 0; j < (int)count; j++) {
if(NTCAN_IS_INTERACTION(rxcmsg[j].len))
printf("message sent from the same port! \n");
int len = NTCAN_LEN_TO_DATASIZE(rxcmsg[j].len);
printf("CAN-ID of received message %d : %03x\n",j, NTCAN_ID(rxcmsg[j].id));
if (NTCAN_IS_RTR(rxcmsg[j].len)) {
printf("Received a RTR message (%d)", len);
} else {
printf("Received a data message with %d bytes : ", len);
for (i = 0; i < len; i++)
printf("%02x ", rxcmsg[j].data[i]);
}
printf("\n\n");
}
}
continue;
}
return(0);
}
......in main()......
// create thread
if (pthread_create(&tid, NULL, background_thread, &rxhandle) != 0) {
perror("pthread_create");
return (-1);
}
// detach the created thread
if (pthread_detach(tid) != 0) {
perror("pthread_detach");
return (-1);
}
- 编译执行。同时连接另一台笔记本电脑,使用CANreal抓取此程序发送的CAN消息,同时也可以利用CANreal向总线发送消息,并查看子线程,它也会打印出来CANreal发送的CAN消息。