c - FreeRTOS:为什么我的任务在调用 vTaskStartScheduler 后没有开始?

标签 c embedded freertos

我正在 Xilinx UltraScale+ ZCU102 设备上为 RPU 编写应用程序,需要在 FreeRTOS 中运行一些任务。我的应用程序首先创建一个“启动”任务,然后创建其余任务。在成功创建我的启动任务并调用 vTaskStartScheduler() 之后,启动任务没有运行。

我注意到 FreeRTOS FAQ 页面 ( http://www.freertos.org/FAQHelp.html ) 说:

If the project you have created is compiling, and at least executing up to the point that the scheduler is started, but only a single task is executing or no tasks are executing at all after the call to vTaskStartScheduler(), then it is likely that the interrupt vector table is incorrect.

所以我首先检查以确保中断 vector 表是正确的。我正在使用 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 生成的文件,我认为中断 vector 表设置正确,所以我认为我的 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 配置中的问题那么可能。

最佳答案

不需要移植ENABLE_INTERRUPTS()吗??

关于c - FreeRTOS:为什么我的任务在调用 vTaskStartScheduler 后没有开始?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57386081/

相关文章:

c - 算法复杂度与运行时间

c - 使用 Atmega328P 对 Romeo 板上的按钮开关进行编程

c++ - 传递 &arr(整个 block 的地址)或仅传递数组名称(第一个元素的地址)有什么区别吗?

stack - 在 FreeRtos 或 TI rtos 中计算堆栈大小

embedded - vTaskCreatePinnedToCore() 的行为不符合预期

c - 在 C 中,将结构作为参数传递给 printf 的预期行为是什么?

c - 静态库不需要头?

检查数组中的重复项并删除它们最坏情况的复杂度是 O(n^2) 还是 O(n^3)?

memory-management - 适用于无需动态内存分配的开发的语言

c - 在 xtaskcreate 中设置完美的 usStackDepth 重要吗?