当前位置:   article > 正文

Ubuntu22.04 lgh Ethercat master安装笔记_ubuntu igh

ubuntu igh

         最近打算买一台伺服电机,测试一下EtherCAT 接口。打算采用开源的lgh。网络上有许多的lgh 安装指南,但是照着安装仍然由一些问题,只能边做边记笔记。

硬件

  • Dell T3360 台式机
  • UP Squared 6000 边缘控制器

ubuntu 操作系统版本:

  1. root@T3660:/home/yao2023/etherlab# uname -a
  2. Linux T3660 6.2.0-31-generic #31~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Aug 16 13:45:26 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
  1. root@T3660:/home/yao2023/etherlab# lsb_release -a
  2. No LSB modules are available.
  3. Distributor ID: Ubuntu
  4. Description: Ubuntu 22.04.3 LTS
  5. Release: 22.04
  6. Codename: jammy

下载源代码

git clone https://gitlab.com/etherlab.org/ethercat.git /home/yao2023/etherlab     

配置和安装

配置

  1. ./bootstrap
  2. sudo su
  3. ./configure --disable-8139too --prefix=/opt/etherlab --sysconfdir=/etc

安装

  1. make
  2. make all modules
  3. sudo make modules_install install
  4. sudo depmod

查看以太网的mac地址

使用 ifconfig

  1. root@T3660:/home/yao2023/etherlab# ifconfig
  2. docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
  3. inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
  4. inet6 fe80::42:cbff:fe8a:1e8f prefixlen 64 scopeid 0x20<link>
  5. ether 02:42:cb:8a:1e:8f txqueuelen 0 (以太网)
  6. RX packets 0 bytes 0 (0.0 B)
  7. RX errors 0 dropped 0 overruns 0 frame 0
  8. TX packets 77 bytes 10819 (10.8 KB)
  9. TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
  10. enp0s31f6: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
  11. ether 74:86:e2:19:66:0f txqueuelen 1000 (以太网)
  12. RX packets 0 bytes 0 (0.0 B)
  13. RX errors 0 dropped 0 overruns 0 frame 0
  14. TX packets 0 bytes 0 (0.0 B)
  15. TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
  16. device interrupt 19 memory 0x72600000-72620000
  17. enp4s0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
  18. ether a0:36:9f:30:32:a1 txqueuelen 1000 (以太网)
  19. RX packets 0 bytes 0 (0.0 B)
  20. RX errors 0 dropped 0 overruns 0 frame 0
  21. TX packets 0 bytes 0 (0.0 B)
  22. TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
  23. device memory 0x72100000-721fffff
  1. chmod +x /opt/etherlab/etc/init.d/ethercat
  2. sudo cp -f script/init.d/ethercat /etc/init.d/
  3. sudo mkdir -p /etc/sysconfig/
  4. sudo chown yao.yao /etc/sysconfig/
  5. cp -f /opt/etherlab/etc/sysconfig/ethercat /etc/sysconfig/
  6. sudo mkdir -p /etc/udev/rules.d/
  7. sudo chown yao.yao /etc/udev/rules.d/
  8. touch /etc/udev/rules.d/99-ethercat.rules
  9. echo MASTER0_DEVICE="$(cat /sys/class/net/enp2s0/address)" > /etc/sysconfig/ethercat
  10. echo DEVICE_MODULES="generic" >> /etc/sysconfig/ethercat
  11. chmod go+rwx /etc/udev/rules.d/99-ethercat.rules
  12. echo "KERNEL=="\"EtherCAT[0-9]*\"", MODE="\"777\"", GROUP=""\"ethercat\"" > /etc/udev/rules.d/99-ethercat.rules

UP Squared 6000 系统上的安装

硬件 ATOM 6000

操作系统 ubuntu 22.04

内核: 15.5.0-1043-intel-iotg

