沉寂了几年了,觉得应该分享些什么了。前段时间用FreeRTOS做了些东西,陆续拿出来给大家拍砖。
应该说本人是Linux的粉丝吧,所以我业余时间分享的经验也多半是应用Linux作为桌面开发平台的。闲话少说,进入正题。
选用FreeRTOS绝对不是应为他的代码是如何的优秀,而是因为他在自由软件社区展现出的很强的生命力。要知道,如果一个自由软件社区足够的活跃,就意味着有更多的爱好者不停的解决和修正他运行的过程中遇到的诸多问题。
由于本人的工作中会采用STM32的CortexM的MCU,所以后续的调试方法会以STM32LDiscovery的开发板为例。
FreeRTOS 发布包中有针对不同平台的移植和实例,要想在Linux主机交叉编译需要选用arm-none-eabi-gcc这样的编译工具链,而选用ST的MCU后一个廉价的ST-Link可以作为调试工具,而STM32LDiscovery的板子上自带就有这样的工具。硬件调试工具提供的下载调试程序的通道,还需要一个能够支持GDB Server的服务程序才能用arm-none-eabi-gdb完成代码的调试。
下面的网站讲述了一个st-link的Linux工具可以支持下载调试你的二进制代码。
http://www.wolinlabs.com/blog/linux.stm32.discovery.gcc.html
我个人比较喜欢openocd,他有自己特有的telnet模式可以对目标板进行各种设置,他在支持标准GDB Server的同时还针对嵌入式系统提供RTOS的支持,很多人不太了解这对调试有何好处。如果用gdb调试Linux下的多线程程序可以用info thread这样的命令观察线程的运行状态,当然可以很容的检查线程栈溢出等情况。
准备资源
下载最新的openocd,系统自带的多半太陈旧,嵌入式系统的发展要比PC更快
git clone git://git.code.sf.net/p/openocd/code openocd
FreeRTOS 8.1.2
为FreeRTOS 8.1.2打补丁
openocd对FreeRTOS的支持,需要在运行openocd的时候加入configure -rtos auto选项,下面是我修改过的openocd board 脚本文件
# This is an STM32L discovery board with a single STM32L152RBT6 chip. # http://www.st.com/internet/evalboard/product/250990.jsp source [find interface/stlink-v2.cfg] transport select hla_swd set WORKAREASIZE 0x4000 source [find target/stm32l.cfg] # use hardware reset, connect under reset reset_config srst_only srst_nogate $_TARGETNAME configure -rtos auto
运行的时候只需要如下命令
openocd -f board/stm32ldiscovery.cfg
这时候如果你用arm-none-eabi-gdb通过target remote:3333 load代码的时候,会显示没有检测的RTOS。
网上找了些帖子,都没有解决,大概说明是openocd采用了7.6.2之前版本的一个优先级变量,但是如果你把FreeRTOS换成之前的版本仍旧不能成功检测。
我研究了以下FreeRTOS 8.1.2的代码,发现加回原来的这个全局优先级变量可以解决这个问题,而且只是两条语句对于FreeRTOS优先级调度应该没有什么影响
在task文件中寻找如下行,
PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) 0U;
在下面加入这一行
PRIVILEGED_DATA static unsigned portBASE_TYPE uxTopUsedPriority = tskIDLE_PRIORITY;
在函数xTaskGenericCreate中的如下代码
uxTaskNumber++;
#if ( configUSE_TRACE_FACILITY == 1 )
{
/* Add a counter into the TCB for tracing only. */
pxNewTCB->uxTCBNumber = uxTaskNumber;
}
#endif /* configUSE_TRACE_FACILITY */
的前面加入
#if ( configUSE_TRACE_FACILITY == 1 )
if( pxNewTCB->uxPriority > uxTopUsedPriority )
{
uxTopUsedPriority = pxNewTCB->uxPriority;
}
#endif /* configUSE_TRACE_FACILITY */
重新编译FreeRTOS的实例
(原创文章请著名出处http://blog.csdn.net/rickleaf)
openocd FreeRTOS 调试
开启gdb server
openocd -f board/stm32ldiscovery.cfg
调试下载代码
arm-none-eabi-gdb stm32l1xx_freertos.elf
load
这时候server端显示如下信息
Open On-Chip Debugger 0.9.0-dev-00186-g30203b3-dirty (2014-11-05-23:00)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.sourceforge.net/doc/doxygen/bugs.html
adapter speed: 300 kHz
adapter_nsrst_delay: 100
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
srst_only separate srst_nogate srst_open_drain connect_deassert_srst
Info : clock speed 300 kHz
Info : STLINK v2 JTAG v23 API v2 SWIM v0 VID 0x0483 PID 0x3748
Info : using stlink api v2
Info : Target voltage: 2.918068
Info : stm32l.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : accepting ‘gdb‘ connection on tcp/3333
Info : STM32L flash size is 128kb, base address is 0x8000000
undefined debug reason 7 - target needs reset
Info : Auto-detected RTOS: FreeRTOS
adapter speed: 300 kHz
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x0800021c msp: 0x20004000
STM32L: Enabling HSI
adapter speed: 2000 kHz
Info : Padding image section 0 with 3 bytes
target state: halted
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x20000012 msp: 0x20004000
target state: halted
target halted due to breakpoint, current mode: Thread
xPSR: 0x61000000 pc: 0x20000012 msp: 0x20004000
adapter speed: 300 kHz
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x0800021c msp: 0x20004000
在调试端,通过info thread来查看FreeRTOS的运行状况
GNU gdb (GNU Tools for ARM Embedded Processors) 7.6.0.20140529-cvs
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-linux-gnu --target=arm-none-eabi".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/ricky/workspace/stm32/stm32l1xx_freertos/Debug/stm32l1xx_freertos.elf...done.
(gdb) tar rem:3333
Remote debugging using :3333
0x00000000 in ?? ()
(gdb) load
Loading section .isr_vector, size 0x24c lma 0x8000000
Loading section .text, size 0x3df9 lma 0x800024c
Loading section .data, size 0xa4 lma 0x8004048
Start address 0x800010c, load size 16617
Transfer rate: 4 KB/sec, 5539 bytes/write.
(gdb) c
Continuing.
^C
Program received signal SIGINT, Interrupt.
[Switching to Thread 536872480]
0x08002b78 in prvCheckTasksWaitingTermination ()
at ../system/src/FreeRTOS/Source/tasks.c:2859
2859 while( uxTasksDeleted > ( UBaseType_t ) 0U )
(gdb) info thread
[New Thread 536871864]
[New Thread 536873328]
[New Thread 536871248]
Id Target Id Frame
4 Thread 536871248 (LED3) 0x08001b90 in vPortYield ()
at ../system/src/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c:371
3 Thread 536873328 (Tmr Svc) 0x08001b90 in vPortYield ()
at ../system/src/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c:371
2 Thread 536871864 (LED4) 0x08001b90 in vPortYield ()
at ../system/src/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c:371
* 1 Thread 536872480 (IDLE : : Running) 0x08002b78 in prvCheckTasksWaitingTermination () at ../system/src/FreeRTOS/Source/tasks.c:2859
(gdb)
至此我们可以用openocd做一些和FreeRTOS更紧密的调试了。
关于笔者是如何构建stm32的freertos的编译环境的,我会在后面的文章讲述。
(原创文章请著名出处http://blog.csdn.net/rickleaf)