Keil MDK问题解决:烧写程序报错——超过最大芯片Flash空间无算法
情况是这样的。
8月份的某一天,在STM32&STM8QQ群里有位网友提问。说是在下载程序时报错了,报错信息如下图:(摘自QQ群历史消息)
根据提示08010000H之后的烧写Flash错误,初步怀疑是芯片烧写Flash选择错误。经询问,网友传上来的Flash选择项为下图:
显然,选择的目标芯片是最大64K Flash,最大地址才到0x0800ffff,显然跟烧写算法错误更是没关系的呀,空间不会超过64K。
又经了解到,网友在同一个工程下单跑LED灯程序是正确的,而加入图片显示后,就发生了烧写Flash算法错误。怀疑加入的图片过大,以致于编译后超过了64K空间。按理说,编译如果超过64K空间的话,编译是通不过的,但是他的程序却通过了,让人摸不着头脑。
网友所用芯片型号是:STM32F030C8,几翻核对的确是64K FLash。
让网友传来,编译成功的报告截图:
这下见鬼了,仅RW-data一项就91900,超过了64K。而且还编译成功了。(让查看.map文件,网友却没找对地方,未能给出有效信息。)
网友上传他的工程"oled_15.zip" 到QQ群空间(目前在群空间已经找不到8月份之前的文件了),我下载文件编译后,成功编译,编译时也没有报错(没有硬件,无法烧写Flash验证)。发现显示的图片占据了很大的空间。
这样也排除了Keil环境损坏或杀毒软件的可能,那么最后只有一种可能,还是Keil工程设置中的某项设置没设对。
但是这个问题当时我也没能成功解决。后来某天,在查看其它工程时,发现了一个选项。Target的Liner页下有两选项项可能会有问题。
默认情况下,第一个红框中的勾是点上的,这时下面的第二个红框中是灰色,不让更改;当第一个框勾去掉后,下面的sct文件可以选择其它的文件或者编辑。好像网友的工程中就没有点上,但由于没有原工程,无法验证。
上传个Keil环境自带的hello_arm程序,以这个工程为例去验证一下。
Hello_arm.rar (346.94 KB, 下载次数: 0)
主了方便验证,此程序已经被我做了改动,增加了两个文件,也非常简单。如下图。
“mini.c”文件,就一句话,定义个只读字符串数组。
“RedBmp.c”文件,也是一个只读数组,不同之处在于增加了个定长0x10000,正好64K。
主程序如下,就两条printf语句。
当注释掉第34行的“printf ("%s",gImage_RedBmp);”后,编译成功不报错;当放到注释后,就会报编译错误。这是我们想要的结果。
样例用的是STM32F103R8,仅64K Flash。
我们更换主芯片为STM32F103RB,128K Flash。
重新编译工程,编译成功,没有报错,Flash空间足够了。
这时,我们进入Target设置,Liner页中,设置如下。将默认的第一个红框中的勾点掉,可以看到第二个红框由灰色变为白色的可编辑状态。
点“OK”,保存设置。接下来,重新打开Target设置,我们将目标芯片设置回之前的STM32F103R8。重新编译工程,发生了神奇的事情,编译成功了,没有报错。
那么这个“Hello.sct”里面又是什么呢,我们不妨打开来瞧瞧。
这可不嘛,包含了程序在链接时的ROM和RAM大小信息。本来如果勾选了默认项的话,每次都会按目标芯片的信息,重新生成此.sct文件;但是一旦取掉勾后,就不会重新生成此文件了,还是会按照之前已经产生的文件来链接目标程序。
为了验证这一点,我们将“obj”文件夹下的文件全部删除(包括“Hello.sct”文件)。然后,重新编译程序,由于缺少了.sct文件,直接报错。
到此,问题得到了验证。相信如果那位网友,如果能看到本贴的话,问题也是可以解决的。(我手头暂没对应硬件板,不能做烧写程序测试,相信不会有问题的。)
总结:这是一个新手或借用别人程序,修改了目标芯片后,没有即时正确设置Linker选项。而引起的,表面现象为Flash烧写算法问题,而实质是Link错误的问题。
所谓新手问题多,一般人不会去把Linker页,编辑默认选项的。不知道怎么回事,有人就把这项改了;这个改就改了吧,人家把目标芯片也改小了。让人排除问题都困难重重。
|