В этой статье приведено описание готового сконфигурированного проекта SiFive Freedom Studio, в котором осуществляется сборка и запуск FreeRTOS RISC-V demo в модели sifive_e QEMU, с использованием GCC и GDB (перевод [1]).
[Инструкции по использованию FreeRTOS на ядрах RISC-V]
Если вы захотите выйти за рамки простого запуска демо, описанного на этой страничке, или если вы хотите создать свой собственный проект RISC-V FreeRTOS, то обратитесь к документации [2], где дается общая информация по запуску FreeRTOS kernel на ядрах процессоров RISC-V.
[Организация исходного кода]
Загружаемый ZIP-файл поставляемого пакета FreeRTOS [3] содержит исходный код для всех портов FreeRTOS и все демонстрационные приложения. Т. е. там очень много других файлов, которые могут не понадобиться для использования в FreeRTOS sifive_e QEMU RISC-V demo. См. врезку "Организация исходного кода FreeRTOS" статьи [2] для получения информации по структуре каталогов zip-файла FreeRTOS. Проект sifive_e RISC-V QEMU Freedom Studio находится в директории /Demo/RISC-V-Qemu-sifive_e-FreedomStudio. Дополнительную информацию по сборке см. далее в этой статье.
На архитектурах RISC-V используется дополнительный заголовочный файл freertos_risc_v_chip_specific_extensions.h, расширяющий базовый порт RISC-V. В нем описаны любые специфические особенности используемого целевого чипа RISC-V. Модель QEMU sive5_e не реализует какие-либо регистры сверх тех, которые определены в базовой архитектуре RISC-V, и не эмулирует CLINT. Таким образом, этот проект использует заголовочный файл freertos_risc_v_chip_specific_extensions.h из директории /FreeRTOS/Source/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions.
[Демо-приложение sifive_e QEMU RISC-V]
Константа mainCREATE_SIMPLE_BLINKY_DEMO_ONLY, которая определена в начале main.c, используется для переключения между простым режимом приложения в стиле мигания ('blinky' style) и более сложным тестом и демонстрационным приложением.
mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1. Когда mainCREATE_SIMPLE_BLINKY_DEMO_ONLY установлена в 1, функция main() вызовет main_blinky(), которая в свою очередь создаст базовый пример двух задач (Queue Send Task и Queue Receive Task) и одной очереди.
Queue Send Task: это задача, которая посылает в очередь значения, реализована функцией prvQueueSendTask(). В этой функции организован цикл, которые каждые 1000 эмулируемых миллисекунд вставляет в очередь значение 100.
Queue Receive Task: это задача, которая извлекает из очереди значение, реализована функцией prvQueueReceiveTask(). Она состоит из цикла, тело которого блокируется на попытке чтения из очереди (в состоянии блокировки задаче не потребляет процессорное время CPU). Задача просыпается каждый раз, когда успешно извлекает из очереди значение, и выводит текст 'blink' в консоль QEMU. Таким образом, задача Queue Send Task посылает в очередь значения, а задача Queue Receive Task эти значения извлекает, что происходит каждую секунду.
mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 0. Когда mainCREATE_SIMPLE_BLINKY_DEMO_ONLY установлена в 0, main() вызовет функцию main_full(). В main_full() реализован продвинутый тест и демонстрационное приложение, которое показывает и/или проверяет следующие возможности (вместе с другими вещами):
• Буферы потока (stream buffers [5]). • Буферы сообщения (message buffers [5]). • Оповещения задач [6]. • Группы событий (event groups [7]). • Семафоры [8]. • Мьютексы [9, 10]. • Программные таймеры (software timers [11]). • Очереди (queues [12]).
Созданные задачи это набор стандартных демо-задач. Они используются всеми демонстрационными приложениями портов FreeRTOS. Каждая из таких задач имеет свой специфичный функционал, и просто показывает, как использовать FreeRTOS API, тестируя тем самым порт RTOS.
Создается задача проверки (check-задача), которая периодически инспектирует стандартные demo-задачи (которые содержат код самоконтроля), чтобы убедиться, что все задачи работают достойным образом. Каждый раз при своем выполнении check-задача выводит символ '.' или сообщение об ошибки в консоль QEMU. Это дает визуальную обратную связь о здоровье системы. Если '.' появляется в консоли каждые 3 эмулируемые секунды (это время может отличаться от реальных трех секунд), то проверка не обнаружила проблем. Если консоль отобразила сообщение об ошибке, то проверка показала проблему в одной или нескольких задачах.
[Сборка демо-приложения RTOS]
Важное замечание: сборка проекта не произойдет, если структура директорий проекта отличается от структуры директорий, используемой в релизах официального zip-файла FreeRTOS. Убедитесь, что не стоит галочка чекбокса 'copy projects into workspace', когда импортируете проект в рабочее пространство Eclipse.
Чтобы открыть и собрать проект Freedom Studio RISC-V:
1. Загрузите и установите инструментарий разработки Freedom Studio development tools [13].
2. Запустите Freedom Studio, и либо выберите существующее рабочее пространство (workspace) или создайте новое, когда появится соответствующий стандартный запрос Eclipse.
3. Выберите "Import..." из меню File среды разработки Freedom Studio. Откроется диалоговое окно импорта.
4. В этом диалоге выберите "General -> Existing Project into Workspace".
Откроется диалог импорта проектов (Import Projects).
5. Кнопкой Browse... выберите директорию FreeRTOS/Demo/RISC-V-Qemu-siFive_e-FreedomStudio и убедитесь, что не стоит галочка 'copy projects into workspace'.
6. В окне списка импортируемых проектов Projects выберите проект RTOSDemo и кликните Finish.
7. Установите путь до тулчейна кросс-компилятора (Cross Compiler toolchain path) в свойствах проекта, он должен указывать на каталог, где находятся бинарники riscv64-unknown-elf вашей инсталляции (для Ubuintu это может быть каталог наподобие /usr/bin):
8. Выберите "Build all" из меню 'Project' среды разработки Freedom Studio. Проект должен собраться без каких-либо ошибок или предупреждений, и в результате будет создан файл RTOSDemo.elf.
[Запуск демо-приложения RTOS в эмуляторе QEMU]
1. Загрузите QEMU [14]. Проект собирался и тестировался на основе предварительно скомпилированного исполняемого кода для Windows [15].
2. Используя командную строку, показанную ниже, для запуска QEMU, замените в ней "path/to" на реальный путь до файла RTOSDemo.elf:
qemu-system-riscv32 -kernel path/to/RTOSDemo.elf -S -s -machine sifive_e
3. И наконец, сделайте правый клик на файл "Hardware_QEMU.launch" в Eclipse project explorer, затем выберите в контекстном меню "Debug As->Hardware_QEMU". Должен запуститься отладчик (debugger) и подключиться к QEMU (предполагается, что в результате предыдущего шага QEMU остался запущенным).
[Подробности по конфигурированию и использованию]
Конфигурация, специфичная для порта RTOS. В этой секции приведена информация, основанная на страничке документации, посвященной запуску FreeRTOS на ядрах RISC-V [2]:
• Элементы конфигурации для этого демо находятся в заголовочном файле FreeRTOS/Demo/RISC-V-Qemu-sifive_e-FreedomStudio/FreeRTOSConfig.h. Здесь определены константы, которые можно отредактировать так, чтобы они удовлетворяли вашему приложению. В частности, поскольку эмулируемое ядро SiFive включает машинный таймер (machine timer, MTIMER), определены configMTIME_BASE_ADDRESS и configMTIMECMP_BASE_ADDRESS в (CLINT_CTRL_ADDR) + 0xBFF8 и (CLINT_CTRL_ADDR) + 0x4000 соответственно. • Эмулируемое ядро SiFive не включает никаких дополнительных регистров, которых нет в базовой архитектуре RISC-V. Таким образом, проект использует заголовочный файл freertos_risc_v_chip_specific_extensions.h из директории /FreeRTOS/Source/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions, так что этот каталог находится в путях поиска подключаемых файлов ассемблера. • Обработчик прерывания, предоставленный в SiFive software development kit (SDK), называется trap_handler, так что опции командной строки ассемблера включают -DportasmHANDLE_INTERRUPT=handle_trap. • Файл flash.lds это версия файла настроек компоновщика (linker script), предоставленный в инструментарии разработки, отредактирован для добавления переменной линкера __freertos_irq_stack_top. Она гарантирует, что стек, используемый функцией main до запуска планировщика, повторно используется как стек прерывания после того, как планировщик запустится.
Другие замечания:
• Функция vPortEndScheduler() не реализована. • Используется Source/Portable/MemMang/heap_4.c, включенный в проект RISC-V, чтобы предоставлять способ выделения памяти, требуемый для RTOS kernel. Для полной информации по вариантам выделения памяти см. [16]. • На момент написания этой документации demo не поддерживает вложенность прерываний (interrupt nesting).
[Ссылки]
1. RTOS Demo for RISC-V QEMU sifive_e Model site:freertos.org. 2. FreeRTOS: использование в микроконтроллерах RISC-V. 3. Download FreeRTOS site:freertos.org 4. My application does not run, what could be wrong? site:freertos.org. 5. RTOS Stream & Message Buffers site:freertos.org. 6. FreeRTOS: оповещения задач. 7. FreeRTOS: функции группы бит событий. 8. FreeRTOS: xSemaphoreTake, xSemaphoreGive. 9. Чем отличается мьютекс от семафора? 10. FreeRTOS: практическое применение, часть 4 (управление ресурсами). 11. FreeRTOS: программные таймеры. 12. Очереди FreeRTOS. 13. Freedom Studio development tools site:sifive.com. 14. Download QEMU site:qemu.org. 15. QEMU Binaries for Windows (64 bit) site:qemu.weilnetz.de. 16. FreeRTOS: управление памятью. |