联合体使用技巧
一.前言
c语言里面有了结构体,为什么还有需要联合体。
- 1.第一联合体在某些情况下,比结构体操作更方便。 如操作硬件寄存器、协议数据包的封装和解析。
- 2.更省内存。
二. union操作硬件寄存器
union 对比 struct 可以发现,结构体的操作更加繁琐。
点击查看代码
union device_reg{
uint32_t raw;
struct{
uint32_t en:1;
uint32_t mode:3;
uint32_t freq:10;
uint32_t :18;
}bits;
};
union device_reg reg;
reg.bits.en = 1;
reg.bits.mode = 0x05;
reg.bits.freq = 250;
write_register(0x8000, reg.raw);
/*************************************************************/
struct device_reg {
uint32_t en:1;
uint32_t mode:3;
uint32_t freq:10;
uint32_t :18;
};
struct device_reg reg;
reg.en = 1;
reg.mode = 0x05;
reg.freq = 250;
uint32_t raw_value = (reg.freq << 10) | (reg.mode << 3) | reg.en;
write_register(0x8000, raw_value);
三. union对协议数据进行打包
点击查看代码
#pragma pack(push, 1)
union PS2_UPDATE_FW_DATA_L1_L2
{
u8 all[L1_L2_ALL_MAX_LEN];
struct
{
u8 l1_l2_check_sum;
u8 pootocol_version;
u8 dest_address:4;
u8 src_address:4;
u8 modeule_id;
u8 event_id;
u16 payload_length;
u8 ack;
u8 l3_data_check_sum;
}each;
};
union PS2_UPDATE_FW_DATA_L3
{
u8 all[L3_ALL_MAX_LEN];
struct
{
u8 error_flag;
u8 hand_ack_version[HAND_ACK_VERSION_LEN];
}hand_ack_pack;
struct
{
u16 erase_len;
u32 erase_start_addr;
}erase_flash_write_pack;
struct
{
u32 addr_data;
u8 fw_bin_data[L3_FW_BIN_DATA_MAX_LEN];
}flash_write_pack;
struct
{
u16 data_len;
u32 read_flash_addr;
}flash_read_pack;
struct
{
u32 app_size;
u8 app_version[VERSION_INFO_LEN];
u32 app_check;
}app_check_sum_pack;
u32 jump_app_start_addr;
u16 connect_data;
u8 error_flag;
};
volatile union PS2_UPDATE_FW_DATA
{
u8 all[PS2_UPDATE_FW_DATA_MAX_LEN];
struct
{
union PS2_UPDATE_FW_DATA_L1_L2 ps2_update_fw_data_l1_l2;
union PS2_UPDATE_FW_DATA_L3 ps2_update_fw_data_l3;
}each;
};
#pragma pack(pop)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通