UP Squared 6000 计算机上遇到了下面的问题,启动时: 

  1. root@yao-UPN-EHL01:/home/yao/etherlab# sudo /etc/init.d/ethercat start
  2. Starting EtherCAT master 1.5.2 modprobe: ERROR: could not insert 'ec_master': Exec format error
  3. failed

网络上建议的方法:

使用dmesg命令查看原因。

dmesg

  1. [ 1158.061004] ec_master: disagrees about version of symbol module_layout
  2. [ 1414.135696] ec_master: disagrees about version of symbol module_layout

        结果是disagrees about version of symbol module_layout。看来是版本不兼容。ec_master是一个linux 内核库,它必须与当前运行的内核兼容。

1 使用uname -r 命令看当前内核的版本为 15.5.0-1046-intel-iotg

2 使用modinfo命令看/lib/modules/5.15.0-1043-intel-iotg/ethercat/master/ec_master.ko的信息

  1. modinfo /lib/modules/5.15.0-1043-intel-iotg/ethercat/master/ec_master.ko
  2. filename: /lib/modules/5.15.0-1043-intel-iotg/ethercat/master/ec_master.ko
  3. version: 1.5.2 1.5.2-343-gb029271b
  4. license: GPL
  5. description: EtherCAT master driver module
  6. author: Florian Pose <fp@igh-essen.com>
  7. srcversion: 3EC58E246A5BE6A6C05916D
  8. depends:
  9. retpoline: Y
  10. name: ec_master
  11. vermagic: 5.15.0-1036-intel-iotg SMP mod_unload modversions
  12. parm: main_devices:MAC addresses of main devices (array of charp)
  13. parm: backup_devices:MAC addresses of backup devices (array of charp)
  14. parm: debug_level:Debug level (uint)
  15. parm: run_on_cpu:Bind kthreads to a specific cpu (uint)

            结果发现它们的版本不同,一个是1043,一个是1036。可能是我一开始指定了15.5.0-1036-intel-iotg 安装后,以后make clean 去不掉mc-master.ko。于是:

          删除 /lib/modules/5.15.0-1043-intel-iotg/ec_master.ko(这个版本是15.5.0-1036-intel-iotg)

然后,重新编译,成功了。

运行

  1. root@T3660:/home/yao2023/etherlab# sudo /etc/init.d/ethercat start
  2. Starting EtherCAT master 1.6.0-rc1 done
  3. root@T3660:/home/yao2023/etherlab# sudo /etc/init.d/ethercat stop
  4. Shutting down EtherCAT master 1.6.0-rc1 done

