MDK 4.12 下结构体定义语法

本文介绍了在使用MDK4.12编译器时遇到的结构体与联合体内存对齐问题,特别是在STM32平台上的表现。通过对比IAR STVD环境,展示了不同编译器对于内存布局的不同处理方式,并提供了使用__packed关键字解决此类问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在做移植时,遇到个问题,之前采用的IAR  STVD环境都没有问题,今天采用MDK 4.12,出现了问题,出现 'expected an identifier'警告。

typedef struct _data
{
     u8 phy_id[8];
    u8 sec_id[6];
    u8 switch_s;
    union battery
    {            
        u16 battery0; //高位字节填充整数部分,低位字节填充小数部分
        struct {
        u8 battery2; //电池部分的小数部分
        u8 battery1; //电池能量的整数部分
        };
    };

}data;
 
typedef struct _message
{
  u8 cmd;
  struct _data data;
  u8 reserved;
  u16 ack;
}message;
//message 的大小字节对齐为21个字节

下图是不顾警告直接编译后动态调试时所看到的结构内容,明显的没有battery0的符号,后面证实,这里MDK没有给分配空间

(STVD 编译的STM8S程序)发送端填充结构体内容如下:

		msg.cmd = TAG_COORDINARY_CMD;
		seq++;
		
		battery_h=3;
		_memcpy(&msg.data.phy_id[4],(char *)&seq,4);
		_memcpy(msg.data.sec_id,(char *)&seq,4);
		msg.data.switch_s = 0;
		msg.data.battery0 = battery_h << 8 | battery_l; //标签电压值
		msg.reserved = 0x36;
		msg.ack = 0xFFEE;

(MDK 编译的STM32程序) 接收端接收后内容如下:


万恶的MDK啊,reserved 和ack的数值都是错误的。


非的改成这样才能编译通过:

typedef struct _data
{
     u8 phy_id[8];
    u8 sec_id[6];
    u8 switch_s;
    union 
    {            
        u16 battery0; //高位字节填充整数部分,低位字节填充小数部分
        struct {
        u8 battery2; //电池部分的小数部分
        u8 battery1; //电池能量的整数部分
        }batt; 
    }battery;
}data;
这样问题又来了,与原来的字节数比多了几个字节,估计是对齐导致的。这里是24个字节。


最后是使用__packed进行修饰才正常,调试也通过

typedef __packed struct _data
{
 	u8 phy_id[8];
	u8 sec_id[6];
	u8 switch_s;
	__packed union 
	{		    
		u16 battery0; //高位字节填充整数部分,低位字节填充小数部分
		__packed struct {
		u8 battery2; //电池部分的小数部分
		u8 battery1; //电池能量的整数部分
		}batt;
	}battery;
}data;


typedef __packed struct _message
{
  u8 cmd;
  struct _data data;
  u8 reserved;
  u16 ack;
}message;


总结:

MDK 4.12在处理联合体与结构体时,语法上与IAR STVD VS等工具的编译器有些出入。

MDK 4.12下编译STM32程序时,要注意结构体大小问题,默认是字对齐方式的。可使用__packed关键字修饰为字节方式对齐。




                
### Keil MDK 4.12 评估板下载及相关资源 对于 Keil MDK 4.12 的评估版,用户可以通过官方渠道免费获取其功能受限的版本。以下是关于如何合法下载和使用该工具的相关信息: #### 官方下载途径 Keil MDK 是由 Arm 提供的一款集成开发环境 (IDE),主要用于基于 Arm Cortex-M 和其他微控制器的应用程序开发。MDK 4.12 版本属于较早发布的版本,但仍可通过以下方式获得: - 用户可以访问 [Arm Developer](https://developer.arm.com/tools-and-software/embedded/keil-mdk) 页面并注册账户以下载评估版软件[^3]。 - 在安装过程中,系统会提示输入许可证密钥 (License Key)。如果未提供有效许可,则默认进入评估模式。 #### 功能限制说明 在评估模式下运行时,Keil MDK 将施加一定的项目大小限制(通常为 32 KB),超出此范围可能导致编译失败或其他错误消息提示[^4]。具体表现为当目标应用程序超过限定容量后,在链接阶段会出现如下警告:“Error: L6908E – Code size limit exceeded”。 #### 获取帮助文档和支持材料 为了更好地理解和操作 MDK 4.12 及其关联硬件平台,请查阅随附的帮助文件以及在线支持服务: - **User Manual**: 包含详细的设置指南、特性描述等内容; - **Reference Manuals & Data Sheets**: 针对特定 MCU 器件的数据手册和技术参考资料; - **Example Projects**: 示例工程展示了各种外设驱动方法及其配置流程; 此外还可以参考第三方社区论坛分享的经验贴或者教程视频来加深理解实际应用过程中的技巧要点[^5]。 ```python # Python脚本仅作为演示用途展示如何自动化处理某些任务 import os def check_file_size(file_path): """检查给定路径下的文件尺寸是否小于等于32KB""" max_allowed_bytes = 32 * 1024 # 即32KB转换成字节数形式表示 try: file_stats = os.stat(file_path) if file_stats.st_size <=max_allowed_bytes : return True,"File Size within limits." else: return False,f"Exceeded allowed size:{file_stats.st_size} bytes." except Exception as e: return None,str(e) if __name__ == "__main__": result,msg=check_file_size(r"C:\path\to\your_project.axf") if isinstance(result,bool): print(msg) elif result is None: print(f"An error occurred while checking the file.{msg}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值