AVR单片机开发中无法将.h文件带const修饰的数组传递给C函数求助
问题原因分析
- 核心原因:AVR 哈佛架构地址空间隔离
AVR系列MCU采用哈佛架构,程序存储区(Flash)和数据存储区(RAM)是独立编址的。默认配置下,全局范围的const修饰数组会被编译器分配到Flash存储区以节省RAM空间,而普通的uint8_t *指针默认指向RAM地址空间。直接用RAM指针访问Flash地址时,实际读取的是同编号的RAM地址,该区域未初始化时默认值为0,因此会出现传输字节全为0x00的现象。
非const数组、main函数内定义的数组均存储在RAM中,指针直接访问可以得到正确值,和你测试的结果完全吻合。 - 次要可能:头文件全局变量声明错误
如果Buffers.h中没有给Sensor_Firmware加extern声明,且被多个C文件重复包含,可能会导致编译器分配重复的无效地址,但该问题概率较低,且不会只在const修饰时才触发。
修复方案
分两种可选方案:
方案1:临时拷贝到RAM传输
如果固件体积不大,直接在调用WrMulti前,将Flash中的固件数组拷贝到RAM临时数组后再传入函数即可:
#include <avr/pgmspace.h> uint8_t firmware_buf[sizeof(Sensor_Firmware)]; memcpy_P(firmware_buf, Sensor_Firmware, sizeof(Sensor_Firmware)); WrMulti(&platform, reg_addr, firmware_buf, sizeof(Sensor_Firmware));
其中memcpy_P是avr-gcc提供的专门从Flash拷贝数据到RAM的函数。
方案2:修改WrMulti函数支持Flash常量读取
直接修改WrMulti的取值逻辑,兼容Flash存储的const数组:
- 首先修改函数参数声明,匹配const数组传入的类型:
uint8_t WrMulti(VL53L5CX_Platform *p_platform,uint16_t RegisterAdress, const uint8_t *p_values,uint32_t size)
- 修改填充临时数组的逻辑,使用
pgm_read_byte读取Flash内容:
#include <avr/pgmspace.h> for (int i = 2; i < (new_size); i++ ) { // 直接访问Flash地址的字节 temp_array[i] = pgm_read_byte(&p_values[count]); count++; }
修改后无论传入的数组是在RAM还是Flash中,都可以正常读取数据。
内容的提问来源于stack exchange,提问作者D_A
相关产品推荐
相关产品推荐

