1 Star 8 Fork 9

bichongming / SOEM_Imx6ull

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
GPL-2.0

SOEM主站开发笔记-- 点亮第一个LED

本周实现了SOEM 点亮第一个LED的操作,记录一下实现的过程。

开发平台使用的是野火的imx6ull。

1. 下载代码

SOEM的代码在github上就可以找到,它的官网下载链接是:

https://github.com/OpenEtherCATsociety/SOEM

主站代码如果懒得下载可以直接下载我提供的工程。我的项目资料托管在gitee,里面有zip 形式的代码压缩包。

https://gitee.com/jeasonb/soem_-imx6ull

2.编译代码

SOEM的代码支持很多的平台,我的实验是基于linux 平台进行的。另外一方面就是 SOEM 是使用cmake 生成和管理Makefile 文件的,如果读者的开发环境没有cmake的话是需要去安装一个的。

先分享一个错误的编译过程:

root@jeason:~/work/ethercat/SOEM-master# ls
appveyor.yml  bin  ChangeLog  cmake  CMakeLists.txt  doc  Doxyfile  drvcomment.txt  LICENSE  osal  oshw  README.md  soem  test
root@jeason:~/work/ethercat/SOEM-master# mkdir build
root@jeason:~/work/ethercat/SOEM-master# cd build/
root@jeason:~/work/ethercat/SOEM-master/build# cmake ..
-- The C compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
OS is linux
LIB_DIR: lib
-- Configuring done
-- Generating done
-- Build files have been written to: /root/work/ethercat/SOEM-master/build
root@jeason:~/work/ethercat/SOEM-master/build# make
Scanning dependencies of target soem
[  4%] Building C object CMakeFiles/soem.dir/soem/ethercatbase.c.o
[  9%] Building C object CMakeFiles/soem.dir/soem/ethercatcoe.c.o
[ 14%] Building C object CMakeFiles/soem.dir/soem/ethercatconfig.c.o
[ 19%] Building C object CMakeFiles/soem.dir/soem/ethercatdc.c.o
[ 23%] Building C object CMakeFiles/soem.dir/soem/ethercateoe.c.o
[ 28%] Building C object CMakeFiles/soem.dir/soem/ethercatfoe.c.o
[ 33%] Building C object CMakeFiles/soem.dir/soem/ethercatmain.c.o
[ 38%] Building C object CMakeFiles/soem.dir/soem/ethercatprint.c.o
[ 42%] Building C object CMakeFiles/soem.dir/soem/ethercatsoe.c.o
[ 47%] Building C object CMakeFiles/soem.dir/osal/linux/osal.c.o
[ 52%] Building C object CMakeFiles/soem.dir/oshw/linux/nicdrv.c.o
[ 57%] Building C object CMakeFiles/soem.dir/oshw/linux/oshw.c.o
[ 61%] Linking C static library libsoem.a
[ 61%] Built target soem
Scanning dependencies of target slaveinfo
[ 66%] Building C object test/linux/slaveinfo/CMakeFiles/slaveinfo.dir/slaveinfo.c.o
[ 71%] Linking C executable ../../../../bin/slaveinfo
[ 71%] Built target slaveinfo
Scanning dependencies of target eepromtool
[ 76%] Building C object test/linux/eepromtool/CMakeFiles/eepromtool.dir/eepromtool.c.o
[ 80%] Linking C executable ../../../../bin/eepromtool
[ 80%] Built target eepromtool
Scanning dependencies of target simple_test
[ 85%] Building C object test/linux/simple_test/CMakeFiles/simple_test.dir/simple_test.c.o
[ 90%] Linking C executable ../../../../bin/simple_test
[ 90%] Built target simple_test
Scanning dependencies of target my_test
[ 95%] Building C object test/linux/my_test/CMakeFiles/my_test.dir/my_test.c.o
[100%] Linking C executable ../../../../bin/my_test
[100%] Built target my_test
root@jeason:~/work/ethercat/SOEM-master/build#

