历史上的今天
今天是:2025年07月26日(星期六)
2019年07月26日 | STM32 固件库移植出错
2019-07-26 来源:eefocus
1 问题描述
最近项目上需要用到STM32F103VET6芯片。之前一直使用的是8年前的库,决定更新为最新版的固件库。在建立新工程编译时出现了以下错误:“..OBJNH3N STM32.sct(7): error: L6236E: No section matches selector - no section to be FIRST/LAST.”

2 问题分析
2.1 问题定位
双击出错信息,Keil跳转到如下窗口:

错误出现在“xxxx.sct”文件,sct文件,全名scatter file,中文名分散加载文件,是ARM程序链接时的输入参数。默认设置下,Keil会自动生成.sct文件。出错的的“NH3N STM32.sct”文件就是keil自动生成的。
2.2 分散加载机制(sct文件)
分散加载机制允许为链接器指定映像的存储器映射信息,可实现对映像组件分组和布局的全面控制。分散加载区域分两类:
加载区:该映像文件开始运行前存放的区域,即当系统启动或加载时应用程序存放的区域。
执行区:映像文件运行时的区域,即系统启动后,应用程序进行执行和数据访问的存储器区域。
2.3 本工程sct文件分析
对于本工程生成的.sct文件来说。
6 ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
加载区,指定了程序映像在存储区存放的起始地址:0x08000000,总共的大小为0x00080000。这与图3中的存放代码的Flash区域地址一致。上电后,从此地址处加载代码。
11 RW_IRAM1 0x20000000 0x00010000 { ; RW data
执行区,指定了运行时临时存放代码的地方。起始地址:0x20000000,总共的大小:0x00010000。这与图3中的SRAM区域地址一致。上电后,程序在此区域内运行。

上边说了Keil在编译工程时会自动生成.sct文件。那么Keil是怎样知道加载区(ROM)起始地址以及执行区(RAM)起始地址的呢?
其实我们新建工程时第一步就是选择芯片的具体型号,Keil会根据我们设置的芯片型号加载默认的ROM、RAM起始地址和存储区大小。
在“Options for Target…”的“Target”选项卡可以看到默认的设置。下图即是我的工程keil的默认设置。从图中可知IROM1就是程序映像存储区参数,IRAM1就是运行时临时代码存放区参数。两个名称前边都加了“I”,代表内部存储区的意思,对应图标“on-chip”。如果系统有外部扩展的ROM和RAM,还需要在“off-chip”对应的区域设置存储区起始地址和大小。“Startup”单选框用于选择系统启动起始区域。通过和生成的.scf文件对比,此默认设置和.sct文件中的代码表述一致。

另外,可以设置多个IROM、ROM、IRAM和RAM区,这和.sct文件支持多个不连续的加载区和运行区相对应。但是启动加载区只能选择一个。
报错的代码行是:
7 *.o (RESET, +First)
这一行代码指定了启动代码的首次执行地址。RESET标号表示的地址就是启动地址。其中First属性符表示把RESET代表的代码放在最开始处,也就是指定RESET代表的地址为启动地址。
2.4 报错原因
报错信息中的“no section to be FIRST/LAST”也就是说没有找到FIRST或者LAST对应的区域,也就是说没有找到RESET标号对应的代码。RESET标号对应的代码也就是单片机复位之后执行的代码。因此可以判断keil没有找到STM32的启动文件。
3 问题解决
3.1 启动文件存放位置
通过以上的分析,找到STM32的启动文件,并加载到工程中就可以解决问题了。
在官方库文件中可以找到启动文件,文件存放路径:STM32F10x_StdPeriph_Lib_V3.5.0LibrariesCMSISCM3DeviceSupportSTSTM32F10xstartuparm。在此路径下总共有8个启动文件。

3.2 启动文件适用环境
这8个启动文件分别适用于什么场合?对于本工程应该选择哪一个启动文件?
仔细查看可知这8个文件的文件名都是startup_stm32f10x_xx.s 格式的。这些启动文件分别适用于不同类型及flash大小的器件。
文件名 适用类别 适用型号
startup_stm32f10x_cl.s 互联型的器件 STM32F105xx,STM32F107xx
startup_stm32f10x_hd.s 大容量器件 STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_hd_vl.s 大容量器件 STM32F100xx
startup_stm32f10x_ld.s 小容量器件 STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_ld_vl.s 小容量器件 STM32F100xx
startup_stm32f10x_md.s 中容量器件 STM32F101xx,STM32F102xx,STM32F103xx
startup_stm32f10x_md_vl.s 中容量器件 STM32F100xx
startup_stm32f10x_xl.s Flash在512K到1024K字节器件 STM32F101xx,STM32F102xx,STM32F103xx
3.3 STM32 内部Flash容量等级划分规则
那么STM32内部Flash是按照什么样的标准划分大、小、中容量的?
每种系列的器件的划分标准是不太一样的。可能从芯片数据手册中找到划分标准。对于STM32F103xx系列的划分标准如下图所示。

3.4 找到合适的启动文件
由数据手册中的选型部分可知STM32F103VET6的Flash大小为512Kbytes,属于大容量系列,因此应该选择启动文件:startup_stm32f10x_hd.s 。
使用notepad++打开此启动文件,启动文件采用汇编语言编写,主要完成系统底层初始化并找到程序main函数执行入口。在启动文件中可以找到如下代码:
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size

可以看到这就是.scf文件要找的RESET标号对应的代码。
3.5 往工程中添加启动文件
(以下操作以我自己的工程为例)
把启动文件startup_stm32f10x_hd.s拷贝到工程文件里的CMSIS文件夹里。然后在keil工程树中右击“CMSIS”,在弹出菜单中选择“Manage Project Items”,在弹出的“Manage Project Items”窗口中,在“CMSIS”group中点击“Add Files…”添加刚才的拷贝的启动文件。


3.6 编译验证
启动文件添加好后,重新编译工程,编译顺利通过。

【参考】
1、Keil sct分散加载文件 http://blog.csdn.net/kobesdu/article/details/38258449
2、关于arm启动代码的启动流程 https://www.cnblogs.com/blackeyes/articles/4742264.html
3、STM32F10x 启动代码文件选择 https://wenku.baidu.com/view/263f7f5c0066f5335b81215f.html
史海拾趣
|
前天我用木马克星杀了一次毒,等杀完以后,再点击按Ctrl+Alt+delete的键时,系统没有任何反应,不弹出任务管理器,请问这是什么问题 请各位高手给以解答 在此万分感谢!!!… 查看全部问答> |
|
运行于EK-STM32F学习板上的STM32固件库中的例子 相关链接:http://www.stmicroelectronics.com.cn/stonline/mcu/images/STM32F10xxx_Library_Manual_ChineseV2.pdf… 查看全部问答> |
|
根据 ST 虚拟串口 的例子,改写了一个用USB与上位机通信的程序。现在的问题是,原程序 把 USB_Init();语句放在了 main 函数里面,这样如果插着USB线给 ARM 上电的话,就会导致 usb的初始化 ...… 查看全部问答> |
|
请问香主,我在www.stmfans.com里面看到了一个帖子说STM32有内置的硬件CRC计算单元,我在库文件、datasheet上都没有找到。请问真是的是有吗?如果有,在那个模块?stmfans的链接如下:http://www.stmfans.com/bbs/viewthread.php?tid=325&high ...… 查看全部问答> |
|
各位好:我在ad程序里添加了两个变量:float in_voltage[NP]; float step_h[NP];后出现这个错误error: can\\\'t allocate .ebss (sz: 00002898 page: 1) in DRAMH0 (avail: ...… 查看全部问答> |
|
最近一个月多月,工作上的事情繁多,没能够及时的完成前期参与的论坛活动,深感抱歉!先开个帖子,我慢慢的补吧 本来打算做成这样的。 总体设计框图 实现的功能 1. 完成A/D转换,FFT变换 ...… 查看全部问答> |
|
define.h #include #define uchar unsigned char #define uint unsigned int sbit led1=P1^0; uchar num; main.c #include void main(void) { TMOD=0x01; TH0=(65536-45872)/256; TH0=(65536-45872)%256; EA=1; ET0=1; TR0=1; ...… 查看全部问答> |




