我在编程调试中遇到以下问题,关于一个CAN帧,我定义了它的结构体:
方案1:
struct {
uint16_t a ;
uint8_t b ;
uint8_t c ;
uint32_t over_current :1;
uint32_t dcdc_output_overvolt :1;
uint32_t over_temp_l2_a :1;
uint32_t over_temp_l3_a :1;
uint32_t k1k2_open_fault_a :1;
uint32_t k1k2_adhesion_fault_a :1;
uint32_t fuse_fault_a :1;
uint32_t iso_fault_a :1;
uint32_t iso_timeout_a :1;
uint32_t output_volt_over_bcl_a :1;
uint32_t output_current_over_bcl_a :1;
uint32_t volt_mismatch_a :1;
uint32_t dcdc_output_volt_over_a :1;
uint32_t pem_a :1;
uint32_t pre_charge_timeout_a :1;
uint32_t vehicle_volt_over_cml_a :1;
uint32_t cp_offline_a :1;
uint32_t output_volt_over_bcp_a :1;
uint32_t volt_over60_before_iso_a :1;
uint32_t secc_errcode_flag_a :1;
uint32_t :12; // 保留12位
}
memcpy(&ccu_can11[0], data, sizeof(ccu_can11_bsd_a_t));
然后执行函数,按位与。CAN发送帧00 00 00 00 01 00 00 00 ,没反应, 00 00 01 00 00 00 00 00
定位到40bit;和我希望的端序完全颠倒了,呆住。我希望的是00 00 00 00 01 00 00 00在32bit;尝试联合体:
方案2:
ypedef union {
struct {
uint64_t a :16;
uint64_t b :8;
uint64_t c :8;
uint64_t ccu_over_current_a :1;
uint64_t dcdc_output_overvolt_a :1;
uint64_t over_temp_l2_a :1;
uint64_t over_temp_l3_a :1;
uint64_t k1k2_open_fault_a :1;
uint64_t k1k2_adhesion_fault_a :1;
uint64_t fuse_fault_a :1;
uint64_t iso_fault_a :1;
uint64_t iso_timeout_a :1;
uint64_t output_volt_over_bcl_a :1;
uint64_t output_current_over_bcl_a :1;
uint64_t volt_mismatch_a :1;
uint64_t dcdc_output_volt_over_a :1;
uint64_t pem_a :1;
uint64_t pre_charge_timeout_a :1;
uint64_t vehicle_volt_over_cml_a :1;
uint64_t cp_offline_a :1;
uint64_t output_volt_over_bcp_a :1;
uint64_t volt_over60_before_iso_a :1;
uint64_t secc_errcode_flag_a :1;
uint64_t :12; // 保留12位
} bits; // 位域视图
uint64_t fault_value; // 整数值视图
} ccu_can11_u;
同上;丝毫没有好转;并且这次进一步发现,01 00 00 00 00 00 00 00
定位到32bit;阿巴阿巴了。
但是联合体这样使用:
方案3:
typedef union {
struct {
uint32_t ccu_over_current_a :1;
uint32_t dcdc_output_overvolt_a :1;
uint32_t over_temp_l2_a :1;
uint32_t over_temp_l3_a :1;
uint32_t k1k2_open_fault_a :1;
uint32_t k1k2_adhesion_fault_a :1;
uint32_t fuse_fault_a :1;
uint32_t iso_fault_a :1;
uint32_t iso_timeout_a :1;
uint32_t output_volt_over_bcl_a :1;
uint32_t output_current_over_bcl_a :1;
uint32_t volt_mismatch_a :1;
uint32_t dcdc_output_volt_over_a :1;
uint32_t pem_a :1;
uint32_t pre_charge_timeout_a :1;
uint32_t vehicle_volt_over_cml_a :1;
uint32_t cp_offline_a :1;
uint32_t output_volt_over_bcp_a :1;
uint32_t volt_over60_before_iso_a :1;
uint32_t secc_errcode_flag_a :1;
uint32_t :12; // 保留12位
} bits; // 位域视图
uint32_t fault_value; // 整数值视图
} ccu_can11_u;
typedef struct {
uint16_t a ;
uint8_t b ;
uint8_t c ;
ccu_can11_u can11;
} ccu_can11_bsd_a_t;
就可以定位到 00 00 00 00 01 00 00 00在32bit;我是试了这个后才去试2的方案的。然后 自己给自己整懵了。麻烦详细解释一下为什么? 我使用的是64位系统,为什么 u64没有按照小端序排列呢?如果按照小端序,我的第1,第2方案都应该正确才对,我定义了每一个位;
而且01 00 00 00 00 00 00 00对应到32是我万万没想到的。
咋都是deepseek,我想知道导致问题的原因,我也问过deepseek了。它只是总结分析,感觉最靠谱的说法是对齐或者填充导致的。