上面的虽然最后都成功的编译出了可执行的文件,但是 并没有使用交叉编译工具链,编译出来的版本是基于当前的开发服务器版本的。所以就是说如果是需要在树莓派或者ubuntu 上直接搭建SOEM的主站的小伙伴可以使用这种编译方法,但是为了在imx6ull 上跑主站,我们显然是不能这么编译。

我们需要设置工具链!!!

在进行开发之前我已经将交叉编译工具链安装到我的系统路径下,所以我不需要export PATH

root@jeason:~/work/ethercat/SOEM-master/build# which arm-linux-gnueabihf-gcc
/usr/bin/arm-linux-gnueabihf-gcc

如果没有将工具链的路径加入到系统路径 请执行

export PATH=$PATH:/your/tool/path   #  /your/tool/path 是你的工具链的位置

接下来修改系统内的默认编译工具 执行

export CC=arm-linux-gnueabihf-gcc

经过上述的操作之后现在我们的编译工具链就已经设置好了

此时就可以开始新的编译了

root@jeason:~/work/ethercat/SOEM-master_2/SOEM-master# mkdir build
root@jeason:~/work/ethercat/SOEM-master_2/SOEM-master# cd build/
root@jeason:~/work/ethercat/SOEM-master_2/SOEM-master/build# cmake ..
-- The C compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/arm-linux-gnueabihf-gcc
-- Check for working C compiler: /usr/bin/arm-linux-gnueabihf-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
OS is linux
LIB_DIR: lib
-- Configuring done
-- Generating done
-- Build files have been written to: /root/work/ethercat/SOEM-master_2/SOEM-master/build
root@jeason:~/work/ethercat/SOEM-master_2/SOEM-master/build# make
Scanning dependencies of target soem
[  5%] Building C object CMakeFiles/soem.dir/soem/ethercatbase.c.o
[ 10%] Building C object CMakeFiles/soem.dir/soem/ethercatcoe.c.o
[ 15%] Building C object CMakeFiles/soem.dir/soem/ethercatconfig.c.o
[ 21%] Building C object CMakeFiles/soem.dir/soem/ethercatdc.c.o
[ 26%] Building C object CMakeFiles/soem.dir/soem/ethercateoe.c.o
[ 31%] Building C object CMakeFiles/soem.dir/soem/ethercatfoe.c.o
[ 36%] Building C object CMakeFiles/soem.dir/soem/ethercatmain.c.o
[ 42%] Building C object CMakeFiles/soem.dir/soem/ethercatprint.c.o
[ 47%] Building C object CMakeFiles/soem.dir/soem/ethercatsoe.c.o
[ 52%] Building C object CMakeFiles/soem.dir/osal/linux/osal.c.o
[ 57%] Building C object CMakeFiles/soem.dir/oshw/linux/nicdrv.c.o
[ 63%] Building C object CMakeFiles/soem.dir/oshw/linux/oshw.c.o
[ 68%] Linking C static library libsoem.a
[ 68%] Built target soem
Scanning dependencies of target slaveinfo
[ 73%] Building C object test/linux/slaveinfo/CMakeFiles/slaveinfo.dir/slaveinfo.c.o
[ 78%] Linking C executable slaveinfo
[ 78%] Built target slaveinfo
Scanning dependencies of target eepromtool
[ 84%] Building C object test/linux/eepromtool/CMakeFiles/eepromtool.dir/eepromtool.c.o
[ 89%] Linking C executable eepromtool
[ 89%] Built target eepromtool
Scanning dependencies of target simple_test
[ 94%] Building C object test/linux/simple_test/CMakeFiles/simple_test.dir/simple_test.c.o
[100%] Linking C executable simple_test
[100%] Built target simple_test
root@jeason:~/work/ethercat/SOEM-master_2/SOEM-master/build#

