首页 > 解决方案 > 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 配置中的问题那样可能。

标签: cembeddedfreertos

解决方案


你不需要 portENABLE_INTERRUPTS() 吗?


推荐阅读