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

嵌入式双分区下const char*跨共享内存赋值LVGL数组问题咨询

问题根因

你遇到的矛盾和const char*语法约束没有直接关系,本质是两个嵌入式系统/安全隔离的底层限制:

  • 你为map数组指定的.guiMem_data段如果被链接脚本分配到只读Flash区域,整个数组所占内存是硬件写保护的,无论指针本身还是指向的内容都无法运行时修改,强制写会直接触发内存访问错误。
  • A组(安全区)和B组(非安全区)地址空间隔离,SyringeData里的syringename是A区本地地址,B组拿到这个指针没有权限访问,直接传指针会触发安全异常。
  • 额外的认知误区:const char*的语义是指针指向的字符串内容不可修改,指针变量本身是可修改的,不存在“必须初始化时赋值、之后不能改”的要求,你之前的理解有误。
实现方案

按以下步骤调整即可满足需求,完全符合LVGL的接口要求和安全隔离规则:

1. 调整内存段分配,让map数组可写

LVGL的菜单/滚轮/下拉控件对map参数的要求仅为:指针指向的字符串内容在控件使用期间保持有效,不要求数组本身是只读常量。

  • 首先检查链接脚本中.guiMem_data段的属性:如果该段被分配到Flash区域,修改链接脚本将其挪到可写RAM区域;如果该段本身就是RAM段,无需调整段属性,现有定义的顶层非const指针本身就是可写的。
  • 如果不需要固定段分配,也可以直接去掉__attribute__((section(".guiMem_data")))修饰,将数组定义在默认RAM段,验证功能后再做段对齐调整。
  • 绝对不要通过强转去掉const的方式修改只读Flash区域的数据,医疗设备场景下这类操作会带来严重的稳定性风险。

2. 改造跨安全区字符串传递逻辑,禁止直接传递A区指针

因为B组无A组访问权限,不能直接把A区的syringename地址传给B组,需要通过共享内存中转:

  • 在两组合法可见的共享内存区域(TrustZone架构下需配置为非安全属性、两区都可访问),划分一块固定大小的字符串缓冲区池,比如预留8个32字节的缓冲区,足够存储注射器名称字符串。
  • A组往共享内存写入SyringeData数据时,不要存A区本地的syringename指针,而是将激活状态的注射器名称字符串拷贝到共享内存的空闲缓冲区中,再将缓冲区在共享内存中的偏移量、或者B组地址空间映射下的缓冲区地址存入共享内存的结构体中。
  • B组读取时,仅访问共享内存范围内的地址,不要尝试访问任何A区地址空间的指针。

3. 运行时动态填充map数组

调整完成后,运行时更新逻辑非常简单:

  • 每次触发注射器列表更新时,遍历共享内存中的SyringeData数组,筛选出activate == true的有效条目。
  • 依次将有效条目对应的共享内存字符串地址赋值给map数组的偶数位元素,奇数位固定赋值为常量字符串"\n"的地址,所有有效条目填充完成后,最后一位赋值为""(空串)作为结束标记,和你初始化的结构完全一致。
  • 填充完成后调用对应LVGL控件的选项更新接口(比如lv_roller_set_options、lv_list_add_text等,根据你用的菜单组件选择对应API),通知LVGL刷新显示即可。
参考代码示例

调整后的map数组定义(假设.guiMem_data已经配置为可写RAM段):

// 数组内元素为指向const char的指针,指针本身存在RAM可修改,指向的字符串内容不修改
static const char* map[] __attribute__((section(".guiMem_data"))) = {0};
enum { MAX_MAP_ITEMS = 16 }; // 预留足够的条目空间,固定数组大小

// 填充逻辑伪代码
void update_syringe_map(void)
{
    uint8_t map_idx = 0;
    for (int i = 0; i < SYRINGE_MAX_CNT; i++) {
        if (shared_syringe_data[i].activate && map_idx < MAX_MAP_ITEMS - 2) {
            map[map_idx++] = shared_syringe_data[i].syringename; // 指向共享内存内的字符串
            map[map_idx++] = "\n";
        }
    }
    map[map_idx] = ""; // 补结束标记
    lv_roller_set_options(ui_syringe_roller, map, LV_ROLLER_MODE_NORMAL); // 通知LVGL更新
}

内容的提问来源于stack exchange,提问作者DaveR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:09:23