Hi, I’m trying to run FreeRTOS on my 32-bit RISC-V core. The RISC-V core has ZiCSR extension and CLINT. I have succesfully compiled FreeRTOS and I’m now running it on the core. xTaskCreate
works properly but when vTaskStartScheduler
is added on the code, it suddenly ends under the function prvProcessTimerOrBlockTask
. Below is the object dump and highlighted in read is where it stops running (specifically at ECALL):
Here are my observations:
- Right after entering and exiting
xTaskResumeAll
(address 0x3aa4), it then copies the value of baseregister x10 to x15 (address 0x3aa8). And if x15 is zero it will go straight to ECALL (address 0x3aac) - When I checked the object dump of function
xTaskResumeAll
, x10 is somehow the return value of that function (which is then passed toprvProcessTimerOrBlockTask
when it goes back). That meansxTaskResumeAll
returns zero which causedprvProcessTimerOrBlockTask
to go straight to ECALL - This is the first and last occurence that this happened on the whole run
I think if xTaskResumeAll
did not returned zero, this will not happen so I would like to ask under what occurence that xTaskResumeAll returns zero and why is that it must never be zero? Or is there other problem?
Here is the code I’m trying to run:
/* Standard includes. */
#include <stdint.h>
#include "rv32i.h"
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
void vApplicationTickHook( void );
void vUartSend_1( void *pvParameters );
void vUartSend_2( void *pvParameters );
extern void freertos_risc_v_trap_handler( void );
void main( void )
{
uart_print("FreeRTOS DEMO\n");
csr_write(MTVEC, (uint32_t)&freertos_risc_v_trap_handler);
xTaskCreate( vUartSend_1,
"UART_SEND",
configMINIMAL_STACK_SIZE * 2U,
NULL,
1,
NULL );
xTaskCreate( vUartSend_2,
"UART_SEND",
configMINIMAL_STACK_SIZE * 2U,
NULL,
2,
NULL );
/* Start the tasks and timer running. */
vTaskStartScheduler();
uart_print("ERROR: You reached past the vTaskStartScheduler()");
}
void vUartSend_1( void *pvParameters ){
while(1){
uart_print("This is the first line\n");
vTaskDelay(100);
uart_print("This is the second line\n");
vTaskDelay(100);
}
}
void vUartSend_2( void *pvParameters ){
while(1){
uart_print("This is the THIRD line\n");
vTaskDelay(50);
uart_print("This is the FOURTH line\n");
vTaskDelay(50);
}
}
void SystemIrqHandler( uint32_t mcause )
{
uart_print("freeRTOS: Unknown interrupt \n");
}
void vApplicationTickHook( void ){
}
void vApplicationMallocFailedHook( void )
{
taskDISABLE_INTERRUPTS();
uart_print("FreeRTOS_FAULT: vApplicationMallocFailedHook (solution: increase 'configTOTAL_HEAP_SIZE' in FreeRTOSConfig.h)\n");
__asm volatile( "nop" );
__asm volatile( "ebreak" );
for( ;; );
}
void vApplicationIdleHook( void )
{
uart_print("FreeRTOS_FAULT: vApplicationStackOverflowHook\n");
}
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
taskDISABLE_INTERRUPTS();
uart_print("FreeRTOS_FAULT: vApplicationStackOverflowHook\n");
__asm volatile( "nop" );
__asm volatile( "nop" );
__asm volatile( "ebreak" );
for( ;; );
}
And here is the FreeRTOSConfig.h:
#define configMTIME_BASE_ADDRESS ( 0x80000000UL )
#define configMTIMECMP_BASE_ADDRESS ( 0x80000008UL )
#define configISR_STACK_SIZE_WORDS ( 128 )
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configCPU_CLOCK_HZ 100000000
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 8* 1024 ) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 0
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configGENERATE_RUN_TIME_STATS 0
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 4
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH 4
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); __asm volatile( "ebreak" ); for( ;; ); }
#endif /* FREERTOS_CONFIG_H */
I would really appreciate all advice, answers, or hints you might provide.