FreeRTOS:为什么我的任务在调用 vTaskStartScheduler 后没有启动?

Can*_*ack 5 c embedded freertos

我正在 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
...
Run Code Online (Sandbox Code Playgroud)

在我的应用程序的链接描述文件中,我有以下内容

// lscript.ld
...
SECTIONS
{
.vectors : {
   KEEP (*(.vectors))
   *(.boot)
} > psu_r5_ddr_0_MEM_0
...
Run Code Online (Sandbox Code Playgroud)

因为我在这里使用 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
...
Run Code Online (Sandbox Code Playgroud)

最小堆栈大小和总堆大小大于默认值,并且我们仅使用静态分配的内存。没有漂浮物。

在程序入口处,我调用这个函数:

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
}
Run Code Online (Sandbox Code Playgroud)

在我的应用程序代码中,创建 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
Run Code Online (Sandbox Code Playgroud)

本次调用成功退出,并且发生对vTaskStartScheduler的调用,启动任务没有启动。我单步执行了 vTaskStartScheduler 调用,发现它没有提前退出或出错。

有什么想法吗?我需要启动启动任务,以便也可以安排其余的任务。

请注意:我已在使用 FreeRTOS v10.0 的其他硬件平台上成功运行了我正在使用的代码。我所需要做的就是更新构建 FreeRTOS 库的 BSP。因此,我并不排除问题出在 C 代码中,只是认为问题出现在项目设置或 FreeRTOS 配置中的可能性较小。

小智 0

你不需要移植ENABLE_INTERRUPTS()吗?