一点一滴搭建机器人平台(一)——CAN通信实现(宜鼎EMUC-B202)

本文详细记录了在Ubuntu20.04系统中安装宜鼎科技CAN卡的驱动、修改driver/main.c文件、编译过程、配置设备及波特率,以及使用C++进行CAN通信的步骤,最后提到了CMake的使用。
摘要由CSDN通过智能技术生成

1 绪论

        回顾之前的文章,发现记录自己的学习过程真的挺有用,至少当自己再次遇到相同问题的时候,可以想到自己曾经研究过这些东西,也能很快的进行定位。所以,索性就把当前项目调试中遇到的一些知识也做一个记录吧。

2 CAN卡的使用

        本次记录的内容也很简单,就是如何使用已经内置在工控机中的CAN卡。目前手中的工控机内置的是宜鼎科技的CAN卡,当时定制它的目的是因为它支持socketcan,因为之前用过以太网的Socket接口,觉得这个应该使用起来会简单一些吧。

2.1 驱动文件的修改

        官方网站可以搜索到驱动程序。在下面这个网址内输入EMUC-B202,就可以搜索到对应的驱动程序。

Brochure-宜鼎国际Innodisk

        由于我的系统是ubuntu20.04,官方的这个驱动包在实际使用中会报错。感谢工程师董岗,给了我一个最新版本。其实就是修改driver/main.c文件。至于官方的那个不能用,就是因为linux内核升级以后,有些函数的形参、返回值发生了变化,以至于无法编译通过。

2.2  编译过程

        其实,对于编译过程,文件中有一个PDF写的很清楚了,我按照自己的理解,把步骤简单写一写。

Step1:

        首先在ubuntu命令行中执行dmesg指令,打印的东西挺多,在里面找如下的记录:

        

Step2:

        linux系统下解压驱动文件,在根目录下执行make指令进行编译。如果不成功,可以考虑安装gcc、g++这些工具链。

        make以后生成了两个文件,emuc2socketcan.ko和emucd_32 or emucd_64。这两个文件很关键,其实就是底层的一个驱动文件。从后文创建CAN卡自启动的那个脚本可以看出,需要把这两个文件拷贝到指定目录中,方便系统启动时加载。具体可以看add_2_boot.sh这个脚本。

Step3:

        使用如下命令给脚本start.sh增加执行权限,并运行。

chmod +x start.sh
./start.sh

        执行完成后,就可以使用ifconfig命令查到设备了。

        这里的can0和can1的名称,是在start.sh文件中定义的。设备的波特率也是在这个文件中定义的。

Step4:

        创建两个终端。在第一个终端中,输入以下指令:

        在第二个终端中,输入以下指令:

        这样就证明成功安装了驱动。

Step5:

        想要系统上电后自动加载驱动,同样需要配置好start.sh文件中的波特率,名称,还有错误类型后。在boot exec文件夹下,修改add_2_boot.sh的权限并执行。

chmod +x add_2_boot.sh
./add_2_boot.sh

Step6:

        重启设备,然后再次执行STEP4中的指令。如果成功,则说明本次的驱动安装成功。

Step7:

        下面就是激动人心的编程环节了。

        首先是初始化部分:

        

extern int can_fd;
int can_init(void)
{
    /****************通过 ip 指令设置 can0 参数******************/
    can_fd = socket(AF_CAN, SOCK_RAW, CAN_RAW);
    if (can_fd < 0)
    {
        perror("socket can creat error!\n");
        return -1;
    }
    const char *ifname = "can0";
    struct ifreq ifr;
    strcpy(ifr.ifr_name, ifname); // 制定编号为can0的设备,获取设备索引
    ioctl(can_fd, SIOCGIFINDEX, &ifr);
    struct sockaddr_can addr;
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;
    /*将套接字与can0绑定*/
    int bind_res = bind(can_fd, (struct sockaddr *)&addr, sizeof(addr));
    if (bind_res < 0)
    {
        perror("can 0 bind error!\n");
        return -1;
    }

    /*过滤规则设置*/
    struct can_filter rfilter[3];
    rfilter[0].can_id = 1;
    rfilter[0].can_mask = CAN_SFF_MASK; // 标准帧

    rfilter[1].can_id = 2;
    rfilter[1].can_mask = CAN_SFF_MASK; // 标准帧

    rfilter[2].can_id = 3;
    rfilter[2].can_mask = CAN_SFF_MASK; // 标准帧

    return can_fd;
}

           测试代码部分:

int can_fd;
int main(int argc, char *argv[])
{
    can_init();
    while (1)
    {
/*测试源码*/
#if 1
        struct can_frame tx_frame, rx_frame; // 发送frame和接收frame
        ssize_t nbytes = read(can_fd, &rx_frame, sizeof(struct can_frame));
        if (nbytes < 0)
        {
            perror("Error in socket read");
            return 1;
        }

        // 打印接收到的CAN数据
        #if 0
                printf("Received frame with ID 0x%X, DLC %d, data: ", rx_frame.can_id, rx_frame.can_dlc);
                for (int i = 0; i < rx_frame.can_dlc; ++i)
                    printf("%02X ", rx_frame.data[i]);
                printf("\n");
        #endif


        // 发送CAN数据帧
        tx_frame.can_id = 0x123;
        tx_frame.can_dlc = 8;
        for (int i = 0; i < tx_frame.can_dlc; i++)
        {
            tx_frame.data[i] = rx_frame.data[i];
        }
        nbytes = write(can_fd, &rx_frame, sizeof(struct can_frame));
        if (nbytes != sizeof(struct can_frame))
        {
            perror("Error in socket write");
            return 1;
        }

        printf("CAN frame sent successfully.\n");
#endif
    }

    return 0;
}

3 结束语

        最近学了很多东西C++还有CMake的知识,感觉前方道路漫漫啊。。。。加油

先在这里保存一个简单的CMakeLists.txt文件吧。

cmake_minimum_required(VERSION 3.0)

project(CAN_DEMO)

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
aux_source_directory(src SRCLIST)
include_directories(include)

add_executable(can_demo ${SRCLIST} main.cpp)

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值