可以很明显看到现在工具链已经切换过去了,并且已经编译出来了我们想要的可执行文件。 这一阶段的开发环境搭建就完成了,接下来就是撸代码了。

3.运行demo查看效果

在正式的撸代码之前,我们需要对官方提供的CMakeLists.txt 进行一定程序的修改。

1.设置输出bin 的路径,因为我不希望去SOEM/test/linux/xxx/xx下面去找我的可执行文件,所以要限定可执行文件的生成路径。

在cmake 中添加这条语句:

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) 

这句话的意思就是让输出的文件 到你工程路径下的bin 文件夹

SOEM 为我们提供了三个 DEMO ,分别是①读取从站的信息②从站的 eeprom 操作(读取,写入,这个功能可以实现烧录XML文件)③简单的测试demo

程序编译完成之后我们可以先运行一下测试程序(slaveinfo),检查一下当前环境的硬件信息。程序的运行效果如下:

root@imx6ull14x14evk:/mnt/ethercat/SOEM-master/bin# ls
1.bin  111.bin  eepromtool  my_test  no_cpu.bin  simple_test  slaveinfo  spi.bin
root@imx6ull14x14evk:/mnt/ethercat/SOEM-master/bin# ./slaveinfo eth1
SOEM (Simple Open EtherCAT Master)
Slaveinfo
Starting slaveinfo
ec_init on eth1 succeeded.
1 slaves found and configured.
Calculated workcounter 3
Not all slaves reached safe operational state.
Slave 1 State= 8 StatusCode=   0 : No error

Slave:1
 Name:ECAT-EVB
 Output size: 48bits
 Input size: 48bits
 State: 8
 Delay: 0[ns]
 Has DC: 1
 DCParentport:0
 Activeports:1.0.0.0
 Configured address: 1001
 Man: 00000009 ID: 00009252 Rev: 00000001
 SM0 A:1000 L: 128 F:00010026 Type:1
 SM1 A:1080 L: 128 F:00010022 Type:2
 SM2 A:1100 L:   6 F:00010064 Type:3
 SM3 A:1400 L:   6 F:00010020 Type:4
 FMMU0 Ls:00000000 Ll:   6 Lsb:0 Leb:7 Ps:1100 Psb:0 Ty:02 Act:01
 FMMU1 Ls:00000006 Ll:   6 Lsb:0 Leb:7 Ps:1400 Psb:0 Ty:01 Act:01
 FMMUfunc 0:1 1:2 2:3 3:0
 MBX length wr: 128 rd: 128 MBX protocols : 04
 CoE details: 23 FoE details: 00 EoE details: 00 SoE details: 00
 Ebus current: 0[mA]
 only LRD/LWR:0
End slaveinfo, close socket
End program
root@imx6ull14x14evk:/mnt/ethercat/SOEM-master/bin#

通过上述的片段可以看出,我只是接了一个ethcat的从站模块,而且这个模块只是一个简单的8个LED 和8个按键的板子。

至于eeprom的demo 可以用来烧录xml 的bin文件,这里就不去继续演示了。

4.修改代码

这里要修改的代码是依据simpletest 这个demo的。其路径是在 test\linux\simple_test\simple_test.c

这里面是一个简单的主站的测试demo。

主函数的介绍

//  ./slaveinfo eth1
int main(int argc, char *argv[])
{
   printf("SOEM (Simple Open EtherCAT Master)\nSimple test\n");

   if (argc > 1) // 输入参数检验,只支持一个参数的输入
   {
      /* create thread to handle slave error handling in OP */
//      pthread_create( &thread1, NULL, (void *) &ecatcheck, (void*) &ctime);
      osal_thread_create(&thread1, 128000, &ecatcheck, (void*) &ctime); // 创建一个监控线程,打印换行符和检测错误信息。
      /* start cyclic part */
      simpletest(argv[1]); // 开启测试脚本
   }
   else
   {
      printf("Usage: simple_test ifname1\nifname = eth0 for example\n");
   }

   printf("End program\n");
   return (0);
}

