查看: 859|回复: 0
收起左侧

在VEGA RISC-V开发板上运行FreeRTOS

[复制链接]

  离线 

  • TA的每日心情
    拍拍
    2022-6-27 11:09
  • 签到天数: 25 天

    [LV.4]

    发表于 2020-8-20 19:45:39 | 显示全部楼层 |阅读模式

    有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    本帖最后由 sky 于 2020-8-25 18:51 编辑

    在“使用Eclipse和MCUXpresso IDE调试RV32M1-VEGA RISC-V开发板”中,我们介绍了如何构建和调试基于VEGA RISC-V开发板的应用程序。在本文中,我们将介绍如何基于最新的FreeRTOS V10.2.0版本为RISC-V开发板启用FreeRTOS。

    国外芯片技术交流-在VEGA RISC-V开发板上运行FreeRTOSrisc-v单片机中文社区(1)

    在VEGA RISC-V板上运行FreeRTOS闪烁程序


    最新发布的FreeRTOS V10.2.0版本提供了对RISC-V ISA的基本支持。本文介绍如何将FreeRTOS添加到VEGA SDK应用程序中,然后使用NXP MCUXpresso IDE或任何其它Eclipse IDE,以及GNU MCU Eclipse插件运行该示例程序:


    国外芯片技术交流-在VEGA RISC-V开发板上运行FreeRTOSrisc-v单片机中文社区(2)

    VEGA 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端口

    国外芯片技术交流-在VEGA RISC-V开发板上运行FreeRTOSrisc-v单片机中文社区(3)


    McuLibrary


    3.    将以下包含添加到编译器包含的库中:

    1. ../McuLib/config
    2. ../McuLib/config/fonts
    3. ../McuLib/fonts
    4. ../McuLib/src
    5. ../McuLib/FreeRTOS/Source/include
    6. ../McuLib/FreeRTOS/Source/portable/GCC/RISC-V
    7. ../McuLib/SEGGER_RTT
    8. ../McuLib/SEGGER_Sysview
    9. ../McuLib/TraceRecorder/config
    10. ../McuLib/TraceRecorder/include
    11. ../McuLib/TraceRecorder/streamports/Jlink_RTT/include
    12. ../McuLib/HD44780
    复制代码

    国外芯片技术交流-在VEGA RISC-V开发板上运行FreeRTOSrisc-v单片机中文社区(4)



    4.    使用-include添加全局的包含

    1. "${ProjDirPath}/src/IncludeMcuLibConfig.h"
    复制代码

    国外芯片技术交流-在VEGA RISC-V开发板上运行FreeRTOSrisc-v单片机中文社区(5)


    -include设置


    5.  在与-include一起使用的头文件中,指定与RISC-V一起使用的FreeRTOS,以及使用的SDK:

    1. #define McuLib_CONFIG_SDK_VERSION_USED McuLib_CONFIG_SDK_MCUXPRESSO_2_0

    2. #define McuLib_CONFIG_CPU_IS_ARM_CORTEX_M (0)
    3. #define McuLib_CONFIG_CPU_IS_RISC_V (1)

    4. #define McuLib_CONFIG_SDK_USE_FREERTOS (1)

    5. #define McuLib_CONFIG_SDK_VERSION_MAJOR (2)
    6. #define McuLib_CONFIG_SDK_VERSION_MINOR (2)
    7. #define McuLib_CONFIG_SDK_VERSION_BUILD (0)
    复制代码

    6.    在同一文件中,配置VEGA开发板上LED的引脚:

    1. /* red LED */
    2. #define McuLED1_CONFIG_IS_LOW_ACTIVE   (0)
    3. #define LEDpin1_CONFIG_GPIO_NAME       GPIOA
    4. #define LEDpin1_CONFIG_PORT_NAME       PORTA
    5. #define LEDpin1_CONFIG_PIN_NUMBER      24u
    6. #define LEDpin1_CONFIG_DO_PIN_MUXING   1

    7. /* green LED */
    8. #define McuLED2_CONFIG_IS_LOW_ACTIVE   (0)
    9. #define LEDpin2_CONFIG_GPIO_NAME       GPIOA
    10. #define LEDpin2_CONFIG_PORT_NAME       PORTA
    11. #define LEDpin2_CONFIG_PIN_NUMBER      23u
    12. #define LEDpin2_CONFIG_DO_PIN_MUXING   1

    13. /* blue LED */
    14. #define McuLED3_CONFIG_IS_LOW_ACTIVE   (0)
    15. #define LEDpin3_CONFIG_GPIO_NAME       GPIOA
    16. #define LEDpin3_CONFIG_PORT_NAME       PORTA
    17. #define LEDpin3_CONFIG_PIN_NUMBER      22u
    18. #define LEDpin3_CONFIG_DO_PIN_MUXING   1

    19. /* sts LED */
    20. #define McuLED4_CONFIG_IS_LOW_ACTIVE   (0)
    21. #define LEDpin4_CONFIG_GPIO_NAME       GPIOE
    22. #define LEDpin4_CONFIG_PORT_NAME       PORTE
    23. #define LEDpin4_CONFIG_PIN_NUMBER      0u
    24. #define LEDpin4_CONFIG_DO_PIN_MUXING   1
    复制代码

    7.    将标准启动代码替换为FreeRTOS特定的版本的启动代码。 此版本使用freertos_risc_v_trap_handler作为默认陷阱处理程序。 此版本取自V10.2.0的FreeRTOS发行版:

    1. /* ------------------------------------------------------------------------- */
    2. /*  @file:    startup_RV32M1_ri5cy.s                                         */
    3. /*  @purpose: RI5CY Core Device Startup File                                 */
    4. /*            RV32M1_ri5cy                                                   */
    5. /*  @version: 1.0                                                            */
    6. /*  @date:    2018-10-2                                                      */
    7. /*  @build:   b180926                                                        */
    8. /* ------------------------------------------------------------------------- */
    9. /*                                                                           */
    10. /* Copyright 1997-2016 Freescale Semiconductor, Inc.                         */
    11. /* Copyright 2016-2018 NXP                                                   */
    12. /* All rights reserved.                                                      */
    13. /*                                                                           */
    14. /* SPDX-License-Identifier: BSD-3-Clause                                     */


    15. // Copyright 2017 ETH Zurich and University of Bologna.
    16. // Copyright and related rights are licensed under the Solderpad Hardware
    17. // License, Version 0.51 (the "License"); you may not use this file except in
    18. // compliance with the License.  You may obtain a copy of the License at
    19. // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
    20. // or agreed to in writing, software, hardware and materials distributed under
    21. // this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    22. // CONDITIONS OF ANY KIND, either express or implied. See the License for the
    23. // specific language governing permissions and limitations under the License.

    24. .extern freertos_risc_v_trap_handler

    25. #define EXCEPTION_STACK_SIZE 0x58

    26.     .text
    27.     .section .vectors, "ax"
    28.     .option norvc;

    29.     jal x0, freertos_risc_v_trap_handler
    30.     jal x0, freertos_risc_v_trap_handler
    31.     jal x0, freertos_risc_v_trap_handler
    32.     jal x0, freertos_risc_v_trap_handler
    33.     jal x0, freertos_risc_v_trap_handler
    34.     jal x0, freertos_risc_v_trap_handler
    35.     jal x0, freertos_risc_v_trap_handler
    36.     jal x0, freertos_risc_v_trap_handler
    37.     jal x0, freertos_risc_v_trap_handler
    38.     jal x0, freertos_risc_v_trap_handler
    39.     jal x0, freertos_risc_v_trap_handler
    40.     jal x0, freertos_risc_v_trap_handler
    41.     jal x0, freertos_risc_v_trap_handler
    42.     jal x0, freertos_risc_v_trap_handler
    43.     jal x0, freertos_risc_v_trap_handler
    44.     jal x0, freertos_risc_v_trap_handler
    45.     jal x0, freertos_risc_v_trap_handler
    46.     jal x0, freertos_risc_v_trap_handler
    47.     jal x0, freertos_risc_v_trap_handler
    48.     jal x0, freertos_risc_v_trap_handler
    49.     jal x0, freertos_risc_v_trap_handler
    50.     jal x0, freertos_risc_v_trap_handler
    51.     jal x0, freertos_risc_v_trap_handler
    52.     jal x0, freertos_risc_v_trap_handler
    53.     jal x0, freertos_risc_v_trap_handler
    54.     jal x0, freertos_risc_v_trap_handler
    55.     jal x0, freertos_risc_v_trap_handler
    56.     jal x0, freertos_risc_v_trap_handler
    57.     jal x0, freertos_risc_v_trap_handler
    58.     jal x0, freertos_risc_v_trap_handler
    59.     jal x0, freertos_risc_v_trap_handler
    60.     jal x0, freertos_risc_v_trap_handler

    61.     // reset vector
    62.     jal x0, Reset_Handler

    63.     // Illegal instrution exception
    64.     jal x0, IllegalInstruction_Handler

    65.     // ecall handler
    66.     jal x0, freertos_risc_v_trap_handler

    67.     // LSU error
    68.     jal x0, LSU_Handler

    69.     .section .startup

    70. /* Reset Handler */
    71. Reset_Handler:

    72.     # Disable global interrupt. */
    73.     csrci mstatus, 8

    74.     # initialize stack pointer
    75.     la sp, __StackTop

    76.     # initialize global pointer
    77.     la gp, __global_pointer

    78. #ifndef __NO_SYSTEM_INIT
    79.     jal SystemInit
    80. #endif

    81.     call __libc_init_array

    82.     # Enable global interrupt. */
    83.     csrsi mstatus, 8

    84.     jal main
    85.     ebreak

    86.     .size Reset_Handler, . - Reset_Handler

    87.     .global _init
    88.     .global _fini
    89. _init:
    90. _fini:
    91.     ret

    92.   // saves all caller-saved registers (except return address)
    93. store_regs:
    94.     sw  x3, 0x00(x2)  // gp
    95.     sw  x4, 0x04(x2)  // tp
    96.     sw  x5, 0x08(x2)  // t0
    97.     sw  x6, 0x0c(x2)  // t1
    98.     sw  x7, 0x10(x2)  // t2
    99.     sw x10, 0x14(x2)  // a0
    100.     sw x11, 0x18(x2)  // a1
    101.     sw x12, 0x1c(x2)  // a2
    102.     sw x13, 0x20(x2)  // a3
    103.     sw x14, 0x24(x2)  // a4
    104.     sw x15, 0x28(x2)  // a5
    105.     sw x16, 0x2c(x2)  // a6
    106.     sw x17, 0x30(x2)  // a7

    107.     csrr a0, 0x7B0
    108.     csrr a1, 0x7B1
    109.     csrr a2, 0x7B2
    110.     sw a0, 0x34(x2)  // lpstart[0]
    111.     sw a1, 0x38(x2)  // lpend[0]
    112.     sw a2, 0x3c(x2)  // lpcount[0]
    113.     csrr a0, 0x7B4
    114.     csrr a1, 0x7B5
    115.     csrr a2, 0x7B6
    116.     sw a0, 0x40(x2)  // lpstart[1]
    117.     sw a1, 0x44(x2)  // lpend[1]
    118.     sw a2, 0x48(x2)  // lpcount[1]

    119.     csrr a0, 0x341
    120.     sw a0, 0x4c(x2)  // mepc
    121.     csrr a1, 0x300
    122.     sw a1, 0x50(x2)  // mstatus
    123.     jalr x0, x1

    124.     // load back registers from stack
    125. end_except:
    126.     lw a1, 0x50(x2)  // mstatus
    127.     csrrw x0, 0x300, a1
    128.     lw a0, 0x4c(x2)  // mepc
    129.     csrrw x0, 0x341, a0

    130.     lw a0, 0x40(x2)  // lpstart[1]
    131.     lw a1, 0x44(x2)  // lpend[1]
    132.     lw a2, 0x48(x2)  // lpcount[1]
    133.     csrrw x0, 0x7B4, a0
    134.     csrrw x0, 0x7B5, a1
    135.     csrrw x0, 0x7B6, a2
    136.     lw a0, 0x34(x2)  // lpstart[0]
    137.     lw a1, 0x38(x2)  // lpend[0]
    138.     lw a2, 0x3c(x2)  // lpcount[0]
    139.     csrrw x0, 0x7B0, a0
    140.     csrrw x0, 0x7B1, a1
    141.     csrrw x0, 0x7B2, a2

    142.     lw  x3, 0x00(x2)  // gp
    143.     lw  x4, 0x04(x2)  // tp
    144.     lw  x5, 0x08(x2)  // t0
    145.     lw  x6, 0x0c(x2)  // t1
    146.     lw  x7, 0x10(x2)  // t2
    147.     lw x10, 0x14(x2)  // a0
    148.     lw x11, 0x18(x2)  // a1
    149.     lw x12, 0x1c(x2)  // a2
    150.     lw x13, 0x20(x2)  // a3
    151.     lw x14, 0x24(x2)  // a4
    152.     lw x15, 0x28(x2)  // a5
    153.     lw x16, 0x2c(x2)  // a6
    154.     lw x17, 0x30(x2)  // a7

    155.     lw  x1, 0x54(x2)
    156.     addi x2, x2, EXCEPTION_STACK_SIZE
    157.     mret

    158.     .weak IRQ_Handler
    159.     .type IRQ_Handler, %function
    160. IRQ_Handler:
    161.     addi x2, x2, -EXCEPTION_STACK_SIZE
    162.     sw x1, 0x54(x2)
    163.     jal x1, store_regs
    164.     la x1, end_except
    165.     csrr a0, mcause
    166.     jal x0, SystemIrqHandler
    167.     .size IRQ_Handler, . - IRQ_Handler

    168.     .macro define_exception_entry entry_name handler_name
    169.     .weak \entry_name
    170. \entry_name:
    171.     addi x2, x2, -EXCEPTION_STACK_SIZE
    172.     sw x1, 0x54(x2)
    173.     jal x1, store_regs
    174.     la x1, end_except
    175.     jal x0, \handler_name
    176.     .endm

    177. define_exception_entry IllegalInstruction_Handler IllegalInstruction_HandlerFunc
    178. define_exception_entry Ecall_Handler Ecall_HandlerFunc
    179. define_exception_entry LSU_Handler LSU_HandlerFunc

    180.     .weak IllegalInstruction_HandlerFunc
    181.     .type IllegalInstruction_HandlerFunc, %function
    182. IllegalInstruction_HandlerFunc:
    183.     j .
    184.     .size IllegalInstruction_HandlerFunc, . - IllegalInstruction_HandlerFunc

    185.     .weak Ecall_HandlerFunc
    186.     .type Ecall_HandlerFunc, %function
    187. Ecall_HandlerFunc:
    188.     j .
    189.     .size Ecall_HandlerFunc, . - Ecall_HandlerFunc

    190.     .weak LSU_HandlerFunc
    191.     .type LSU_HandlerFunc, %function
    192. LSU_HandlerFunc:
    193.     j .
    194.     .size LSU_HandlerFunc, . - LSU_HandlerFunc
    复制代码

    8.    在链接器文件中,添加一个符号以标记IRQ堆栈的结尾:

    1. __freertos_irq_stack_top = .;
    复制代码

    国外芯片技术交流-在VEGA RISC-V开发板上运行FreeRTOSrisc-v单片机中文社区(6)


    __freertos_irq_stack_top


    9.  通过以上设置,我就可以在VEGA开发板上使用FreeRTOS和RISC-V。


    演示应用程序

    我已经在GitHub上添加了一个简单的“blinky”应用程序,代码如下:

    1. /*
    2. * Application.c
    3. *
    4.   *      Author: Erich Styger
    5. */
    6. #include "Application.h"
    7. #include "McuLib.h"
    8. #include "McuWait.h"
    9. #include "McuLED1.h"
    10. #include "McuLED2.h"
    11. #include "McuLED3.h"
    12. #include "McuLED4.h"
    13. #include "McuRTOS.h"
    14. #include "FreeRTOS.h"
    15. #include "task.h"

    16. static void AppTask(void *pv) {
    17.   for(;;) {
    18.     McuLED1_On();
    19.     vTaskDelay(pdMS_TO_TICKS(100));
    20.     McuLED1_Off();
    21.     McuLED2_On();
    22.     vTaskDelay(pdMS_TO_TICKS(100));
    23.     McuLED2_Off();
    24.     McuLED3_On();
    25.     vTaskDelay(pdMS_TO_TICKS(100));
    26.     McuLED3_Off();
    27.     McuLED4_On();
    28.     vTaskDelay(pdMS_TO_TICKS(100));
    29.     McuLED4_Off();
    30.     vTaskDelay(pdMS_TO_TICKS(500));
    31.     McuLED4_Neg();
    32.   }
    33. }

    34. void APP_Run(void) {
    35.   /* initialize McuLib drivers */
    36.   McuLib_Init();
    37.   McuRTOS_Init();
    38.   McuWait_Init();
    39.   McuLED1_Init(); /* red */
    40.   McuLED2_Init(); /* green */
    41.   McuLED3_Init(); /* blue */
    42.   McuLED4_Init(); /* red status */

    43.   if (xTaskCreate(AppTask, "App", 500/sizeof(StackType_t), NULL, tskIDLE_PRIORITY+1, NULL) != pdPASS) {
    44.     for(;;){} /* error */
    45.   }
    46.   vTaskStartScheduler();
    47.   /* shoul not end up here... */
    48.   for(;;) { }
    49. }
    复制代码

    以下是使用NXP MCUXpresso IDE 10.3.1在VEGA开发板上调试应用程序的屏幕截图:

    国外芯片技术交流-在VEGA RISC-V开发板上运行FreeRTOSrisc-v单片机中文社区(7)


    使用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:

    1. #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单片机中文网





    上一篇:RISC-V架构简介
    下一篇:蜂鸟FPGA开发板和JTAG调试器介绍
    RISCV作者优文
    全球首家只专注于RISC-V单片机行业应用的中文网站
    回复

    使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

    RISC-V单片机中文网上一条 /2 下一条



    版权及免责声明|RISC-V单片机中文网 |网站地图

    GMT+8, 2024-4-26 14:38 , Processed in 0.890827 second(s), 44 queries .

    快速回复 返回顶部 返回列表