该文章 中讲述了 FreeRTOS RISC-V-Qemu-virt_GCC 的 启动流程,本篇文章讲述一下 运行了流程
我将 RISC-V-Qemu-virt_GCC 做了一些改动
FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/main_blinky.c 改为如下
static void prvQueueSendTask( void *pvParameters )
{
for( ;; )
{
vSendString( "1111" );
vTaskDelay(1000);
}
}
static void prvQueueReceiveTask( void *pvParameters )
{
for( ;; )
{
vSendString( "2222" );
vTaskDelay(1000);
}
}
int main_blinky( void )
{
vSendString( "Hello FreeRTOS!" );
xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE * 2U, NULL,
mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );
xTaskCreate( prvQueueSendTask, "Tx", configMINIMAL_STACK_SIZE * 2U, NULL,
mainQUEUE_SEND_TASK_PRIORITY, NULL );
vTaskStartScheduler();
return 0;
}
如何从代码编译角度查看系统中有多少任务
1. 系统创建的任务
grep portTASK_FUNCTION_PROTO * -nr
2. 用户 创建的任务
grep -w "xTaskCreate(" * -nr
流程
我将按时间流走过的流程总结为如下
1. boot
2. fist task
3. mtimer interrupt
4. fist task & ecall
5. second task & ecall
6. third task & ecall
7. fourth task & ecall
8. third task ...
当前配置里面 不会在 mtimer interrupt 中 调度, 只能用户任务主动调度
_start
main
main_blinky
vTaskStartScheduler
xPortStartScheduler
xPortStartFirstTask
...
ret
任务1:prvTimerTask
prvProcessTimerOrBlockTask
刚进入就产生 mtimer 中断
freertos_risc_v_trap_handler
保存任务1
test_if_asynchronous
handle_asynchronous
test_if_mtimer
xTaskIncrementTick
processed_source
mret
任务1:prvTimerTask
prvProcessTimerOrBlockTask
.. 中间有很多 mtimer 中断
portYIELD_WITHIN_API/ecall
freertos_risc_v_trap_handler
保存任务1
test_if_asynchronous
handle_synchronous
test_if_environment_call
vTaskSwitchContext
taskSELECT_HIGHEST_PRIORITY_TASK
processed_source
mret
任务2:prvQueueReceiveTask
vSendString("2222");
vTaskDelay/portYIELD_WITHIN_API/ecall
freertos_risc_v_trap_handler
保存任务1
test_if_asynchronous
handle_synchronous
test_if_environment_call
vTaskSwitchContext
taskSELECT_HIGHEST_PRIORITY_TASK
processed_source
mret
任务3:prvQueueSendTask
vSendString("1111");
vTaskDelay/portYIELD_WITHIN_API/ecall
freertos_risc_v_trap_handler
保存任务1
test_if_asynchronous
handle_synchronous
test_if_environment_call
vTaskSwitchContext
taskSELECT_HIGHEST_PRIORITY_TASK
processed_source
mret
任务4:prvIdleTask
freertos_risc_v_trap_handler
保存任务1
test_if_asynchronous
handle_synchronous
test_if_environment_call
vTaskSwitchContext
taskSELECT_HIGHEST_PRIORITY_TASK
processed_source
mret
任务3:prvQueueSendTask
vSendString("1111");
vTaskDelay/portYIELD_WITHIN_API/ecall
...
ecall 后的 freertos_risc_v_trap_handler
1. ecall
此时硬件做动作
mcause 被设置成 0xb
mepc 被设置成 0x80001d28
2. freertos_risc_v_trap_handler
freertos_risc_v_trap_handler
addi sp, sp, -portCONTEXT_SIZE
store_x x1, 1 * portWORD_SIZE( sp )
store_x x5, 2 * portWORD_SIZE( sp )
...
store_x x31, 28 * portWORD_SIZE( sp )
csrr t0, mstatus
store_x t0, 29 * portWORD_SIZE( sp )
portasmSAVE_ADDITIONAL_REGISTERS
load_x t0, pxCurrentTCB
store_x sp, 0( t0 )
csrr a0, mcause
csrr a1, mepc
test_if_asynchronous:
srli a2, a0, __riscv_xlen - 1
beq a2, x0, handle_synchronous
handle_synchronous:
addi a1, a1, 4
store_x a1, 0( sp )
test_if_environment_call:
li t0, 11
bne a0, t0, is_exception
-------------------------------------------------------------------------------------------
load_x sp, xISRStackTop
-------------------------------------------------------------------------------------------
jal vTaskSwitchContext
taskSELECT_HIGHEST_PRIORITY_TASK/__clzSI2(UWtype x)
count_leading_zeros (ret, x);
j processed_source
load_x t1, pxCurrentTCB
load_x sp, 0( t1 )
load_x t0, 0( sp )
csrw mepc, t0
load_x t0, 29 * portWORD_SIZE( sp )
csrw mstatus, t0
load_x x1, 1 * portWORD_SIZE( sp )
load_x x5, 2 * portWORD_SIZE( sp )
...
load_x x31, 28 * portWORD_SIZE( sp )
addi sp, sp, portCONTEXT_SIZE
mret
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)