2.30. CANFESTIVAL
Overview
CanFestival是基于CANOPEN的一个开源协议栈,而CANOPEN是一个基于CAN的高层应用协议,内部对CAN报文的11/29位ID、8字节数据的使用都进行了严格的定义。在运用CanFestival前需要有CAN以及CANOPEN的基本知识。目前SDK适配CanFestival-v3.10。
提供CanFestival应用示例、配置介绍和常见问题。
2.30.1. 应用实例
示例演示:
演示协议栈主站、从站使用等。
example: 具体示例代码详见 apps/common/example/third_party/canfestival/canfestival_main.c
。
2.30.2. 配置说明
- 1.在板级文件
apps/.../board.h
中打开宏TCFG_CAN_ENABLE
并打开宏TCFG_CANOPEN_ENABLE
,若运行CANOPEN务必将CAN的模式设定为增强模式。 #define TCFG_CAN_ENABLE 1 #if TCFG_CAN_ENABLE #define TCFG_CANOPEN_ENABLE 1 #if TCFG_CANOPEN_ENABLE #undef TCFG_CAN_ENABLE #define TCFG_CAN_ENABLE 1 #endif #endif
- 1.在板级文件
2.在CanFestival配置文件
apps/common/example/third_party/canfestival/include/jieli/canopen_def.h
中选择CanFestival的主从机模式以及定时中断使用的定时器。最好不要同时使能主站和从站,可以主站和从站动态切换#define TCFG_CANOPEN_MASTER_ENABLE 0 /*!< CANOPEN协议栈作主机模式*/ #define TCFG_CANOPEN_SLAVE_ENABLE 1 /*!< CANOPEN协议栈作从机模式*/ #define TCFG_CANOPEN_TIMER_10MS_ENABLE 1 /*!< 使能选择使用系统定时器最小支持10ms心跳时间,失能选择使用独立定时器最小支持1ms心跳时间*/
2.30.3. 流程说明
1.canfestival根目录下的canfestival_main.c是CANOPEN协议栈的主函数入口;/src是CanFestival的.c源文件;/include是CanFestival的.h源文件;/drive是CanFestival的接收与发送等接口文件,包括字典.c/.h文件;/bsp是CanFestival的CAN和Timer硬件接口。
2.CANOPEN协议栈首先在canfestival_main.c创建主线程,并对硬件和协议栈进行初始化。
static void canopen_main_task(void *p) { canopen_can_init();//can硬件初始化 #if TCFG_CANOPEN_TIMER_10MS_ENABLE canopen_sys_timer_enable();//系统定时器初始化 #else canopen_solo_timer_enable();//独立定时器初始化 #endif canopen_driver_init(); //can接收任务与定时中断调用任务创建 #if TCFG_CANOPEN_MASTER_ENABLE unsigned char nodeID = 0x01; setNodeId(&TestMaster_Data, nodeID);//设置canfestival主机ID setState(&TestMaster_Data, Initialisation);//初始化canopen NMT网络主机设备 setState(&TestMaster_Data, Operational);//进入操作状态 #endif #if TCFG_CANOPEN_SLAVE_ENABLE unsigned char nodeID = 0x03; setNodeId(&TestSlave_Data, nodeID);//设置canfestival从机ID setState(&TestSlave_Data, Initialisation);//初始化canopen NMT网络从机设备 setState(&TestSlave_Data, Operational);//进入操作状态 #endif while (1) { /*应用层,可在此处添加canopen协议条件发送报文。SDO或PDO*/ os_time_dly(50); } }
Note
说明:
SDK中CANOPEN协议栈主站中仅有2s一次的心跳报文;从站集合了心跳报文、SDO、PDO等报文,具体请查看
/drive/TestSlave.eds
和/drive/TestSlave.od
。其中/drive/TestSlave.c
和/drive/TestSlave.h
是对应从站字典文件生成的.c/.h文件。CANOPEN协议栈最重要的是字典文件,如果想基于SDK示例中的字典文件进行二次开发,建议熟悉一下CANOPEN协议栈的字典文件内部定义以及CanFestival字典文件如何使用,其中CanFestival字典文件需要配置对应的python环境才能打开.od文件。.od字典文件准备好后建议导出的.c/.h文件名和SDK中使用的主站从站.c/.h文件名一致,否则会报错,需要根据错误修改代码。
2.30.4. 常见问题
协议栈启动后容易出现死机、复位、CPU占用高等情况。
答:排查是否配置了阻塞式接收死等方式,如果是则改用信号量的方式;检查是否CanFestival定时中断过于频繁,可以根据实际心跳报文的设置时间,调整定时回调的时间,注意不能动态调整回调时间。
心跳报文设定在1s一次,用不上10ms或者1ms的回调,如何更改为100ms回调?
答:在
canfstival/bsp/bsp_canopen.c
中找到系统定时器或独立定时器的配置函数进行修改。修改bsp_canopen.c后需要同步修改canfstival/include/jieli/timerscfg.h
中的协议栈心跳时间///canfstival/bsp/bsp_canopen.c ...... //独立定时器修改方法 void canopen_timer_run(void) { u8 precesion; //precesion = 10;//单位0.1ms //从1ms回调修改为100ms回调 precesion = 1000;//单位0.1ms ...... } //系统定时器修改方法 void canopen_sys_timer_enable(void) { os_sem_create(&canopen_timer_sem, 0); /*sys_hi_timer_add(NULL, canopen_sys_timer_isr, 10);*/ sys_hi_timer_add(NULL, canopen_sys_timer_isr, 100);//从10ms回调修改为100ms回调 } ///canfstival/include/jieli/timerscfg.h ...... #define MS_TO_TIMEVAL(ms) ((ms) / 100)//(ms)/回调时间ms = 1ms #define US_TO_TIMEVAL(us) ((us) / 100000)//(us)/回调时间us = 1us
目前SDK中CANOPEN协议栈的CAN硬件功能使用较少,能否自行添加功能?
答:可以,建议在
canfstival/bsp/bsp_canopen.c
中can初始化函数执行相关硬件初始化操作。void canopen_can_init(void) { canopen_hdl = dev_open("can", NULL); dev_ioctl(canopen_hdl, IOCTL_CAN_SET_DMA_FRAMES, 1); dev_ioctl(canopen_hdl, IOCTL_CAN_SET_RECV_WAIT_SEM, 0); //自行添加中断或其他功能 }