Перейти к содержанию
    

xvr

Свой
  • Постов

    3 583
  • Зарегистрирован

  • Посещение

  • Победитель дней

    2

Весь контент xvr


  1. Т.е. у вас в uxInterruptNesting ноль. Присвойте 1 Первое скорее. В общем там лежит sp мз пользовательской таски. Но может лежать и нечто смещённое - это от вас зависит (точнее от port.c и пр). Именно port часть обрабатывает его. В любом случае это точно НЕ xISRStackTop - это стек прерываний, он никогда в TCB не пишется А uxSavedTaskStackPointer это вообше не понятно что такое, нечто сугубо внутренее для оригинального port (откуда вы его брали). Посмотрите, где он ещё используется. Возможно он вообще не нужен.
  2. Когда вы стартуете первую таску система должна думать, что вы возвращаетесь из прерывания верхнего уровня, т.к. только там происходит переключение тасков. Так что при входе в vPortStartFirstTask нестинг должен бьть 1
  3. Во первых созранение и восстановление стека в TCB в portSAVE_CONTEXT и portRESTORE_CONTEXT надо делать только при 0 в uxInterruptNesting (но это не должно ломать первую таску) Проверте что в этот моент лежит в pxCurrentTCB (не NULL ли случаем). И если нет, что лежит в первом слове этой струкутры (pxStack), опять же не NULL и совпадает ли с тем, что вы инициализировали в pxPortInitialiseStack uxInterruptNesting проверте перед входом в vPortStartFirstTask - должен быть 1
  4. Где то тут приводили очень элегантный способ - в пользвательских секциях кода до и после инициализации ставите #if 0 и #endif и дописываете нужные вам вызовы инициализации в правильном порядке после #endif
  5. Эти нет (точнее bss в стартапе нужно нулями прописать. В линкере их инициализирвоанть не надо) bss должен затереть нулями стартап (вы на С пишете, так что неинициализированные глобальнае переменные должны быть нулями при старте - стандарт С никто не отменял). Динамическая память выделется из heap (или откуда вы сами менеджер памяти настроите), в любом случае он (менеджер) к начальному содержимому heap нечуствителен
  6. Это в том случае, если таски могут изменить gp. Если у вас нет каких либо экстраординарных тасков (например из загружаемых модулей), то этого скорее всего не случится. И gp можно не трогать. pxPortInitialiseStack создаёт, а vPortStartFirstTask его запускает (первый запуск слегка отличается от классического переключения тасков - там нет входа в прерывание, а сама vPortStartFirstTask по сути эмулирует выход из прерывания) Ok
  7. Желательно. Иначе вам придётся устраивать танцы с бубном если захочется переключить задачи по таймеру (а оно обязательно захочестя) Она создаёт специальный фрейм, который при выходе из него (в момент выхода из прерывания) запустит main таска Загружать явно в нужное значение (и не забыть его созранить и восстеновить в контексте) Либо проинициализировать один раз в стартапе и больше НИГДЕ не трогать (вполне нормальный подход, если весь код ваш, и вы нигде руками gp не меняете)
  8. Yield полностью соотвествует тому, что я написал. Таймерное прерывание не соотвествует - оно не обновляет TCB, а вместо этого сохраняет пользовательский стек в глобальной переменной uxSavedTaskStackPointer Это значит, что либо из него невозможно переключение задач (для этого нужно переключить TCB), либо код переключений в port.c берёт на себя манипуляцию по перекладыванию данных между TCB и uxSavedTaskStackPointer В принципе это (невозможность переключения задач из прерываний) тоже вполне возможный вариант, но тогда порт должен обеспечить вызов yield прерывания (откуда и происходит переключения задач) сразу после окончания обработки всей цепочки вложенных прерываний. Для этого скорее всего потребуется аппаратная поддержка. Я не знаком со всеми вариантами архитектур FreeRTOS, увы. Я разбирался с ESP32 и RISC-V. Про остальные могу только догадываться 😞
  9. У каждого порта она своя, т.к. хранит регистры процессора, которые очевидно разные. И опять же, от порта зависит - есть для него явно описанная структура или нет. То, на что указывает xISRStackTop Они у вас там есть. Но переключение между ними неправильное. У FreeRTOS есть 2 вида стеков - стек задачи (он же пользовательский). Этот вид существует по 1 штуке на каждую задачу. Когда задача испольняется он активен (загружен в sp) И стек прерываний - он всего один на всех, на нём запускаются прерывания самой FreeRTOS. Соотвественно в обработчике прерываний вы должны сначала сохранить все регистры по текущему sp, а потом выяснить, на каком имеено стеке вы сейчас находитесь (анализом уровня вложенности прерываний в спеу. переменной). Если на пользовательском - то сохранить sp в текущий TCB и переключить sp на xISRStackTop. Если нет, то ничего делать не надо. При выходе обратный процесс - переключение стека (если надо), восстановление регистров, возврат из прерывания yield ничем не отличается от обычного прерывания. ESP32 порт это делает - https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/bb6071e1df3168a64dc2ce79de8aa91b7995ba23/portable/ThirdParty/GCC/Xtensa_ESP32 PS. Он ещё и SMP - некоторые вещи могут быть не совсем такие, как в обычном FreeRTOS
  10. Именно то, чего у вас нет 🙂 При переключении контекста вы должны сохранить контекст текущей задачи в стек задачи, НЕ В ISR! Потом текущий указатель стека (пользовательской задачи) сохранить в поле в текущем TCB (на него указывает глобальная переменная pxCurrentTCB). И только потом переключаться на стек ISR. Восстановление аналогично - загрузка пользовательского стека из TCB, восстановление контекста и возврат. Переключение задач обеспечивается изменением этого самого pxCurrentTCB на другой TCB. pxCurrentTCB включает пользовательский SP первым полем (если у вас нет поддержки SMP). А Task Frame - это и есть пользовательский стек. Создаётся при создании задачи и указатель на него (на верх или низ - зависит от архитектуры) кладётся в TCB, куда потом будет указывать pxCurrentTCB. Оттуда и стартует пользовательская задача (стековый фрейм для её запуска формируется при создании задачи). В дальнейшем он будет живым стеком задачи, и SP задачи (пока FreeRTOS обрабатывает прерывание) будет храниться в TCB Для обработки вложенных прерываний нужно перед тем, как сохранять состояние понять откуда вас позвали - из пользовательского кода или из ISR. Если из пользовательского кода, то делаете всё как описанно выше. Если из ISR, то никаких стеков вообще переключать не нужно - сохраняете контекст прямо по текущему SP Вход в ISR. При первом входе (от пользователя) она будет 0, при дальнейших вложенных ISR - больше нуля. При выходе из ISR - декрементируется
  11. https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08/ProductDocuments/DataSheets/ATtiny804-06-07-1604-06-07-DataSheet-DS40002312A.pdf страница 185: Event system - страница 114 Источник event - ASYNCCHn (страница 121)
  12. От скольких вольт питается ваша схема? Если меньше 5, то диод D1 стоит убрать - через него питание 5V с USB прямиком идёт на питание всей схемы. Ну и надеюсь что вы не забыли подключить выводя питания к м/сх (не обозначенным на схеме). И блокировочные конденсаторы не забыли
  13. У MAX3232 перепутаны TX и RX каналы. Конденсатор C5 подключён мягко выражаясь странно. LED1 подключён к каналу TX только CH340, на передачу от MAX3232 он реагировать не будет Назначение R1 и R3 непонятны.
  14. В MicrochipStudio открыть MCC и настроить TCA на счёт внешних импульсов, TCB в free runner режим (с ограничением счета сверху), что бы он вырабатывал прерывания в 1 Hz. В прерываниях забирать насчитанное из TCA и сбрасывать его. Если MCC не умеет ваш контролер, то читать DS и настраивать вручную.
  15. Одним таймером считаете импульсы на порту A, другим засекаете 1 секугду (или меньше - по вкусу). По окончании секунды проверяете сколько насчитали - если болше 64, ставите порт B в 1, если меньше - в 0. Ещё надо бы контролировать переполнение первого таймера, что бы очень высокая частота не окзалась очень низкой 🙂 Если на входе возможен дребезг (например от механического контакта), его надо подавить ДО входа в МК или с помощью фильтра в CCL
  16. Глава 16 в DS - всё о портах. Глава 7.1 - адреса, где они лежат
  17. Ошибка в ArmClang?

    Предположу что здесь UB - компилятор знает что такое malloc и считает Ptr-1 не инициализированной памятью. Он же не в курсе, что вы в потраха менеджера памяти полезли. Сделайте Ptr volatile переменной, возможно поможет
  18. Насколько я помню ESP32 умеет работать сразу в 2х ипостасях - и устройство и точка доступа. Точно, умеет - Поднимаете на точке конфигурационный интерфейс, а на station - рабочий.
  19. А что там тогда делает CH340G? Он не может вместе с ST232 на одни и те же ардуиновские TX/RX работать.
  20. Как соединили выводы ST232 и Arduino? Надеюсь не подсоединили TX Arduino к TX ST232?
  21. Вы бы хоть схему приложили 🙂
  22. Если у вас в других модах проц не работает (S/U/H), то да
  23. В листинге у вас 16 gp (у процессора их 32), и 20 плавучки (у процесора её тоже 32 штуки)
  24. В стек ничего, у него для сохранения регистры есть. Не пойдёт - в прерывании надо сохранять ВСЕ gp регистры (все 32 целых и все 32 плавучки). У вас же не вызов С функции - внутри пользовательского кода все регистры важны, это только на границе вызова С функций можно что то не сохранять. Ничего. В ISA прописано, читали?
×
×
  • Создать...