英文原文:http://www.freertos.org/FAQHelp.html#faq
很遗憾我并不知道你的程序为什么不能运行,但是以下列出了一些不同问题的常用解决方案。
很遗憾我并不知道你的程序为什么不能运行,但是以下列出了一些不同问题的常用解决方案。
1.程序能够编译,但是不能运行
官方例子中提供的每一个移植好的程序样例在相应的硬件平台上都能正确编译和运行而不用做任何的修改。提供的样例工程将确保新用户尽可能花费最少的时间和精力开始使用FreeRTOS。我们推荐从提供的已经预配置的例子中选择一个合适的略作修改来开始自己新的工程,这样做可以确保新的工程包含了必要的源文件和头文件,以及安装了必要的中断服务程序。如果你创建的工程已经能够编译并且可以运行,但是调用完vTaskStartScheduler()函数后只有一个任务运行或没有任务运行,那么很可能是你中断向量表不正确。
ARM CORTEX-M用户特别注意:ARM Cortex-M3,ARM Cortex-M4和ARM Cortex-M4F上的移植需要FreeRTOS处理安装的SysTick,PendSV和SVCCall中断向量,中断向量表可以分别直接使用FreeRTOS定义的xPortSysTickHandler(),xPortPendSVHandler()和vPortSVCHandler()三个函数。但是,如果中断向量表是与CMSIS兼容的话,用户需在FreeRTOSConfig.h中添加以下三行代码以使FreeRTOS和CMSIS中中断向量名字做映射。
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
使用“#define”这种方法仅在你使用的开发工具提供的默认中断向量名称是定义为[WEAK]的,否则的话你就应该将它们注释掉或者删掉。
2.栈
到目前位置栈溢出依然是最常见的问题,一个任务的栈的有效大小通过xTaskCreate()或者xTaskCreateStatic()的usStackDepth参数设置。可以尝试通过增加或降低有问题的任务的栈大小来解决问题,不要编写需要大量栈控件的中断服务函数。调用了字符串格式化函数的任务有可能需要大量的栈空间,尤其是在使用GCC编译器的时候,这样的任务发生栈溢出的可能性最大。任务被创建的时候分配给任务的栈空间的每一个字节被初始化为0xa5,这使得检查一个任务是否栈溢出变得非常简单,另外定义在task.c中的函数usTaskCheckFreeStackSpace()展示了如何在程序运行的时候检查栈的使用情况(函数执行效率低,建议仅在调试过程中使用)。3.中断不能执行
首先,确认在使用FreeRTOS时出现的问题在不使用FreeRTOS的时候是否依然存在,这可以通过写一个不使用FreeRTOS的简单应用来验证。在调度器运行之前调用FreeRTOS的API函数应保持中断是禁能的,直到第一个任务she开始运行的时候再重新使能。这样做是为了保证在使用FreeRTOS API初始化系统期间不会因为中断引起系统崩溃。调度器开始运行前后调度器可能处在一个不同的状态。不要使用taskENTER_CRITICAL()和taskEXIT_CRITICAL()之外的任何方式去改变微控制器中断的使能位或优先级。由于一些库函数自己也会使能/禁能中断,而这两个宏可以保持中断嵌套调用的深度,使用这两个宏可以确保中断只在完全退出嵌套的前提下才能重新使能中断。4.我在官方提供的应用例子中添加了一个简单的任务,然后程序就奔溃了
创建任务需要的内存是从内核堆中获得的,许多FreeRTOS官方提供的应用案例的堆大小仅够维持应用案例所提供的任务,并没有为以后增加任务提供足够的堆空间。空闲任务是启动FreeRTOS调度器的时候自动创建的,如果没有足够的堆空间创建空闲任务,那么函数vTaskStartScheduler()会返回,程序也不会继续运行下去。为改进这些,你可以增加堆空间,也可以减少应用案例中的任务。5.中断中使用FreeRTOS API函数
不要在中断服务程序中使用没有以“...FromISR()”结尾的FreeRTOS API函数。如果中断的优先级大于configMAX_SYSCALL_INTERRUPT_PRIORITyoY设置的优先级,那么该中断服务程序中不应该调用FreeRTOS API函数。当你设置中断优先级的时候请务必注意以下几点:- configMAX_SYSCALL_INTERRUPT_PRIORITY定义在头文件FreeRTOSConfig.h中,在ARM CORTEX-M平台上,中断优先级的数值比较小意味着中断逻辑优先级比较高,不要忘记给中断优先级赋值,否则中断会默认给优先级赋值为0,优先级值为0一位置中断逻辑优先级最高且大于configMAX_SYSCALL_INTERRUPT_PRIORITY所表示的优先级。
- 当你在不同的ARM CORTEX-M3平台的芯片上指定优先级的时候,请注意不同的CORTEX-M3芯片使用的表示优先级的bit位数是不同的。
- 在ARM CORTEX-M3内部使用字节的几个最高有效位表示中断的优先级,ARM以及各个ARM CORTEX-M许可厂商提供的库函数可以用来给中断优先级赋值,但是有些库函数赋值给了最高有效位,有些赋值给了最低有效位。
- 表示中断优先级的比特位被分为了抢占优先级和子优先级两组,为尽可能的简单化和兼容性,应确保所有的比特位分配给‘抢占优先级组’。