文章

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

举例说明

  1. 在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);
}
  1. 编译执行。同时连接另一台笔记本电脑,使用CANreal抓取此程序发送的CAN消息,同时也可以利用CANreal向总线发送消息,并查看子线程,它也会打印出来CANreal发送的CAN消息。