sky 发表于 2020-8-20 19:45:39

在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]
查看完整版本: 在VEGA RISC-V开发板上运行FreeRTOS