Программирование ARM FreeRTOS: использование в микроконтроллерах RISC-V Sun, September 08 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

FreeRTOS: использование в микроконтроллерах RISC-V Печать
Добавил(а) microsin   

Архитектура набора инструкций RISC-V (ISA) [3] легко расширяется, и никак не описывает что-то конкретное в физических реализациях микроконтроллера RISC-V (MCU) или системы на чипе (system on chip, SoC). В этом соответствии порт FreeRTOS RISC-V также расширяемый - в нем предоставляется поддержка базовых регистров, которые являются общими для всех реализаций RISC-V, а также набор макросов, которые должны быть реализованы для поддержки аппаратных особенностей и расширений, таких как дополнительные регистры.

Примечание: как было отмечено на страничке обновления FreeRTOS V10.3.0 [2], настройка конфигурации configCLINT_BASE_ADDRESS устарела, и была заменена на описанные там же настройки configMTIME_BASE_ADDRESS и configMTIMECMP_BASE_ADDRESS. Старые приложения, которые все еще используют configCLINT_BASE_ADDRESS, будут генерировать предупреждение компилятора, но в основном будут продолжать нормально выполнять сборку и работать, как раньше.

[Быстрый старт]

Основная часть документации [1] предоставляет подробную информацию по сборке FreeRTOS для ядер RISC-V, однако самый простой путь быстрого запуска - использовать один из следующих предварительно сконфигурированных примеров проектов (этот список корректен на момент составления):

• Эмулятор SiFive sifive_e QEMU, с использованием Freedom Studio и GCC [4].
• MiFive M2GL025 Creative Board и Renode, с использованием GCC и SoftConsole IDE [6].
• VEGAboard PULP RI5CY Demo, с использованием GCC и Eclipse [7].

Пример проектов RISC-V находится в подкаталогах FreeRTOS/Demo, которые начинаются с "RISC-V", его можно загрузить в составе основного ZIP-файла пакета FreeRTOS. Эти проекты можно использовать непосредственно, или просто как рабочий пример и справочный образец для файлов исходного кода, опций конфигурации, и описанных далее настроек компилятора.

В общем для сборки FreeRTOS на основе ядра RISC-V вам понадобится:

1. Подключить в свой проект файлы исходного кода ядра FreeRTOS, и исходные файлы слоя порта FreeRTOS RISC-V.
2. Убедитесь, что путь поиска подключаемых файлов ассемблера включает путь к файлу заголовка, который описывает любые детали реализации, специфичные для используемого чипа.
3. Определите либо константу в FreeRTOSConfig.h, либо переменную линкера для указания памяти, используемой как стек прерываний.
4. Определите в FreeRTOSConfig.h опции configMTIME_BASE_ADDRESS и configMTIMECMP_BASE_ADDRESS.
5. Для ассемблера задайте #define portasmHANDLE_INTERRUPT для имени функции обработки внешних прерываний, предоставленной вашим поставщиком чипа или поставщиком инструментария.
6. Инсталлируйте FreeRTOS trap handler.

Также могут быть полезны следующие дополнительные ссылки:

• Creating a new FreeRTOS project [9].
• FreeRTOS kernel quick start guide [10].
• Adapting a FreeRTOS demo to different hardware [11].

Функциональные особенности порта FreeRTOS RISC-V:

• Предоставляется для обоих компиляторов GCC и IAR.
• Поддерживается только machine mode integer execution на ядрах 32-bit и 64-bit RISC-V. Однако все находится в активной разработке, и в будущих релизах FreeRTOS добавятся фичи и функциональность, требуемые всем пользователям.
• Реализован отдельный стек прерываний, при этом значительно сокращается использование RAM на маленьких MCU, так как устраняется необходимость для каждой задачи поддерживать стек, достаточный как для прерывания, так и обычного кода.
• Предоставляется базовый порт, который может быть расширен для реализации определенной специфики конкретной архитектуры чипа RISC-V.

