Лабораторная работа
Данная лабораторная работа подготовлена Кириленко Яковом Александровичем по заказу Альянса RISC-V, допускается к использованию под лицензией CC BY 4.0.
Приведённые ниже команды рассчитаны на выполнение в рабочей среде Syntacore Kit, распространяемой Альянсом RISC-V в образовательных целях. Обратите внимание, что в другом окружении приведённые примеры команд могут не работать или работать иначе.
Установка исходного кода FreeRTOS
В данной работе используется релиз FreeRTOSv202212.01. С целью воспроизводимости лабораторной рекомендуется скачать его следующим образом:
Скачивание
wget http://https://github.com/FreeRTOS/FreeRTOS/releases/download/202212.01/FreeRTOSv202212.01.zip
Распаковка
unzip FreeRTOSv202212.01.zip && mv FreeRTOSv202212.01 FreeRTOS
Сборка и запуск демонстрационной версии приложения
Перед выполнением команд проверьте, указан ли в переменной PATH путь /opt/syntacore/sc-dt/2023.08/riscv-gcc/bin (2023.08 - версия Syntacore Kit):
echo $PATH | grep riscv-gcc/bin
Если нет, добавьте в файл следующую строку (путь зависит от версии используемой рабочей среды):
export PATH=$PATH:/opt/syntacore/sc-dt/2023.08/riscv-gcc/bin
Перейдите в каталог с демонстрационным приложением RISC-V-Qemu-virt_GCC.
cd FreeRTOS/FreeRTOS/Demo/RISC-V-Qemu-virt_GCC/
Попробуйте собрать демо.
make
При попытке сборки будет получено следующее сообщение об ошибке:
main.c: Assembler messages: main.c:53: Error: unrecognized opcode `csrw mtvec,a5' main.c:84: Error: unrecognized opcode `csrc mstatus,8' main.c:111: Error: unrecognized opcode `csrc mstatus,8' main.c:125: Error: unrecognized opcode `csrc mstatus,8' make: *** [Makefile:62: build/main.o] Error 1
Обратите внимание, что в Makefile указаны флаги компилятора и компоновщика -march=rv32imac, задающие архитектуру набора команд rv32imac со стандартными расширениями. Однако перечисленные в листинге инструкции являются частью расширения Zicsr, вынесенного из базовой ISA версии выше 2.2. И для gcc версии 11.1.0 и выше необходимо отдельно указывать расширение Zicsr.
Итак, чтобы собрать демо, необходимо в Makefile в строках 17 и 24 заменить -march=rv32imac на -march=rv32ima_zicsr.
Makefile
CROSS = riscv64-unknown-elf- CC = $(CROSS)gcc OBJCOPY = $(CROSS)objcopy ARCH = $(CROSS)ar BUILD_DIR = build RTOS_SOURCE_DIR = $(abspath ../../Source) DEMO_SOURCE_DIR = $(abspath ../Common/Minimal) 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=rv32imac_zicsr -mabi=ilp32 -mcmodel=medany \ -Wall \ -fmessage-length=0 \ -ffunction-sections \ -fdata-sections \ -fno-builtin-printf LDFLAGS = -nostartfiles -Tfake_rom.lds \ -march=rv32imac_zicsr -mabi=ilp32 -mcmodel=medany \ -Xlinker --gc-sections \ -Xlinker --defsym=__stack_size=300 \ -Xlinker -Map=RTOSDemo.map 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 vector.S\ $(RTOS_SOURCE_DIR)/portable/GCC/RISC-V/portASM.S OBJS = $(SRCS:%.c=$(BUILD_DIR)/%.o) $(ASMS:%.S=$(BUILD_DIR)/%.o) DEPS = $(SRCS:%.c=$(BUILD_DIR)/%.d) $(ASMS:%.S=$(BUILD_DIR)/%.d) $(BUILD_DIR)/RTOSDemo.axf: $(OBJS) fake_rom.lds Makefile $(CC) $(LDFLAGS) $(OBJS) -o $@ $(BUILD_DIR)/%.o: %.c Makefile @mkdir -p $(@D) $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@ $(BUILD_DIR)/%.o: %.S Makefile @mkdir -p $(@D) $(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@ clean: rm -rf $(BUILD_DIR) -include $(DEPS)
Снова соберите демо.
make
Теперь можно запустить демонстрационную версию приложения, имитирующего мигание светодиода.
Запуск приложения в qemu
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
Вывод
Hello FreeRTOS! 0: Tx: Transfer1 0: Rx: Blink1 0: Tx: Transfer2 0: Rx: Blink2 0: Tx: Transfer1 0: Rx: Blink1 0: Tx: Transfer2 0: Rx: Blink2 0: Tx: Transfer1 0: Rx: Blink1 0: Tx: Transfer2 0: Rx: Blink2 0: Tx: Transfer1 0: Rx: Blink1 0: Tx: Transfer2 0: Rx: Blink2 0: Tx: Transfer1 0: Rx: Blink1 0: Tx: Transfer2 0: Rx: Blink2 0: Tx: Transfer1 0: Rx: Blink1 0: Tx: Transfer2 0: Rx: Blink2 0: Tx: Transfer1 0: Rx: Blink1 0: Tx: Transfer2 0: Rx: Blink2 0: Tx: Transfer1 0: Rx: Blink1 0: Tx: Transfer2 0: Rx: Blink2 0: Tx: Transfer1 0: Rx: Blink1 0: Tx: Transfer2 0: Rx: Blink2
Создание своего приложения
Создание задач
В этом же каталоге создадим файл example.c, создающий и запускающий две задачи vTask1 и vTask2 с одинаковым приоритетом.