1.问题:采用结构体接收PDO数组是,出现数据不对的情况。
结构体定义如下:
//0x1701 RxPDO
typedef struct PACKED
{
uint16 ControlWord; //0x6040
int32 TargetVelocity; //0x60FF
int16 TorqueOffset; //0x60B2
//UINT8 ModeOfOperation; //0x6060
//UINT32 PhysicalOutput; //0x60FE
//UINT16 TouchProbeFunction; //0x60B8
}MAXPOS_DRIVE_RxPDO_t;
//0x1B00 TxPDO
typedef struct PACKED
{
uint16 StatusWord; //0x6041
int32 PositionActualValue; //0x6064
int32 PositionLoopError; //0x60F4
int32 VelocityActualValue; //0x606C
int16 TorqueActualValue; //0x6077
}MAXPOS_DRIVE_TxPDO_t;
typedef struct _MAXPOS_ServoDrive
{
MAXPOS_DRIVE_RxPDO_t OutParam;
MAXPOS_DRIVE_TxPDO_t InParam;
} MAXPOS_ServoDrive_t;
typedef struct _MAXPOS_Drive_pt
{
MAXPOS_DRIVE_RxPDO_t *ptOutParam;
MAXPOS_DRIVE_TxPDO_t *ptInParam;
} MAXPOS_Drive_pt;
强制转换接收数据:
RDM_slave[slc-1].ptInParam = (MAXPOS_DRIVE_TxPDO_t*)ec_slave[slc].inputs;
2.原因:C++的结构体对齐问题
许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的起始地址的值是某个数k的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus)。这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度。
但是由于数组存放位置关系,导致强制转换时数据截取有偏差。
https://www.cnblogs.com/motadou/archive/2009/01/17/1558438.html
3.解决办法
(1)加入#pragma pack(2)强制修改对齐字节数
(2)采用字节偏移读取,不用结构体。
position_actual_value[i] = *((int*)(ec_slave[1].inputs + 2));
position_actual_value[i] = RDM_slave[i].ptInParam->PositionActualValue;
printf("position_actual_value_ ----- %ld \n", position_actual_value[i]);
//采用如下方式
printf("position_actual_value_=== %ld \n", *((int*)(ec_slave[1].inputs + 2)));