在VEGA RISC-V开发板上运行FreeRTOS
本帖最后由 sky 于 2020-8-25 18:51 编辑在“使用Eclipse和MCUXpresso IDE调试RV32M1-VEGA RISC-V开发板”中,我们介绍了如何构建和调试基于VEGA RISC-V开发板的应用程序。在本文中,我们将介绍如何基于最新的FreeRTOS V10.2.0版本为RISC-V开发板启用FreeRTOS。https://www.yiboard.com/data/attachment/forum/201904/23/111909o6w6vxeu4cdldv6a.png在VEGA RISC-V板上运行FreeRTOS闪烁程序
最新发布的FreeRTOS V10.2.0版本提供了对RISC-V ISA的基本支持。本文介绍如何将FreeRTOS添加到VEGA SDK应用程序中,然后使用NXP MCUXpresso IDE或任何其它Eclipse IDE,以及GNU MCU Eclipse插件运行该示例程序:
https://www.yiboard.com/data/attachment/forum/201904/23/111909yz99xjfsjxjtzs6i.pngVEGA RISC-V开发板上的FreeRTOS
以下是我们所需的组件:1. MCUXpresso IDE以及VEGA RISC-V开发板2.GitHub的McuLib和FreeRTOS在现有VEGA项目启用FreeRTOS,请执行以下步骤:1. 在MCUXpresso IDE中新建一个基于VEGA RISC-V(RI5CY)的项目,或使用VEGA SDK for RISC-V中的现有项目2. 添加McuLib和FreeRTOS端口https://www.yiboard.com/data/attachment/forum/201904/23/111910qp87vb5fic77574s.png
McuLibrary
3. 将以下包含添加到编译器包含的库中:../McuLib/config
../McuLib/config/fonts
../McuLib/fonts
../McuLib/src
../McuLib/FreeRTOS/Source/include
../McuLib/FreeRTOS/Source/portable/GCC/RISC-V
../McuLib/SEGGER_RTT
../McuLib/SEGGER_Sysview
../McuLib/TraceRecorder/config
../McuLib/TraceRecorder/include
../McuLib/TraceRecorder/streamports/Jlink_RTT/include
../McuLib/HD44780https://www.yiboard.com/data/attachment/forum/201904/23/111910eovkzvvj0z7dhh70.png
4. 使用-include添加全局的包含"${ProjDirPath}/src/IncludeMcuLibConfig.h"https://www.yiboard.com/data/attachment/forum/201904/23/111909keojj0ojedw22fk1.png
-include设置
5.在与-include一起使用的头文件中,指定与RISC-V一起使用的FreeRTOS,以及使用的SDK:#define McuLib_CONFIG_SDK_VERSION_USED McuLib_CONFIG_SDK_MCUXPRESSO_2_0
#define McuLib_CONFIG_CPU_IS_ARM_CORTEX_M (0)
#define McuLib_CONFIG_CPU_IS_RISC_V (1)
#define McuLib_CONFIG_SDK_USE_FREERTOS (1)
#define McuLib_CONFIG_SDK_VERSION_MAJOR (2)
#define McuLib_CONFIG_SDK_VERSION_MINOR (2)
#define McuLib_CONFIG_SDK_VERSION_BUILD (0)6. 在同一文件中,配置VEGA开发板上LED的引脚:/* red LED */
#define McuLED1_CONFIG_IS_LOW_ACTIVE (0)
#define LEDpin1_CONFIG_GPIO_NAME GPIOA
#define LEDpin1_CONFIG_PORT_NAME PORTA
#define LEDpin1_CONFIG_PIN_NUMBER 24u
#define LEDpin1_CONFIG_DO_PIN_MUXING 1
/* green LED */
#define McuLED2_CONFIG_IS_LOW_ACTIVE (0)
#define LEDpin2_CONFIG_GPIO_NAME GPIOA
#define LEDpin2_CONFIG_PORT_NAME PORTA
#define LEDpin2_CONFIG_PIN_NUMBER 23u
#define LEDpin2_CONFIG_DO_PIN_MUXING 1
/* blue LED */
#define McuLED3_CONFIG_IS_LOW_ACTIVE (0)
#define LEDpin3_CONFIG_GPIO_NAME GPIOA
#define LEDpin3_CONFIG_PORT_NAME PORTA
#define LEDpin3_CONFIG_PIN_NUMBER 22u
#define LEDpin3_CONFIG_DO_PIN_MUXING 1
/* sts LED */
#define McuLED4_CONFIG_IS_LOW_ACTIVE (0)
#define LEDpin4_CONFIG_GPIO_NAME GPIOE
#define LEDpin4_CONFIG_PORT_NAME PORTE
#define LEDpin4_CONFIG_PIN_NUMBER 0u
#define LEDpin4_CONFIG_DO_PIN_MUXING 17. 将标准启动代码替换为FreeRTOS特定的版本的启动代码。 此版本使用freertos_risc_v_trap_handler作为默认陷阱处理程序。 此版本取自V10.2.0的FreeRTOS发行版:/* ------------------------------------------------------------------------- */
/*@file: startup_RV32M1_ri5cy.s */
/*@purpose: RI5CY Core Device Startup File */
/* RV32M1_ri5cy */
/*@version: 1.0 */
/*@date: 2018-10-2 */
/*@build: b180926 */
/* ------------------------------------------------------------------------- */
/* */
/* Copyright 1997-2016 Freescale Semiconductor, Inc. */
/* Copyright 2016-2018 NXP */
/* All rights reserved. */
/* */
/* SPDX-License-Identifier: BSD-3-Clause */
// Copyright 2017 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License.You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
.extern freertos_risc_v_trap_handler
#define EXCEPTION_STACK_SIZE 0x58
.text
.section .vectors, "ax"
.option norvc;
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
jal x0, freertos_risc_v_trap_handler
// reset vector
jal x0, Reset_Handler
// Illegal instrution exception
jal x0, IllegalInstruction_Handler
// ecall handler
jal x0, freertos_risc_v_trap_handler
// LSU error
jal x0, LSU_Handler
.section .startup
/* Reset Handler */
Reset_Handler:
# Disable global interrupt. */
csrci mstatus, 8
# initialize stack pointer
la sp, __StackTop
# initialize global pointer
la gp, __global_pointer
#ifndef __NO_SYSTEM_INIT
jal SystemInit
#endif
call __libc_init_array
# Enable global interrupt. */
csrsi mstatus, 8
jal main
ebreak
.size Reset_Handler, . - Reset_Handler
.global _init
.global _fini
_init:
_fini:
ret
// saves all caller-saved registers (except return address)
store_regs:
swx3, 0x00(x2)// gp
swx4, 0x04(x2)// tp
swx5, 0x08(x2)// t0
swx6, 0x0c(x2)// t1
swx7, 0x10(x2)// t2
sw x10, 0x14(x2)// a0
sw x11, 0x18(x2)// a1
sw x12, 0x1c(x2)// a2
sw x13, 0x20(x2)// a3
sw x14, 0x24(x2)// a4
sw x15, 0x28(x2)// a5
sw x16, 0x2c(x2)// a6
sw x17, 0x30(x2)// a7
csrr a0, 0x7B0
csrr a1, 0x7B1
csrr a2, 0x7B2
sw a0, 0x34(x2)// lpstart
sw a1, 0x38(x2)// lpend
sw a2, 0x3c(x2)// lpcount
csrr a0, 0x7B4
csrr a1, 0x7B5
csrr a2, 0x7B6
sw a0, 0x40(x2)// lpstart
sw a1, 0x44(x2)// lpend
sw a2, 0x48(x2)// lpcount
csrr a0, 0x341
sw a0, 0x4c(x2)// mepc
csrr a1, 0x300
sw a1, 0x50(x2)// mstatus
jalr x0, x1
// load back registers from stack
end_except:
lw a1, 0x50(x2)// mstatus
csrrw x0, 0x300, a1
lw a0, 0x4c(x2)// mepc
csrrw x0, 0x341, a0
lw a0, 0x40(x2)// lpstart
lw a1, 0x44(x2)// lpend
lw a2, 0x48(x2)// lpcount
csrrw x0, 0x7B4, a0
csrrw x0, 0x7B5, a1
csrrw x0, 0x7B6, a2
lw a0, 0x34(x2)// lpstart
lw a1, 0x38(x2)// lpend
lw a2, 0x3c(x2)// lpcount
csrrw x0, 0x7B0, a0
csrrw x0, 0x7B1, a1
csrrw x0, 0x7B2, a2
lwx3, 0x00(x2)// gp
lwx4, 0x04(x2)// tp
lwx5, 0x08(x2)// t0
lwx6, 0x0c(x2)// t1
lwx7, 0x10(x2)// t2
lw x10, 0x14(x2)// a0
lw x11, 0x18(x2)// a1
lw x12, 0x1c(x2)// a2
lw x13, 0x20(x2)// a3
lw x14, 0x24(x2)// a4
lw x15, 0x28(x2)// a5
lw x16, 0x2c(x2)// a6
lw x17, 0x30(x2)// a7
lwx1, 0x54(x2)
addi x2, x2, EXCEPTION_STACK_SIZE
mret
.weak IRQ_Handler
.type IRQ_Handler, %function
IRQ_Handler:
addi x2, x2, -EXCEPTION_STACK_SIZE
sw x1, 0x54(x2)
jal x1, store_regs
la x1, end_except
csrr a0, mcause
jal x0, SystemIrqHandler
.size IRQ_Handler, . - IRQ_Handler
.macro define_exception_entry entry_name handler_name
.weak \entry_name
\entry_name:
addi x2, x2, -EXCEPTION_STACK_SIZE
sw x1, 0x54(x2)
jal x1, store_regs
la x1, end_except
jal x0, \handler_name
.endm
define_exception_entry IllegalInstruction_Handler IllegalInstruction_HandlerFunc
define_exception_entry Ecall_Handler Ecall_HandlerFunc
define_exception_entry LSU_Handler LSU_HandlerFunc
.weak IllegalInstruction_HandlerFunc
.type IllegalInstruction_HandlerFunc, %function
IllegalInstruction_HandlerFunc:
j .
.size IllegalInstruction_HandlerFunc, . - IllegalInstruction_HandlerFunc
.weak Ecall_HandlerFunc
.type Ecall_HandlerFunc, %function
Ecall_HandlerFunc:
j .
.size Ecall_HandlerFunc, . - Ecall_HandlerFunc
.weak LSU_HandlerFunc
.type LSU_HandlerFunc, %function
LSU_HandlerFunc:
j .
.size LSU_HandlerFunc, . - LSU_HandlerFunc8. 在链接器文件中,添加一个符号以标记IRQ堆栈的结尾:__freertos_irq_stack_top = .;https://www.yiboard.com/data/attachment/forum/201904/23/111909ye9ehibxnsiihns7.png
__freertos_irq_stack_top
9.通过以上设置,我就可以在VEGA开发板上使用FreeRTOS和RISC-V。
演示应用程序我已经在GitHub上添加了一个简单的“blinky”应用程序,代码如下:/*
* Application.c
*
* Author: Erich Styger
*/
#include "Application.h"
#include "McuLib.h"
#include "McuWait.h"
#include "McuLED1.h"
#include "McuLED2.h"
#include "McuLED3.h"
#include "McuLED4.h"
#include "McuRTOS.h"
#include "FreeRTOS.h"
#include "task.h"
static void AppTask(void *pv) {
for(;;) {
McuLED1_On();
vTaskDelay(pdMS_TO_TICKS(100));
McuLED1_Off();
McuLED2_On();
vTaskDelay(pdMS_TO_TICKS(100));
McuLED2_Off();
McuLED3_On();
vTaskDelay(pdMS_TO_TICKS(100));
McuLED3_Off();
McuLED4_On();
vTaskDelay(pdMS_TO_TICKS(100));
McuLED4_Off();
vTaskDelay(pdMS_TO_TICKS(500));
McuLED4_Neg();
}
}
void APP_Run(void) {
/* initialize McuLib drivers */
McuLib_Init();
McuRTOS_Init();
McuWait_Init();
McuLED1_Init(); /* red */
McuLED2_Init(); /* green */
McuLED3_Init(); /* blue */
McuLED4_Init(); /* red status */
if (xTaskCreate(AppTask, "App", 500/sizeof(StackType_t), NULL, tskIDLE_PRIORITY+1, NULL) != pdPASS) {
for(;;){} /* error */
}
vTaskStartScheduler();
/* shoul not end up here... */
for(;;) { }
}以下是使用NXP MCUXpresso IDE 10.3.1在VEGA开发板上调试应用程序的屏幕截图:https://www.yiboard.com/data/attachment/forum/201904/23/111909i5q3fvpfdf9vqfii.png
使用MCUXpresso IDE调试RISC-V FreeRTOS应用程序
限制该移植过程仍在“正在进行中”:● 到目前为止,我只在RV32M1 RI5CY上运行它。● 它使用LPIT0计时器作为滴答计时器。● Tickless Idle模式尚未实现。● 尚不支持中断嵌套。● SEGGER SystemViewer尚未经过测试● Percepio Tracealizer尚未测试
故障排除● 目前我必须使用OpenOCD来调试VEGA板,而OpenOCD并不是很慢(与J-Link相比)。如果调试失败,请尝试重新启动电路板和调试器。● OpenOCD取代了Windows USB驱动程序,这显然影响了以正常方式使用J-Link。尝试将USB驱动程序恢复为原始驱动程序并重新启动主机。● 使用OpenOCD调试任务代码通常会进入中断服务程序:解决方法是设置断点,然后运行。● FreeRTOS V10.2.0改变了内部的数据结构,可能破坏RTOS调试过程。例如,FreeRTOS定时器可能无法在调试器中正确显示。作为一种解决方法,我已经为FreeRTOS timers.c添加了一个定义来支持以前的API:#define TIMER_LEGACY_API (1)/* << EST: needed to have TAD working */总结我现在可以使用Eclipse(MCUXpresso IDE)在VEGA开发板上运行FreeRTOS V10.2.0。 IDE具有非常有用的FreeRTOS调试视图。最大的问题是OpenOCD调试器。它有效,但在使用RTOS时速度很慢且有很多限制。我可能需要探索除OpenOCD之外的其他调试器,以获得更好的调试体验。参考链接◾ FreeRTOS on RISC-V: https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html◾ FreeRTOS demo for PULP/VEGA: https://www.freertos.org/RTOS-RISC-V-Vegaboard_Pulp.html本篇完,感谢关注:RISC-V单片机中文网
页:
[1]