### Can-festival 使用

**概述**
- CanFestival是一个开源（LGPL和GPL）CANopen框架。遵循ANSI-C，支持多平台。Canfestival是一个通信库，它的作用是掌握通信并把通信功能全部包揽过来
- Canfestival最主要的思想有两个，一个是字典思想，所有的参数和配置都是存在字典里面的。Canfestival能够运行于多种类型的平台


可根据手册进行 can-festival 源码移植与开发，其中包含有 xenomai 的编译方法，可快速移植并测试实时程序

---
### 使用 can-festival 与 rtcan 驱动在 sx21 上的测试说明
  1. 移植 can-festival 源码
  2. 重新编译 kernel ，并选择支持 rtcan 驱动
  3. 编写 can-festival 实时程序，并选择驱动为 rtcan 设备
  4. 测试 jitter

#### 程序源码以及 can-festival 协议层驱动说明
在 Linux 系统中， CAN 总线接口设备作为网络设备被系统进行统一管理，所以使用标准 posix socket 接口操作 can 设备，在编译实时程序时只需在链接时添加 xenomai 库即可完成 posix rt 程序编译
在使用 rtcan 驱动时，通过 Alchemy 接口操作 rtcan 设备即可

详细规则如下

```c
// ...
// 通过 RTCAN_SOCKET 宏控制驱动普通 can 设备以及 rtcan 设备
#define RTCAN_SOCKET

#ifdef RTCAN_SOCKET
#include "rtdm/rtcan.h"
#define CAN_IFNAME     "rtcan%s"
#define CAN_SOCKET     rt_dev_socket
#define CAN_CLOSE      rt_dev_close
#define CAN_RECV       rt_dev_recv
#define CAN_SEND       rt_dev_send
#define CAN_BIND       rt_dev_bind
#define CAN_IOCTL      rt_dev_ioctl
#define CAN_SETSOCKOPT rt_dev_setsockopt
#define CAN_ERRNO(err) (-err)
#else
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include "linux/can.h"
#include "linux/can/raw.h"
#include "net/if.h"
#ifndef PF_CAN
#define PF_CAN 29
#endif

// ... 
```

在链接时需添加如下链接库即可

  **Warning** 
  - canfestival_can_socket 为 can-festival 协议层驱动源文件生成的动态库名
  - 当使用 Alchemy 接口时，需要额外链接 alchemy 库


```cmake
target_link_libraries(canfestival_can_socket PUBLIC 
    -Wl,--no-as-needed -Wl,@${XENO_LIBS_DIR}/cobalt.wrappers
    -Wl,@${XENO_LIBS_DIR}/modechk.wrappers ${XENO_LIBS_DIR}/xenomai/bootstrap.o
    -Wl,--wrap=main
    -Wl,--dynamic-list=${XENO_LIBS_DIR}/dynlist.ld
    alchemy copperplate
    cobalt modechk
)
```

以 linux 系统为例, 安装方式如下

  **Warning** 其他部分则需要调整 can-festival 源码中 times-xxx 的实现部分
- 通用 unix 接口（标准 posix 接口）
can-festival 协议层驱动源文件使用 drivers/timers_unix
- alchemy 接口
can-festival 协议层驱动源文件使用 drivers/timers_xeno


目录结构
```terminal
├── drivers
│   ├── can_socket
│   │   ├── can_socket.c
│   │   └── CMakeLists.txt
│   ├── timers_unix
│   │   ├── Makefile
│   │   ├── Makefile.in
│   │   ├── timers_unix.c
│   ├── timers_xeno
│   │   ├── Makefile
│   │   ├── Makefile.in
│   │   └── timers_xeno.c
│   └── unix
│       ├── libcanfestival_unix.a
│       ├── Makefile
│       ├── Makefile.in
│       ├── unix.c
```

用户需根据目标产物更换不用协议层驱动

```cmake
set(
    SRC_LISTS 
    example/TestMasterMicroMod/TestMasterMicroMod.c
    example/TestMasterMicroMod/TestMaster.c
    # ...
    # ...
    src/timer.c
    # drivers/timers_unix/timers_unix.c # 编译标准 posix 接口的协议层驱动实现
    drivers/timers_xeno/timers_xeno.c # 编译 Alchemy 接口的协议层驱动实现
    drivers/unix/unix.c
)

add_executable(${CMAKE_PROJECT_NAME} ${SRC_LISTS})
```