Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
nuc980
EtherCAT
NUC980 DIY项目大挑战 - EtherCAT实现
10.00
发布于 2022-05-08 13:33:39 浏览:3707
订阅该版
[tocm] ### 1.背景 最近计划DIY一个EtherCAT控制器,一直在看资料和选型,初步定了NUC980的方案,主要是看中NUC980的RAM比较大,采购还算方便(最近缺芯,大家都懂)。 选定硬件之后,NUC980跑什么系统呢?从以往经验来看,ARM9一般跑linux比较多,资源也好找,同时官方提供BSP。但这次任务有点特殊,EtherCAT对实时性要求比较高,linux不是最合适的。结合MCU开发经验,就准备上个RTOS,以前M3和M4的芯片,主要用FreeRTOS,最近也开始用RT-Thread。新唐官方也推出了NUC980的RT-Thread版BSP,对开发者非常友好,最终决定了NUC980+RT-Thread的方案。 刚好最近官方有个DIY项目官方活动,就报了名。 ### 2.EtherCAT主站软件方案 EtherCAT本身还是比较复杂的,我们就不自己造轮子了,考虑用开源方案,毕竟硬件成本这么低,商用方案是真的用不起啊! 现在开源主站主要就两种,SOEM和IGH(相关的资料网上很多,这儿就不展开了),IGH只支持linux,所以只能选SOME,最新版本是SOEM1.4,本次移植就基于该版本。 ### 3. 移植过程 **3.1 RT-Thread 下载** 本次移植基于最新发布的release4.1.0, 这个可以到github下载,最近Gitee也更新了。移植EtherCAT之前,首先把Nuvoton的BSP跑起来。这个参考官方的文档就可以了。 **3.2 Some移植** 下载soem-1.4.0,将整个目录放在rt-thread项目里,下图是我的目录,供参考 在some-1.4.0及其子目录中需要手工编辑SConscript脚本,这儿就不展开了。后续我把源码打包发上来。 Some移植主要是三个文件 osal.c,oshw.c和nicdrv.c。 osal.c 主要是微秒及的延时和定时函数; oshw.c 主要是网络端和本机端数据的大小端转换; nicdrv.c 主要是网络数据收发。 Some已经给出了很多操作系统移植,我的移植是基于rtk,这个是嵌入式系统,和我们的开发环境最接近。 **3.2.1 osal.c移植** 主要内容是实现osal_usleep和osal_gettimeofday两个函数。 我开始思路是自定义一个定时器用于EtherCAT,当时用了Timer4。等实现差不多了,发现系统时钟用的是Timer5,很多地方功能重复。最终和系统共用Timer5,省了个Timer,代码也简化了不少。下面就是改动过的相关代码,osal_timer_init这个初始化函数要在启动EhterCAT功能之前调用。 ``` static rt_uint32_t us_ticks; void osal_timer_init(void) { rt_uint32_t cmp = ETIMER_GetCompareData(5); us_ticks = 1 * cmp / (1000000 / RT_TICK_PER_SECOND); rt_kprintf("rt-thread hwtimer5 1us = %d ticks\n", us_ticks); } int osal_usleep (uint32 usec) { //udelay(usec); /*ajustment for precision*/ //usec -= usec / 4080; usec -= usec / 1500; /*rt_hw_us_delay work for a delay less than 16us*/ do{ if(usec>=1000) { rt_hw_us_delay(1000); usec -= 1000; }else{ rt_hw_us_delay(usec); usec = 0; } }while(usec>0); return 0; } int osal_gettimeofday(struct timeval *tv, struct timezone *tz) { // return gettimeofday(tv, tz); RT_ASSERT (tv != NULL); rt_uint32_t timer_tick,rt_tick; rt_base_t level = rt_hw_interrupt_disable(); timer_tick = ETIMER_GetCounter(5); rt_tick = rt_tick_get(); rt_hw_interrupt_enable(level); tv->tv_sec = rt_tick/1000; tv->tv_usec = (rt_tick % 1000)*1000 + timer_tick / us_ticks; return 0; } ``` **3.2.2 oshw.c移植** 不需做什么工作。 **3.2.3 nicdrv.c移植** 主要修改就是调用自己的网络发送和接收函数,我把它们命名为net_send和net_recv。这两个函数最好的实现是直接操作网卡(或者叫emac),我现在的实现参考了tcpdump的方法,在协议栈中加钩子(hook)实现,这样对原来系统影响最小,网口除了EtherCAT,还可以当正常的网口用。 ecx_setupnic函数中创建mutex(这个按照rt-thread格式改一下即可),安装网络钩子 ecx_closenic函数中删除mutex,卸载网络钩子。 **3.2.4 net_hook.c实现** 主要实现EtherCAT数据帧收发,中间加了个环形缓冲区用于接收。具体原理就是在网卡加个钩子函数,有数据来的时候先经过钩子函数,我们把EtherCAT数据帧截住,不传给原来的lwip协议栈;如果要发送数据,就直接调用发送函数,绕过lwip协议栈。这样也不影响lwip协议栈工作。 具体实现见附件。 **3.2.5 some基本功能测试** 采用官方的slave_info测试代码,测试主要分为时钟测试和soem EtherCAT协议栈基本功能测试。在终端中输入 soem_test + 回车即可。 我接了一个汇川IS620N驱动器,下面是输出的部分内容: ``` Slave:1 Name:IS620N Output size: 96bits Input size: 224bits State: 4 Delay: 0[ns] Has DC: 1 DCParentport:0 Activeports:1.0.0.0 Configured address: 1001 Man: 00100000 ID: 000c0108 Rev: 00010001 SM0 A:1000 L: 128 F:00010026 Type:1 SM1 A:1400 L: 128 F:00010022 Type:2 SM2 A:1800 L: 12 F:00010064 Type:3 SM3 A:1c00 L: 28 F:00010020 Type:4 FMMU0 Ls:00000000 Ll: 12 Lsb:0 Leb:7 Ps:1800 Psb:0 Ty:02 Act:01 FMMU1 Ls:0000000c Ll: 28 Lsb:0 Leb:7 Ps:1c00 Psb:0 Ty:01 Act:01 FMMUfunc 0:1 1:2 2:0 3:0 MBX length wr: 128 rd: 128 MBX protocols : 04 CoE details: 0d FoE details: 00 EoE details: 00 SoE details: 00 Ebus current: 0[mA] only LRD/LWR:0 ``` ### 4. 运动控制测试 基础工作做好以后,我们就能真正的控制电机运行了。在控制电机运行之前,还需要了解CIA402相关的规范,启动伺服需要按照规范要求,按顺序来。 程序主要流程如下,具体代码见附件。 a)初始化时钟 osal_timer_init b)初始化网卡ec_init c)等待进入INIT态 d)初始化驱动器(is620n)ec_config_init e)DC配置 f)申请并等待进入Pre-OP态 g)配置过程数据TxPDO/RxPDO(自定义函数process_data_config) h)配置FMMU ec_config_map i)申请并等待进入Safe-OP态 j)设置CSP模式 k)发送和接收过程数据1次,触发SLAVE l)申请并等待进入OP态 m)进入过程数据收发循环 在进入数据数据收发循环后,按次序发送控制字启动伺服(6040h发送6,7和15),然后就可以不断发送新的控制位置让电机转起来了! ### 5. 总结 整个移植过程还是充满了挑战,主要也是因为今年才开始接触EtherCAT,很多概念是边学边用,网上也参考了不少同学的帖子。很多人反应汇川的伺服用SOEM驱动DC同步模式总是有问题,确实遇到了很多奇奇怪怪的问题。经过这两个月的折腾,总算开了个头,基础打好了。 下一步可优化的就是现在的网络移植改用直接操作emac,这样可以减少网络抖动。 附件程序里还参考本站贴子移植了uffs文件系统,编译如果有问题,可能还需要下载uffs、ramdisk、optparse和netutils包。 链接: https://pan.baidu.com/s/1uWbiUfzX1R061OJQ5LG6OQ?pwd=wdtt 提取码: wdtt SOEM已经提交PR #1260,等待通过。有问题可通过本帖留言或邮件联系我,大家一起改进。
22
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
lg28870983
这家伙很懒,什么也没写!
文章
1
回答
2
被采纳
0
关注TA
发私信
相关文章
1
ENV下的NUC980能移动到RT STUDIO上吗?
2
NUC980 生成 UFFS 文件系统镜像
3
怎样生成基于NUC980、rt_thread系统的板级支持包(MDK开发环境)
4
这个接口在哪个文件里面的。
5
NUC980IOT开发板rt工程创建文件
6
NUC980之EMAC功能模块的硬件介绍
7
nuc980DDR和MDK的IRAM是怎样的映射关系
8
ncu977 跑rtthread 操作io没有反应
9
NUC980开发板生成Keil工程找不到Device和编译出错
10
rtthread studio创建NUC980工程无法设置RTC日期和时间
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
机器人操作系统 (ROS2) 和 RT-Thread 通信
4
国产MCU移植系列教程汇总,欢迎查看!
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
ART-Pi
FinSH
USB
文件系统
DMA
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
ota在线升级
WIZnet_W5500
UART
flash
packages_软件包
cubemx
PWM
freemodbus
BSP
潘多拉开发板_Pandora
定时器
ADC
中断
flashDB
socket
Debug
GD32
编译报错
msh
keil_MDK
at_device
rt_mq_消息队列_msg_queue
ulog
C++_cpp
SFUD
本月问答贡献
出出啊
1512
个答案
341
次被采纳
小小李sunny
1437
个答案
289
次被采纳
张世争
774
个答案
167
次被采纳
crystal266
546
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
2
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
2
次点赞
crystal266
2
篇文章
1
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部