IgH调试注意事项

1,不要在虚拟机测试,否则IgH无法收发数据包

现象:虚拟机中运行IgH master并绑定网卡后,主站由ORPHANED状态转换成IDLE状态,但无法收发数据报。

这是因为虚拟机用的是虚拟网卡,需通过iptables将数据包到转发到真实的网卡上,实现收发数据的目的。但IgH替换了网卡驱动程序,收到数据包后,处理流程没有走内核的网络协议栈,所以工作中tcp/ip层的iptables就不起作用,导致IgH无法正常收发报文。

虚拟机网络原理参考:ubuntu20.04 搭建kernel调试环境第六篇(下)-网络原理-CSDN博客  

解决:物理机安装ubuntu用来测试IgH。

2,获取IgH的INFO、WARNING、ERR信息

root@ubuntu:/home/gsf# echo 7 7 7 7 > /proc/sys/kernel/printk

#define EC_MASTER_INFO(master, fmt, args...) \
    printk(KERN_INFO "EtherCAT %u: " fmt, master->index, ##args)
 
#define EC_MASTER_WARN(master, fmt, args...) \
    printk(KERN_WARNING "EtherCAT WARNING %u: " fmt, master->index, ##args)
 
#define EC_MASTER_ERR(master, fmt, args...) \
    printk(KERN_ERR "EtherCAT ERROR %u: " fmt, master->index, ##args)

3,获取IgH的DEBUG信息

root@ubuntu:/home/gsf# vim /etc/init.d/ethercat

#MASTER_ARGS= 改成下面

MASTER_ARGS="debug_level=2"

务必注意:注意,make modules_install install后,需要重新修改

DEBUG主要是输出一些收发报文的数据,比如:

[73996.353863] EtherCAT DEBUG 0: ec_master_send_datagrams(device_index = 0)
[73996.353863] EtherCAT DEBUG 0: Adding datagram 0x2E
[73996.353864] EtherCAT DEBUG 0: frame size: 46
[73996.353864] EtherCAT DEBUG 0: Sending frame:
[73996.353864] EtherCAT DEBUG: FF FF FF FF FF FF 6C 24 08 29 52 19 88 A4 0E 10 
[73996.353867] EtherCAT DEBUG: 05 2E 01 00 20 01 02 00 00 00 02 00 00 00 00 00 
[73996.353869] EtherCAT DEBUG: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[73996.353871] EtherCAT DEBUG: 00 00 00 00 00 00 00 00 00 00 00 00 

4,dmesg日志不全

现象:IgH源码中加了很多打印,连接从站后,发现dmesg会失了部分日志。

下面的下图显示的是ec_master_idle_thread --> ecrt_master_send --> ec_master_send_datagrams发送数据报文时,增加的printk打印。

datagram->index用的是master->datagram_index++,初始化是master->datagram_index为0,所以所有主站发送的数据报文的index应该是从0递增的,最大值255(master->datagram_index是uint8_t类型),到最大值后又从0开始计数。

原因:主站初始化时,ec_master_idle_thread线程循环执行,循环时间比较短,见下面代码:

ec_master_idle_thread函数:

if (ec_fsm_master_idle(&master->fsm)) {

    set_current_state(TASK_INTERRUPTIBLE);
    schedule_timeout(1);   --------------- 1个jiffies

} else {

    schedule();  ---------切换到其他线程执行,如果系统空闲,会继续执行该线程

}

不接从站,printk信息比较少,可以完整输出。接上从站,代码流程复杂,自己加了很多printk,由于循环时间短,每轮循环都有大量的信息,来不及输出,就丢失了部分log。

解决:

方法一:直接修改主站的循环周期

ec_master_idle_thread函数:

//ec_master_set_send_interval(master, 1000000 / HZ);
ec_master_set_send_interval(master, 5000000); -------改动1,主站周期从4ms改成5s

if (ec_fsm_master_idle(&master->fsm)) {

    // set_current_state(TASK_INTERRUPTIBLE);
    // schedule_timeout(1); 
    msleep(100); ----------改动2,注掉上面2行

} else {

    //schedule(); 
    msleep(100); ----------改动2,注掉上面1行

}

方法二:间接修改主站的循环周期

因为ec_master_idle_thread 每个周期都会执行ecrt_master_send --> ec_master_send_datagrams发送数据报文,所以可以在发送报文时加个延时:

ec_master_idle_thread函数:

//ec_master_set_send_interval(master, 1000000 / HZ);
ec_master_set_send_interval(master, 5000000); -------改动1,主站周期从4ms改成5s


-----------------------------------------------------------------------------


void ec_master_send_datagrams(
        ec_master_t *master, /**< EtherCAT master */
        ec_device_index_t device_index /**< Device index. */
        )
{


    do {
        frame_data = NULL;
        follows_word = NULL;
        more_datagrams_waiting = 0;

        // fill current frame with datagrams
        list_for_each_entry(datagram, &master->datagram_queue, queue) {
            if (datagram->state != EC_DATAGRAM_QUEUED ||
                    datagram->device_index != device_index) {
                continue;
            }

            ……

            list_add_tail(&datagram->sent, &sent_datagrams);
            datagram->index = master->datagram_index++;

            EC_MASTER_DBG(master, 2, "Adding datagram 0x%02X\n",
                    datagram->index);

            msleep(100); ------------在这里加个延时

修改后,log是全的。报文从0开始,发送、接收是一一对应的:

5,过滤掉IgH主站插网线之前的log

IgH主站网卡没有插网线,意味着网卡的link_state处于down状态,ec_master_idle_thread周期性执行ecrt_master_send发送数据报文,在ecrt_master_send中如果网卡处于link down状态,则会设置报文为EC_DATAGRAM_ERROR,在这里加个printk(见下代码),log中过滤关键字EC_DATAGRAM_ERROR就可以了。

void ecrt_master_send(ec_master_t *master)
{
    ec_datagram_t *datagram, *n;
    ec_device_index_t dev_idx;

    if (master->injection_seq_rt != master->injection_seq_fsm) {
        // inject datagram produced by master FSM
        ec_master_queue_datagram(master, &master->fsm_datagram);
        master->injection_seq_rt = master->injection_seq_fsm;
    }

    ec_master_inject_external_datagrams(master);

    for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
            dev_idx++) {
        if (unlikely(!master->devices[dev_idx].link_state)) {
            // link is down, no datagram can be sent
            list_for_each_entry_safe(datagram, n,
                    &master->datagram_queue, queue) {
                if (datagram->device_index == dev_idx) {
                    //在这里加行log
                    printk(KERN_ERR "geshifei %s %d:  set datagram->state = EC_DATAGRAM_ERROR\n",__func__, __LINE__);
                    datagram->state = EC_DATAGRAM_ERROR;
                    list_del_init(&datagram->queue);
                }
            }

6,IgH发送、接收的报文怎么看

以IgH读从站状态的广播报文0x0130为例,打开DEBUG后,demsg看到的报文:

发送报文:

[18773.590655] geshifei ec_master_send_datagrams 1059:  Adding datagram datagram->index=0
[18773.590656] EtherCAT DEBUG 0: frame size: 46
[18773.590656] EtherCAT DEBUG 0: Sending frame:
[18773.590658] EtherCAT DEBUG: FF FF FF FF FF FF 6C 24 08 29 52 19 88 A4 0E 10 
[18773.590664] EtherCAT DEBUG: 07 00 00 00 30 01 02 00 00 00 00 00 00 00 00 00 
[18773.590669] EtherCAT DEBUG: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[18773.590674] EtherCAT DEBUG: 00 00 00 00 00 00 00 00 00 00 00 00 

响应报文:

[18773.710617] EtherCAT DEBUG 0: Received frame:
[18773.710618] EtherCAT DEBUG: FF FF FF FF FF FF 6E 24 08 29 52 19 88 A4 0E 10 
[18773.710624] EtherCAT DEBUG: 07 00 01 00 30 01 02 00 00 00 02 00 01 00 00 00 
[18773.710628] EtherCAT DEBUG: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
[18773.710633] EtherCAT DEBUG: 00 00 00 00 00 00 00 00 00 00 00 00 
[18773.710636] geshifei ec_master_receive_datagrams 1224:  datagram->index=0

7,wireshark报文怎么看

1)注意source mac被从站改动过,为什么改,不清楚,感觉没必要。

2)正常情况下,发送的报文WC = 0,响应报文的WC不为0(存在从站的情况下)

所以可通过上面两个特征来判断哪个是发送报文,哪个是接收报文。

datagram->index用的是master->datagram_index++,初始化是master->datagram_index为0,所以所有主站发送的数据报文的index应该是从0递增的,最大值255(master->datagram_index是uint8_t类型),到最大值后又从0开始计数。

响应的报文,不会(也不能)修改Index值,因为IgH主站程序收到响应报文后,需要根据报文的index去匹配对应的发送报文,然后将发送报文从内部的发送队列中删除。

  • 19
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Xenomai是一个实时操作系统框架,它允许在Linux上实现硬实时性能。IGH(Interrupt-to-User Space Gate)是Xenomai框架中的一个组件,它提供了一种实时事件通知机制,可以将硬件中断快速地通知到用户空间。IGH允许应用程序在中断到达时直接响应,在实时性方面比Linux默认的中断处理要更加可靠和高效。该组件的实时性能使得它非常适合机器人、汽车控制、航空及其他需要高精度实时控制的应用场景。因此,Xenomai IGH被广泛应用在工业和嵌入式系统领域,为用户提供高性能、高可靠性的实时控制。 ### 回答2: Xenomai是实时操作系统,而IGh则是其中的一个内核模块。该模块提供了针对Inter-Process Communication (IPC)的软实时支持,可以确保IPC操作在实时系统中实时响应。它基于POSIX IPC,并提供了安全、可靠的IPC操作。 IGh还支持实时内存分配和管理,可以在内核空间和用户空间之间进行高效的通信,从而支持实时应用程序的开发、调试和部署。同时,IGh还扩展了一些基于消息传递的实时异步通信机制,例如Mailboxes,Semaphores和Message Queues等。这些机制可以被用于实现高性能、高精度的实时调度,保证了高效的硬实时响应能力。总之,IGh是Xenomai实时操作系统中一个非常重要的组成部分,它提供了一些关键的实时特性,包括IPC操作和实时内存管理等,从而可以确保实时系统的稳定性和高性能。 ### 回答3: Xenomai是一个实时操作系统开发框架,提供了一组用于开发硬实时任务的工具和库。而IGh是Xenomai中的一个重要部分,是一个通用接口,它提供了与实时内核交互的方式,实现了任务的优先级、时序、同步和互斥控制等一系列实时特性。IGh的API接口简单易用,对通过POSIX接口开发的应用程序进行了透明的封装,从而使应用程序更容易移植到Xenomai中。IGh还提供了实时性能监测和分析工具,以帮助用户进行实时性能调优。在工业自动化、航空航天、医疗器械等需要高精度、高可靠性和高实时性的应用领域,Xenomai IGh都有着广泛的应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值