应用代码

  1. /**
  2. * compile : gcc test.c -o test -I/opt/etherlab/include -L/opt/etherlab/lib -lethercat
  3. */
  4. #include <errno.h>
  5. #include <signal.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <sys/resource.h>
  9. #include <sys/time.h>
  10. #include <sys/types.h>
  11. #include <unistd.h>
  12. #include <sys/mman.h>
  13. /****************************************************************************/
  14. #include "ecrt.h"
  15. /****************************************************************************/
  16. /*Application Parameters*/
  17. #define TASK_FREQUENCY 10 /*Hz*/
  18. #define TARGET_VELOCITY 110000 /*target velocity*/
  19. #define PROFILE_VELOCITY 3 /*Operation mode for 0x6060:0*/
  20. /*****************************************************************************/
  21. /*EtherCAT*/
  22. static ec_master_t *master = NULL;
  23. static ec_master_state_t master_state = {};
  24. static ec_domain_t *domain1 = NULL;
  25. static ec_domain_state_t domain1_state = {};
  26. static ec_slave_config_t *sc;
  27. static ec_slave_config_state_t sc_state = {};
  28. /****************************************************************************/
  29. /*Process Data*/
  30. static uint8_t *domain1_pd = NULL;
  31. #define DM3E 0,0 /*EtherCAT address on the bus*/
  32. #define VID_PID 0x00004321,0x00008100 /*Vendor ID, product code*/
  33. /*Offsets for PDO entries*/
  34. static struct{
  35. unsigned int operation_mode;
  36. unsigned int ctrl_word;
  37. unsigned int target_velocity;
  38. unsigned int status_word;
  39. unsigned int current_velocity;
  40. unsigned int current_position;
  41. }offset;
  42. const static ec_pdo_entry_reg_t domain1_regs[] = {
  43. {DM3E, VID_PID, 0x6040, 0, &offset.ctrl_word},
  44. {DM3E, VID_PID, 0x6060, 0, &offset.operation_mode },
  45. {DM3E, VID_PID, 0x60FF, 0, &offset.target_velocity},
  46. {DM3E, VID_PID, 0x6041, 0, &offset.status_word},
  47. {DM3E, VID_PID, 0x606C, 0, &offset.current_velocity},
  48. {DM3E, VID_PID, 0x6064, 0, &offset.current_position},
  49. {}
  50. };
  51. /***************************************************************************/
  52. /*Config PDOs*/
  53. static ec_pdo_entry_info_t device_pdo_entries[] = {
  54. /*RxPdo 0x1600*/
  55. {0x6040, 0x00, 16},
  56. {0x6060, 0x00, 8 },
  57. {0x60FF, 0x00, 32},
  58. /*TxPdo 0x1A00*/
  59. {0x6041, 0x00, 16},
  60. {0x606C, 0x00, 32},
  61. {0x6064, 0x00, 32}
  62. };
  63. static ec_pdo_info_t device_pdos[] = {
  64. //RxPdo
  65. {0x1600, 3, device_pdo_entries + 0 },
  66. //TxPdo
  67. {0x1A00, 3, device_pdo_entries + 3 }
  68. };
  69. static ec_sync_info_t device_syncs[] = {
  70. { 0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE },
  71. { 1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE },
  72. { 2, EC_DIR_OUTPUT, 1, device_pdos + 0, EC_WD_DISABLE },
  73. { 3, EC_DIR_INPUT, 1, device_pdos + 1, EC_WD_DISABLE },
  74. { 0xFF}
  75. };
  76. /**************************************************************************/
  77. /*************************************************************************/
  78. void check_domain1_state(void)
  79. {
  80. ec_domain_state_t ds;
  81. ecrt_domain_state(domain1, &ds);
  82. if (ds.working_counter != domain1_state.working_counter)
  83. {
  84. printf("Domain1: WC %u.\n", ds.working_counter);
  85. }
  86. if (ds.wc_state != domain1_state.wc_state)
  87. {
  88. printf("Domain1: State %u.\n", ds.wc_state);
  89. }
  90. domain1_state = ds;
  91. }
  92. void check_master_state(void)
  93. {
  94. ec_master_state_t ms;
  95. ecrt_master_state(master, &ms);
  96. if (ms.slaves_responding != master_state.slaves_responding)
  97. {
  98. printf("%u slave(s).\n", ms.slaves_responding);
  99. }
  100. if (ms.al_states != master_state.al_states)
  101. {
  102. printf("AL states: 0x%02X.\n", ms.al_states);
  103. }
  104. if (ms.link_up != master_state.link_up)
  105. {
  106. printf("Link is %s.\n", ms.link_up ? "up" : "down");
  107. }
  108. master_state = ms;
  109. }
  110. /****************************************************************************/
  111. void check_slave_config_states(void)
  112. {
  113. ec_slave_config_state_t s;
  114. ecrt_slave_config_state(sc, &s);
  115. if (s.al_state != sc_state.al_state)
  116. {
  117. printf("slave: State 0x%02X.\n", s.al_state);
  118. }
  119. if (s.online != sc_state.online)
  120. {
  121. printf("slave: %s.\n", s.online ? "online" : "offline");
  122. }
  123. if (s.operational != sc_state.operational)
  124. {
  125. printf("slave: %soperational.\n", s.operational ? "" : "Not ");
  126. }
  127. sc_state = s;
  128. }
  129. /*******************************************************************************/
  130. void cyclic_task()
  131. {
  132. static uint16_t command=0x004F;//用来帮助判断状态字的值
  133. uint16_t status;
  134. /*Receive process data*/
  135. ecrt_master_receive(master);
  136. ecrt_domain_process(domain1);
  137. /*Check process data state(optional)*/
  138. check_domain1_state();
  139. //Check for master state
  140. check_master_state();
  141. //Check for slave configuration state(s)
  142. check_slave_config_states();
  143. /*Read state*/
  144. status = EC_READ_U16(domain1_pd + offset.status_word);//读取状态字
  145. //DS402 CANOpen over EtherCAT status machine
  146. if( (status & command) == 0x0040 )
  147. {
  148. EC_WRITE_U16(domain1_pd + offset.ctrl_word, 0x0006 );
  149. EC_WRITE_S8(domain1_pd + offset.operation_mode, PROFILE_VELOCITY);
  150. //设置控制模式
  151. command = 0x006F;
  152. }
  153. else if( (status & command) == 0x0021)
  154. {
  155. EC_WRITE_U16(domain1_pd + offset.ctrl_word, 0x0007 );
  156. command = 0x006F;
  157. }
  158. else if( (status & command) == 0x0023)
  159. {
  160. EC_WRITE_U16(domain1_pd + offset.ctrl_word, 0x000f );
  161. command = 0x006F;
  162. }
  163. //operation enabled
  164. else if( (status & command) == 0x0027)
  165. {
  166. EC_WRITE_S32(domain1_pd + offset.target_velocity, TARGET_VELOCITY);
  167. EC_WRITE_U16(domain1_pd + offset.ctrl_word, 0x001f );
  168. }
  169. /*Send process data*/
  170. ecrt_domain_queue(domain1);
  171. ecrt_master_send(master);
  172. }
  173. /****************************************************************************/
  174. int main(int argc, char **argv)
  175. {
  176. printf("Requesting master...\n");
  177. master = ecrt_request_master(0);
  178. if (!master)
  179. {
  180. exit(EXIT_FAILURE);
  181. }
  182. domain1 = ecrt_master_create_domain(master);
  183. if (!domain1)
  184. {
  185. exit(EXIT_FAILURE);
  186. }
  187. if (!(sc = ecrt_master_slave_config(master, DM3E, VID_PID)))
  188. {
  189. fprintf(stderr, "Failed to get slave configuration for slave!\n");
  190. exit(EXIT_FAILURE);
  191. }
  192. printf("Configuring PDOs...\n");
  193. if (ecrt_slave_config_pdos(sc, EC_END, device_syncs))
  194. {
  195. fprintf(stderr, "Failed to configure slave PDOs!\n");
  196. exit(EXIT_FAILURE);
  197. }
  198. else
  199. {
  200. printf("*Success to configuring slave PDOs*\n");
  201. }
  202. if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs))
  203. {
  204. fprintf(stderr, "PDO entry registration failed!\n");
  205. exit(EXIT_FAILURE);
  206. }
  207. printf("Activating master...\n");
  208. if (ecrt_master_activate(master)) {
  209. exit(EXIT_FAILURE);
  210. }
  211. else
  212. {
  213. printf("*Master activated*\n");
  214. }
  215. if (!(domain1_pd = ecrt_domain_data(domain1))) {
  216. exit(EXIT_FAILURE);
  217. }
  218. printf("*It's working now*\n");
  219. while (1)
  220. {
  221. usleep(100000/TASK_FREQUENCY);
  222. cyclic_task();
  223. }
  224. return EXIT_SUCCESS;
  225. }

编译

gcc testB.c -o test -lethercat 

运行

  • 启动ethercat 
  • 运行程序test

结束

下一步,连接松下的伺服驱动,希望顺利一点。

参考文章:

Ubuntu 20.04 , Igh 安装,驱动汇川伺服电机

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号