ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
21 ноября
1416078
klen (18.03.2024 17:56, просмотров: 5829)
вот Вам мое видение порта freertos для QingKeV4 V4F (микросхемы аля ch32v307) 

пока портировал писал для себя камменты в голове фалов порта.

сегодня почистил и дооформил.

c портом прилагаю в архиве наисвежайшее ядро freertos "сегодняшнее и3 remotes/origin/HEAD "

freertos_kgp_qkv4f.tar.xz


ниже содержание камментов - "что? зачем? почему?"


/* FreeRTOS Kernel V11.0.1+ kgp/klibc куда пойдете - copy направо или на лево - это ваше личное решение! я иду вверх! присоеденяйтесь... Чернов Сергей aka Klen Santakheza klen_s@mail.ru */ /* * Порт построен на базе кода FreeRTOS\Source\portable\GCC\RISC-V-RV32 и кода * порта из MounRiver_Studio как результат изучения riscv и размышлений как бы * сделать все половчее чем "лишь бы как то заработало". * Первый из них является линшь заготовкой и не может работать, второй работает * из коробки но сделан с ошибками в стиле "хуяк-хуяк в продакшэн" - например у * "узкоглазых братьев" напрочь не предусмотрено переключение режимов процессора, * и потоки РАБОТАЮТ В РЕЖИМЕ machine, а не как полагается в режиме user!!! * это говнокод и трэш, друзья мои. Но их понть можно - "кейтайские пейсайтели из * MounRiver" кажется не умеют читать "кейтайские доки" на процессор - они уперлись * в то что mstatus традиционно в riscv доступен ТОЛЬКО в режиме machine :) * .... нешмагла... а мы сделали! * * в связи с тем что данный порт целевой - для ядера QingKeV4 микросхем ch32v307 * файл freertos_risc_v_chip_specific_extensions.h исключен, работа с регистрами * сопроцессора внесена в port_asm.s * макросы portasmSAVE_ADDITIONAL_REGISTERS и portasmRESTORE_ADDITIONAL_REGISTER * внесены под дефайн portasmADDITIONAL_CONTEXT_SIZE по этому порт должен * без проблем заработать на всех вариантах ядра QingKeV4 - V4A, V4B, V4C и V4F * посредством настройки portasmADDITIONAL_CONTEXT_SIZE. * * * отличия от потрта MounRiver_Studio * * 0. порт строился на связке с исходниками freertos kernel из main - ветки * https://github.com/FreeRTOS/FreeRTOS-Kernel.git * соответсвенно он является "наисвежайшим" :) версии V11.0.1+ * само ядро в моем случае тоже доработано (отдельная тема), в частности на предмет реентерабельности, * использования ситемного таймера ядра процессора и тд.... * но работа порта от этого не зависит. ядро отдельно - порт отдельно! * * 1. freertos_port_machine_mode_init() * данная функция добалена в порт и должна быть вызвана в reset/crt коде в машинном режиме до выхода в режим пользователя. * данная мера необходима в связи с тем что необходимо протестировать регистр mtvec на валидность адреса в нем и выполнить * сохранение указателя вершины стека обработчиков в регистре mscratch, эти регистры доступны только в машинном режиме. * * 2. проблема uxCriticalNesting - невозможно использовать статические объекты freertos. * изначально в обоих исходных портах uxCriticalNesting инициализируется в 0xaaaaaaaa, что бы пометить сотояние до запуска планировщика. * однако это имее негативный побочный эффект. практически любой api freertos (например размещение статических мьютексов) * сбросит прерывания и не включит их!! это ломает логику работы системы до старта планировщика, на которую в таком * случае ложатся ограничения по использованию статического размещения объектов freertos. для исключения данной проблемы * выполняется сброс uxCriticalNesting в исходное соcтояние, необходимый для устранения проблем при вызове функций работы с объектами * freertos до старта шедуллера. имеем результат: в freertos_port_machine_mode_init() выполняется uxCriticalNesting = 0 ; * * 3 xPortStartFirstTask * * * 4. xPortSetInterruptMask/vPortClearInterruptMask * нехуй писать в mstatus 0x7800 и засирать состояние fpu по каждому прерыванию. решаем проблему так - выполняем csrrci - * чтение регистра и ТОЛЬКО сброс!!! бита глобального прерывания при выходе взад записываем исходное сотояние, * также получаем бонус! исключаем четыре иструкции загрузки регистров так как используем indirect варианты команд доступа к mstatus ! * имеем результат: * portUBASE_TYPE xPortSetInterruptMask(void) { portUBASE_TYPE uvalue=0; __asm volatile("csrrci %0, mstatus, %1":"=r"(uvalue):"i"(0x8)); return uvalue; } * void vPortClearInterruptMask(portUBASE_TYPE uvalue) { __asm volatile("csrw mstatus, %0"::"r"(uvalue)); } * * 5. TODO #0: выполнив пункт 2 открывается возможность сделать "ленивое" сохранение/востановление регистров сопроцессора. * на данный момент все гоняется "туда-сюда по полной" при смене контекста - и целочисленные регистры и регистры fpu. * однако наличие флагов * src::mstatus [14:13] Floating-point unit status * позволяют выполнять отслеживание изменения состояния fpu за время кванта времени выполненя потока(task) выполнять сохранение/востановление * только в случае необходимости, что сущенственно снизить время на переключение контектов потоков которые редко или вообще не не исполняют код, * использующий fpu * как результат приведенных рассуждений, планируется в ближайшее время это реализовать в шедуллере и посмотерь каков выйгрыш по времени и при * каких условиях, выработать методику разработки и проектирования кода с эффективным использованием этой фичи. * * 6. TODO #1: порт назван как qkv4 - то есть для всех вариантов: V4A, V4B, V4C и V4F. но по факту данный код для V4F у которого есть fpu. * я решил поступить как делает японский автопром - сначала ебалайка на колесиках в ПОЛНОЙ КОМПЛЕКТАЦИИ, а уж потом что то отключать дефайнами, * а не как у гейропейцев и у нас - сделать полуфабрикат, а потом прикручивать скотчем костыли. расширяющие фцнкционал... */