1.configASSERT( ucCurrentPriority >= ucMaxSysCallPriority )报错
最近用FreeRTOS开发一个商用项目,用到了FreeRTOS,测试时发现一个奇怪的问题,代码运行一段时间后要么fault,要么某个任务像死了一样不在运行。找了很久没找到是什么问题,最后无奈,打开了FreeRTOS调试功能发现以下代码报错。
#if( configASSERT_DEFINED == 1 )
void vPortValidateInterruptPriority( void )
{
extern uint32_t ulPortGetIPSR( void );
uint32_t ulCurrentInterrupt;
uint8_t ucCurrentPriority;
ulCurrentInterrupt = ulPortGetIPSR();
/* Is the interrupt number a user defined interrupt? */
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
{
/* Look up the interrupt's priority. */
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
/* The following assertion will fail if a service routine (ISR) for
an interrupt that has been assigned a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
function. ISR safe FreeRTOS API functions must *only* be called
from interrupts that have been assigned a priority at or below
configMAX_SYSCALL_INTERRUPT_PRIORITY.
Numerically low interrupt priority numbers represent logically high
interrupt priorities, therefore the priority of the interrupt must
be set to a value equal to or numerically *higher* than
configMAX_SYSCALL_INTERRUPT_PRIORITY.
Interrupts that use the FreeRTOS API must not be left at their
default priority of zero as that is the highest possible priority,
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
and therefore also guaranteed to be invalid.
FreeRTOS maintains separate thread and ISR API functions to ensure
interrupt entry is as fast and simple as possible.
The following links provide detailed information:
http://www.freertos.org/RTOS-Cortex-M3-M4.html
http://www.freertos.org/FAQHelp.html */
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
}
/* Priority grouping: The interrupt controller (NVIC) allows the bits
that define each interrupt's priority to be split between bits that
define the interrupt's pre-emption priority bits and bits that define
the interrupt's sub-priority. For simplicity all bits must be defined
to be pre-emption priority bits. The following assertion will fail if
this is not the case (if some bits represent a sub-priority).
If the application only uses CMSIS libraries for interrupt
configuration then the correct setting can be achieved on all Cortex-M
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
scheduler. Note however that some vendor specific peripheral libraries
assume a non-zero priority group setting, in which cases using a value
of zero will result in unpredicable behaviour. */
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
}
#endif /* configASSERT_DEFINED */
该代码在port.c文件内,具体报错位置是:
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
该报错意思是当前中断的优先级大于系统能够管理的优先级。
在FreeRTOS内有一个configMAX_SYSCALL_INTERRUPT_PRIORITY的宏,它是配置FreeRTOS能够管理中断的最大优先级,在FreeRTOS内中断优先级分组只能全部配置成抢占优先级,没有子优先级,FreeRTOS也没有处理子优先级的代码。在FreeRTOS内只有大于configMAX_SYSCALL_INTERRUPT_PRIORITY才能调用FreeRTOS API(中断优先级很低),小于configMAX_SYSCALL_INTERRUPT_PRIORITY不能调用FreeRTOS的API(中断优先级很高),如果调用了就会出现上述问题,经查我的代码内中断的优先级很高,比系统能够管理的中断优先级还要高,还在中断内调用了FreeRTOS的API,该语句就会报错configASSERT( ucCurrentPriority >= ucMaxSysCallPriority )。将中断优先级调低,FreeRTOS运行不稳定的问题成功解决,跑了一个月都没有死。
2.configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 )报错。
此处报错,第一种是因为高于configMAX_SYSCALL_INTERRUPT_PRIORITY优先级的中断调用了RTOS的API导致的,解决办法,将中断优先级调低,比configMAX_SYSCALL_INTERRUPT_PRIORITY要低,就可以调用RTOS的API了。
第二种是因为中断发送消息队列,发送信号量等操作使用了不带ISR结尾的API,而是调用了普通不带ISR的API导致的,解决办法,将API替换为带ISR结尾的API便可以解决问题。
1478

被折叠的 条评论
为什么被折叠?