上面的主函数的主要执行部分其实是在 simpletest 中去实现的这一部分的代码如下:(注释在代码中)

/* 注意 : 这部分代码会看到很多变量第一次出现,我刚开始看得时候也是不知道那些是什么  
 * 现在大概就是明白 很多的变量是全局变量,可以作用在整个程序的运行空间之内,所以这些参数会在我们执行init  或者是 config 函数的时候被更新
*/
void simpletest(char *ifname)  // 这里还是需要网卡  我的是  eth1  主要是用于 初始化函数的
{
    int i, j, oloop, iloop, chk;
    //needlf = FALSE;
    inOP = FALSE;

   printf("Starting simple test\n");

   /* initialise SOEM, bind socket to ifname */
   if (ec_init(ifname))  //  初始化网卡,绑定端口等很多的操作 未深究
   {
      printf("ec_init on %s succeeded.\n",ifname);
      /* find and auto-config slaves */

       if ( ec_config_init(FALSE) > 0 )     // 配置从站
      {
         printf("%d slaves found and configured.\n",ec_slavecount);

         ec_config_map(&IOmap);
         // 配置 PDO 映射   这个 IOmap我的理解就是一个 内存池,SOEM 会将PDO 的指针 根据从站的 eeprom 内部的 PDO 参数
         // 将映射的地址 指向这一片的空间,实验测试中发现 ec_slave[0].outputs[0]的地址 就是指向了IOmap的起始地址
         // 所以将其称之为映射是非常合理的!
         ec_configdc();// 配置时钟, 还不是很清楚机理
         printf("Slaves mapped, state to SAFE_OP.\n");
         /* wait for all slaves to reach SAFE_OP state */
         ec_statecheck(0, EC_STATE_SAFE_OP,  EC_TIMEOUTSTATE * 4); // 切换第1个从站到 OP (operation)模式
         // 这段代码应该是初始化的一些操作
         oloop = ec_slave[0].Obytes;  // 从站1的输出的 长度
         if ((oloop == 0) && (ec_slave[0].Obits > 0)) oloop = 1;  // 不足一字节按照一字节来算 ??
         if (oloop > 8) oloop = 8;
         
         iloop = ec_slave[0].Ibytes;
         if ((iloop == 0) && (ec_slave[0].Ibits > 0)) iloop = 1;
         if (iloop > 8) iloop = 8;

         printf("segments : %d : %d %d %d %d\n",ec_group[0].nsegments ,ec_group[0].IOsegment[0],ec_group[0].IOsegment[1],ec_group[0].IOsegment[2],ec_group[0].IOsegment[3]);

         printf("Request operational state for all slaves\n");
         expectedWKC = (ec_group[0].outputsWKC * 2) + ec_group[0].inputsWKC;
         printf("Calculated workcounter %d\n", expectedWKC);
         ec_slave[0].state = EC_STATE_OPERATIONAL;
         /* send one valid process data to make outputs in slaves happy*/
         ec_send_processdata(); // 发送PDO 数据
         ec_receive_processdata(EC_TIMEOUTRET); // 接收PDO数据
         /* request OP state for all slaves */
         ec_writestate(0); // 切换状态
         chk = 200;
         /* wait for all slaves to reach OP state */
         do
         {
            ec_send_processdata();
            ec_receive_processdata(EC_TIMEOUTRET);
            ec_statecheck(0, EC_STATE_OPERATIONAL, 50000);
         }
         while (chk-- && (ec_slave[0].state != EC_STATE_OPERATIONAL));
         // 等待第一个从站的状态切换到OPERATIONAL  或者最多尝试200 次超时
 
   // 这之下就是开始操作的代码了
         if (ec_slave[0].state == EC_STATE_OPERATIONAL )
         {
            printf("Operational state reached for all slaves.\n");
            inOP = TRUE;
                /* cyclic loop */
            for(i = 1; i <= 10000; i++)  // 循环执行 
            {
               ec_send_processdata(); // 发送PDO 数据
               wkc = ec_receive_processdata(EC_TIMEOUTRET); // 接收PDO数据
					// wkc 
					// LRD(读)	1
					// LWR(写)	1
					// LRW(读写)—读成功	1
					// LRW(读写)—写成功	2
					// LRW(读写)—全部完成	3
                    if(wkc >= expectedWKC) // 这句话的意思应该是 从站的操作完成了
                    {
                        printf("Processdata cycle %4d, WKC %d , O:", i, wkc);

                        for(j = 0 ; j < oloop; j++)
                        {
                            printf(" %2.2x", *(ec_slave[0].outputs + j));
                        }

                        printf(" I:");
                        for(j = 0 ; j < iloop; j++)
                        {
                            printf(" %2.2x", *(ec_slave[0].inputs + j));
                        }
                        printf(" T:%"PRId64"\r",ec_DCtime);
                        //needlf = TRUE;
                    }
                    osal_usleep(5000);
                }
                inOP = FALSE;
            }
            else
            {
                printf("Not all slaves reached operational state.\n");
                ec_readstate();
                for(i = 1; i<=ec_slavecount ; i++)
                {
                    if(ec_slave[i].state != EC_STATE_OPERATIONAL) // 看看哪个从站没达到状态
                    {
                        printf("Slave %d State=0x%2.2x StatusCode=0x%4.4x : %s\n",
                            i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode));
                    }
                }
            }
            printf("\nRequest init state for all slaves\n");
            ec_slave[0].state = EC_STATE_INIT;
            /* request INIT state for all slaves */
            ec_writestate(0); 
        }
        else
        {
            printf("No slaves found!\n");
        }
        printf("End simple test, close socket\n");
        /* stop SOEM, close socket */
        ec_close();
    }
    else
    {
        printf("No socket connection on %s\nExecute as root\n",ifname);
    }
}

