### 源码移植与应用

#### 源码构建

**源码下载与构建方法**

1. 简介
本示例程序包含两种编程接口实现驱动电机示例
通过不同接口创建实时或非实时应用程序, 以下两种通用实时应用程序接口仅在创建实时应用时不同以外无其他不同，用户可通过 IGH ETHERCAT 接口创建 ethercat 相关驱动协议流程，编写相应的驱动程序

2. igh ethercat 实时程序示例以及构建示例

```shell
git clone https://codeup.sinsegye.com.cn/automation/so/mom/rtigh-cpp-template.git
cd rtigh-cpp-template
./build.sh
# ./build.sh -b debug  # 编译 debug 版本程序
# 目标生成物存储在 install 路径下
# install
# └── x64_Release
# └── bin
# ├── igh_ec_posix          # Posix 接口示例可执行文件
# ├── igh_ec_xenomai        # xkernel Alchemy 接口示例可执行文件
# └── igh_ec_xenomai_posix  # xkernel Posix 接口示例可执行文件
```

igh ethercat 相关文档以及接口文档可查看如下链接

- [IGHEtherCAT Doc](https://docs.etherlab.org/ethercat/1.6/pdf/ethercat_doc.pdf)
- [IGHEtherCAT 文档(中文版仅供参考)](https://blog.csdn.net/qq_43530144/article/details/106068637)

#### 交叉编译工具链安装方法

以 linux 系统为例, 安装方式如下

**Warning** 默认将交叉编译工具链安装在 /opt 目录, 若因需要更改交叉编译工具链路径，则同步更新工程模板下的交叉编译工具链配置文件



```shell
# 以 x.x.x 版本为例, x86_64-sinsegye-linux-gnu_linux_x.x.x.zip
sudo unzip x86_64-sinsegye-linux-gnu_linux_x.x.x.zip -d /opt
```

### 程序示例说明

**Posix 接口**
程序示例-主程序
  ```c
    int main(int argc, char **argv) {
        if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
            perror("mlockall failed\n");
            return -1;
        }

        master = ecrt_request_master(0);
        if (!master) {
            return -1;
        }

        domain = ecrt_master_create_domain(master);
        if (!domain) {
            return -1;
        }

        sc_server = ecrt_master_slave_config(master, SERVER_SLAVE_POS, SINSEGYE_S_V3);
        if (!sc_server) {
            return -1;
        }

        ecrt_slave_config_sdo32(sc_server, 0x60C5, 0x00, 1000);
        ecrt_slave_config_sdo32(sc_server, 0x60C6, 0x00, 1000);

        printf("Configuring PDOs...\n");

        if (ecrt_slave_config_pdos(sc_server, EC_END, slave_syncs)) {
            fprintf(stderr, "Failed to configure slave 2 PDOs!\n");
            exit(EXIT_FAILURE);
        } else {
            printf("*Success to configuring slave 2 PDOs*\n");
        }

        if (ecrt_domain_reg_pdo_entry_list(domain, g_domain_regs)) {
            fprintf(stderr, "server PDO entry registration failed!\n");
            exit(EXIT_FAILURE);
        }

        ecrt_slave_config_dc(sc_server, 0x0300, PERIOD_NS, 4400000, 0, 0);

        printf("Activating master...\n");
        if (ecrt_master_activate(master)) return -1;

        if (!(domain_pd = ecrt_domain_data(domain))) {
            return -1;
        }

        struct sched_param param = {.sched_priority = 82};

        pthread_attr_t th_attr;
        pthread_attr_init(&th_attr);
        pthread_attr_setdetachstate(&th_attr, PTHREAD_CREATE_JOINABLE);
        pthread_attr_setinheritsched(&th_attr, PTHREAD_EXPLICIT_SCHED);
        pthread_attr_setschedpolicy(&th_attr, SCHED_FIFO);
        pthread_attr_setschedparam(&th_attr, &param);

        int ret = pthread_create(&cyclic_thread, &th_attr, &CyclicTask, NULL);
        if (ret) {
            fprintf(stderr, "%s: pthread_create cyclic task failed\n", strerror(-ret));
            return 1;
        }

        sleep(1);

        pthread_join(cyclic_thread, NULL);

        return 0;
    }
  ```
**Alchemy 接口**
程序示例-主程序
  ```c
    int main(int argc, char *argv[]) {
        int ret;

        signal(SIGTERM, SignalHandler);
        signal(SIGINT, SignalHandler);

        if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
            rt_printf("mlockall failed\n");
            return -1;
        }

        master = ecrt_request_master(0);
        if (!master) {
            return -1;
        }

        domain = ecrt_master_create_domain(master);
        if (!domain) {
            return -1;
        }

        sc_server = ecrt_master_slave_config(master, SERVER_SLAVE_POS, SINSEGYE_S_V3);
        if (!sc_server) {
            return -1;
        }

        ecrt_slave_config_sdo32(sc_server, 0x60C5, 0x00, 1000); // 设置加速度
        ecrt_slave_config_sdo32(sc_server, 0x60C6, 0x00, 1000); // 设置减速度

        rt_printf("Configuring PDOs...\n");

        if (ecrt_slave_config_pdos(sc_server, EC_END, slave_syncs)) {
            rt_printf("Failed to configure slave 2 PDOs!\n");
            exit(EXIT_FAILURE);
        } else {
            rt_printf("*Success to configuring slave 2 PDOs*\n");
        }

        if (ecrt_domain_reg_pdo_entry_list(domain, g_domain_regs)) {
            rt_printf("server PDO entry registration failed!\n");
            exit(EXIT_FAILURE);
        }

        ecrt_slave_config_dc(sc_server, 0x0300, PERIOD_NS, 4400000, 0, 0);

        rt_printf("Activating master...\n");
        if (ecrt_master_activate(master))
            return -1;

        if (!(domain_pd = ecrt_domain_data(domain))) {
            return -1;
        }

        ret = rt_task_create(&my_task, "my_task", 0, 80, kT_FPU);
        if (ret < 0) {
            rt_printf("Failed to create task: %s\n", strerror(-ret));
            return -1;
        }

        rt_printf("Starting my_task...\n");
        ret = rt_task_start(&my_task, &CyclicTask, NULL);
        if (ret < 0) {
            rt_printf("Failed to start task: %s\n", strerror(-ret));
            return -1;
        }

        while (run) {
            sched_yield();
        }

        rt_printf("Deleting realtime task...\n");
        rt_task_delete(&my_task);

        rt_printf("End of Program\n");
        ecrt_release_master(master);

        return 0;
    }
  ```