dingzijie
dingzijie

注册于 5 months ago

回答
4
文章
0
关注者
1

问题已经解决 加了timeout就可以了。

下载完程序后断电再上电一下就好了,也不清楚为什么。

这步做了吗?rt_hw_spi_device_attach

#define SPI2_DEVICE_NAME     "spi20"
#define SPI2_BUS_NAME     "spi2"

struct rt_spi_device *spi2_dev_ecat;

这个设备声明已经加了

问题2
1,在can_rtthread里有函数
static rt_err_t can1ind(rt_device_t dev, void *args, rt_int32_t hdr, rt_size_t size)
{
rt_event_t pevent = (rt_event_t)args;
rt_event_send(pevent, 1 << (hdr));
return RT_EOK;
}
其中事件的发送正好激活canopen_recv_thread_entry 里的事件等待内容。
但是我不太清楚can1ind怎么在程序里被调用的。
想学好rt-thread真心不容易。希望有高人指点一下,谢谢。

在can_sample的例子里仅仅设置了硬件虑波

#ifdef RT_CAN_USING_HDR
struct rt_can_filter_item items[5] =
{
RT_CAN_FILTER_ITEM_INIT(0x100, 0, 0, 0, 0x700, RT_NULL, RT_NULL), /* std,match ID:0x100~0x1ff,hdr为-1,设置默认过滤表 */
RT_CAN_FILTER_ITEM_INIT(0x300, 0, 0, 0, 0x700, RT_NULL, RT_NULL), /* std,match ID:0x300~0x3ff,hdr为-1 */
RT_CAN_FILTER_ITEM_INIT(0x211, 0, 0, 0, 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, 0, 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

而在开启CANOPEN后 在can_rtthread里需要
if (rt_event_recv(&canpara->event,
(1 << canpara->filter->items[0].hdr),
canpara->eventopt,
RT_WAITING_FOREVER, &e) != RT_EOK)
{
continue;
}
这句话字面意思等待一个事件发生。好像是滤波相关事件。到底应该怎么理解。为什么程序在这里就死循环了???
有高人吗?



whj467467222 发表于 2020-6-29 12:07
抛开canopen只看can的话,是不是现在无法正常收发数据?


CAN是正常的 当在ENV里配置好CANOPEN后 程序运行后就死循环。FINSH就不能使用。

#define CANFESTIVAL_CAN_DEVICE_NAME "can1"//"bxcan1"
请确保 你们的名字是统一的

ENV配置完之后 只要统一一下名字就好,给的例子程序可以用。

whj467467222 发表于 2020-6-29 08:59
确保的你CAN能收发报文之后:
1.接受到报文之后调用canDispatch(&ObjDiction_Data, &msg);
2.定时器能1ms ...


我是用RT thread 里面自带的例子。你说的两个函数 分别在两个线程里都启用了。cf_recv和cf_timer。
关键问题是
while (1)
{
if (rt_event_recv(&canpara->event,
(1 << canpara->filter->items[0].hdr),
canpara->eventopt,
RT_WAITING_FOREVER, &e) != RT_EOK)
{
continue; //初始化有问题 程序一直死在这里 无法运行下去
}

if (e & (1 << canpara->filter->items[0].hdr))
{
msg.hdr = canpara->filter->items[0].hdr;
while (rt_device_read(candev, 0, &msg, sizeof(msg)) == sizeof(msg))
{
co_msg.cob_id = msg.id;
co_msg.len = msg.len;
co_msg.rtr = msg.rtr;
memcpy(co_msg.data, msg.data, msg.len);
EnterMutex();
canDispatch(OD_Data, &co_msg);
LeaveMutex();
}
}
}
你说的 canDispatch(OD_Data, &co_msg);数据分发无法进入到这一步。

问题2给的例子程序里面 也没有NMT 主站控制分站状态的例子。

1,如果打开了 RT_CAN_USING_HDR
2,在初始化阶段就会有
#define RT_CAN_FILTER_ITEM_INIT(id,ide,rtr,mode,mask,ind,args) \
{(id), (ide), (rtr), (mode), (mask), -1, (ind), (args)}
其中的-1 是#FFFFFFFF
3,rt_event_recv(&canpara->event,
(1 << canpara->filter->items[0].hdr),
canpara->eventopt,
RT_WAITING_FOREVER, &e) != RT_EOK)

其实就会把 1 << canpara->filter->items[0].hdr 移动32下

4,所以在
if (rt_event_recv(&canpara->event,
(1 << canpara->filter->items[0].hdr),
canpara->eventopt,
RT_WAITING_FOREVER, &e) != RT_EOK)
{
continue; //程序会死循环
}

5,问题,初始化给的原始数值就存在问题,还是我没有看明白。

有真正的高人来指点一下嘛?

whj467467222 发表于 2020-6-28 18:40
先去熟悉一下canopen协议了之后,再看看能不能收到心跳报文


谢谢你的回复,但是没什么帮助!

我的是用BSP STM32F767 的基础上用CanFestvial。can.c 里已经包含了 case RT_CAN_CMD_SET_FILTER:的代码。
但是rt_event_recv的set为恒为0 程序还是不能运行。RTT的CanFestvial 的402例子程序到底应该怎么用?我用周力工测试can口通讯是正常的。

发布
问题

分享
好友