关于上述的代码的 wkc 部分,我参考了 孔晨星 同志的博客

https://blog.csdn.net/kcx295810/article/details/113128954

wkc介绍

不是很懂这一部分。 以上就是官方的代码了

我自己的代码改动在这里, 主要的内容都在注释里面了

/** \file
 * \brief Example code for Simple Open EtherCAT master
 *
 * Usage : simple_test [ifname1]
 * ifname is NIC interface, f.e. eth0
 *
 * This is a minimal test.
 *
 * (c)Arthur Ketels 2010 - 2011   
 */

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "ethercat.h"
#define EC_TIMEOUTMON 500

char IOmap[4096];  //  个人理解 这里就是给提供了一块内存空间
OSAL_THREAD_HANDLE thread1;      // demo 里面的一个 检测线程
OSAL_THREAD_HANDLE thread_freash;// 笔者自己加的  每5ms 就去刷新一下pdo 数据
int expectedWKC;
volatile int wkc;
boolean inOP;
uint8 currentgroup = 0;
// 状态监测线程,主要是监测ethcat 的异常状态? 
// 这个线程笔者并没去深究,大概的用途就是去 定时的检测当前从站的在线状态,及时发现从站掉线
OSAL_THREAD_FUNC ecatcheck( void *ptr )
{
    int slave;
    (void)ptr;                  /* Not used */
    while(1)
    {
        if( inOP && ((wkc < expectedWKC) || ec_group[currentgroup].docheckstate))
        {           
            /* one ore more slaves are not responding */
            ec_group[currentgroup].docheckstate = FALSE;
            ec_readstate();// 读取从站状态
            for (slave = 1; slave <= ec_slavecount; slave++) // 遍历
            {
               if ((ec_slave[slave].group == currentgroup) && (ec_slave[slave].state != EC_STATE_OPERATIONAL)) 
               {
                  ec_group[currentgroup].docheckstate = TRUE;
                  if (ec_slave[slave].state == (EC_STATE_SAFE_OP + EC_STATE_ERROR))
                  {
                     printf("ERROR : slave %d is in SAFE_OP + ERROR, attempting ack.\n", slave);
                     ec_slave[slave].state = (EC_STATE_SAFE_OP + EC_STATE_ACK);
                     ec_writestate(slave);  // 将指定的状态写到指定的从站之中
                  }
                  else if(ec_slave[slave].state == EC_STATE_SAFE_OP)
                  {
                     printf("WARNING : slave %d is in SAFE_OP, change to OPERATIONAL.\n", slave);
                     ec_slave[slave].state = EC_STATE_OPERATIONAL;
                     ec_writestate(slave);
                  }
                  else if(ec_slave[slave].state > EC_STATE_NONE)
                  {
                     if (ec_reconfig_slave(slave, EC_TIMEOUTMON))
                     {
                        ec_slave[slave].islost = FALSE;
                        printf("MESSAGE : slave %d reconfigured\n",slave);
                     }
                  }
                  else if(!ec_slave[slave].islost)
                  {
                     /* re-check state */
                     ec_statecheck(slave, EC_STATE_OPERATIONAL, EC_TIMEOUTRET);
                     if (ec_slave[slave].state == EC_STATE_NONE)
                     {
                        ec_slave[slave].islost = TRUE;
                        printf("ERROR : slave %d lost\n",slave);
                     }
                  }
               }
               if (ec_slave[slave].islost) // 检查从站是否 离线?
               {
                  if(ec_slave[slave].state == EC_STATE_NONE)
                  {
                     if (ec_recover_slave(slave, EC_TIMEOUTMON)) // 恢复和从站之间的连接
                     {
                        ec_slave[slave].islost = FALSE;
                        printf("MESSAGE : slave %d recovered\n",slave);
                     }
                  }
                  else
                  {
                     ec_slave[slave].islost = FALSE;
                     printf("MESSAGE : slave %d found\n",slave);
                  }
               }
            }
            if(!ec_group[currentgroup].docheckstate)
               printf("OK : all slaves resumed OPERATIONAL.\n");
        }
        osal_usleep(10000);
    }
}

