1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
|
#include <rtthread.h>
#include "rtdevice.h"
#ifdef RT_USING_CAN
#define CAN_DEV_NAME "can1" /* CAN 设备名称 */
static struct rt_semaphore rx_sem; /* 用于接收消息的信号量 */
static rt_device_t can_dev; /* CAN 设备句柄 */
#define THREAD_PRIORITY 25
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 5
static rt_thread_t tid1 = RT_NULL;
static volatile int running = 0;
static int data_buf[10];
static uint32_t data_cnt = 0;
rt_err_t lp40_recv(uint16_t id, uint8_t *msg)
{
if(crc_high_first(msg,6)){
}
return RT_EOK;
}
/* 接收数据回调函数 */
static rt_err_t can_rx_call(rt_device_t dev, rt_size_t size) {
/* CAN 接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */
rt_sem_release(&rx_sem);
return RT_EOK;
}
static void can_rx_thread(void *parameter) {
int i;
//rt_err_t res;
struct rt_can_msg rxmsg = {0};
/* 设置接收回调函数 */
rt_device_set_rx_indicate(can_dev, can_rx_call);
#ifdef RT_CAN_USING_HDR
struct rt_can_filter_item items[5] = {
RT_CAN_FILTER_ITEM_INIT(0x100, 0, 0, 1, 0x700, RT_NULL, RT_NULL), /* std,match ID:0x100~0x1ff,hdr 为 - 1,设置默认过滤表 */
RT_CAN_FILTER_ITEM_INIT(0x300, 0, 0, 1, 0x700, RT_NULL, RT_NULL), /* std,match ID:0x300~0x3ff,hdr 为 - 1 */
RT_CAN_FILTER_ITEM_INIT(0x211, 0, 0, 1, 0x7ff, RT_NULL, RT_NULL), /* std,match ID:0x211,hdr 为 - 1 */
RT_CAN_FILTER_STD_INIT(0x486, RT_NULL, RT_NULL), /* std,match ID:0x486,hdr 为 - 1 */
{0x555, 0, 0, 1, 0x7ff, 7,} /* std,match ID:0x555,hdr 为 7,指定设置 7 号过滤表 */
};
struct rt_can_filter_config cfg = {5, 1, items}; /* 一共有 5 个过滤表 */
/* 设置硬件过滤表 */
res = rt_device_control(can_dev, RT_CAN_CMD_SET_FILTER, &cfg);
RT_ASSERT(res == RT_EOK);
#endif
int rx_count = 0;
while (running) {
/* hdr 值为 - 1,表示直接从 uselist 链表读取数据 */
rxmsg.hdr_index = -1;
/* 阻塞等待接收信号量 */
if(rt_sem_take(&rx_sem, RT_WAITING_FOREVER)==RT_EOK){
/* 从 CAN 读取一帧数据 */
rt_device_read(can_dev, 0, &rxmsg, sizeof(rxmsg));
/* 打印数据 ID 及内容 */
rt_kprintf("recv %ld : id = %d, ide=%d :", ++rx_count, rxmsg.id, rxmsg.ide);
for (i = 0; i < rxmsg.len; i++) {
rt_kprintf(" %02x", rxmsg.data[i]);
}
rt_kprintf("\n");
}
}
}
/* 线程 1 的入口函数 */
static void thread1_entry(void *parameter) {
struct rt_can_msg msg = {0};
int count = 0;
msg.id = 0x123; /* ID 为 0x78 */
msg.ide = RT_CAN_STDID; /* 标准格式 */
//msg.ide = RT_CAN_EXTID; /* 标准格式 */
msg.rtr = RT_CAN_DTR; /* 数据帧 */
msg.len = 8; /* 数据长度为 8 */
/* 待发送的 8 字节数据 */
msg.data[0] = 0x00;
msg.data[1] = 0x11;
msg.data[2] = 0x22;
msg.data[3] = 0x33;
msg.data[4] = 0x44;
msg.data[5] = 0x55;
msg.data[6] = 0x66;
msg.data[7] = 0x77;
while(running) {
/* 线程 1 采用低优先级运行,一直打印计数值 */
rt_kprintf("send %d : id = %d, ide=%d :", ++count, msg.id, msg.ide);
for(int i=0;i<msg.len;i++)
rt_kprintf(" %02x", msg.data[i]);
rt_kprintf("\n");
rt_device_write(can_dev, 0, &msg, sizeof(msg));
for(int i=0;i<100;i++){
rt_thread_mdelay(50);
if(!running)
break;
}
}
rt_device_close(can_dev);
}
int can_sample(int argc, char *argv[]) {
rt_err_t res;
rt_size_t size;
rt_thread_t thread;
char can_name[RT_NAME_MAX];
if (argc == 2) {
rt_strncpy(can_name, argv[1], RT_NAME_MAX);
} else {
rt_strncpy(can_name, CAN_DEV_NAME, RT_NAME_MAX);
}
if(running){
rt_kprintf("can_sample is running, stop it before restart!\n can_sample_stop\n", can_name);
return RT_ERROR;
}
/* 查找 CAN 设备 */
can_dev = rt_device_find(can_name);
if (!can_dev) {
rt_kprintf("find %s failed!\n", can_name);
return RT_ERROR;
}
running = 1;
res = rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
/* 以中断接收及发送方式打开 CAN 设备 */
res = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX);
/* 初始化 CAN 接收信号量 */
/* 设置 CAN 的工作模式为正常工作模式 */
res = rt_device_control(can_dev, RT_CAN_CMD_SET_MODE, (void *)RT_CAN_MODE_NORMAL);
//res = rt_device_control(can_dev, RT_CAN_CMD_SET_MODE, (void *)RT_CAN_MODE_LOOPBACK);
res = rt_device_control(can_dev, RT_CAN_CMD_SET_BAUD, (void *)CAN125kBaud);
RT_ASSERT(res == RT_EOK);
/* 创建数据接收线程 */
thread = rt_thread_create("can_rx", can_rx_thread, RT_NULL, 1024, 25, 10);
if (thread != RT_NULL) {
rt_thread_startup(thread);
} else {
rt_kprintf("create can_rx thread failed!\n");
}
if (size == 0) {
rt_kprintf("can dev write data failed!\n");
}
/* 创建线程 1,名称是 thread1,入口是 thread1_entry*/
tid1 = rt_thread_create("thread1",
thread1_entry, RT_NULL,
THREAD_STACK_SIZE,
THREAD_PRIORITY, THREAD_TIMESLICE);
/* 如果获得线程控制块,启动这个线程 */
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
else
rt_kprintf("start can send fail\n");
return res;
}
int can_sample_stop(int argc, char *argv[]) {
if(running){
running = 0;
//rt_sem_release(&rx_sem);
rt_sem_detach(&rx_sem);
}
return RT_EOK;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(can_sample, can device sample);
MSH_CMD_EXPORT(can_sample_stop, can device sample stop);
#endif
|