宿迁哪里有做网站开发的常州网站制作策划

张小明 2026/1/19 20:23:53
宿迁哪里有做网站开发的,常州网站制作策划,网站响应方案,wordpress新建查询跳转在嵌入式开发中#xff0c;特别是在翻芯片 SDK 的时候#xff0c;经常会遇到 union 关键字嵌在结构体里#xff0c;配合位域#xff08;bit-field#xff09;使用#xff0c;SDK的库函数中基本上全是这玩意儿#xff0c;新手可能会比较头疼。比如下面这段代码#xff0…在嵌入式开发中特别是在翻芯片 SDK 的时候经常会遇到 union 关键字嵌在结构体里配合位域bit-field使用SDK的库函数中基本上全是这玩意儿新手可能会比较头疼。比如下面这段代码是我从apm32f407xx.h中copy过来的其中定义了一个 CRC 模块的寄存器映射复制typedef struct {/** [urlhome.php?modspaceuid247401]brief[/url] DATA register */union {__IOM uint32_t DATA;struct {__IOM uint32_t DATA : 32;} DATA_B;};/** [urlhome.php?modspaceuid247401]brief[/url] independent DATA register */union {__IOM uint32_t INDATA;struct {__IOM uint32_t INDATA : 8;__IM uint32_t RESERVED : 24;} INDATA_B;};/** brief Control register */union {__OM uint32_t CTRL;struct {__OM uint32_t RST : 1;__IM uint32_t RESERVED : 31;} CTRL_B;};} CRC_T;代码里union 和位域可能会让人出现几个疑问union 到底是啥为啥 SDK 这么设计本文会从基础讲起层层深入解答这些疑问确保搞懂 union 的用法和底层逻辑。一、union 是什么跟 struct 有什么区别1. union 的定义union联合体是 C 语言的一种数据结构允许在同一块内存存储不同类型的变量。注意是同一块内存这跟 struct结构体完全不同。-结构体struct每个成员有自己的内存空间内存依次排列。比如复制struct Example {uint32_t a; // 占 4 字节uint8_t b; // 占 1 字节};这个结构体大小是 4 1 5 字节忽略对齐。a 和 b 各占一块独立内存互不干扰。-联合体union所有成员共享同一块内存大小由最大的成员决定。比如复制union Example {uint32_t a; // 占 4 字节uint8_t b; // 占 1 字节};这个 union 大小是 4 字节uint32_t 是最大成员。a 和 b 共享这 4 字节改 a 会影响 b因为它们是同一块内存的不同“视图”。2. union 的核心特点-内存共享所有成员从同一地址开始改一个成员其他成员的值会变。-大小确定union 的大小是最大成员的大小包括对齐。-多视角访问可以用不同类型或结构访问同一块内存。二、SDK 中的 union 在干嘛我们来看 SDK 的 CRC_T 结构体。为了方便分析我们还是把开头的代码copy过来哈。复制typedef struct {/** brief DATA register */union {__IOM uint32_t DATA;struct {__IOM uint32_t DATA : 32;} DATA_B;};/** brief independent DATA register */union {__IOM uint32_t INDATA;struct {__IOM uint32_t INDATA : 8;__IM uint32_t RESERVED : 24;} INDATA_B;};/** brief Control register */union {__OM uint32_t CTRL;struct {__OM uint32_t RST : 1;__IM uint32_t RESERVED : 31;} CTRL_B;};} CRC_T;分析一下它描述了一个 CRC循环冗余校验硬件模块的寄存器映射包含三个寄存器DATA、INDATA 和 CTRL。每个寄存器用 union 定义提供两种访问方式1. 整体访问直接读写整个 32 位寄存器比如 CRC_T.CTRL。2. 位域访问用位域bit-field操作具体位比如 CRC_T.CTRL_B.RST只操作第 0 位。例子- CRC_T.CTRL 0x00000001; 写整个 32 位设置复位位。- CRC_T.CTRL_B.RST 1; 只设置第 0 位复位位其他位不动。- CRC_T.INDATA_B.INDATA 0xFF; 设置低 8 位RESERVED 的 24 位保持不变。union 的作用让同一块 32 位内存硬件寄存器既可以整体读写也可以按位操作提供了两种“视角”。三、为什么 SDK 用 union 这么设计SDK 用 union 是为了灵活性、可读性和内存效率尤其在嵌入式系统中操作硬件寄存器时1. 多视角访问- 整体写寄存器CRC_T.CTRL适合初始化或快速设置。- 位域CRC_T.CTRL_B.RST适合精确控制某些位代码更直观。2. 代码可读性- CRC_T.CTRL_B.RST 1; 比 CRC_T.CTRL | (1 0); 更清晰名字直接对应芯片手册的位定义。3. 内存效率- union 让 CTRL 和 CTRL_B 共享内存整个 CRC_T 结构体大小是三个寄存器12 字节没有冗余。4. 硬件映射- CRC_T 通常通过指针映射到硬件寄存器地址比如 CRC_T *crc (CRC_T *)0x4000_1000;。union 确保整体和位域操作都作用于同一地址。为什么不用单独的 struct- 不用 union只能用位运算、|、移位操作寄存器代码复杂易出错。- union 结合位域让代码更简洁减少手动位操作。四、什么时候用 unionunion 在嵌入式开发中很常见适合以下场景1. 硬件寄存器操作- 映射控制、状态或数据寄存器提供整体和按位访问。- 如 SDK 的 CRC_T 结构。2. 节省内存- 当多种数据类型同一时间只用一种union 节省空间。比如通信协议复制union Message {uint32_t raw_data;struct {uint8_t type;uint8_t id;uint16_t value;} parsed;};3. 数据转换- 在 float 和 uint32_t 间转换分析位模式复制union FloatConverter {float f;uint32_t u;};4. 协议解析- 解析网络数据包用不同结构体访问同一块数据。啥时候不用- 如果成员需要同时存储不同值用 struct。- 如果不需要多视角访问直接用简单变量或位域。五、位域bit-field的基础知识位域是结构体中指定成员占用位数的机制用 : 数字 表示。比如复制struct {uint32_t RST : 1; // 占 1 位uint32_t RESERVED : 31; // 占 31 位} CTRL_B;规则-指定位数如 RST : 1 占 1 位位数不能超过类型宽度uint32_t 是 32 位。-不指定位数用类型宽度比如 uint16_t RST; 占 16 位。-分配顺序按声明顺序依次分配通常在一个存储单元storage unit常见为 int 或类型大小内。-对齐和端序分配受编译器和硬件端序大端/小端影响。在 union 中位域和整体变量共享同一内存需确保总位数不超过 union 大小这里是 32 位。六、扩展1把 RESERVED 改成 33 位会怎样这里我们进行一个改动把 CTRL 的 union 改成像下面这样看看会发生什么。复制union {__OM uint32_t CTRL;struct {__OM uint32_t RST : 1;__IM uint32_t RESERVED : 33;} CTRL_B;};嗯意料之中这玩意儿它报错了1. 为什么会报错- 位域总位数是 RST1 位 RESERVED33 位 34 位。- 但 uint32_t 只有 32 位34 位超出了类型宽度。-结果编译器报错比如 GCC 会说 error: width of RESERVED exceeds its type。2. RESERVED 表示什么RESERVED 是位域的“占位符”对应硬件寄存器的保留位通常不可写读可能是 0 或未定义。原代码中RESERVED : 31 表示 CTRL 的高 31 位是保留位RST 是第 0 位。3. RESERVED这玩意儿会不会溢出到下一个地址不会union 的所有成员共享同一块内存比如 0x4000_1008。位域 CTRL_B 必须装在 CTRL 的 32 位里RESERVED : 33 不会溢出到下一个地址比如 0x4000_100C而是直接报错。修复方法- 确保位域总位数不超过 32 位比如 : 31。- 如果硬件有多个寄存器用两个 uint32_t复制union {struct {uint32_t CTRL;uint32_t CTRL_EXT;};struct {__OM uint32_t RST : 1;__IM uint32_t RESERVED : 31;__IM uint32_t RESERVED2 : 2;} CTRL_B;};七、扩展2去掉 : 数字用 uint16_t 会怎样我们再想想如果去掉位域的 : 数字改成下面这样又会发生什么复制union {__OM uint32_t CTRL;struct {__OM uint16_t RST;__IM uint16_t RESERVED;} CTRL_B;};这样改完后有一个疑问联合体(union)包含的struct结构体其中的RST和RESERVED的位域位是会顺延吗也就是说是RST占CTRL的前面16位RESERVED占后面的16位这样还是说一起共用CTRL的前面16位或者都是后面16位不知道啊怎么办呢咱们写个代码验证一下复制#include stdio.h#include stdint.hunion {uint32_t CTRL;struct {uint16_t RST;uint16_t RESERVED;} CTRL_B;} test;int main() {test.CTRL 0x56781234;printf(CTRL: 0x%08X\n, test.CTRL);printf(RST: 0x%04X\n, test.CTRL_B.RST); // 预期 0x1234printf(RESERVED: 0x%04X\n, test.CTRL_B.RESERVED); // 预期 0x5678test.CTRL_B.RST 0xABCD;printf(After RST 0xABCD, CTRL: 0x%08X\n, test.CTRL); // 预期 0x5678ABCDtest.CTRL_B.RESERVED 0xEF01;printf(After RESERVED 0xEF01, CTRL: 0x%08X\n, test.CTRL); // 预期 0xEF01ABCDreturn 0;}结果1. 位域分配规则- 没写 : 数字编译器根据类型分配- uint16_t RST; 占 16 位。- uint16_t RESERVED; 占 16 位。- 总共 16 16 32 位刚好等于 union 的 32 位由 uint32_t CTRL 决定。- 分配顺序- 位域按声明顺序顺延分配。- 假设小端序常见于 ARMRST 占低 16 位bit 0-15RESERVED 占高 16 位bit 16-31。- 内存布局- CTRL整个 32 位bit 0-31。- CTRL_B.RST低 16 位bit 0-15。- CTRL_B.RESERVED高 16 位bit 16-31。2.地址顺延还是共享顺延RST 占前 16 位bit 0-15RESERVED 占后 16 位bit 16-31。它们**不共享**同一块 16 位因为位域按顺序依次分配填满 32 位内存。3. 与 CTRL 的关系CTRL 和 CTRL_B 共享同一地址- 写 CTRL_B.RST 0x1234; 改 CTRL 的低 16 位。- 写 CTRL_B.RESERVED 0x5678; 改 CTRL 的高 16 位。- 写 CTRL 0x56781234; 影响 RST0x1234和 RESERVED0x5678。4. 会不会有问题代码合法不会报错因为 16 16 32 位匹配 union 大小。但需注意-硬件匹配确认寄存器是否真的分成低 16 位控制和高 16 位保留。-端序小端序下RST 是低 16 位大端序可能反过来需查手册。-编译器差异位域分配依赖编译器GCC、Keil 等可能有细微差异。八、总结核心要点- union 让同一块内存寄存器支持多视角访问整体和位域提高灵活性和可读性。- 位域按声明顺序顺延分配需确保总位数不超过类型或 union 大小。- 扩展 1RESERVED : 33超 32 位编译报错不会溢出到下一地址。- 扩展 2uint16_t RST 和 RESERVED顺延分配RST 占低 16 位RESERVED 占高 16 位合法但需匹配硬件。- 始终参考硬件手册确认寄存器定义和端序。最后的扩展不同编译器GCC/Keil/IAR对位域分配的差异有哪些见下表特性GCCKeilIAR存储单元大小通常使用位域声明的类型大小如 uint32_t 为 32 位。可能因架构如 ARM调整存储单元。基于目标架构通常以 int 或声明类型如 uint32_t为存储单元。倾向于紧凑分配。通常以声明类型如 uint32_t为存储单元优化嵌入式设备紧凑性。位顺序小端序从低位LSB到高位MSB分配。大端序可能反过来。依赖目标架构如 ARM Cortex-M。小端序通常从低位到高位分配匹配 ARM 架构。明确支持硬件寄存器映射。小端序从低位到高位分配优化 ARM 架构。支持硬件寄存器位域映射。对齐方式可能插入填充以满足架构对齐要求如 4 字节对齐。可通过 #pragma pack 或 -fpack-struct 控制。倾向于紧凑分配减少填充适合嵌入式资源限制。对齐依赖目标如 ARM。优化紧凑分配尽量减少填充。支持 __packed 等扩展控制对齐。未命名位域如 : 0强制换到新存储单元如下一个 int 或类型大小。行为明确但依赖架构对齐。类似 GCC强制新存储单元。可能因目标如 Cortex-M调整对齐。支持 : 0 强制新存储单元行为与硬件寄存器对齐一致。超大位域处理超大位域如 : 33 在 uint32_t通常报警告或错误具体取决于 -Werror 设置。严格检查超大位域如 : 33报错防止溢出。强调硬件一致性。严格检查超大位域报错。支持硬件寄存器映射行为更可预测。可移植性高度依赖目标架构和端序。需明确指定选项如 -mstrict-align提高一致性。针对 ARM 优化跨平台一致性较好但仍需测试不同目标。针对多种架构ARM、8051 等优化跨平台一致性较高。扩展支持支持标准 C 位域扩展较少。需手动配置如 linker 脚本。支持 sfr、sbit 等扩展简化寄存器操作。支持 sfr、sbit、__packed 等扩展优化嵌入式寄存器操作。优缺点优点免费灵活支持多种架构。缺点需手动配置位域行为可能不一致。优点集成 IDE优化 ARM 寄存器操作。缺点商业授权成本高。优点紧凑代码硬件支持强。缺点昂贵C 标准支持较旧如 C14。---------------------作者DKENNY链接https://bbs.21ic.com/icview-3466182-1-1.html来源21ic.com此文章已获得原创/原创奖标签著作权归21ic所有任何人未经允许禁止转载。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

