[信息] Keil问题解决:烧程序报错,超过最大芯片Flash空间无算法

[复制链接]
 楼主| 一刀一级 发表于 2021-9-6 10:36 | 显示全部楼层 |阅读模式
Keil MDK问题解决:烧写程序报错——超过最大芯片Flash空间无算法

   情况是这样的。
   8月份的某一天,在STM32&STM8QQ群里有位网友提问。说是在下载程序时报错了,报错信息如下图:(摘自QQ群历史消息)
    235006bllh7s6a66tthtty.png

   根据提示08010000H之后的烧写Flash错误,初步怀疑是芯片烧写Flash选择错误。经询问,网友传上来的Flash选择项为下图:
    235403vr1ooef0hrhx8fbh.png    
   显然,选择的目标芯片是最大64K Flash,最大地址才到0x0800ffff,显然跟烧写算法错误更是没关系的呀,空间不会超过64K。

   又经了解到,网友在同一个工程下单跑LED灯程序是正确的,而加入图片显示后,就发生了烧写Flash算法错误。怀疑加入的图片过大,以致于编译后超过了64K空间。按理说,编译如果超过64K空间的话,编译是通不过的,但是他的程序却通过了,让人摸不着头脑。

    000038ws4rs11z1xbbr4cz.png

   网友所用芯片型号是:STM32F030C8,几翻核对的确是64K FLash。
    000055ez7n9pvfp9ago0v1.jpg    
    000248tf99swwkzzqw8auw.png

   让网友传来,编译成功的报告截图:
    000503yhrdcqilotdsropp.png    
   这下见鬼了,仅RW-data一项就91900,超过了64K。而且还编译成功了。(让查看.map文件,网友却没找对地方,未能给出有效信息。   
   网友上传他的工程"oled_15.zip" 到QQ群空间(目前在群空间已经找不到8月份之前的文件了),我下载文件编译后,成功编译,编译时也没有报错(没有硬件,无法烧写Flash验证)。发现显示的图片占据了很大的空间

   这样也排除了Keil环境损坏或杀毒软件的可能,那么最后只有一种可能,还是Keil工程设置中的某项设置没设对。
   但是这个问题当时我也没能成功解决。后来某天,在查看其它工程时,发现了一个选项。Target的Liner页下有两选项项可能会有问题。
    002241g0b7u95y7it54icz.jpg
  默认情况下,第一个红框中的勾是点上的,这时下面的第二个红框中是灰色,不让更改;当第一个框勾去掉后,下面的sct文件可以选择其它的文件或者编辑。好像网友的工程中就没有点上,但由于没有原工程,无法验证。


   上传个Keil环境自带的hello_arm程序,以这个工程为例去验证一下。 rar.gif Hello_arm.rar (346.94 KB, 下载次数: 0)
   主了方便验证,此程序已经被我做了改动,增加了两个文件,也非常简单。如下图。

   “mini.c”文件,就一句话,定义个只读字符串数组。
    003611srlgg0lq79l0hcnr.jpg
  
   “RedBmp.c”文件,也是一个只读数组,不同之处在于增加了个定长0x10000,正好64K。
    003617wddpt0w21duupm30.jpg

   主程序如下,就两条printf语句。
    003624b5b3vv9929c923x4.jpg

   当注释掉第34行的“printf ("%s",gImage_RedBmp);”后,编译成功不报错;当放到注释后,就会报编译错误。这是我们想要的结果。
    004455vcnig2joknfw7wqd.jpg
   
   样例用的是STM32F103R8,仅64K Flash。
    004718ozdwvcimj3c7f6xh.jpg

   我们更换主芯片为STM32F103RB,128K Flash。
    005005allyvp29nccs09mc.jpg

   重新编译工程,编译成功,没有报错,Flash空间足够了。
   
005204xf1kffggosefoksl.jpg

   这时,我们进入Target设置,Liner页中,设置如下。将默认的第一个红框中的勾点掉,可以看到第二个红框由灰色变为白色的可编辑状态。
    005524qpw2n9kyn9xkhten.jpg

   点“OK”,保存设置。接下来,重新打开Target设置,我们将目标芯片设置回之前的STM32F103R8。重新编译工程,发生了神奇的事情,编译成功了,没有报错。
    005944af7b7r79kzuu6ve9.jpg

   那么这个“Hello.sct”里面又是什么呢,我们不妨打开来瞧瞧。
   
011044uaadol7a7kdirrfi.jpg
   这可不嘛,包含了程序在链接时的ROM和RAM大小信息。本来如果勾选了默认项的话,每次都会按目标芯片的信息,重新生成此.sct文件;但是一旦取掉勾后,就不会重新生成此文件了,还是会按照之前已经产生的文件来链接目标程序。


   为了验证这一点,我们将“obj”文件夹下的文件全部删除(包括“Hello.sct”文件)。然后,重新编译程序,由于缺少了.sct文件,直接报错。
    011818v3uumbc7fc5rmm05.jpg

   到此,问题得到了验证。相信如果那位网友,如果能看到本贴的话,问题也是可以解决的。(我手头暂没对应硬件板,不能做烧写程序测试,相信不会有问题的。)

   总结:这是一个新手或借用别人程序,修改了目标芯片后,没有即时正确设置Linker选项。而引起的,表面现象为Flash烧写算法问题,而实质是Link错误的问题。

   所谓新手问题多,一般人不会去把Linker页,编辑默认选项的。不知道怎么回事,有人就把这项改了;这个改就改了吧,人家把目标芯片也改小了。让人排除问题都困难重重。

小叶三千 发表于 2021-9-6 13:31 | 显示全部楼层
之前买到过一片STM32F103C8T6,读取Flash大小居然是128K。。。但是实际的还是64K
sonicll 发表于 2021-9-7 08:44 | 显示全部楼层
这其实就是分散加载的用法,使用.sct文件定义链接地址,不使用keil的UI界面里的地址设置
nawu 发表于 2021-10-4 12:38 | 显示全部楼层
如何知道是不是超出了呢
qcliu 发表于 2021-10-4 12:44 | 显示全部楼层
如何读出flash大小是多少啊
tfqi 发表于 2021-10-4 12:52 | 显示全部楼层
能对程序进行瘦身吗
wiba 发表于 2021-10-4 12:57 | 显示全部楼层
obj文件是干什么用的呢
zljiu 发表于 2021-10-4 13:00 | 显示全部楼层
会不会是误读啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

57

主题

344

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部