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

jcxz

Свой
  • Постов

    13 830
  • Зарегистрирован

  • Посещение

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

    38

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


  1. Ну если вам нравится текстом - кто ж вам мешает? А я буду делать как удобнее мне и пользователям моих устройств.
  2. Не совсем. Если trap генерируется программный (например: в результате проверки каких-то переменных в программе обнаружено их недопустимое состояние), то делается вызов trap() (это не макрос и не функция в обычном виде, это возбуждение прерывания SVC, оформленное в виде функции (IAR умеет такое)). Внутри ISR SVC защёлкивается в ОЗУ дамп = id_trap+аргументы+регистры+стек, потом делается реинит всей периферии и CPU с активацией только нужной для trap-режима. МК можно рестартовать или не рестартовать. Главное - отключить все работающие DMA и перевести все интерфейсы работающие с внешней периферией в дефолтное выключенное состояние (выключить питание моторов, отключить Ethernet, USB, CAN и т.п.). Если trap не программный, а вход в ловушку идёт из ISR HF или ISR MPU или ISR шинных ошибок или ошибок чётности памяти (и т.п.), которые сами являются по факту событиями ошибки, то симулируется как будто была получена SVC (повышение приоритета прерывания до максимума и т.д.), и содержимое регистров и стека берётся таким, каким оно было до входа в этот ISR (HF, MPU, ...) Чтобы причина trap указывала на причину, вызвавшую исходный ISR, а не на код внутри ISR. Также для HF декодируется причина fault-а (по соответствующим регистрам), и эта инфа передаётся как номер и аргументы trap(). Для таких ловушек у меня есть целый класс номеров: #define TRAP_EXC_HARD 0x100 //исключение Hard Fault (неуточнённое) #define TRAP_EXC_HARD_VECTTBL 0x101 //ошибка при попытке считать содержимое таблицы векторов прерываний #define TRAP_EXC_HARD_FORCED 0x102 //произошла эскалациЯ прерываниЯ до HardFault (исходный fault неизвестен) #define TRAP_EXC_MPU 0x110 //MEMORY MANAGER FAULT (неуточнённое) #define TRAP_EXC_MPU_IERR 0x111 //MM FAULT: нарушение прав доступа к коду #define TRAP_EXC_MPU_DERR 0x112 //MM FAULT: нарушение прав доступа к данным #define TRAP_EXC_MPU_MUSTKE 0x113 //MM FAULT: при выходе из обработчика прерываниЯ возникло порождённое прерывание MemFault #define TRAP_EXC_MPU_MSTKE 0x114 //MM FAULT: при входе в обработчик прерываниЯ возникло порождённое прерывание MemFault #define TRAP_EXC_MPU_LSPE 0x115 //MM FAULT: при отложенном сохранении состоЯниЯ FPU возникла ошибка #define TRAP_EXC_BUS 0x120 //BUS FAULT (неуточнённое) #define TRAP_EXC_BUS_IBUS 0x121 //BUS FAULT: ошибка при попытке выборки инструкции #define TRAP_EXC_BUS_PRECISE 0x122 //BUS FAULT: точнаЯ ошибка при обращении к данным #define TRAP_EXC_BUS_IMPRECISE 0x123 //BUS FAULT: неточнаЯ ошибка при обращении к данным #define TRAP_EXC_BUS_USTK 0x124 //BUS FAULT: при попытке выхода из обработчика прерываниЯ #define TRAP_EXC_BUS_STK 0x125 //BUS FAULT: при попытке входа в обработчик прерываниЯ #define TRAP_EXC_BUS_LSPE 0x126 //BUS FAULT: при отложенном сохранении состоЯниЯ FPU #define TRAP_EXC_USAGE 0x130 //USAGE FAULT (неуточнённое) #define TRAP_EXC_USAGE_DIV0 0x131 //USAGE FAULT: попытка делениЯ на 0 #define TRAP_EXC_USAGE_UNALIGN 0x132 //USAGE FAULT: попытка невыровненного доступа к памЯти #define TRAP_EXC_USAGE_NOCP 0x133 //USAGE FAULT: попытка доступа к отсутствующему или отключенному сопроцессору #define TRAP_EXC_USAGE_INVPC 0x134 //USAGE FAULT: ошибочное значение в EXC_RETURN #define TRAP_EXC_USAGE_INVSTAT 0x135 //USAGE FAULT: попытка выполнениЯ инструкции при неверном значении бита T или полЯ IT регистра EPSR #define TRAP_EXC_USAGE_UNDEF 0x136 //USAGE FAULT: попытка выполнить неизвестную или привилегированную инструкцию у некоторых ещё есть аргументы. Вообще типичное содержимое trap.h из текущего проекта: А зачем его воспроизводить? Адрес есть, значит можно встать на этот адрес и проанализировать, что там не так. А дальше действовать по обстоятельствам.
  3. Я вроде сразу в исходном посте ещё писал: Номер ловушки + набор аргументов (определяемый номером ловушки) как раз это и есть. Войду в режим ловушки. Аналог синего окна смерти винды. И функционал тот же - защёлкнуться в данном состоянии чтобы дать возможность пользователю найти причину. Ну т.е. - сделаете примерно то же самое, но только хуже (так как без предварительного реинита программы)? А почему тогда критикуете мой способ? Это не повисание. Это режим ловушки. Повиснуть - это значит молча и без какой-либо индикации войти в непонятное состояние устройства. Которое невозможно определить по внешним признакам. Вот это и есть повисание. А режим ловушки штатный и известный пользователям (на время отладки). Даёт возможность надёжно обнаружить ошибку (а не замести её под ковёр, перегрузившись) и дать возможность программисту устранить её. В вашем может ничего не говорил, а я по этому дампу неоднократно находил причину. Так как можно увидеть адрес, увидеть содержимое регистров. Этого чаще всего уже достаточно для нахождения причины. Не всегда конечно, но в большинстве случаев. Если следовать вашей логике, то непонятно зачем в отладчиках выводят содержимое регистров? или памяти, стека? Ведь там тоже - половина - мусор. Чтобы понять где мусор, а где полезные данные - на то у программиста есть голова. Вы бы исходный вопрос темы прочитали, что-ли. Где там про ваш цинк что-то написано?? Я предложил свой способ для решения вопроса ТС. Если вы с ним не согласны - предложите свой. Но к чему тут проблемы цинка (причём только определённые) - совсем не ясно. И всегда, для любого способа борьбы с багами, можно придумать такой сценарий, который не будет работать. Предложите свой способ, а мы придумаем кучу ситуаций, когда он не сработает.
  4. В периферии nuvoton-ов не разбираюсь. Но копал бы WDT. Обычно во всех WDT с которыми я работал, была возможность сброса при записи недопустимого значения в какие-либо регистры WDT. Думаю и в nuvoton должно быть что-то подобное.
  5. Вопрос был в том: Читали ли вообще что эта функция делает и как она работает? Прежде чем использовать её в ISR. И допустим ли её вызов из ISR? В результате - костылинг победил здравый смысл....
  6. Хорошо - предположим перед ней 100 байт линейного кода. Достаточно? Причём такого, что даже нигде к памяти не обращается (иначе скорей всего случился бы вылет по MPU или HF из-за обращения по недопустимым адресам) - что само по себе очень редкий случай. Получаем: 100/2^32 = ~2.3e-8 - вероятность попадания в такой регион при переходе по случайному адресу. С такой вероятностью можно считать это событие вообще невероятным. Да ладно? Предположим - работаете вы не один, а есть другие люди, тестирующие ваш девайс или работающие над проектом. В девайсе несколько десятков настроек + довольно богатый функционал. Далее к вам обращается тестировщик: вот тестировал вчера вечером девайс, вдруг он завис (или перегрузился; а скорее даже скажет: "Контроллер крутил мотор и вдруг мотор остановился (девайс - инвертор для PMSM-моторов" (так как тестировщик даже не заметил, что девайс просто молча перезагрузился)). Спрашиваете его: "Какую последовательность действий выполнял перед этим событием?" В ответ - "Не помню, много что делал, параллельно ещё меня отвлекали". Т.е. - воспроизвести баг вы не можете. А если ещё девайс - мощный мотор на стенде, в несколько сотен кВт, который на своём столе просто не запустите. Как собираетесь искать баг? А в моём случае я просто попрошу его показать содержимое ловушки. И с большой вероятностью сразу найду причину. Опять не соглашусь. Как раз в последнее время много приходится отлаживать девайсов "за тридевять земель". В 9-и случаев из 10-и благодяря системе ловушек, баг нахожу сразу, за несколько секунд. Большинство из таких багов: 1. Впаяли не тот чип (например - не ту SPI-флешку). Драйвер SPI-флешь при старте читает ID флешки и падает в ловушку. Или читает регистры защиты флешь - и также падает в ловушку из-за установленной защиты, которой не должно быть. Причина определяется сразу по дампу ловушки. 2. Непропай - опять ошибка инициализации какого-либо драйвера и падение в ловушку. Опять определяется сразу по дампу ловушки. 3. Подали не то питание или что-то не подключили или подключили неправильно - опять ловушка. И опять причина находится сразу. 4. Сильный перегрев платы - уходит частота генератора на плате - падаем в ловушку. Причина находится быстро. ... и таких багов - большинство. И реально ловушки помогают. Так как проверками у меня обложены все потенциально опасные места. Я не понимаю вашу логику. Вы пытаетесь доказать, что моя система ловушек не пригодна по отдельным, частным случаям, когда она бы не сработала. Это примерно то же самое, что говорить: "Вот я вчера шёл не заметил кочку и споткнулся, упал. Получается - глаза мне не помогли её увидеть. Значит глаза не нужны". Это если следовать вашей логике. Странная логика.... Ок - раскомментировали вы отладочный вывод. Время выполнения кода изменилось, а также изменилось распредление памяти - проявление бага пропало. И будете искать баг до морковкина заговения. Так что такой способ - так себе способ. Хорошо, я понял - вы почему-то против моего способа. Тогда предложите ваше решение. Вот случай (исходя из вопроса ТС): Вызываете сервис ОС, он возвращает вам ошибку (например какой-то ресурс недоступен). Ваши дествия? Повиснуть? Перегрузиться? Что будете делать. Я просто вызову trap(TRAP_OS, ...) (и по выводу сразу найду место бага). Но что будете делать вы? Или другой случай: У меня есть множество функций с assert-ами (проверками входных аргументов на входе). Если проверка не проходит - trap(TRAP_ASSERT, регион_assert-а, ...). И сразу вижу причину и место. Каково ваше решение в этом случае (без механизма ловушек)? Повиснуть? Перегрузиться?
  7. слабый линух + слабый прогер = гремучая смесь
  8. Вызываете sysprintf() из ISR? А что внутри неё - смотрели? Рассчитана ли она на такой вызов?
  9. Что-то странное рассказываете... При неконтролируемой передаче управления (например - вследствие разрушения стека) вероятность попасть в точку старта прошивки (это всего от 0 до нескольких байт после точки) - близка к вероятности выигрыша в лотерею суперприза. Просто достаточно посчитать - какова вероятность случайного выпадения заданного адреса в случайном 32-битном значении? "Разблокируется флешь" - вообще равно нулю. Так как в используемых мной сейчас XMC4xxx модифицировать внутреннюю флешь может только код, находящийся в ОЗУ. И копирует его туда бутлоадер после множества проверок и программирований MPU. Вероятность попасть в какой-то удачный адрес при неконтролируемой передаче управления - крайне мала. В 99% будет попадание в такое место, при котором будет сгенерирован HF (а соответственно - и последующий trap) или по недопустимой команде или по недопустимому обращению к памяти. Пишу это не от фонаря, а потому что использую это давно и много раз помогало. В том числе и при улётах неизвестно куда. Да, fault сработает не сразу, но по содержимому регистров CPU или дампов стеков как правило - можно быстро найти место начальной проблемы. Срабатывание сторожевика - это ещё один источник возбуждения trap(). И такой случай должен быть расследован программистом при отладке прошивки в обязательном порядке. Наличие внешнего WDT нисколько не мешает использовать и внутренний. Почти во всех проектах имею внешний WDT. И везде он у меня работает совместно с внутренним WDT.
  10. В смысле? Очевидно - при помощи отладчика. А как же ещё? Запускаю отладчик и смотрю что там происходит. ни чего не понял... Что за "файл прерывания" и какое он имеет отношение к ошибкам инициализации железа, и почему "операционка валится" куда-то? Из вопроса ТС видно, что речь не только о вызове сервисов ОС, но и об "инициализации железа". А значит - речь о всех критических ошибках вообще, а не только об ошибках использования сервисов РТОС.
  11. При возникновении критической ошибки (такой ошибки, выполнение программы после которой невозможно), все мои прошивки переходят в режим ловушки (trap): Запоминается номер trap, его аргументы, состояние регистров CPU и вершины текущего стека (это контекст trap); делается сброс всей периферии (возможно - с переключением CPU на более низкую частоту; а возможно и со сбросом всего устройства), инициализируется только минимально необходимый набор периферии (система тактирования, GPIO, MPU, WDT, отладочный UART, ...) и в отладочный UART начинается периодический вывод состояния ловушки (запомненного контекста) с индикацией режима ловушки через доступные средства индикации (лампочки и т.п.). Т.е. - реализую аналог "синего окна смерти" винды. Делаю примерно то же самое. В устройствах, где имеется FRAM, у меня также события критических ошибок (с контекстом) сохраняются в журнал критических ошибок (расположенный во FRAM). Но после предварительного сброса/рестарта CPU. В терминале вывод состояния ловушки выглядит так: По логу виден номер trap (3) + набор аргументов данного номера (в квадратных скобках) + регистры + вершина стека. PS: А почему вопрос в разделе "Операционные системы\FreeRTOS"? Обработка критических ошибок не имеет никакого отношения к ОС.
  12. Например тем, что если на любую цепь питания светодиодов где-то упадёт сетевой провод, то всё полученное с того провода прилетит в ваш управляющий контроллер. К чему вы должны быть готовы, разрабатывая его.
  13. Если задачи - независимы друг от друга, то критическая секция нужна. Потому как пишущая задача вполне может захотеть обновить данные до того, как предыдущие данные считаны читающей задачей. Так что = критическая секция (для сериализации доступа к данным) + какой-либо механизм нотификации (об обновлении данных) читающей задаче. Второе может быть как простым volatile-флажком, так и каким-то средством из арсенала ОС. А если предыдущие данные ещё не считаны, но пришли новые? Куда их девать? Вот для того и нужны критическая секция + нотификатор. Из контекста вопроса видно, что передаваемые данные - какие-то параметры, которые могут приходить в любое время, асинхронно работе системы. В том числе и прийти несколько раз подряд с коротким интервалом. Неправильный алгоритм. Сперва читающий процесс должен сбросить флажок-нотификатор, и только потом - считывать данные. Так как иначе он может сбросить флаг новых данных, даже не прочитав их. Это не так. Флажков в РТОС бывает много разных. И в любом случае всегда советовать весьма тяжёлый мьютекс - так себе совет. Мьютекс я бы советовал в самом последнем случае. PS: Если не нравится критическая секция или мьютекс (который весьма сложен внутри, намного сложнее критической секции, а потому требует много ресурсов от ОС; и применять его лишний раз в простых случаях - неоптимально), то есть множество других вариантов межзадачной синхронизации. Вместо критической секции (которая может запрещать все прерывания), можно останавливать шедулер ОС на время чтения/записи разделяемых данных (что является аналогом критической секции, но без помех работе прерываний). Кроме того - есть механизмы межзадачной синхронизации вне-РТОС функционала. Спин-блокировка например. Если у ТС процессор = Cortex-M, то для атомизации доступа к разделяемым данным можно использовать механизм эксклюзивного доступа. В случае, если объём передаваемых параметров небольшой (~десятки байт), то эксклюзивный доступ намного легче (по занимаемым ресурсам) чем мьютекс. И при этом совершенно не мешает работе прерываний. При выборе конкретного способа синхронизации в каждом конкретном случае, следует идти от простого к сложному: Сперва примерить самый простой способ. Если не подходит - переходим к более сложному, примеряем его. И так далее... Только так можно создавать оптимальные программы.
  14. Совершенно непонятно одно: зачем вообще нужен какой-то диммер, если управление осуществляет МК?? У вас нет программиста, способного написать нужный алгоритм управления ключами питания светодиодов?
  15. Точно также - анализируя сигналы шин. Я выше уже писал: КР580ВМ80 - это не МК, у него все шины торчат наружу. Можно легко детектировать моменты чтения команд из памяти и адреса, по которым они выполняются. И останавливать в нужный момент (HLD или RDY). Простой схемой из нескольких логических элементов. Также легко можно реализовать бряк по обращению к данным по какому-либо адресу. Смотреть регистры CPU или содержимое памяти конечно сложнее. Тут без программы не обойтись. Написать программу на каком-нибудь ARM-е, подключив его к шинам КР580ВМ80 и следить за потоком команд, эмулируя внутри ход выполнения программы. Тогда, при остановке на бряке, внутри ARM-а будет всё содержимое ОЗУ и регистров КР580ВМ80. Но вот просто остановить на каком-то адресе - достаточно простой схемки из нескольких логических элементов. PS: Когда-то в середине 90-хх, будучи студиоузом, я придумал и спаял RAM-диск (на 256КБ) для своего тогдашнего домашнего компа на КР580ВМ80. "Контроллер" этого диска был построен на всего 4 или 5 простых логических ИС (логика, триггеры, 8-разрядный регистр вроде был). Он был подключен к шинам КР580ВМ80, перехватывал команды, выбираемые процессором из ОЗУ и, обнаружив определённый код команды (один из неиспользуемых кодов команд), переключал обращение к штатному ОЗУ компа на обращение к моему диску. Таким образом, чтобы прочитать или записать байт на этот диск, нужно было выполнить любую команду с операндом M, перед которой поставить этот код неиспользуемой команды. Помню, что встроить этот контроллер в шину КР580ВМ80 было несложно. Даже для студента всего недолго знакомого с электроникой. Почти все нужные сигналы там уже были.
  16. Никаких "эмуляторов" никуда втыкать не надо. Я выше уже писал как можно сделать. Нужно только прочитать описание работы КР580ВМ80А. Обнаружить в описании сигналы HLD, RDY, HLDA, WAIT. Почитать как они работают. Далее можно с помощью этих сигналов останавливать CPU на нужном адресе памяти и с помощью них же шагать по командам. Т.е. - достаточно будем поднять пару ножек CPU (или перерезать пару дорожек), чтобы врезаться в эти цепи. Например здесь достаточно подробно описан КР580ВМ80А: https://elancev.narod.ru/texno/bm80/bm80.htm
  17. Я же вроде писал: См.выделенную часть цитаты. Перегруженная операция приведения типа как раз и должна заменить свойство чтения борланда. Клацаете настолько быстро, что даже вопрос, на который отвечаете, не успеваете полностью прочитать?
  18. Это только для самых узких полос нужно. 7.8кГц, 10.4кГц, ... На ~20.8кГц, ~31.25кГц уже вроде как и точности обычного кварца должно хватить. К тому же - неизвестно какой у вопрошающего требуемый температурный диапазон работы.
  19. Разве перегрузка операторов присваивания и приведения типа - не оно? Конечно запись их определения будет не такой компактной (может даже дополнительные типы данных придётся создать), но конечный результат вроде должен дать примерно то же самое.
  20. Конечно - сужать полосу. Сами же пишете. И при этом почему-то выбрали самые широкие полосы. Можно же вплоть до 7800Гц сужать. Чем уже полоса - тем более компактно сосредоточена энергия сигнала и меньше помех влетает в более узкую полосу. Соответственно - больше дальность.
  21. У КР580ИК80 все сигналы/шины торчат наружу. Память - тоже снаружи. Также имеются подробные описания диаграмм работы всех этих шин/сигналов. А значит вполне возможно взять любой МК, подключиться им к шинам/сигналам КР580ИК80 и написать программу на МК, которая будет анализировать передаваемые по шинам данные, выдавать управляющие сигналы (HALT и т.п.) на КР580ИК80. И реализовать все необходимые функции отладочного эмулятора: Просмотр содержимого регистров/памяти (по захваченным и сохранённым с шин данным), breakpoint-ы (анализируя адрес выбираемой из памяти команды и остановку в нужный момент) и т.д. Т.е. - сваять собственный J-Link для КР580ИК80. Если знакомый хоть немного умеет программировать микроконтроллеры (а он должен это уметь), то такое сделать несложно. Да даже на абдурине можно слепить. Если конечно овчинка стоит выделки.....
  22. Разве в тех мамонтах были какие-то отладочные интерфейсы? Насколько помню - там была возможность потактового исполнения с помощью сигнала HALT (или как-то так назывался). По-крайней мере были учебные стенды, которые позволяли пошагово выполнять программу. И можно захватывать передаваемое по шинам процессора. Но вот - как смотреть содержимое регистров процессора и ячеек ОЗУ? не ясно.... Имхо: ему наверное будет лучше воспользоваться каким-либо программным симулятором i8080.
  23. "Ошибки" никакой нет. Не несите чушь. Дальше то что??? Значит для вас STM - истина в последней инстанции. В том числе почему-то и в вопросах русскоязычной и англоязычной терминологии. Это странно. Но это ваше личное дело. Каждый сходит с ума по своему. Называю и впредь буду называть J-Link и St-link и т.п. - отладочными эмуляторами. Вопрос закрыт.
  24. А в чём ошибка то? которую нужно признать. Вот 2 ваших ложных высказывания, которые я опроверг конкретными фактами выше: И где именно вы признали свою ошибку? Чего-то не видно..... Может не будем переходить на личности? ok?
  25. Категорически не использую ни PL2303 ни CH340. Исключительно только CP21xx и FTDI. Может поэтому и не сталкиваюсь с проблемами с USB-UART?
×
×
  • Создать...