函数 | 功能和用途 | 使用场景 |
---|---|---|
ec_sdoerror2string |
将SDO(Service Data Object)错误代码转换为可读的字符串。 | 用于诊断和记录EtherCAT SDO通信中的错误。 |
ec_ALstatuscode2string |
将AL(Application Layer)状态代码转换为可读的字符串。 | 用于解释EtherCAT从站的AL状态信息。 |
ec_soeerror2string |
将SOE(Servo Drive Object Error)错误代码转换为可读的字符串。 | 用于诊断和记录伺服驱动器中的错误。 |
ec_mbxerror2string |
将邮箱(Mailbox)错误代码转换为可读的字符串。 | 用于处理EtherCAT邮箱通信中的错误。 |
ecx_err2string |
将EtherCAT通信错误结构体ec_errort 转换为可读的字符串。 |
用于诊断和记录SOEM库中的通信错误。 |
ecx_elist2string |
将EtherCAT上下文结构体ecx_contextt 中的从站错误信息转换为可读的字符串。 |
用于获取从站错误信息的字符串表示。 |
ec_elist2string (仅在EC_VER1下可用) |
将从站错误信息转换为可读的字符串。 | 同上,但在早期的SOEM版本中使用此函数。 |
ethercatprint.h
和 ethercatprint.c
文件是 SOEM(Simple Open EtherCAT Master)库的一部分,用于提供对 EtherCAT 网络中通信错误和状态的处理和打印输出功能。以下是这两个文件的主要功能和作用:
错误信息转换:
通信错误分析:
状态信息输出:
适用于故障排除:
提供用户友好的错误信息:
总的来说,ethercatprint.h
和 ethercatprint.c
文件的主要功能和作用是为 EtherCAT 网络提供详细的错误诊断和状态报告,以帮助用户更好地理解网络问题并采取适当的行动。这对于在 EtherCAT 应用中确保可靠性和稳定性非常重要。
char* ec_sdoerror2string(uint32 sdoerrorcode)
sdoerrorcode
:一个表示 EtherCAT SDO 错误代码的 32 位整数。char* ec_ALstatuscode2string(uint16 ALstatuscode)
ALstatuscode
:一个表示 EtherCAT AL 状态代码的 16 位整数。char* ec_soeerror2string(uint16 errorcode)
errorcode
:一个表示 EtherCAT SOE 错误代码的 16 位整数。char* ec_mbxerror2string(uint16 errorcode)
errorcode
:一个表示 EtherCAT 邮箱通信错误代码的 16 位整数。char* ecx_err2string(const ec_errort Ec)
Ec
:一个表示 EtherCAT 主站错误的 ec_errort
结构体。char* ecx_elist2string(ecx_contextt *context)
context
:一个指向 ecx_contextt
结构体的指针,表示 EtherCAT 主站上下文。char* ec_elist2string(void)
/*
* 在GNU通用公共许可证版本2下获得许可,附带例外情况。请参阅
* 项目根目录中的LICENSE文件以获取完整的许可信息
*/
/** \file
* \brief
* 用于将EtherCAT错误转换为可读消息的模块。
*
* 使用SDO中止消息和AL状态代码来传达从站错误给用户应用程序。此模块将二进制代码转换为可读文本。有关定义的错误代码,请参阅EtherCAT协议文档。
*/
#include
#include "oshw.h"
#include "ethercattype.h"
#include "ethercatmain.h"
#define EC_MAXERRORNAME 127
/** SDO错误列表类型定义 */
typedef struct
{
/** 从SDO返回的错误代码 */
uint32 errorcode;
/** 可读的错误描述 */
char errordescription[EC_MAXERRORNAME + 1];
} ec_sdoerrorlist_t;
/** AL状态代码列表类型定义 */
typedef struct
{
/** AL状态代码 */
uint16 ALstatuscode;
/** 可读描述 */
char ALstatuscodedescription[EC_MAXERRORNAME + 1];
} ec_ALstatuscodelist_t;
/** SoE错误列表类型定义 */
typedef struct
{
/** SoE错误代码 */
uint16 errorcode;
/** 可读描述 */
char errordescription[EC_MAXERRORNAME + 1];
} ec_soeerrorlist_t;
/** MBX错误列表类型定义 */
typedef struct
{
/** MBX错误代码 */
uint16 errorcode;
/** 可读描述 */
char errordescription[EC_MAXERRORNAME + 1];
} ec_mbxerrorlist_t;
char estring[EC_MAXERRORNAME];
/** SDO错误列表定义 */
const ec_sdoerrorlist_t ec_sdoerrorlist[] = {
{0x00000000, "无错误" },
{0x05030000, "切换位未更改" },
{0x05040000, "SDO协议超时" },
{0x05040001, "客户端/服务器命令规范不合法或未知" },
{0x05040005, "内存不足" },
{0x06010000, "不支持对对象的访问" },
{0x06010001, "尝试读取只写对象" },
{0x06010002, "尝试写入只读对象" },
{0x06010003, "子索引无法写入,对于写访问,SI0必须为0" },
{0x06010004, "不支持可变长度对象的SDO完全访问" },
{0x06010005, "对象长度超过邮箱大小" },
{0x06010006, "对象映射到RxPDO,SDO下载被阻止" },
{0x06020000, "对象在对象目录中不存在" },
{0x06040041, "对象无法映射到PDO" },
{0x06040042, "要映射的对象数量和长度将超过PDO长度" },
{0x06040043, "一般参数不兼容原因" },
{0x06040047, "设备内部不兼容性通用" },
{0x06060000, "由于硬件错误而访问失败" },
{0x06070010, "数据类型不匹配,服务参数的长度不匹配" },
{0x06070012, "数据类型不匹配,服务参数的长度太高" },
{0x06070013, "数据类型不匹配,服务参数的长度太低" },
{0x06090011, "子索引不存在" },
{0x06090030, "参数值范围超出(仅适用于写访问)" },
{0x06090031, "参数值太高" },
{0x06090032, "参数值太低" },
{0x06090036, "最大值小于最小值" },
{0x08000000, "一般错误" },
{0x08000020, "数据无法传输或存储到应用程序" },
{0x08000021, "由于本地控制,数据无法传输或存储到应用程序" },
{0x08000022, "由于当前设备状态,数据无法传输或存储到应用程序" },
{0x08000023, "对象字典动态生成失败或不存在对象字典" },
{0xffffffff, "未知" }
};
/** AL状态代码列表定义 */
const ec_ALstatuscodelist_t ec_ALstatuscodelist[] = {
{0x0000 , "无错误" },
{0x0001 , "未指定的错误" },
{0x0002 , "没有内存" },
{0x0011 , "无效的请求状态更改" },
{0x0012 , "未知的请求状态" },
{0x0013 , "不支持引导" },
{0x0014 , "没有有效的固件" },
{0x0015 , "无效的邮箱配置" },
{0x0016 , "无效的邮箱配置" },
{0x0017 , "无效的同步管理器配置" },
{0x0018 , "没有有效的输入" },
{0x0019 , "没有有效的输出" },
{0x001A , "同步错误" },
{0x001B , "同步管理器看门狗" },
{0x001C , "无效的同步管理器类型" },
{0x001D , "无效的输出配置" },
{0x001E , "无效的输入配置" },
{0x001F , "无效的看门狗配置" },
{0x0020 , "从站需要冷启动" },
{0x0021 , "从站需要INIT" },
{0x0022 , "从站需要PREOP" },
{0x0023 , "从站需要SAFEOP" },
{0x0024 , "无效的输入映射" },
{0x0025 , "无效的输出映射" },
{0x0026 , "设置不一致" },
{0x0027 , "不支持Freerun" },
{0x0028 , "不支持同步" },
{0x0029 , "Freerun需要3缓冲模式" },
{0x002A , "背景看门狗" },
{0x002B , "没有有效的输入和输出" },
{0x002C , "严重的同步错误" },
{0x002D , "没有同步错误" }, // 曾经是“无效的输出FMMU配置”
{0x002E , "无效的输入FMMU配置" },
{0x0030 , "无效的DC SYNC配置" },
{0x0031 , "无效的DC锁存配置" },
{0x0032 , "PLL错误" },
{0x0033 , "DC同步IO错误" },
{0x0034 , "DC同步超时错误" },
{0x0035 , "DC无效的同步周期时间" },
{0x0036 , "DC无效的sync0周期时间" },
{0x0037 , "DC无效的sync1周期时间" },
{0x0041 , "MBX_AOE" },
{0x0042 , "MBX_EOE" },
{0x0043 , "MBX_COE" },
{0x0044 , "MBX_FOE" },
{0x0045 , "MBX_SOE" },
{0x004F , "MBX_VOE" },
{0x0050 , "EEPROM无法访问" },
{0x0051 , "EEPROM错误" },
{0x0060 , "从站本地重新启动" },
{0x0061 , "设备识别值已更新" },
{0x00f0 , "应用程序控制器可用" },
{0xffff , "未知" }
};
/** SoE错误列表定义 */
const ec_soeerrorlist_t ec_soeerrorlist[] = {
{0x0000, "无错误" },
{0x1001, "没有IDN" },
{0x1009, "对元素1的无效访问" },
{0x2001, "没有名称" },
{0x2002, "名称传输太短" },
{0x2003, "名称传输太长" },
{0x2004, "名称无法更改(只读)" },
{0x2005, "此时名称受写保护" },
{0x3002, "属性传输太短" },
{0x3003, "属性传输太长" },
{0x3004, "属性无法更改(只读)" },
{0x3005, "此时属性受写保护" },
{0x4001, "没有单位" },
{0x4002, "单位传输太短" },
{0x4003, "单位传输太长" },
{0x4004, "单位无法更改(只读)" },
{0x4005, "此时单位受写保护" },
{0x5001, "没有最小输入值" },
{0x5002, "最小输入值传输太短" },
{0x5003, "最小输入值传输太长" },
{0x5004, "最小输入值无法更改(只读)" },
{0x5005, "此时最小输入值受写保护" },
{0x6001, "没有最大输入值" },
{0x6002, "最大输入值传输太短" },
{0x6003, "最大输入值传输太长" },
{0x6004, "最大输入值无法更改(只读)" },
{0x6005, "此时最大输入值受写保护" },
{0x7002, "操作数据传输太短" },
{0x7003, "操作数据传输太长" },
{0x7004, "操作数据无法更改(只读)" },
{0x7005, "此时操作数据受写保护(状态)" },
{0x7006, "操作数据小于最小输入值" },
{0x7007, "操作数据小于最大输入值" },
{0x7008, "无效操作数据:不支持配置的IDN" },
{0x7009, "操作数据受密码保护" },
{0x700A, "操作数据受写保护,已配置为周期性" },
{0x700B, "无效的间接寻址:(例如,数据容器,列表处理)" },
{0x700C, "操作数据受其他设置的写保护" },
{0x700D, "保留" },
{0x7010, "过程命令已激活" },
{0x7011, "过程命令不可中断" },
{0x7012, "此时无法执行过程命令(状态)" },
{0x7013, "无法执行过程命令(无效或错误的参数)" },
{0x7014, "无数据状态" },
{0x8001, "没有默认值" },
{0x8002, "默认值传输太长" },
{0x8004, "默认值无法更改,只读" },
{0x800A, "无效的驱动号" },
{0x800A, "一般错误" },
{0x800A, "没有元素被寻址" },
{0xffff, "未知" }
};
/** MBX错误列表定义 */
const ec_mbxerrorlist_t ec_mbxerrorlist[] = {
{0x0000, "无错误" },
{0x0001, "6字节邮箱头的语法错误" },
{0x0002, "不支持邮箱协议" },
{0x0003, "通道字段包含错误的值" },
{0x0004, "不支持该服务" },
{0x0005, "无效的邮箱头" },
{0x0006, "接收的邮箱数据长度太短" },
{0x0007, "从站内存不足" },
{0x0008, "数据长度不一致" },
{0xffff, "未知" }
};
/** 查找与SDO错误代码相关的文本字符串。
*
* @param[in] sdoerrorcode = 根据EtherCAT协议定义的SDO错误代码
* @return 可读字符串
*/
const char* ec_sdoerror2string( uint32 sdoerrorcode)
{
int i = 0;
while ( (ec_sdoerrorlist[i].errorcode != 0xffffffffUL) &&
(ec_sdoerrorlist[i].errorcode != sdoerrorcode) )
{
i++;
}
return ec_sdoerrorlist[i].errordescription;
}
/** 查找与AL状态代码相关的文本字符串。
*
* @param[in] ALstatuscode = 根据EtherCAT协议定义的AL状态代码
* @return 可读字符串
*/
char* ec_ALstatuscode2string( uint16 ALstatuscode)
{
int i = 0;
while ( (ec_ALstatuscodelist[i].ALstatuscode != 0xffff) &&
(ec_ALstatuscodelist[i].ALstatuscode != ALstatuscode) )
{
i++;
}
return (char *) ec_ALstatuscodelist[i].ALstatuscodedescription;
}
/** 查找与SoE错误代码相关的文本字符串。
*
* @param[in] errorcode = 根据EtherCAT协议定义的SoE错误代码
* @return 可读字符串
*/
char* ec_soeerror2string( uint16 errorcode)
{
int i = 0;
while ( (ec_soeerrorlist[i].errorcode != 0xffff) &&
(ec_soeerrorlist[i].errorcode != errorcode) )
{
i++;
}
return (char *) ec_soeerrorlist[i].errordescription;
}
/** 查找与MBX错误代码相关的文本字符串。
*
* @param[in] errorcode = 根据EtherCAT协议定义的MBX错误代码
* @return 可读字符串
*/
char* ec_mbxerror2string( uint16 errorcode)
{
int i = 0;
while ( (ec_mbxerrorlist[i].errorcode != 0xffff) &&
(ec_mbxerrorlist[i].errorcode != errorcode) )
{
i++;
}
return (char *) ec_mbxerrorlist[i].errordescription;
}
/** 将错误转换为文本字符串。
*
* @param[in] Ec = 描述错误的结构体。
* @return 可读字符串
*/
char* ecx_err2string(const ec_errort Ec)
{
char timestr[20];
sprintf(timestr, "时间:%12.3f", Ec.Time.sec + (Ec.Time.usec / 1000000.0) );
switch (Ec.Etype)
{
case EC_ERR_TYPE_SDO_ERROR:
{
sprintf(estring, "%s SDO 错误:从站:%d 索引:%4.4x.%2.2x 错误:%8.8x %s\n",
timestr, Ec.Slave, Ec.Index, Ec.SubIdx, (unsigned)Ec.AbortCode, ec_sdoerror2string(Ec.AbortCode));
break;
}
case EC_ERR_TYPE_EMERGENCY:
{
sprintf(estring, "%s 紧急错误:从站:%d 错误:%4.4x\n",
timestr, Ec.Slave, Ec.ErrorCode);
break;
}
case EC_ERR_TYPE_PACKET_ERROR:
{
sprintf(estring, "%s 数据包错误:从站:%d 索引:%4.4x.%2.2x 错误:%d\n",
timestr, Ec.Slave, Ec.Index, Ec.SubIdx, Ec.ErrorCode);
break;
}
case EC_ERR_TYPE_SDOINFO_ERROR:
{
sprintf(estring, "%s SDO 信息错误:从站:%d 索引:%4.4x.%2.2x 错误:%8.8x %s\n",
timestr, Ec.Slave, Ec.Index, Ec.SubIdx, (unsigned)Ec.AbortCode, ec_sdoerror2string(Ec.AbortCode));
break;
}
case EC_ERR_TYPE_SOE_ERROR:
{
sprintf(estring, "%s SoE 错误:从站:%d IDN:%4.4x 错误:%4.4x %s\n",
timestr, Ec.Slave, Ec.Index, (unsigned)Ec.AbortCode, ec_soeerror2string(Ec.ErrorCode));
break;
}
case EC_ERR_TYPE_MBX_ERROR:
{
sprintf(estring, "%s MBX 错误:从站:%d 错误:%4.4x %s\n",
timestr, Ec.Slave, Ec.ErrorCode, ec_mbxerror2string(Ec.ErrorCode));
break;
}
default:
{
sprintf(estring, "%s 错误:%8.8x\n",
timestr, (unsigned)Ec.AbortCode);
break;
}
}
return (char*) estring;
}
/** 在 ec_errorlist 中查找错误并转换为文本字符串。
*
* @param[in] context = 上下文结构
* @return 可读字符串
*/
char* ecx_elist2string(ecx_contextt *context)
{
ec_errort Ec;
if (ecx_poperror(context, &Ec))
{
return ecx_err2string(Ec);
}
else
{
return "";
}
}
#ifdef EC_VER1
char* ec_elist2string(void)
{
return ecx_elist2string(&ecx_context);
}
#endif
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* Headerfile for ethercatprint.c
*/
#ifndef _ethercatprint_
#define _ethercatprint_
#ifdef __cplusplus
extern "C"
{
#endif
char* ec_sdoerror2string( uint32 sdoerrorcode);
char* ec_ALstatuscode2string( uint16 ALstatuscode);
char* ec_soeerror2string( uint16 errorcode);
char* ec_mbxerror2string( uint16 errorcode);
char* ecx_err2string(const ec_errort Ec);
char* ecx_elist2string(ecx_contextt *context);
#ifdef EC_VER1
char* ec_elist2string(void);
#endif
#ifdef __cplusplus
}
#endif
#endif
修改时间 | 修改说明 |
---|---|
2023年11月5日 | EtherCAT主站SOEM – 4 – SOEM之ethercatprint.h/c文件解析 |
以上就是EtherCAT主站SOEM – 4 – SOEM之ethercatprint.h/c文件解析的内容。
有不明白的地方欢迎留言;有建议欢迎留言,我后面编写文档好改进。
创作不容,如果文档对您有帮助,记得给个赞。