esp32移植canopen协议栈(四)

前言


本文续接上一篇文章,上一个工程中我们已经实现了定时器,本文我们正式开始移植canfestival (canopen协议栈的一种),这个网上的介绍很多,感兴趣的可以搜一下,本文着重介绍其移植过程。

一、建立源码canopen目录

在移植之前先看下我们之前工程的目录结构。
在这里插入图片描述
现在我们在components下建立canopen目录,在canopen目录下在依次建立inc, src,objdict分别存放canopen协议栈的头文件,源文件,和我们自己的对象字典,如下图所示。
在这里插入图片描述
现在inc,src,objdict是三个空目录,下一步我们去下载canfestival源码填充这3个目录吧。

二、canfestival源码下载

直接下最新的,下载链接canfestival
打开界面如下
在这里插入图片描述
我们点击这个zip,可以下载源码的zip包。

在这里插入图片描述
在文件夹中打开
在这里插入图片描述
右键点击空白处,然后从终端中打开
在这里插入图片描述
使用unzip canfestival-de1fc3261f21.zip命令解开zip包

在这里插入图片描述
进入解压后的目录,内容如下
在这里插入图片描述

三、canfestival移植

我们进入到include目录下,发现一些头文件如下
在这里插入图片描述
我们需要拷贝该目录下所有的.h到我们工程目录下的inc目录下,我这里是一起拷贝的,当然你也可以一个个的拷贝。
在这里插入图片描述
拷贝后的工程目录canopen的inc下应如下所示
在这里插入图片描述
然后我们进入到none文件夹下,把这3个头文件也拷贝到工程目录canopen中的inc下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
拷贝后的工程目录canopen,inc应如图所示
在这里插入图片描述
接下来我们需要回到上一级,把AVR目录下的config.h,拷贝到工程目录canopen目录下的inc下(只拷贝这个哦,其他的不要拷贝)
在这里插入图片描述

拷贝后的工程目录应如下所示
在这里插入图片描述
接下来我们去拷贝源码文件,回到canfestival源码根目录,下面有个src文件夹,我们进入到src文件夹下拷贝所有的.c文件到项目目录下的canopen目录下src下。(我这里是全部拷贝,你也可以一个个的拷贝)
在这里插入图片描述

拷贝后的工程目录应如下所示
在这里插入图片描述
至此我们得源码文件移植完毕,下面我们要对源码和我们得esp32平台进行适配,也就是要修改一些源文件。

四、canfestival适配

我们在工程目录下新建canopen.hpp的cpp文件,如下图所示
在这里插入图片描述
我们在main中包含canopen.hpp,假装编译一下,看下报错。果不其然,它报了找不到canopen.hpp
在这里插入图片描述
我们在main目录下的CMakeLists.txt中加入canopen.hpp的路径
在这里插入图片描述
果然就编译通过了
在这里插入图片描述
接下来我们需要让canopen协议栈在esp32上跑起来,计划是canopen协议栈的初始化在Canopen的构造函数中执行。
我们还未对canopen协议栈源码文件做任何修改,过程中肯定有很多报错,但是没有关系,遇到一个报错我们改一个就好啦,遇一对,改一双!!!嘻嘻。

首先我们现在canopen.hpp中包含canfestival.h假装编译,看它能咋滴。
在这里插入图片描述
果然,它找不到canfestival.h
在这里插入图片描述
我们在canopen目录下新建CMakeLists.txt文件,然后在其中写如下内容, 再次编译
在这里插入图片描述

idf_component_register(SRCS "canopen.hpp" 
                    INCLUDE_DIRS "" "./inc"
)

编译时一定要先点垃圾桶,再点编译
在这里插入图片描述
现在发现报错不一样啦,现在报错是在config.h中,我们打开config.h看下,找不到这些,我们从AVR目录下拷贝的config.h它还以为我们是iar呢,全都注释掉,再次编译
在这里插入图片描述
编译通过了
在这里插入图片描述
接下来我们写Canopen类的构造函数,也就是要初始化canfestival协议栈。我们是主站(也有叫主机的说法),我们需要指定主站的id(node id),指定主站使用的对象字典,指定主站can总线的传输速率。所以我们Canopen的构造函数要有3个参数,一个是node_id,一个是字典,还有can接口的速率,这个我们用默认参数来代替(默认是500Kbps)。还需要维护一个can接口的指针,一个定时器来做canopen的心跳
我们来写构造函数
在这里插入图片描述