// PDO 刷新线程,定时的去 收  发 PDO 数据。
OSAL_THREAD_FUNC ecatfreash( void *ptr )
{
   (void)ptr;         
   int i, oloop, iloop, chk;              /* Not used */
   inOP = FALSE;
   char *ifname = "eth1";
   if (ec_init(ifname))  // 初始化网卡1  基于野火的 i.mx6ull  这个是右面的那个网卡
   {
      printf("ec_init on %s succeeded.\n",ifname);
      /* find and auto-config slaves */

      if ( ec_config_init(FALSE) > 0 )  //  检查是否初始化完成了
      {
         printf("%d slaves found and configured.\n",ec_slavecount);

         ec_config_map(&IOmap); //根据 FMMU 的地址 完成数据的映射。

         ec_configdc();  //  配置时钟信息

         printf("Slaves mapped, state to SAFE_OP.\n");
         /* wait for all slaves to reach SAFE_OP state */
         ec_statecheck(0, EC_STATE_SAFE_OP,  EC_TIMEOUTSTATE * 4);  // 检查当前的状态

         oloop = ec_slave[0].Obytes;
         if ((oloop == 0) && (ec_slave[0].Obits > 0)) oloop = 1;
         if (oloop > 8) oloop = 8;
         iloop = ec_slave[0].Ibytes;
         if ((iloop == 0) && (ec_slave[0].Ibits > 0)) iloop = 1;
         if (iloop > 8) iloop = 8;

         printf("segments : %d : %d %d %d %d\n",ec_group[0].nsegments ,ec_group[0].IOsegment[0],ec_group[0].IOsegment[1],ec_group[0].IOsegment[2],ec_group[0].IOsegment[3]);

         printf("Request operational state for all slaves\n");
         expectedWKC = (ec_group[0].outputsWKC * 2) + ec_group[0].inputsWKC;
         printf("Calculated workcounter %d\n", expectedWKC);
         ec_slave[0].state = EC_STATE_OPERATIONAL;
         /* send one valid process data to make outputs in slaves happy*/
         ec_send_processdata();              
         ec_receive_processdata(EC_TIMEOUTRET);
         /* request OP state for all slaves */
         ec_writestate(0);
         chk = 200;
         /* wait for all slaves to reach OP state */
         do
         {
            ec_send_processdata();
            ec_receive_processdata(EC_TIMEOUTRET);
            ec_statecheck(0, EC_STATE_OPERATIONAL, 50000);
         }
         while (chk-- && (ec_slave[0].state != EC_STATE_OPERATIONAL)); //等待第一个从站进入到可以操作的状态 或者200个周期没进入 判定为超时
         if (ec_slave[0].state == EC_STATE_OPERATIONAL )
         {
            printf("Operational state reached for all slaves.\n");
            inOP = TRUE;
                /* cyclic loop */
            //for(i = 1; i <= 10000; i++)
            while(1)  // 笔者的改动之处 线程在这里进行无限的循环,每隔5ms 刷新一下pdo
            {
               ec_send_processdata();
               wkc = ec_receive_processdata(EC_TIMEOUTRET);  //
               osal_usleep(5000);                 
            }
               inOP = FALSE;
         }
         else
         {
               printf("Not all slaves reached operational state.\n");
               ec_readstate();
               for(i = 1; i<=ec_slavecount ; i++)
               {
                  if(ec_slave[i].state != EC_STATE_OPERATIONAL)
                  {
                     printf("Slave %d State=0x%2.2x StatusCode=0x%4.4x : %s\n",
                           i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode));
                  }
               }
         }
         printf("\nRequest init state for all slaves\n");
         ec_slave[0].state = EC_STATE_INIT;
         /* request INIT state for all slaves */
         ec_writestate(0);
      }
      else
      {
         printf("No slaves found!\n");
      }
   }
}

