freertos应用程序常见错误排查

freertos系统应用程序常见问题

对一些比较常见的问题,下面简要的以 FAQ(问答)的形式给出可能的原因和解决方法。

问题现象:在一个 Demo 应用程序中增加了一个简单的任务,导致应用程序崩溃

  1. 任务创建时需要在内存堆中分配空间。许多 Demo 应用程序定义的堆空间大小只 够用于创建 Demo 任务——所以当任务创建完成后,就没有足够的剩余空间来增加其 它的任务,队列或信号量。
  2. 空闲任务是在 **vTaskStartScheduler()**调用中自动创建的。如果由于内存不足而无法创建空闲任务,**vTaskStartScheduler()**会直接返回。在调用 vTaskStartScheduler() 后加上一条空循环[for( ; ; )]可以使这种错误更加容易调试。
  3. 如果要添加更多的任务,可以增加内存堆空间大小,或是删掉一些已存在的 Demo 任务。

问题现象:在中断中调用一个 API 函数,导致应用程序崩溃

除了具有后缀为”FromISR”函数名的 API 函数,千万不要在中断服务例程中调用其 它 API 函数。

问题现象:有时候应用程序会在中断服务例程中崩溃

需要做的第一件事是检查中断是否导致了栈溢出。

在不同的移植平台和不同的编译器上,中断的定义和使用方法是不尽相同的——所 以,需要做的第二件事是检查在中断服务例程中使用的语法,宏和调用约定是否符合 Demo 程序的文档描述,以及是否和 Demo 程序中提供的中断服务例程范例相同。

如果应用程序工作在 Cotex M3 上,需要确定给中断指派优先级时,使用低优先级 号数值表示逻辑上的高优先级中断,因为这种方式不太直观,所以很容易被忘记。一个 比较常见的错误就是,在优先级高于 configMAX_SYSCALL_INTERRUPT_PRIORITY 的中断中调用了 FreeRTOS API 函数。

问题现象:在启动第一个任务时,调度器就崩溃了

如果使用的是 ARM7,那么请确定调用 vTaskStartScheduler()时处理器处于管理 模式(Supervisor mode)。最简单的方式就是在 main()之前的 C 启动态码中将处理器设 置为管理模式。ARM7 的 Demo 应用程序就是这么做的。

如果处理器不在管理模式下,调度器是无法启动的。

问题现象:临界区无法正确嵌套

除了 taskENTER_CRITICA()和 taskEXIT_CRITICAL(),千万不要在其它地方修改控制器的中断使能位或优先级标志。这两个宏维护了一个嵌套深度计数,所以只有当所有的嵌套调用都退出后计数值才会为 0,也才会使能中断。

问题现象:在调度器启动前应用程序就崩溃了

如果一个中断会产生上下文切换,则这个中断不能在调度器启动之前使能。这同样适用于那些需要读写队列或信号量的中断。在调度器启动之前,不能进行上下文切换。

还有一些 API 函数不能在调度器启动之前调用。在调用 vTaskStartScheduler()之前,最好是限定只使用创建任务,队列和信号量的 API 函数。

问题现象:在调度器挂起时调用 API 函数,导致应用程序崩溃

调用 vTaskSuspendAll()使得调度器挂起,而唤醒调度器调用 xTaskResumeAll()。 千万不要在调度器挂起时调用其它 API 函数。

问题现象:函数原型 pxPortInitialiseStack()导致编译失败

每种移植都需要定义一个对应的宏,以把正确的内核头文件加入到工程中。如果编译函数原型 pxPortInitialiseStack()时出错,这种现象基本上可以确定是因为没有正确定义相应的宏。

可以基于相应平台的 Demo 工程建立新的应用程序。这种方式就不用担心没有包 含正确的文件,也不必担心没有正确地配置编译器选项。

经验分享 程序员 微信小程序 职场和发展