关于程序员:NUC980-DIY项目大挑战-EtherCAT实现

2次阅读

共计 3729 个字符,预计需要花费 10 分钟才能阅读完成。

本文由 RT-Thread 论坛用户 @lg28870983 原创公布:https://club.rt-thread.org/as…

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/1uWbi…
提取码: wdtt

SOEM 曾经提交 PR #1260,期待通过。有问题可通过本帖留言或邮件分割我,大家一起改良。

正文完
 0