1.背景
2.EtherCAT主站軟件方案
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功能之前調用。
1staticrt_uint32_tus_ticks;
2voidosal_timer_init(void)
3{
4rt_uint32_tcmp=ETIMER_GetCompareData(5);
5us_ticks=1*cmp/(1000000/RT_TICK_PER_SECOND);
6rt_kprintf("rt-threadhwtimer51us=%dticks
",us_ticks);
7}
8intosal_usleep(uint32usec)
9{
10//udelay(usec);
11/*ajustmentforprecision*/
12//usec-=usec/4080;
13usec-=usec/1500;
14/*rt_hw_us_delayworkforadelaylessthan16us*/
15do{
16if(usec>=1000)
17{
18rt_hw_us_delay(1000);
19usec-=1000;
20}else{
21rt_hw_us_delay(usec);
22usec=0;
23}
24}while(usec>0);
25return0;
26}
27intosal_gettimeofday(structtimeval*tv,structtimezone*tz)
28{
29//returngettimeofday(tv,tz);
30RT_ASSERT(tv!=NULL);
31rt_uint32_ttimer_tick,rt_tick;
32rt_base_tlevel=rt_hw_interrupt_disable();
33timer_tick=ETIMER_GetCounter(5);
34rt_tick=rt_tick_get();
35rt_hw_interrupt_enable(level);
36tv->tv_sec=rt_tick/1000;
37tv->tv_usec=(rt_tick%1000)*1000+timer_tick/us_ticks;
38return0;
39}
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協議?;竟δ軠y試。在終端中輸入 soem_test + 回車即可。
我接了一個匯川IS620N驅動器,下面是輸出的部分內容:
1Slave:1
2Name:IS620N
3Outputsize:96bits
4Inputsize:224bits
5State:4
6Delay:0[ns]
7HasDC:1
8DCParentport:0
9Activeports:1.0.0.0
10Configuredaddress:1001
11Man:00100000ID:000c0108Rev:00010001
12SM0A:1000L:128F:00010026Type:1
13SM1A:1400L:128F:00010022Type:2
14SM2A:1800L:12F:00010064Type:3
15SM3A:1c00L:28F:00010020Type:4
16FMMU0Ls:00000000Ll:12Lsb:0Leb:7Ps:1800Psb:0Ty:02Act:01
17FMMU1Ls:0000000cLl:28Lsb:0Leb:7Ps:1c00Psb:0Ty:01Act:01
18FMMUfunc0:11:22:03:0
19MBXlengthwr:128rd:128MBXprotocols:04
20CoEdetails:0dFoEdetails:00EoEdetails:00SoEdetails:00
21Ebuscurrent:0[mA]
22onlyLRD/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. 總結
版權聲明:本文為RT-Thread論壇用戶「lg28870983」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:
https://club.rt-thread.org/ask/article/160414965e80294e.html
———————End———————
你可以添加微信:rtthread2020 為好友,注明:公司+姓名,拉進RT-Thread官方微信交流群!
愛我就給我點在看
點擊閱讀原文
-
RT-Thread
+關注
關注
31文章
1293瀏覽量
40190
原文標題:NUC980 DIY項目大挑戰 - EtherCAT實現
文章出處:【微信號:RTThread,微信公眾號:RTThread物聯網操作系統】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論