基于STM32构建EtherCAT主站(SOEM方案)2

2020年的12月初,我写了一篇《基于STM32构建EtherCAT主站(SOEM方案)1》博客,同时也上传了基于原子stm32f767开发板的源码(soem1.4.0版本,采用HAL库,控制伺服)。有兴趣的可以去我的博客目录找找。后续我会把整理好的源码上传到GitHub,如果发现了bug,或者我有讲错的地方,可以在评论区留言。欢迎指正。
在这里插入图片描述
在这里插入图片描述
基于STM32构建EtherCAT主站(SOEM方案)2_第1张图片
之前打算把移植过程都写到博客上的,后来由于有其它事要忙,就没继续写了。期间也有一些网友私信我,为什么不把博客写完。
好吧,在2022年元旦前后,我将把后续的几篇移植博客写完。未来,如果有时间的话,我还会分享一些《igh+xenomai》demo(一些有意思的小项目)。

我的梦想是写一个EtherCAT五轴数控系统(实现基础功能即可,在zynq、imx6ull、stm32mp157中选用一款作为数控系统的芯片跑linux或者其它实时系统,基于QT开发上位机),研究EtherCAT主站只是朝梦想方向前进的一小步,希望能在30岁之前把系统干出来。

哈哈,言归正传,继续来讲soem。王惠娇同志的硕士论文《基于嵌入式平台的EtherCAT主站实现研究》,把soem移植讲的很清楚了,有兴趣的可以读一下。如果你有移植lwip的经验,那么移植soem还是挺容易的。我个人移植过soem1.3.1和soem1.4.0,这两个版本基本没啥变动,因此移植过程也是一样的。soem项目中主要包含osal、oshw、soem三个文件夹。soem库采用了分层设计的思想,把操作系统层和硬件层抽象了出来,因此移植过程才会比较简单,只需修改osal和oshw文件夹中的文件即可。
基于STM32构建EtherCAT主站(SOEM方案)2_第2张图片
移植的代码我是参考rtk子文件夹的(soem官方提供的移植平台代码),这是最贴近单片机开发的一个平台,lw_emac对应于stm32网卡驱动。
基于STM32构建EtherCAT主站(SOEM方案)2_第3张图片

SOEM源码目录结构

soem:主站主体
osal:操作系统抽象层。提供了函数的抽象,如定时器和线程等。
oshw:硬件抽象层,网卡驱动。
test:应用示例代码

整个移植过程

1.stm32定时器驱动:tim2用于系统时基,为osal.c中的函数提供时间信息。tim5定时器中断用于应用层中的周期性程序。
2.以太网驱动,lan8720芯片初始化,以太网接收函数、以太网发送函数
3.nicdrv.c:把bfin_EMAC_send、bfin_EMAC_recv等函数替换成stm32的以太网收发函数。
4.oshw.c文件中修改一些大小端序的定义。
5.编译keil,采用–gnu编译(keil中可以设置),还会有一些其它的报错,主要是一些编译器导致的问题。根据报错修改即可。
6.参考soem/test/rtk/main.c文件,把其main函数移植到stm32中。
7.ethercat IO从站控制例程编写、ethercat伺服从站例程编写。
基于STM32构建EtherCAT主站(SOEM方案)2_第4张图片
90%的移植工作集中在图中的红圈部分,大家根据自己板子的硬件,酌情修改即可。
下面的内容取自https://lipoyang.hatenablog.com/entry/2019/12/08/101951,一位日本网友的soem移植总结,大家在github上也能找到他的代码。
https://github.com/lipoyang/SOEM4Arduino
基于STM32构建EtherCAT主站(SOEM方案)2_第5张图片

1.soem文件中的移植

(1.1)节省内存资源

最初的 SOEM 使用过多的 RAM 在单片微控制器上运行。因此,通过根据目标的内存容量减少以下常量来减少 RAM 使用量。
EC_MAXODLIST:CoE 对象字典的最大数量
EC_MAXOELIST:CoE 对象条目的最大数量
EC_MAXSLAVE:从站连接的最大数量
EC_MAXBUF:以太网帧缓冲区的数量

(1.2)时钟

原SOEM使用时间。但是,单片机系统可能没有实时时钟,或者即使有实时时钟,也可能精度不够。我决定用计时器来计算从微机启动开始经过的时间,并用它来代替。

(1.3)省略 LAN 端口冗余

原始 SOEM 支持两个 LAN 端口以进行冗余配置。但是,在只有一个 LAN 端口的系统的情况下,RAM 是浪费的。因此,删除以下与 LAN 口冗余配置相关的变量和函数。
ecx_redportt、ecx_init_redundant、ec_init_redundant

2.osal文件夹中的移植

(2.1)定时器和时钟

