硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3026|回复: 6
收起左侧

[客户分享] F407ZG的内部Flash分散文件重定义,以便使用内部Flash做数据存储

[复制链接]

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
发表于 2017-11-15 16:10:12 | 显示全部楼层 |阅读模式
stm32内部的flash可以自己擦除写入,可以选一个page作为数据(参数)存储区,节省一个外部的EEPROM。这个擦除次数大约是10K次。
F103的flash每个page是2k,比较好用。选最后一两个page作为数据存储区,也不会影响到代码的存储,不用修改sct文件。
不幸的是,F407的flash,最后几个page都是128K的,擦除/写入一个page很费事情,而且可能导致代码code的空间不够用。F4的前四个page是16k的,第一个16k是程序引导/中断向量,不可轻易使用。第2~4个page正好用来存数据,第5个page继续开始存code。
F4的flash扇区(page)的分布如下:

F407ZG的Flashdi'zhi

F407ZG的Flashdi'zhi

修改后的sct文件如下:
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x08000000 0x00004000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00004000  {  ; load address = execution address 第一个16K 的page给初始化代码用。
   *.o (RESET, +First)
   *(InRoot$$Sections)
  }
  RW_IRAM1 0x20000000 0x00000400  {  ; RW data 留了1K RAM给初始化程序使用,实际看map文件,它们其实没有用任何RAM。
   .ANY (+RW +ZI)
  }
}
LR_IROM2 0x08020000 0x000E0000  {    ; load region size_region
  ER_IROM2 0x08020000 0x000E0000  {  ; load address = execution address从第一个128的page开始存储我们的code
   .ANY (+RO)
  }
  RW_IRAM3 0x20000400 0x0001FC00  {  ; RW data  常规RAM区,95K可用。
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x10000000 0x00010000  {   ; 这个RAM区千万不能给DMA相关变量。可以给emwin或者RTOS做内存。
   .ANY (+RW +ZI)
  }
}

sct文件在哪里呢?请看下图,

sct文件修改

sct文件修改

评分

参与人数 1 +5 收起 理由
eric2013 + 5

查看全部评分

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107527
QQ
发表于 2017-11-16 00:32:34 | 显示全部楼层
还有个方便的办法,直接这样定义,编译器会自动处理。

/* 将16KB 一个扇区的空间预留出来做为参数区 For MDK */
const uint8_t para_flash_area[16*1024] __attribute__((at(ADDR_FLASH_SECTOR_3)));
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
 楼主| 发表于 2017-11-16 11:17:22 | 显示全部楼层

回 eric2013 的帖子

eric2013:还有个方便的办法,直接这样定义,编译器会自动处理。

/* 将16KB 一个扇区的空间预留出来做为参数区 For MDK */
const uint8_t para_flash_area[16*1024] __attribute__((at(ADDR_FLASH_SECTOR_3))); (2017-11-16 00:32)
你这个更方面易懂!
怎么不早说![s:151][s:151]
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
 楼主| 发表于 2017-11-20 15:00:46 | 显示全部楼层

回 eric2013 的帖子

eric2013:还有个方便的办法,直接这样定义,编译器会自动处理。

/* 将16KB 一个扇区的空间预留出来做为参数区 For MDK */
const uint8_t para_flash_area[16*1024] __attribute__((at(ADDR_FLASH_SECTOR_3))); (2017-11-16 00:32)
这个方法发现一个问题,mdk把这个flash区域全部初始化为0了。
我希望这块flash能够保持原数据,mdk不能初始化它了。,应该怎么写?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107527
QQ
发表于 2017-11-21 01:52:50 | 显示全部楼层

回 caicaptain2 的帖子

caicaptain2:这个方法发现一个问题,mdk把这个flash区域全部初始化为0了。
我希望这块flash能够保持原数据,mdk不能初始化它了。,应该怎么写?

 (2017-11-20 15:00) 
可以修改成这样进行定义:

const uint8_t para_flash_area[16*1024] __attribute__((at(ADDR_FLASH_SECTOR_3))) = {0xFF};
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
 楼主| 发表于 2017-11-21 08:47:46 | 显示全部楼层

回 eric2013 的帖子

eric2013:可以修改成这样进行定义:

const uint8_t para_flash_area[16*1024] __attribute__((at(ADDR_FLASH_SECTOR_3))) = {0xFF}; (2017-11-21 01:52)
这个尝试过了,16k空间里面,只有第一个字节初始化为0xff,其他都是0.
其实,我期望的是,编译后,不能对这个空间写任何值,复位后保持原样。
回复

使用道具 举报

336

主题

2045

回帖

3058

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3058
 楼主| 发表于 2017-11-21 08:50:01 | 显示全部楼层
经过仔细试验后,sct文件方法行不通。
虽然map文件显示,中间的16k flash未被占用,但是程序代码不会自动跳过这个区域。执行到这个地址后,会跑飞。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-5 06:40 , Processed in 0.276160 second(s), 33 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表