由于本人对linux系统内核这块比较感兴趣,下一份工作想做linux驱动相关的;于是最近一旦有空都在研究linux内核源码,面对linux内核这个庞然大物,越看越觉得不能太过急躁,且由于还要工作,只能在业余时间看看,所以不能贪多,只能挑自己感兴趣的深入研究,其他的大概了解一下就行了;除此之外我还喜欢在真实的外设上测试学到的东西,作为电子信息专业的毕业生,理所当然地手头有各种板子以及单片机~~~~,昨天在看stm32相关资料时看到野火的教程《uCOS-III 应用开发指南—基于 STM32F103系列》,试着移植ucos-iii到stm32上,整个过程还算比较顺利的,但遇到了一个比较典型的问题,在此分享出来,作为备忘,也希望能够帮到类似问题的人。
一、先来说说背景知识:
STM32F103C8T6这块芯片做成的最小系统板在某宝应该是最多的了,价格比51最小系统板便宜,当然片上资源更加丰富;
这块芯片有64K程序存储器、20KSRAM;
这块芯片目前能跑的RTOS估计只有ucos(包括二代和三代)、RTOS;
二、ucos移植过程:
包括从ucos官网下载相关源码以及下载CM3相关源码、安装keil、创建工程等过程在此不做叙述,具体可以自行问谷歌或度娘;ucos-iii的移植可以参考《uCOS-III 应用开发指南—基于 STM32F103系列》,个人觉得写的很不错。
那么问题来了:
----------------------分隔符---------------------------------------
linking...
.Objectsucos-led.axf: Error: L6406E: No space in execution regions with .ANY selector matching lib_mem.o(.bss).
.Objectsucos-led.axf: Error: L6406E: No space in execution regions with .ANY selector matching os_cfg_app.o(.bss).
.Objectsucos-led.axf: Error: L6406E: No space in execution regions with .ANY selector matching os_var.o(.bss).
.Objectsucos-led.axf: Error: L6406E: No space in execution regions with .ANY selector matching startup_stm32f10x_hd.o(STACK).
.Objectsucos-led.axf: Error: L6406E: No space in execution regions with .ANY selector matching app.o(.bss).
.Objectsucos-led.axf: Error: L6406E: No space in execution regions with .ANY selector matching os_var.o(.data).
.Objectsucos-led.axf: Error: L6406E: No space in execution regions with .ANY selector matching cpu_core.o(.data).
.Objectsucos-led.axf: Error: L6406E: No space in execution regions with .ANY selector matching stm32f10x_rcc.o(.data).
.Objectsucos-led.axf: Error: L6406E: No space in execution regions with .ANY selector matching cpu_core.o(.bss).
.Objectsucos-led.axf: Error: L6406E: No space in execution regions with .ANY selector matching lib_mem.o(.data).
.Objectsucos-led.axf: Error: L6406E: No space in execution regions with .ANY selector matching os_prio.o(.data).
.Objectsucos-led.axf: Error: L6406E: No space in execution regions with .ANY selector matching os_cpu_c.o(.data).
.Objectsucos-led.axf: Error: L6407E: Sections of aggregate size 0x8e30 bytes could not fit into .ANY selector(s).
Not enough information to list image symbols.
Not enough information to list the image map.
Finished: 2 information, 0 warning and 13 error messages.
".Objectsucos-led.axf" - 13 Error(s), 0 Warning(s).
----------------------分隔符---------------------------------------
一下子这么多错误,看得我懵了,讲道理按照教程一步一步来的,不应该出错啊,当然书中所提及芯片和我自己用的还是有差别的,于是在这过程中我做了相应修改,书中所用是大容量的,我用的姑且算作中等容量;于是我搜索了相关问题,找到一种解决方案,具体为修改keil中存储器大小配置;为什么要这样改这个呢?原因是带ucos的工程编译后需要0x8e30 bytes(36k的样子)的空间,而c8t6却只有20K。
这是C8T6真实存储器大小:
当然,这种方案可以让程序编译通过,不过并没什么用,根本问题没有解决;我从别处得到印证,ucos可以运行在RAM-8K以上的单片机中,于是我从代码中找原因,最终我在一个头文件中找到这么一行代码:
//lib_cfg.h
#define LIB_MEM_CFG_HEAP_SIZE 27u * 1024u /* Configure heap memory size [see Note #2a]. */
你没有看错,这里把堆空间设置为27K。。。。堆空间都比RAM还大了,这程序怎么可能在单片机是正常运行,于是我把堆空格改为10K,程序编译通过,下载到单片机上,看到LED闪起来。。。证明本次ucos移植完成,之后可以通过STM32来验证ucos的各种理论技术了。
#define LIB_MEM_CFG_HEAP_SIZE 10u * 1024u
三、结语:
学习过程中遇到问题在所难免,但能解决问题的能力才是真正需要掌握东西,解决问题要建立在真实的外设上更有意义。
后续会分享一些ucos、RTOS、linux操作系统相关的积累和感悟。