文章
RX Object Mode
Refer to NTCAN Application Developers Manual document charpter
- 3.11 RX Object Mode
- 4.1.1 canOpen, NTCAN_MODE_OBJECT
- 4.3.1 canTake
- 6.2.3 CMSG, len Bit 5 = No_Data (Object Mode)[Rx]
使用目的
If an application is only interested in the most recent data of a CAN message the handle can be initialized using the object mode instead of the default FIFO mode.
使用场景举例
假设在某个CAN总线中,有一个CAN装置专门收集户外温度,它每隔5分钟就会在总线上发送一次数据。数据是用固定的ID发送。总线上有一台主机执行的应用程序,已经配置好用Object mode receive方式读取此固定ID的数据。每当有新的数据发送过来,底层驱动都会为上层应用程序预备好最新的数据,供应用程序使用canTake()方式去读取。一旦有人要查询气温的时候,上层应用程序执行一次canTake(),就能把最新的数据展示给用户看。
Example code
- objrx.c: 配置用Object Mode接收CAN ID为11-bit ID从0到4的5个CAN消息。每按一下空格键加回车键,就读取一次这5个ID的最新更新上来的数据。
- 只能使用canTake()方式读取数据,不能使用canRead()方式读取数据。
- canTake()方式读取数据,会马上返回,不会block程序执行。
- Object mode receive只支持11-bit ID的CAN消息。
- canTake()返回NTCAN_SUCCESS不代表有数据更新,需要去检查NTCAN_NO_DATA状态。Bit 5(NTCAN_NO_DATA) of CMSG.len为0说明有有效数据存在,如果为1说明No valid data存在。
uint32_t mode=NTCAN_MODE_OBJECT; /* mode bits for canOpen */
/* The rxqueuesize should be set to the maximum number of different
CAN messages (messages with different CAN-IDs) the application
wants to receive. */
int32_t rxqueuesize=5;
int32_t lenRcv=5;
CMSG cmsgObjRcv[5];
/* Initialize the id from 0 to 4 of the CMSG objects of interest. */
for (int i = 0; i < lenRcv; i++)
{
cmsgObjRcv[i].id = i;
}
printf("press SPACE and then ENTER key to canTake() data once. \n");
while(1)
{
// 0x20 is SPACE key number.
if(getchar()==0x20)
{
retvalue = canTake(rxhandle, &cmsgObjRcv[0], &lenRcv);
if(retvalue != NTCAN_SUCCESS)
{
printf("canTake() failed with error %d!\n", retvalue);
}
else
{
for (int i = 0; i < lenRcv; i++)
{
/*check if Bit 5(NTCAN_NO_DATA) of CMSG.len is clear */
if (!(cmsgObjRcv[i].len & 0x20))
{
printf("Id: %d\n", cmsgObjRcv[i].id);
printf("Len: %d\n", (cmsgObjRcv[i].len & 0x0f));
for (int j=0;j<(cmsgObjRcv[i].len & 0x0f);j++)
printf("Byte %d: %#x\n", j, cmsgObjRcv[i].data[j]);
printf("\n");
}
else
{
printf("Id %d: no valid data. \n\n", cmsgObjRcv[i].id);
}
}
printf("================================\n");
}
}
}
测试执行
- 没有收到ID从0-4的CAN消息前,按空格加回车键读取一次所有5个ID的数据,都显示为no valid data。
bobtu@debian:~/ntcantest$ ./objrx
press SPACE and then ENTER key to canTake() data once.
Id 0: no valid data.
Id 1: no valid data.
Id 2: no valid data.
Id 3: no valid data.
Id 4: no valid data.
- 向总线中发送如下CAN消息,按空格加回车键读取一次所有5个ID的数据,其中ID 0和1的数据更新了。

Id: 0
Len: 1
Byte 0: 0x23
Id: 1
Len: 2
Byte 0: 0x23
Byte 1: 0
Id 2: no valid data.
Id 3: no valid data.
Id 4: no valid data.
- 在总线中发送ID从0到4的任意数据,只有最新发送的数据才会被应用程序读取上来。