You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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数组:

  1. 首先修改函数参数声明,匹配const数组传入的类型:
uint8_t WrMulti(VL53L5CX_Platform *p_platform,uint16_t RegisterAdress, const uint8_t *p_values,uint32_t size)
  1. 修改填充临时数组的逻辑,使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 04:24:07