[Файлы исходного кода]

Врезка "Организация исходного кода FreeRTOS" содержит основную информацию по добавлению ядра FreeRTOS в ваш проект. В дополнение к этому порт FreeRTOS RISC-V требует еще одним заголовочный файл. Этот дополнительный хедер описывает специфику чипа, и он необходим, потому что чипы RISC-V часто включают в себя некоторые особенные архитектурные расширения.

Дополнительный хедер это файл freertos_risc_v_chip_specific_extensions.h. Существует по одной реализации этого файла заголовка для каждого поддерживаемого расширения архитектуры, причем все реализации находятся в подкаталогах директориях /FreeRTOS/Source/Portable/[compiler]/RISC-V/chip_specific_extensions.

Чтобы подключить корректный заголовочный файл freertos_risc_v_chip_specific_extensions.h для вашего чипа, просто добавьте путь до него в пути поиска заголовков ассемблера (assembler include path). Обратите внимание, что это пути поиска заголовков именно ассемблера, но не компилятора (compiler's include path). Например:

• Если ваш чип реализует базовую архитектуру RV32I или RV64I, включает Core Local Interrupter (CLINT), но не имеет других расширений регистров, то добавьте /FreeRTOS/Source/Portable/[compiler]/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions в пути поиска заголовков ассемблера.
• Если ваш чип использует ядро PULP RI5KY, как реализовано на RV32M1RM Vega board, где включены 6 дополнительных регистров, и не включен Core Local Interrupter (CLINT), то добавьте /FreeRTOS/Source/Portable/[compiler]/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM к путям поиска заголовков ассемблера.

Для информации, как делать свои собственные заголовочные файлы freertos_risc_v_chip_specific_extensions.h, также см. далее секцию с описанием опций командной строки компилятора и ассемблера, и секцию по портированию FreeRTOS на новые реализации RISC-V.

Каждый порт RTOS поставляется с предварительно сконфигурированным демонстрационным приложением (demo), которое изначально собирает необходимые исходные файлы RTOS, и подключает необходимые заголовочные файлы RTOS. Настоятельно рекомендуется использовать эти demo как базу для всех новых приложений, основанных на FreeRTOS. В этой врезке предоставляется информация по местонахождению и описанию этих предоставленных проектов.

[Базовая структура каталогов]

Загружаемый пакет FreeRTOS включает в себя исходный код для каждого процессорного порта, а также соответствующее demo-приложение. Размещение всех портов в один ZIP-файл упрощает распространение FreeRTOS, однако такое большое количество файлов может показаться пугающим. Однако структура директорий очень проста, и ядро реального времени FreeRTOS содержится всего в 3 файлах (дополнительные файлы требуются, если нужен функционал software timer, event group или co-routine).

На самом верху находятся 2 подкаталога, FreeRTOS и FreeRTOS-Plus:

+-FreeRTOS-Plus    Содержит FreeRTOS-Plus компоненты и демонстрационные проекты.
|
+-FreeRTOS         Содержит файлы исходного кода ядра реального времени (FreeRTOS
                    real time kernel) и демонстрационные проекты.

Дерево директорий FreeRTOS-Plus содержит несколько файлов readme, описывающих содержимое соответствующего подкаталога.

[Структура директории FreeRTOS kernel]

Файлы исходного кода ядра (FreeRTOS kernel) и демонстрационные проекты находятся в двух подкаталогах:

FreeRTOS
    |
    +-Demo      Здесь содержатся проекты демо-приложений.
    |
    +-Source    Содержит исходный код ядра реального времени (real time kernel).

Ядро кода RTOS содержится в 3 файлах: tasks.c, queue.c и list.c, которые находятся в директории FreeRTOS/Source. Эта же директория содержит 2 опциональных файла timers.c и croutine.c, где реализованы функционал программного таймера (software timer) и сопрограмм (co-routine) соответственно.

Каждая процессорная архитектура требует небольшого количества кода RTOS, специфичного для конкретной архитектуры. Это слой портирования (RTOS portable layer), и он находится в подкаталогах FreeRTOS/Source/Portable/[compiler]/[architecture], где [compiler] и [architecture] соответственно используются компилятором для создания порта, и описывается архитектура, на которой запускается порт.

По причинам, описанным на страничке управления памятью [8], схемы выделения кучи (heap) также находятся на слое портирования. Различные примеры схем кучи heap_x.c находятся в директории FreeRTOS/Source/portable/MemMang.

Примеры директорий слоя портирования (portable layer):

• Если используется порт TriCore 1782 с компилятором GCC: файл port.c находится в директории FreeRTOS/Source/Portable/GCC/TriCore_1782. Все другие подкаталоги FreeRTOS/Source/Portable, отличные от FreeRTOS/Source/Portable/MemMang, могут игнорироваться, или могут быть удалены.
• Если используется порт Renesas RX600 с компилятором IAR: файл port.c находится в директории FreeRTOS/Source/Portable/IAR/RX600. Все другие подкаталоги FreeRTOS/Source/Portable, отличные от FreeRTOS/Source/Portable/MemMang, могут игнорироваться, или могут быть удалены.

И так далее, для всех портов аналогично ...

Структура директории FreeRTOS/Source:

FreeRTOS
    |
    +-Source        Файлы ядра (core FreeRTOS kernel files).
        |
        +-include   Заголовочные файлы ядра (core FreeRTOS kernel header files).
        |
        +-Portable  Код, описывающий специфику процессора.
            |
            +-Compiler x    Все порты, поддерживаемые компилятором x.
            +-Compiler y    Все порты, поддерживаемые компилятором y.
            +-MemMang       Примеры реализаций куч (heap).

Загружаемый пакет FreeRTOS также содержит демонстрационное приложение для каждого порта архитектуры процессора и компилятора. Основной код демо-приложения для всех портов находится в директории FreeRTOS/Demo/Common/Minimal (устаревший код находится в директории FreeRTOS/Demo/Common/Full, и он только используется портом PC).

Остальные подкаталоги FreeRTOS/Demo содержат предварительно сконфигурированные проекты, используемые для сборки индивидуальных демо-приложений. Директории именуются таким образом, чтобы показать порт, к которому они относятся. Каждый RTOS порт имеет собственную web-страничку, где более подробна описана директория, в которой можно найти соответствующее демо-приложение для этого порта.

Примеры demo-директорий:

• Если собирается демо-приложение TriCore GCC, предназначенное для аппаратуры Infineon TriBoard: файл проекта демо-приложения находится в директории FreeRTOS/Demo/TriCore_TC1782_TriBoard_GCC. Все другие подкаталоги, находящиеся в папке FreeRTOS/Demo (кроме подкаталога Common) могут игнорироваться, или могут быть удалены.
• Если собирается демо-приложение Renesas RX6000 IAR, предназначенное для аппаратуры RX62N RDK: workspace-файл IAR находится в директории FreeRTOS/Demo/RX600_RX62N-RDK_IAR. Все другие подкаталоги, находящиеся в папке FreeRTOS/Demo (кроме подкаталога Common) могут игнорироваться, или могут быть удалены.

И так далее, для всех портов аналогично ...

Структура директории FreeRTOS/Demo:

FreeRTOS
    |
    +-Demo
        |
        +-Common    Файлы демонстрационных приложений, используемые совместно.
        +-Dir x     Файлы для сборки демо-приложения порта x.
        +-Dir y     Файлы для сборки демо-приложения порта y.

[Создание своего собственного приложения]

Предварительно настроенные демонстрационные приложения предоставляются для того, чтобы проекты уже существовали с правильными исходными файлами ядра RTOS и правильными заданными параметрами компилятора, и как следствие компилировались сразу "из коробки", с минимальными усилиями пользователя. Поэтому настоятельно рекомендуется создавать новые приложения путем модификации существующего предварительно сконфигурированного демонстрационного приложения. Это можно сделать, сначала создав существующее демонстрационное приложение, чтобы обеспечить чистую сборку, а затем постепенно изменять файлы, включенные в проект из каталога FreeRTOS/Demo, вашими собственными исходными файлами приложения.

Примечание: более подробное описание см. на страничке по созданию нового проекта FreeRTOS [9].

[Опции FreeRTOSConfig.h]

В FreeRTOSConfig.h должны быть определены опции configMTIME_BASE_ADDRESS и configMTIMECMP_BASE_ADDRESS. Если целевой чип RISC-V включает machine timer (MTIME), то установите configMTIME_BASE_ADDRESS в базовый адрес MTIME, и configMTIMECMP_BASE_ADDRESS в адрес регистра сравнения (MTIME compare register, MTIMECMP). Иначе установите оба этих определения в 0.

Например, если MTIME base address равен 0x2000BFF8, и MTIMECMP адрес равен 0x20004000, то добавьте в FreeRTOSConfig.h следующие строки:

#define configMTIME_BASE_ADDRESS ( 0x2000BFF8UL )
#define configMTIMECMP_BASE_ADDRESS ( 0x20004000UL )

Если нет MTIME clock, то в FreeRTOSConfig.h добавьте следующие строки:

#define configMTIME_BASE_ADDRESS ( 0 )
#define configMTIMECMP_BASE_ADDRESS ( 0 )

[Настройка стека прерываний]

Порт FreeRTOS RISC-V переключается в выделенный (или системный, system) стек прерываний перед вызовом из прерывания (ISR) любой C-функции.

Память, используемая как стек прерываний, может быть определена либо в файле настроек линкера проекта (linker script), либо на слое порта (FreeRTOS port layer) как выделенный статически массив. Метод настроек линкера предпочтительнее использоваться на MCU с ограниченным объемом памяти, поскольку это позволяет переназначить стек, который используется в main(), до запуска планировщика (стек больше не будет использоваться для этой цели после того, как планировщик запущен), т. е. стек будет переназначен в качестве стека прерываний, что экономит память.

• Для использования в качестве стека прерываний статически определенного массива: определите в FreeRTOSConfig.h опцию configISR_STACK_SIZE_WORDS, которая задает размер выделенного стека прерываний. Обратите внимание, что размер здесь определяется в СЛОВАХ, а не в байтах. Например, для использования 500 слов (это 2000 байт на RV32, где каждое слово имеет размер 4 байта) статически выделенного стека прерываний добавьте в FreeRTOSConfig.h следующую строку:

#define configISR_STACK_SIZE_WORDS ( 500 )

• Чтобы определить стек прерывания через linker script (имейте в виду, что этот способ на момент написания статьи поддерживался только для порта GCC): декларируйте переменную линкера __freertos_irq_stack_top, в которой хранится самый большой адрес стека прерываний, и убедитесь, что не определена опция configISR_STACK_SIZE_WORDS.

Использование этого метода требует редактирования файла linker script (файл настроек компоновки, или сценарий линкера). Если вы не очень знакомы со сценариями линкера, то важно знать по крайней мере при использовании GCC, что '.' это то, что известно как счетчик местоположения (location counter), и здесь хранится адрес памяти, который указывается в linker script. Хотя не нужно очень подробно вникать в тонкости содержимого linker script, просто скопируйте пример ниже.

Стек, который использовался кодом main() до запуска планировщика, больше не требуется после запуска планировщика, так что было бы идеальным использовать эту память повторно путем установки __freertos_irq_stack_top значением, равным самому большому адресу стека, выделенного для использования в main(). Например, если ваш linker script содержит что-то наподобие следующего (реальные файлы настроек линкера могут несколько отличаться):

  .stack : ALIGN(0x10)
  {
    __stack_bottom = .;
    . += STACK_SIZE;
    __stack_top = .;
  } > ram

.. то __stack_top (имя указано только как пример) это переменная линкера, значение которой равно самому большому адресу стека, используемого main() (запомните, что '.' хранит адрес памяти в любом определенном месте linker script). В этом случае, чтобы дать для __freertos_irq_stack_top такое же значение, что и у __stack_top, просто определите __freertos_irq_stack_top сразу после __stack_top. См. пример ниже:

  .stack : ALIGN(0x10)
  {
    __stack_bottom = .;
    . += STACK_SIZE;
    __stack_top = .;
    __freertos_irq_stack_top= .; /* ЭТО ДОБАВЛЕННАЯ СТРОКА. */
  } > ram

Замечание: на момент написания этой документации ядро не проверяет (в отличие от стеков задач) на переполнение стек прерываний.

[Необходимые опции командной строки компилятора и ассемблера]

Различные реализации RISC-V предоставляют разные обработчики для внешних прерываний, так что необходимо указать ядру FreeRTOS, какой следует вызывать обработчик внешнего прерывания (external interrupt handler). Для установки имени внешнего обработчика прерывания:

1. Найдите имя external interrupt handler, предоставленного вашим дистрибутивом (RISC-V run-time software distribution) - это обычно присутствует в пакете SDK, предоставляемом вендором чипа. У обработчика прерывания должен быть один параметр, который является значением cause-регистра RISC-V в момент входа в прерывание. Например, ожидаемый прототип обработчика прерывания может быть (такое имя указано только для примера, используйте корректное имя из вашего пакета ПО поддержки чипа):

void external_interrupt_handler( uint32_t cause );

2. Определите assembler macro (обратите внимание, что это макрос ассемблера, но не макрос компилятора) с именем portasmHANDLE_INTERRUPT, равный имени обработчика прерывания.

Если используется GCC, то этого можно достичь добавлением следующего к командной строке ассемблера, предполагается что обработчик прерывания называется external_interrupt_handler:

-DportasmHANDLE_INTERRUPT=external_interrupt_handler

Если используется IAR то того же самого можно достичь через диалог редактирования опций проекта, путем добавления следующей строки как определяемого символа в категории настроек Assembler. Предполагается, что обработчик прерывания называется vApplicationHandleTrap:

portasmHANDLE_INTERRUPT=vApplicationHandleTrap

IAR RISC V Assembly Options

Рис. 1. Установка опций ассемблера IAR.

Также нужно добавить путь поиска до корректного файла заголовка freertos_risc_v_chip_specific_extensions.h соответствующего вашему чипу RISC-V в настройки assembler include path (обратите внимание, что это пути поиска заголовков ассемблера, но не компилятора). См. также выше секцию "Файлы исходного кода".

[Установка FreeRTOS trap handler]

FreeRTOS trap handler называется freertos_risc_v_trap_handler(), и это "обработчик ловушек", центральная точка входа для всех прерываний (interrupt) и исключений (exception). FreeRTOS trap handler вызывает обработчик внешних прерываний (external interrupt handler) когда источником было внешнее прерывание.

Для установки trap handler:

1. Если используемое ядро RISC-V подключает Core Local Interrupter (CLINT), то в хедере freertos_risc_v_chip_specific_extensions.h опция portasmHAS_SIFIVE_CLINT может быть определена в 1, что приведет к автоматической инсталляции freertos_risc_v_trap_handler(), и никаких других специальных действий не требуется.
2. Во всех других случаях необходимо вручную инсталлировать freertos_risc_v_trap_handler(). Это можно сделать редактированием кода запуска (startup code), предоставленного провайдером вашего чипа.

Замечание: если ваш чип RISC-V использует векторный контроллер прерываний (vectored interrupt controller, VIC), то инсталлируйте freertos_risc_v_trap_handler() в качестве обработчика для каждого вектора.

[Портирование на новые реализации 32-bit или 64-bit RISC-V]

Перед чтением этой секции прочитайте выше секцию "Файлы исходного кода" FreeRTOS RISC-V.

Необходимо в файле freertos_risc_v_chip_specific_extensions.h определить следующие макросы:

portasmHAS_MTIME

Если у чипа есть machine timer (MTIME), то установите опцию portasmHAS_MTIME в 1, иначе установите portasmHAS_MTIME в 0.

portasmADDITIONAL_CONTEXT_SIZE

RISC-V Instruction Set Architecture (ISA) расширяемая, так что чипы RISC-V могут включать дополнительные регистры сверх тех, что требуются спецификацией базовой архитектуры [3].

Определите #define portasmADDITIONAL_CONTEXT_SIZE в количество дополнительных регистров, которые есть в целевом чипе - эта опция может быть нулем. Например, ядро RI5CY на плате разработчика Vega board включает 6 дополнительных регистров, так что предоставленный для этого чипа заголовок freertos_risc_v_chip_specific_extensions.h содержит строку:

#define portasmADDITIONAL_CONTEXT_SIZE 6

portasmSAVE_ADDITIONAL_REGISTERS

portasmSAVE_ADDITIONAL_REGISTERS это макрос ассемблера (не #define), который должен быть реализован для сохранения определенных дополнительных регистров.

Если у чипа нет каких-то специальных регистров расширения (portasmADDITIONAL_CONTEXT_SIZE установлена в 0), то portasmSAVE_ADDITIONAL_REGISTERS должен быть пустым макросом ассемблера, определенным так:

.macro portasmSAVE_ADDITIONAL_REGISTERS
    /* Этот макрос ничего не делает, поскольку нет дополнительных регистров. */
    .endm

Если есть какие-то специальные регистры расширения (portasmADDITIONAL_CONTEXT_SIZE больше нуля) то макрос portasmSAVE_ADDITIONAL_REGISTERS должен делать следующее:

1. Декрементировать указатель стека, чтобы выделить достаточно места для дополнительных регистров, а затем ...
2. Сохранять дополнительные регистры в выделенное пространство стека.

Например, если у чипа есть 3 дополнительных регистра, то portasmSAVE_ADDITIONAL_REGISTERS должен быть определен следующим образом (здесь имена регистров будут зависеть от чипа, и могут быть не теми, что показаны в этом примере):

.macro portasmSAVE_ADDITIONAL_REGISTERS
    /* Используйте макросы portasmADDITIONAL_CONTEXT_SIZE и portWORD_SIZE
       для вычисления, сколько нужно дополнительного места в пространстве
       стека, и вычьте это из указателя стека. Эта строка может быть просто
       скопирована из предоставленного, корректно установленного
       portasmADDITIONAL_CONTEXT_SIZE. Обратите внимание на знак
       минуса ('-'). Макрос portWORD_SIZE уже где-то был определен. */
    addi sp, sp, -(portasmADDITIONAL_CONTEXT_SIZE * portWORD_SIZE) 

/* Следующий шаг - сохранение дополнительных регистров в стек. Здесь подразумевается, что имена у них xx0 .. xx2, но для вашего чипа они могут называться по-другому. Подразумевается, что portasmADDITIONAL_CONTEXT_SIZE == 3. */ sw xx0, 1 * portWORD_SIZE( sp ) sw xx1, 2 * portWORD_SIZE( sp ) sw xx2, 3 * portWORD_SIZE( sp ) .endm

portasmRESTORE_ADDITIONAL_REGISTERS

portasmRESTORE_ADDITIONAL_REGISTERS это макрос, выполняющие обратные макросу portasmSAVE_ADDITIONAL_REGISTERS действия.

Если у чипа нет каких-то специальных регистров расширения (portasmADDITIONAL_CONTEXT_SIZE установлен в 0), то макрос ассемблера portasmRESTORE_ADDITIONAL_REGISTERS должен быть пустым:

.macro portasmSAVE_ADDITIONAL_REGISTERS
    /* Используйте макросы portasmADDITIONAL_CONTEXT_SIZE и portWORD_SIZE
       для вычисления, сколько нужно дополнительного места в пространстве
       стека, и вычьте это из указателя стека. Эта строка может быть просто
       скопирована из предоставленного, корректно установленного
       portasmADDITIONAL_CONTEXT_SIZE. Обратите внимание на знак
       минуса ('-'). Макрос portWORD_SIZE уже где-то был определен. */
    addi sp, sp, -(portasmADDITIONAL_CONTEXT_SIZE * portWORD_SIZE) 

/* Следующий шаг - сохранение дополнительных регистров в стек. Здесь подразумевается, что имена у них xx0 .. xx2, но для вашего чипа они могут называться по-другому. Подразумевается, что portasmADDITIONAL_CONTEXT_SIZE == 3. */ sw xx0, 1 * portWORD_SIZE( sp ) sw xx1, 2 * portWORD_SIZE( sp ) sw xx2, 3 * portWORD_SIZE( sp ) .endm

Если есть какие-то специальные регистры расширения (portasmADDITIONAL_CONTEXT_SIZE больше нуля) то макрос portasmRESTORE_ADDITIONAL_REGISTERS должен делать следующее:

1. Прочитать дополнительные регистры из ячеек стека, которые использовались макросом portasmSAVE_ADDITIONAL_REGISTERS, а затем ...
2. Освободить пространство стека, используемое для хранения дополнительных регистров, путем инкремента указателя стека на корректную величину.

Например, если у чипа есть 3 дополнительных регистра, то portasmRESTORE_ADDITIONAL_REGISTERS должен быть определен следующим образом (здесь имена регистров будут зависеть от чипа, и могут быть не теми, что показаны в этом примере):

.macro portasmRESTORE_ADDITIONAL_REGISTERS
    /* Восстановление из стека дополнительных регистров. Подразумевается,
       что имена у них xx0 .. xx2, но для вашего чипа имена могут
       отличаться. А этом примере portasmADDITIONAL_CONTEXT_SIZE == 3. */
    lw xx0, 1 * portWORD_SIZE( sp )
    lw xx1, 2 * portWORD_SIZE( sp )
    lw xx2, 3 * portWORD_SIZE( sp ) 

/* Используйте макросы portasmADDITIONAL_CONTEXT_SIZE и portWORD_SIZE для вычисления пространства, которое нужно освободить из стека. Эта строка может быть просто скопирована из предоставленного, корректно установленного portasmADDITIONAL_CONTEXT_SIZE. Макрос portWORD_SIZE уже где-то был определен. */ addi sp, sp, (portasmADDITIONAL_CONTEXT_SIZE * portWORD_SIZE) .endm

Опционально файл freertos_risc_v_chip_specific_extensions.h также может включать:

portasmHAS_SIFIVE_CLINT

Если целевой чип RISC-V содержит Core Local Interrupter (CLINT), то определите #define portasmHAS_SIFIVE_CLINT в 1, если хотите, чтобы автоматически устанавливался FreeRTOS RISC-V trap handler.

[Ссылки]

1. Using FreeRTOS on RISC-V Microcontrollers site:freertos.org.
2. Upgrading From FreeRTOS V10.2.1 to V10.3.0 site:freertos.org.
3. RISC-V.
4. FreeRTOS демо для модели RISC-V QEMU sifive_e.
5. sifive / FreeRTOS-metal site:github.com.
6. RTOS Demo for RISC-V MiFive M2GL025 / Renode site:freertos.org.
7. RISC-V RV32M1 VEGAboard Demo (RI5CY Core) site:freertos.org.
8. FreeRTOS: управление памятью.
9. Creating a New FreeRTOS Project site:freertos.org.
10. FreeRTOS kernel quick start guide site:freertos.org.
11. Adapting a FreeRTOS demo to different hardware site:freertos.org.

 

Добавить комментарий


Защитный код
Обновить

Top of Page