int main(int argc, char *argv[])
{  
   printf("SOEM (Simple Open EtherCAT Master)\nSimple test\n");
   if (argc > 1)
   {      
      /* create thread to handle slave error handling in OP */
      // pthread_create( &thread1, NULL, (void *) &ecatcheck, (void*) &ctime);
      osal_thread_create(&thread1, 128000, &ecatcheck, NULL);
      /* start cyclic part */
      // simpletest(argv[1]);      
      
      osal_thread_create(&thread_freash, 128000, &ecatfreash, NULL);
      // 这里需要等待一段时间,让刷新现成初始化好
      while( ec_slave[0].outputs == 0);  //  这个等待是必须的, 因为创建的子线程  ecatfreash  需要一段时间才能完成初始化工作
      while(1)
      {
         ec_slave[0].outputs[0] = ec_slave[0].inputs[0]; // 将第一个从站的 输入 等于输出
         // 显示的效果上面就是  我按下按键之后 从站上的灯就会亮起
         // 测试使用的从站模块是只有8个LED 和 8个 按键的模块。
         osal_usleep(5000);
      }              
   }else
   {  
      printf("Usage: simple_test ifname1\nifname = eth0 for example\n");
   }      
   ec_close();       
   printf("End program %s\n",argv[0]);
   return (0);
}

5.测试效果

运行的效果就是按下板载的按键 S5 对应的D5 亮起

其余的按键也是一样的 S1 按下 D1 亮起

演示

GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.

简介

基于imx6ull的SOEM迁移程序,只是一个简单的demo。可以刷新PDO,其余更高深的应用我也在学习中 展开 收起
C
GPL-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
C
1
https://gitee.com/jeasonb/soem_-imx6ull.git
git@gitee.com:jeasonb/soem_-imx6ull.git
jeasonb
soem_-imx6ull
SOEM_Imx6ull
master

搜索帮助