infoflash 地址 IAR 中获取,通过 ICF文件定义的自定义段地址的方法

在嵌入式开发中,我们经常需要将特定数据(如配置参数、校准数据、日志信息等)存储在Flash的特定区域。使用IAR开发环境时,可以通过ICF(Linker Configuration File)链接器配置文件定义自定义存储段,并在代码中灵活访问这些段的地址。本文将详细介绍如何实现这一功能。

1. ICF文件中定义自定义段

首先,在ICF链接器配置文件中定义自定义存储段。以InfoFlash为例:

icf
/* 定义存储器区域 */
define memory mem with size = 4G;
define region FLASH_region = mem:[from 0x08000000 to 0x0807FFFF];  /* 512KB主Flash */
define region RAM_region   = mem:[from 0x20000000 to 0x2002FFFF];  /* 192KB RAM */

/* 定义InfoFlash区域 - 通常用于存储参数、配置等 */
define symbol __INFO_FLASH_START__ = 0x08070000;  /* 起始地址 */
define symbol __INFO_FLASH_END__   = 0x0807FFFF;  /* 结束地址 */
define symbol __INFO_FLASH_SIZE__  = __INFO_FLASH_END__ - __INFO_FLASH_START__ + 1;

/* 导出符号供C代码使用 */
define exported symbol __INFO_FLASH_START_ADDR__ = __INFO_FLASH_START__;
define exported symbol __INFO_FLASH_END_ADDR__   = __INFO_FLASH_END__;
define exported symbol __INFO_FLASH_SIZE_ADDR__  = __INFO_FLASH_SIZE__;

/* 定义自定义段 */
define block INFO_FLASH_BLOCK with fixed order, alignment = 4
{
    section .info_flash
};

/* 将自定义段放置到InfoFlash区域 */
place at address mem:__INFO_FLASH_START__ { block INFO_FLASH_BLOCK };

2. 在C代码中访问自定义段地址

使用导出的符号

在ICF文件中使用exported关键字导出符号后,在C代码中通过extern声明即可使用:

c#include <stdint.h>
#include <stdio.h>

/* 声明ICF文件中导出的符号 */
extern uint32_t __INFO_FLASH_START_ADDR__;
extern uint32_t __INFO_FLASH_END_ADDR__;
extern uint32_t __INFO_FLASH_SIZE_ADDR__;

/* 定义指向InfoFlash的指针 */
#define INFO_FLASH_START   ((uint32_t)&__INFO_FLASH_START_ADDR__)
#define INFO_FLASH_END     ((uint32_t)&__INFO_FLASH_END_ADDR__)
#define INFO_FLASH_SIZE    ((uint32_t)&__INFO_FLASH_SIZE_ADDR__)

void print_flash_info(void)
{
    printf("InfoFlash Information:\n");
    printf("  Start Address: 0x%08lX\n", INFO_FLASH_START);
    printf("  End Address:   0x%08lX\n", INFO_FLASH_END);
    printf("  Size:          %lu bytes (%lu KB)\n", 
           INFO_FLASH_SIZE, INFO_FLASH_SIZE / 1024);
}


简单总结:

extern unsigned int __ICFEDIT_region_RAM_start__;
extern unsigned int __ICFEDIT_region_RAM_end__;

/* 获取地址值 */
uint32_t ram_start = (uint32_t)&__ICFEDIT_region_RAM_start__;
uint32_t ram_end = (uint32_t)&__ICFEDIT_region_RAM_end__;

/* 或者直接作为指针使用 */
volatile uint32_t *ram_ptr = (volatile uint32_t*)&__ICFEDIT_region_RAM_start__;

printf("RAM起始地址: 0x%08lX\n", ram_start);
printf("RAM结束地址: 0x%08lX\n", ram_end);

icf 文件中需要修改:增加 exported

define exported symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define exported symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF;

 
posted @ 2025-10-30 10:32  口嗨养生博  阅读(12)  评论(0)    收藏  举报