#pragma once 

#include "canfestival.h"
#include "can.hpp"


class Canopen {
private:
    uint8_t _nodeId;
    CO_Data *_dict;
    Can0 *_canHander;
public:
    Canopen(uint8_t id, CO_Data *dict, int kbps = 500) : _nodeId(id), _dict(dict) , _canHander(new Can0(kbps)){
        _dict->canHandle = _canHander; /* 设置can接口指针 */
        /* canfestival 初始化流程, 设置nodeid, 设置初始化状态 --> 设置预操作状态(可省略) --> 设置操作状态 */
        setNodeId(_dict, _nodeId);
        setState(dict, Initialisation);
        setState(dict, Operational);

    }

    ~Canopen() {
        if (_canHander) {
            delete _canHander;
        }
    }
};

此时编译是通过的
在这里插入图片描述
是因为我们没有调用,我们在app_main中调用下,看看有啥报错
在这里插入图片描述
我们先用空指针代替字典,解决编译问题。
在这里插入图片描述
果然提示链接报错,明显是源码没有参与编译导致,我们把源码编译进来,修改canopen目录下的CMakeLists.txt
在这里插入图片描述

在这里插入图片描述

先点垃圾桶在编译,发现报如下错误
在这里插入图片描述
这是因为c++的编译器比较严格,我们把这些警告,错误给去掉修改全局的CMakeLists.txt,如下图所示
在这里插入图片描述
再次编译,看编译器咋说
在这里插入图片描述
它说我们没有getElapsedTime,setTimer,canSend这3个函数。
我们在canfestival.h中找到canSend函数的原型。直接实现
在这里插入图片描述
这里说Message类型的消息不能转换 成我们CanMessage类型的消息。我们需要告诉CanMessage如何转换。
在这里插入图片描述
然后编译,报错
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注释掉,然后编译,报错,说不能使用extern “C” 来实现canSend
在这里插入图片描述
修改canfestival.h如下图所示,加入c++编译检测
在这里插入图片描述
在这里插入图片描述
然后编译,报错,说没有getElapsedTime,setTimer
在这里插入图片描述

我们打开timers.h找到这两个函数的声明
在这里插入图片描述
抄过来直接实现,先随便写个糊弄编译器。
在这里插入图片描述
在这里插入图片描述
编译通过。但我们不能使用假的,我们要用定时器来实现canopen的调度。用智能指针管理timer的生命周期,不用管内存泄漏问题。
在这里插入图片描述
必须在周期到了后调用TimeDispatch函数,这个是canfestival的时间管理接口。我们定时器是10us进一次,这个TIMEVAL_MAX是周期
我们打开timerscfg.h,修改timeCount与us,ms的转换和周期。
在这里插入图片描述
把setTimer函数改成如下接口
在这里插入图片描述
然后我们心跳处理好了,我们处理can的接受帧
在这里插入图片描述
接受到一帧can数据把这个数据转交给canDispatch这个接口处理。
这里编辑器提示,不存在用户定义的从 “CanMessage” 到 “Message” 的适当转换C/C++(312)
ESP-IDF Hint: esp_mac.h header file is not included by esp_system.h anymore. It shall then be manually included with #include “esp_mac.h”

std::optional rx
我们要写一个转换函数,如下图
在这里插入图片描述
我们开启canopen协议栈的打印
在这里插入图片描述
在这里插入图片描述
至此移植工作结束

五、验证

我们使用canfestival的字典编辑工具(这个环境搭建还挺复杂,可以在网上看下怎么搭建)来生成一个简单的字典,试下心跳功能是否OK
在这里插入图片描述
点击文件
在这里插入图片描述
点击新建
在这里插入图片描述
在这里插入图片描述
点击确认
在这里插入图片描述
在这里插入图片描述
这里写1000ms发送一次心跳(1000会自动变成0x3E8,不用管),我们按ctrl + s保存,然后点击文件,点击建立词典
在这里插入图片描述
选择目录后,会在目录下生成test.c,test.h,把这两个文件赋值到,项目目录下的canopen下的objdict目录下。
在这里插入图片描述
在这里插入图片描述
把这两个文件包含进来
在main目录下的CMakeLists.txt中加入
在这里插入图片描述
在这里插入图片描述
编译,烧录到开发板,进行观察
在这里插入图片描述
在这里插入图片描述
心跳ok

六、总结

本文成功移植canfestival,并让其工作起来。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_50267418/article/details/144847438

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值