c - FreeRTOS:为什么我的任务在调用 vTaskStartScheduler 后没有启动?
问题描述
我正在为 Xilinx UltraScale+ ZCU102 设备上的 RPU 编写一个应用程序,该设备需要在 FreeRTOS 中运行一些任务。我的应用程序首先创建一个“启动”任务,然后创建其余任务。在成功创建我的启动任务并调用 vTaskStartScheduler() 后,启动任务没有运行。
我注意到 FreeRTOS 常见问题页面 ( http://www.freertos.org/FAQHelp.html ) 说:
如果您创建的项目正在编译,并且至少执行到调度程序启动,但在调用 vTaskStartScheduler() 后只有一个任务正在执行或根本没有任务正在执行,那么很可能中断向量表不正确。
所以我首先检查以确保中断向量表是正确的。我正在使用 FreeRTOS 10.0,它是作为 ZCU102 BSP 的一部分构建的。
在使用 BSP 创建的文件“port_asm_vectors.S”中,我有
// port_asm_vectors.S
...
.section .vectors,"a"
_vector_table:
ldr pc,=_boot
ldr pc,=Undefined
ldr pc, _swi
ldr pc,=PrefetchAbortHandler
ldr pc,=DataAbortHandler
NOP /* Placeholder for address exception vector*/
ldr pc, _irq
ldr pc,=FIQHandler
_irq: .word FreeRTOS_IRQ_Handler
_swi: .word FreeRTOS_SWI_Handler
...
在我的应用程序的链接器脚本中,我有以下内容
// lscript.ld
...
SECTIONS
{
.vectors : {
KEEP (*(.vectors))
*(.boot)
} > psu_r5_ddr_0_MEM_0
...
因为我在这里使用的是 Xilinx SDK 生成的文件,所以我认为中断向量表设置正确,所以我认为我的 FreeRTOS 配置有问题。
我的 FreeRTOSConfig.h 文件与我看到的示例基本相同,尽管我做了一些更改,例如:
// FreeRTOSConfig.h
...
#define configMINIMAL_STACK_SIZE (250)
#define configTOTAL_HEAP_SIZE (0xC800)
#define configSUPPORT_STATIC_ALLOCATION 1
#define configUSE_TASK_FPU_SUPPORT 2
...
最小堆栈大小和总堆大小大于默认值,我们只使用静态分配的内存。没有浮动。
在程序入口处,我调用这个函数:
void prvSetupHardware( void )
{
BaseType_t xStatus;
XScuGic_Config *pxGICConfig;
portDISABLE_INTERRUPTS();
pxGICConfig = XScuGic_LookupConfig( XPAR_SCUGIC_SINGLE_DEVICE_ID );
configASSERT( pxGICConfig );
configASSERT( pxGICConfig->CpuBaseAddress == ( configINTERRUPT_CONTROLLER_BASE_ADDRESS + configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ) );
configASSERT( pxGICConfig->DistBaseAddress == configINTERRUPT_CONTROLLER_BASE_ADDRESS );
xStatus = XScuGic_CfgInitialize( &xInterruptController, pxGICConfig, pxGICConfig->CpuBaseAddress );
configASSERT( xStatus == XST_SUCCESS );
( void ) xStatus; /* Remove compiler warning if configASSERT() is not defined.
xStatus = XScuGic_SelfTest(&xInterruptController);
configASSERT( xStatus == XST_SUCCESS );
( void ) xStatus; /* Remove compiler warning if configASSERT() is not defined. */
xTxMutex = xSemaphoreCreateMutex();
configASSERT( xTxMutex );
xPort = xSerialPortInitMinimal( configCLI_BAUD_RATE, cmdQUEUE_LENGTH );
/* Disable cache on OCM */
Xil_SetTlbAttributes(OCM_START_ADDR,0x14de2); // S=b1 TEX=b100 AP=b11, Domain=b1111, C=b0, B=b0
}
在我的应用程序代码中,创建 init 任务是创建静态内存区域后首先发生的事情之一。
TaskHandle_t taskId = xTaskCreateStatic(
task_func, // pointer to task entry code
"STARTUP", // task name
0x3EA, // stack depth
0x00000000, // arguments
1, // priority
task_stack_buffer, // statically allocated task stack buffer
pTaskBuffer); // statically allocated, holds tasks data structures
本次调用成功退出,调用vTaskStartScheduler,启动任务未启动。我逐步完成了 vTaskStartScheduler 调用,发现它没有提前退出或出错。
有什么想法吗?我需要启动启动任务,以便也可以安排其余任务。
注意:我已经在其他硬件平台上使用 FreeRTOS v10.0 成功运行了我正在使用的代码。我需要做的就是更新构建 FreeRTOS 库的 BSP。所以我不排除 C 代码中的问题,我只是认为它不像项目设置或 FreeRTOS 配置中的问题那样可能。
解决方案
你不需要 portENABLE_INTERRUPTS() 吗?
推荐阅读
- javascript - 角度 12 中未定义的 Ngrx 状态
- r - 我在数据集中有重复的 ID,并希望在数据列中保留 NA 数量最少的 ID
- javascript - 如果我运行 firebase serve,部分 JavaScript 文件不会执行
- python - 如何修复错误?TypeError: 不支持的操作数类型 -: 'tuple' 和 'int'
- java - JAVA:使用树形图方法获取对象的变量
- python - nltk.pos_tag 和 nltk.word_tokenize - 列表列表
- mysql - 仅返回多个重复父 ID 的子表上最后插入的父 ID
- flutter - 相机预览显示拉伸的图像,当高度降低时颤动
- python - 如何在 streamlit 中获得两个月年日期之间的差异?
- python - TypeError:“int”对象在不同大小的列表上不可下标