实现如下函数,根据微机对定时器进行抽象。
osal_usleep:在以 usec 为单位指定的时间内停止处理。
osal_timer_start:通过以 usec 为单位指定超时时间来启动计时器。
osal_timer_is_expired:返回计时器是否超时。
它还实现了以下抽象时钟的函数。但是,如(1.2)所述,这次将使用从微机启动开始的经过时间。
osal_current_time:获取当前时间。
osal_time_diff:返回两次之间的差值。

(2.2)线程

实现如下函数,根据微机对定时器进行抽象。但是,SOEM 本身并没有使用线程功能。如果在应用端不使用线程,即使不实现也没有问题。
osal_thread_create:创建线程
osal_thread_create_rt:创建实时线程

(2.3)调试输出

为调试输出实现 EC_PRINT 函数。在微机系统的情况下,通常输出到UART(串口)进行调试。 EC_PRINT 函数由宏定义,只有在定义了 EC_DEBUG 宏时才有效。 EC_PRINT 函数的实质是作为一个函数实现的,该函数采用与 printf 函数等效的可变长度参数。如果可以使用 printf 函数,请使用 #define EC_PRINT printf。

3.oshw的移植

(3.1)字节序

以太网协议是大端,但有些 CPU 是大端,有些是小端。因此,实现以下函数应该吸收字节顺序的差异。
oshw_htons:将 16 位整数从 CPU 字节顺序转换为大端。
oshw_ntohs:将 16 位整数从 big endian 转换为 CPU 字节顺序。

(3.2)搜索网络接口

实现以下功能以搜索可用的网络接口。但是,在大多数微机系统中,网络接口都是固定为已知的,如果应用端不需要这个功能,即使不实现也没有问题。
oshw_find_adapters:列出可用的网络接口。
oshw_free_adapters:释放用于枚举网络接口的内存。

(3.3)网卡设备驱动(这是最难的部分!)

实现以下抽象 NIC 设备的函数。
基于STM32构建EtherCAT主站(SOEM方案)2_第6张图片
这是最难的一点,但要点总结如下。

(3.3.1)临界区

为了保护临界区,如果是操作系统环境,请使用互斥锁等。即使在没有 OS 的微型计算机系统中也使用中断,则需要中断禁用/启用处理。

(3.3.2)冗長構成の省略

如(1.3)所述,如果要省略LAN口的冗余配置,删除第二个LAN口相关的变量redport和redstate,处理使用这些变量的冗余配置也删除。

(3.3.3)句柄

在 Windows、Mac 和 Linux 等操作系统环境中,网络通信是基于套接字的,“RAW 套接字”也用于发送和接收原始以太网帧。处理这个的变量是 sockhandle。但是,除非需要在微机系统中处理套接字,否则不需要使用该变量。

(3.3.4)以太网控制器控制处理的实现

这是最重要的部分。根据需要移植的硬件实现以太网控制器的初始化处理、终止处理、帧发送处理、帧接收处理,并从需要的位置调用。
基于STM32构建EtherCAT主站(SOEM方案)2_第7张图片

结语

soem移植大体就这些,说难不难,说简单也不简单。虽然我在2020年就已经把soem移植完了,也驱动了一些伺服,但是并没有在工业中应用,因此对移植后的可靠性也没有把握。自己也在工控行业干过,深知工业产品的高要求,以及细微的问题可能会带来巨大的损失,因此我的博客仅供学习和参考。
电机也不仅仅能转就完事了,我在nucleo f767平台移植过soem主站,板子上除了f767芯片,还有一颗stm32用于stlink功能。f767的时钟由另一颗stm32的PA8引脚提供(MCO功能),频率为8Mhz。测试过程中,发现伺服会周期性抖动。仔细研究后发现,是由于8Mhz的抖动有点大,比如实际是7.99999Mhz。最后只能通过参考时钟,动态调整主站周期,从而解决了问题。说白了就是DC同步,同步方法也是我自己琢磨的,也不敢保证对不对,也许只是碰巧解决了我单伺服的同步问题吧。
我是在研究生期间开始搞ethercat主站的,课题是基于igh+xenomai搞三轴数控。工作后,ethercat并不是我的工作内容,只是周末研究一下。开头说过,我的梦想是diy一套ethercat五轴数控系统。我真的很想有人送我一套工业ethercat主站源码,哈哈,可惜没有,因此只能自己折腾了。xenomai、igh、soem我都搞过,因为是单兵作战的缘故,许多坑要自己踩。经常一个问题要琢磨好久,没人指导,只能在百度、csdn、google、知网上疯狂找资料,反复读代码、调试。唉,搞起来真心累,好几次想放弃。
因为体验过那种被问题卡住时,寝食难安的状态。所以我把一些学习调试的过程写成博客,分享一下。我时间和能力有限,有些问题我也回答不出来。有时工作太累,或者遇到烦心事,没精力和心情回答。请见谅哈。

你可能感兴趣的:(ethercat,stm32,arm,嵌入式硬件,ethercat)