芜湖市建设投资有限公司网站莱芜都市网app

FaceFusion在跨文化影视合作中的桥梁作用 在全球化内容创作日益深入的今天,一部电影、一档综艺或一个广告往往需要面向多个语言和文化市场同步发布。然而,当中国演员出演的剧集要在北美播出,或好莱坞角色需“说中文”登陆中国市场时&#xff…

张小明 2026/1/17 21:15:49 网站建设

网站建设中 油财宝58同城二手房个人出售

​欢迎大家订阅我的专栏:算法题解:C与Python实现! 本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战! 专栏特色 1.经典算法练习:根据信息学竞赛大纲,精心挑选…

张小明 2026/1/17 21:15:54 网站建设

网页制作与网站建设策划书案例东莞网站主页制作

功能测试真的没前途了吗?潭州软件测试精英班:用自动化与性能测试打开职业新赛道在当今快速迭代的软件开发环境中,功能测试——这个曾经被视为“入门门槛低、上手快”的岗位,正面临前所未有的挑战。越来越多的声音指出:…

张小明 2026/1/17 21:15:56 网站建设

怎样推销网站建设一建建设网站首页

LobeChat:构建下一代开源AI聊天平台的技术实践 在生成式AI浪潮席卷全球的今天,用户早已不再满足于简单的问答交互。从智能客服到企业知识引擎,从教育辅导到编程助手,人们对AI助手的期待正变得越来越复杂——不仅要“能聊”&#x…

张小明 2026/1/17 21:15:55 网站建设

网站原型图怎么做google官方网站注册

当你面对百度网盘分享链接时,是否曾经因为找不到提取码而陷入困境?在信息爆炸的时代,资源获取效率直接影响着我们的学习和工作效率。传统的手动搜索方式不仅耗时耗力,还常常因为页面跳转而打乱工作节奏。现在,这一切都…

张小明 2026/1/17 21:15:54 网站建设

网站建设规划案例精品故事网

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 开发一个智能诊断工具,能够自动检测Linux系统中的LD_LIBRARY_PATH环境变量配置问题。要求:1.扫描系统环境变量配置 2.检查常见配置错误模式 3.提供自动修复建…

张小明 2026/1/17 21:15:55 网站建设