GD32E10x FreeRTOS
最近搞GD芯片,可能是年纪大了喜欢新鲜的玩意,于是下载了FreeRTOSv10.3.0,最新版本用于GD32E10x上,确实为难我了。
遇到的问题如下:
1. 调用vTaskStartScheduler();之后 stuck(卡住) in configASSERT,就是启动FreeRTOS后卡死在下面红色标识的那句话。
/* 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 unpredictable behaviour. */ configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
不得不赞扬,FreeRTOS是越做越人性化,写了那么长的拼音注释,怕我看不懂汉字。
那我就解释一下这段拼音的含义(千万别用什么翻译软件,那出来的结果是天书,我年轻时为了省时间也用软件翻译过)
优先级分组:可嵌套向量中断控制器(Nested Vectored Interrupt Controller)允许定义中断优先级的位分割成 定义抢占优
先级的位和定义子优先级的位,为了简单(粗爆)起见,所有位都必须用于设置抢占优先级,如果不是那样下面的断言将会失败。
如果应用程序仅仅使用CMSIS库来配制中断,那么所有的Cortex-M设备都可以在启动任务调度之前通过调用
NVIC_SetPriorityGrouping( 0 ); 来正确地进行中断优先级分组配制。但是,请注意一些特定于供应商的外围库采用非零优
先级组设置,在这种情况下使用一个零值将导致不可预测的行为。
在GD32E10x上是按下面的方法来设置的。
nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
2. 在优先级高于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断里面调用了FreeRTOS的函数会导致下面的断言失败。
/* 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.htmlhttp://www.freertos.org/FAQHelp.html */ configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
这里有点疑问,我怀疑是不是注释写错了,应该是说所有调用FreeRTOS内部函数的中断,其优先级不得高于
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 宏定义的值。而不是configMAX_SYSCALL_INTERRUPT_PRIORITY
废话不多说,到此为止吧。
3. 要防止任务中的变量写越界,否则会导致部分任务无法运行。