Опубликован: 24.11.2024 | Доступ: свободный | Студентов: 1 / 0 | Длительность: 03:11:00
Лекция 7:

Портирование приложений FreeRTOS на процессоры RISC-V

< Лекция 6 || Лекция 7: 12 || Лекция 8 >

Проверка портированной версии FreeRTOS на RISC-V

Пример портированной структуры FreeRTOS

Ниже приведена структура файлов FreeRTOS, портированных на RISC-V (извлеченная из примера Makefile).

CPPFLAGS = \
     -D__riscv_float_abi_soft \
     -DportasmHANDLE_INTERRUPT=handle_trap \
     -I . -I ../Common/include \
     -I $(RTOS_SOURCE_DIR)/include \
     -I $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V \
     -I $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions
CFLAGS = -march=rv32ima -mabi=ilp32 -mcmodel=medany \
     -Wall \
     -fmessage-length=0 \
     -ffunction-sections \
     -fdata-sections \
     -fno-builtin-printf
ASFLAGS = -march=rv32ima -mabi=ilp32 -mcmodel=medany
LDFLAGS = -nostartfiles -Tfake_rom.lds \
     -Xlinker --gc-sections \
     -Xlinker --defsym=__stack_size=300

ifeq ($(DEBUG), 1)
    CFLAGS += -Og -ggdb3
else
    CFLAGS += -O2
endif

SRCS = main.c main_blinky.c riscv-virt.c ns16550.c \
     $(DEMO_SOURCE_DIR)/EventGroupsDemo.c \
     $(DEMO_SOURCE_DIR)/TaskNotify.c \
     $(DEMO_SOURCE_DIR)/TimerDemo.c \
     $(DEMO_SOURCE_DIR)/blocktim.c \
     $(DEMO_SOURCE_DIR)/dynamic.c \
     $(DEMO_SOURCE_DIR)/recmutex.c \
     $(RTOS_SOURCE_DIR)/event_groups.c \
     $(RTOS_SOURCE_DIR)/list.c \
     $(RTOS_SOURCE_DIR)/queue.c \
     $(RTOS_SOURCE_DIR)/stream_buffer.c \
     $(RTOS_SOURCE_DIR)/tasks.c \
     $(RTOS_SOURCE_DIR)/timers.c \
     $(RTOS_SOURCE_DIR)/portable/MemMang/heap_4.c \
     $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V/port.c

ASMS = start.S \
     $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V/portASM.S
Использование FreeRTOS на RISC-V

После завершения переноса на процессор пользователь может свободно создавать приложения, использующие FreeRTOS для управления потоком управления в программе. Ниже приведен простой пример приложения, которое поставляется с установкой FreeRTOS для проверки правильности переноса.

Это тестовое приложение называется программой blinky; оно имитирует мигание светодиода в целевой системе. Она включает две задачи FreeRTOS и планировщик, работающий между ними. Есть также очередь, которая используется для передачи управления между задачами. Поскольку у нас нет платы, в коде используются операторы отображения, чтобы продемонстрировать результат переключения потока выполнения между двумя задачами.

Следующий фрагмент кода показывает пример приложения и вывод, когда программа выполняется на процессоре:

int main_blinky( void )
{
     vSendString( "Hello FreeRTOS!" );
     /* Create the queue. */
     xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );
     if( xQueue != NULL )
     {
          /* Create and start the two tasks */
          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 );
     }
     /* Start the scheduler. */
     vTaskStartScheduler();
     return 0;
}

Вывод программы:


Пример сборки и запуска

Далее мы рассмотрим, как собрать и запустить результат портирования на RISC-V в QEMU.

Первым шагом будет выбор примера RISCV64 для RISC-V QEMU. Для этого возьмём пример из директории /FreeRTOS/Demo/RISC-V-Qemu-virt_GCC.

Для запуска понадобятся:

  • тулчейн GNU RISC-V (можно скачать тулчейн RISC_V от SiFive по ссылке);
  • qemu-riscv32-system;
  • ОС Linux.

Настройка тулчейна

export PATH=<путь до тулчейна>/bin:$PATH

Сборка примера

make

Примечание переводчика

При сборке может возникнуть ошибка unrecognized opcode. Это происходит из-за того, что в Makefile указаны флаги компилятора и компоновщика -march=rv32imac, задающие архитектуру набора команд rv32imac со стандартными расширениями. Однако используемые в демо инструкции csrc и csrw являются частью расширения Zicsr, вынесенного из базовой ISA версии выше 2.2. И для gcc версии 11.1.0 и выше необходимо отдельно указывать расширение Zicsr. То есть необходимо в Makefile заменить все вхождения -march=rv32imac на -march=rv32ima_zicsr.

Также возможна ошибка компиляции из-за неопределенной константы configCLINT_BASE_ADDRESS. В таком случае необходимо определить её в файле FreeRTOSConfig.h, добавив после директив #include строку #define configCLINT_BASE_ADDRESS CLINT_ADDR.

Запуск примера

qemu-system-riscv32 -nographic -machine virt -net none \
  -chardev stdio,id=con,mux=on -serial chardev:con \
  -mon chardev=con,mode=readline -bios none \
  -smp 4 -kernel ./build/RTOSDemo.axf

Более подробное описание сборки и запуска примера можно найти в файле /FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/Readme.md.

Контрольные вопросы

  1. Какие шаги нужно выполнить для портирования FreeRTOS на процессоры RISC-V?
  2. Какой заголовочный файл необходим для порта RISC-V, требующего расширения архитектуры?
  3. В каком случае в конфигурационном файле значения параметров configMTIME_BASE_ADDRESS и configMTIMECMP_BASE_ADDRESS должны быть установлены в 0?
  4. Как указать ядру FreeRTOS, какой обработчик внешних прерываний ему нужно вызвать?
< Лекция 6 || Лекция 7: 12 || Лекция 8 >