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

Про произовдительность текущий нюанс например http://forum.easyelectronics.ru/viewtopic....f=7&t=17529

 

va_start/va_arg/va_end отвечают просто за перемещение указателя стека для выборки неявных параметров функции.

Никаких тормозов вызвать не могут. Быстродействие их может зависеть только от количества дополнительных параметров.

А ввод/вывод чисел с плавающей запятой действительно очень долгий. Ибо тогда в printf идет много делений и умножений.

В этом смысле библиотеки компиляторов по производительности различаются кардинально.

IAR для ARM-Cortex хороший выбор. У него самые быстрые библиотеки в целом и printf в частности.

 

Кстати странно, что такие вопросы возникают. Вы разве не используете профайлер в IAR с JTAG/SWD отладчиком?

 

А вот зачем вы там используете тулс под названием TunerStudio?

Какую пользу он вам приносит?

Это ведь просто визуализатор логов, никих алгоритмов, апроксимаций, интерполяций, а тем более моделей управления он не подсказывает, не так ли?

 

Да, и куда новый софт залили? Смотрю на http://sourceforge.net/projects/rusefi/fil...oad?source=pdlp. Там лежит все тот же проект. Ничего не изменилось.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Торможит chprintf - это имплементация из ChibiOS, в том топике есть ссылка - к стандартным либам отношения не имеет. И там замеряется конкретный вызов который печатает строки - так что %f тут явно не при чём :(

 

о! профайлер в IAR - не знал. буду смотреть и пробовать! как уже говорил, я обычно в Eclipse

 

TunerStudio чуть-чуть больше, чем визуализатор логов. Он во-первых показывает живые данные, а во-вторых позволяет менять настройки - карту топлива редактировать и так далее. Короче всё-таки полезно.

 

Изменения всё-таки в SVN - кототорый тоже на SF, http://svn.code.sf.net/p/rusefi/code/trunk/firmware/

Я сейчас в поле, мне тут не проверить head - так что новый tag делать не могу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Торможит chprintf - это имплементация из ChibiOS, в том топике есть ссылка - к стандартным либам отношения не имеет. И там замеряется конкретный вызов который печатает строки - так что %f тут явно не при чём :(

 

о! профайлер в IAR - не знал. буду смотреть и пробовать! как уже говорил, я обычно в Eclipse

 

TunerStudio чуть-чуть больше, чем визуализатор логов. Он во-первых показывает живые данные, а во-вторых позволяет менять настройки - карту топлива редактировать и так далее. Короче всё-таки полезно.

 

Изменения всё-таки в SVN - кототорый тоже на SF, http://svn.code.sf.net/p/rusefi/code/trunk/firmware/

Я сейчас в поле, мне тут не проверить head - так что новый tag делать не могу.

 

Да варнингов стало 29.

 

Но самые опасные, на мой взгляд, такие: Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement C:\Temp\RUSEFI\chibios\os\hal\platforms\STM32\OTGv1\usb_lld.c 606

Если тип volatile выбран не без оснований, то где во первых мьютексы (или что-либо другое для защиты), во вторых действительно такие переменные надо читать с особой осторожностью.

Последствия таких ошибок как правило сразу не проявляются. Могут вылезти когда кажется все уже отлажено.

 

Потом сообщения типа: Warning[Pe068]: integer conversion resulted in a change of sign C:\Temp\RUSEFI\console\status_loop.c 53

тоже очень плохие. Не следите за знаками? Присваиваете беззнаковому типу отрицательное значение?

 

Неужели GCC этих предупреждений не показывает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Будете смеяться - но да, совершенно осознанно присваивают беззнаковому отрицательное значение, потому что присвоить я хочу (MAX_VALUE - 1000) - и присваиваю его как раз как -1000. Так что именно тут всё в порядке.

 

Про volatile сейчас посмотрю, это сорцы rtos - но им можно написать.

 

Если мы хотим педантично от ворнингов избавиться - то нужно что-то делать с unreachable statement. Какие будут предложения?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если мы хотим педантично от ворнингов избавиться - то нужно что-то делать с unreachable statement. Какие будут предложения?

 

Убрать все эти return-ы.

А зачем они нужны если реально из циклов перед ними нету выхода?

 

Поток варнингов при компиляции замыливает глаз. Очень легко пропустить что-то серьезное.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спрятал эти return от IAR - потому что GCC они нужны. И да, у GCC нет ворнингов в этих местах и как-то выглядит, что у IAR с ворнингами ситуация круче.

 

Остались ворнинги, по которым надо думать - так что завёл тикет, чтоб не забыть: https://sourceforge.net/p/rusefi/tickets/39/

 

wdTtEgJ.png

 

Ну а чтоб не замыливался взгляд кстати в GCC есть другой инструмент - там некоторые ворнинги можно перевести в категорию ошибок, ошибку пропустить уже сложнее :)

 

Я думаю с ворнингами мы позитивно продвинулись вперёд, теперь можно читать сам код уже более высокого уровня? :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я думаю с ворнингами мы позитивно продвинулись вперёд, теперь можно читать сам код уже более высокого уровня? :)

 

Ну как понимаете, реверсить 18 тыс. строк кода не такая быстрая задача.

Но интереса ради посмотрел только начало.

 

Консоль сделана оригинально. Где подсмотрели идею регистрировать обработчики консоли динамически?

Только вот вопрос зачем?

У вас ведь не появятся новые обработчики пока работает одна и та же программа. (и загрузчика нет, ну может пока ;) )

Т.е. все обработчики и так ясны на этапе компиляции. Почему бы их было не собрать в одном массиве в одном месте?

 

А в результате что получилось:

Заметьте, что консоль это отдельная задача.

Самой задаче выделили 384 байт стека.

Стек очень маленький. И вот по всем исходникам там и тут начинаете динамически регистрировать обработчики (узнаю стиль линукса :wacko: ) .

Постепенно забывая где и какие обработчики зарегистрировали, насколько они сложны и сколько требуют стека.

В коментах к обработчикам нет никаких грозных предупреждений, что они работают в такой-то задаче с таким маленьким стеком.

Хуже того, забывая что эти обработчики в отдельной задаче вы не ставите мьютексы или семафоры или другую синхронизацию для защиты общих для задач переменных.

Спокойно читаете АЦП и проч. в консоли в то время как какая-то другая задача может туда писать.

Что еще трагично, RTOS chibios держит управляющую структуру задачи в том же стеке задачи.

Т.е. пропатчить RTOS и использовать встроенный в Cortex-M механизм защиты памяти скорее всего не получится .

Инверсия приоритетов хоть и кажется далекой абстракцией на самом деле при таких обработчиках встанет в полный рост.

А смешанный с управляющими структурами стек может привести к особо тяжелым сбоям.

 

Еще что интересно.

Разрабатываете как бы real-time систему, а _idle_thread пустой. Т.е. не следите за загруженностью процессора, хотя это единственный способ достоверно знать действительно ли вы работаете в реальном времени.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

о! очень хорошие вопросы :) постараюсь ответить на каждый по порядку:

 

регистрировать обработчики консоли динамически - идею взял в своей голове, так показалось элегантно: каждый файлик самодостаточен, у него наружу в магическое место не торчат описание обработчиков или названия команд. Да, на этапе компиляции всё известно - можно бы было явно определить стуктуру, но был бы ворох #if для опциональных модулей и так далее.

 

Добавил немного комментариев в https://svn.code.sf.net/p/rusefi/code/trunk...console_logic.c

Стек маленький - это относится не только к потоку консоли, это относится ко всем потокам rusEfi. Там везде программирование в таком стиле, чтоб стек особо не был нужен. Не знаю, хорошо это или плохо - это не догма, просто пока стек большего размера нигде не был нужен.

По поводу контроля стека - там есть

#define CH_DBG_ENABLE_STACK_CHECK TRUE

которая включает ChibiOS механиизм контроля. Как он сделан я не знаю, но я на практике видел, что он работает - и я его пока доверился.

 

У этой консоли все задачи очень простые по определению - какой-то параметр поменять, что-то отладочное вывыести. Хоть консоль и не критическое место, но обработчки пишутся осознанно очень простыми - в том числе за счёт этого и не особо нужна явная синхронизация. Например, типисный обработчик setRevolutionPeriod - да, там выставляются две переменные и выставляются они не атомарно. Но там и нет проблемы в этом особо - т.е. синхронизации мало, потому что мало мест где она нужна (update: зарефакторил этот обработчик - одна переменная и не нужна была в виде глобальной переменной, всё стало еще честнее)

Ил вот printFullAdcReport - да, там не атомарности вывода состояния всех АЦП каналов. Так она там и не нужна. А атомарность чтения каждой 32 битной переменной у нас надеюсь гарантирована 32битной архитектурой?

 

Тот же volatile - я более чем в курсе, кто он и зачем. Но такой вопрос - а в нашей конкретной реализации stm32f407 volatile вообще актуален? Там есть промежуточные кеши, которые могут у разных потоков разойтись внутри единсвенного ядра? Хотя даже без кешей volatile на порядок операций конечно может влиять. И в теории хочется код конечно правильный в общем, без конкретно stm32f407. Ну, я не бог - где-то приходится срезать углы и писать good enough код.

 

А можно про idle_thread и слежение за загруженностью поподробнее? Буду рад совету на эту тему.

Сейчас ситуация такая: основной код в обработчиках прерываний, а текущая ChibiOS собирает статистику только по потреблению CPU потоками. (см. команду ths и метод cmd_threads) в следующей ChibiOS обещают собирать статистику по прерываниям.

 

А пока у меня есть своя доморощенная https://svn.code.sf.net/p/rusefi/code/trunk...til/histogram.c в которую через hsAdd замеряются два самых важных обработчика.

(Блин, давно пора заставить себя переименовать main_loop в main_event_handler)

Изменено пользователем Андрей239

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

регистрировать обработчики консоли динамически - идею взял в своей голове, так показалось элегантно: каждый файлик самодостаточен, у него наружу в магическое место не торчат описание обработчиков или названия команд. Да, на этапе компиляции всё известно - можно бы было явно определить стуктуру, но был бы ворох #if для опциональных модулей и так далее.

 

Если посмотреть с другой стороны, то ваш подход модуле-центричен, а я бы придерживался потоко-центричной идеологии.

 

Ваша задача заставить приложение работать надежно и для этого вам нужно защитить потоки от разрушений.

Это легче сделать когда все процедуры потоков у вас в одном файле и не требуют бесконечных поисков по сорсам.

Второе вспомогательное средство это анализатор дерева вложений IAR-а.

Опять же из-за того что вы широко используете run-time инициализацию указателей на обработчики, у вас эта фича не работает.

Получается вы создали архитектуру котороая блокирует многие мощные инструменты анализа кода и исправления ошибок.

И это элегантность?

 

Вообще есть подозрение, что вы там уже запутались в своих обработчиках.

Можете опровергнуть мои подозрения и показать листинг запущенных задач и размеры занятых и свободных стековых пространств?

 

Иначе чем объяснить вот такое явление:

post-2050-1389338669_thumb.png

 

Это структура вызовов в обработчике вызываемом в прерывании. Как видно дело доходит до того что, обработчик критического прерывания вызывает print!!!

Это тот который у вас до сих пор необъяснимо медленно работает. Хотя все объяснимо. Там же дальше за put идет еще длинная цепочка слоя эмуляции COM порта через USB c вообще непредсказуемыми задержками.

И это явно. А неявно там еще callbacks есть, которые могут указавать на еще более монструозные цепочки, но они нам не видны.

 

Знаете, что ключевым моментов в системе непрерывного виброконтроля на Саяно-Шушенской ГЭС был интерфейс USB. И ее тогда так и не ввели в нормальную эксплуатацию. И все рвануло.

 

Обращение к драйверу USB и вообще к любым print из прерываний надо убрать категорически.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это структура вызовов в обработчике вызываемом в прерывании. Как видно дело доходит до того что, обработчик критического прерывания вызывает print!!!

Это тот который у вас до сих пор необъяснимо медленно работает. Хотя все объяснимо. Там же дальше за put идет еще длинная цепочка слоя эмуляции COM порта через USB c вообще непредсказуемыми задержками.

И это явно. А неявно там еще callbacks есть, которые могут указавать на еще более монструозные цепочки, но они нам не видны.

 

Знаете, что ключевым моментов в системе непрерывного виброконтроля на Саяно-Шушенской ГЭС был интерфейс USB. И ее тогда так и не ввели в нормальную эксплуатацию. И все рвануло.

 

Обращение к драйверу USB и вообще к любым print из прерываний надо убрать категорически.

Вы права, но есть нюансы - я не идиот :)

Обратите внимание - стек print включает в себя вызов метода chDbgPanic. Этот метод - это действительно panic, если он вызвался - то у нас проблемы посерьёзнее цепочки вызова put

 

А еще не путает котлету print с мухой printf, производительность которой у меня вызывает вопрос. Первая печатает в консоль, вторая - печатает в буффер памяти. Так что не всё так просто объяснимо :)

 

ths запущу, когда до дома доеду. А с потоками - всё-таки главное тут обработчик событий, к сожалению - не поток.

 

Предлагаю чуть-чуть снизить накал страстей, я надеюсь по моему коду видно, что школу я закончил уже давно. Я буду рад ответить на все вопросы, но пожалуйста не делайте поспешных выводов, как например с print, который внутри panic и котороый не printf :)

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы права, но есть нюансы - я не идиот :)

Обратите внимание - стек print включает в себя вызов метода chDbgPanic. Этот метод - это действительно panic, если он вызвался - то у нас проблемы посерьёзнее цепочки вызова put

 

А еще не путает котлету print с мухой printf, производительность которой у меня вызывает вопрос. Первая печатает в консоль, вторая - печатает в буффер памяти. Так что не всё так просто объяснимо :)

 

ths запущу, когда до дома доеду. А с потоками - всё-таки главное тут обработчик событий, к сожалению - не поток.

 

Предлагаю чуть-чуть снизить накал страстей, я надеюсь по моему коду видно, что школу я закончил уже давно. Я буду рад ответить на все вопросы, но пожалуйста не делайте поспешных выводов, как например с print, который внутри panic и котороый не printf :)

 

Не понял.

Не вы ли здесь жаловались на медлительность chvprintf?

А print ее как раз и вызывает.

Еще она вызывается в обработчиках через callbacks. Собственно прослеживая callbacks я на это место и вышел.

 

И что в вашем контексте хуже: мухи или котлеты ? :biggrin:

 

Честно говоря, я тоже использую форматированную печать в обработчиках исключений.

Но при этом пишу прямо в периферию фиксированного UART-а.

Никаких HAL, printf и прочих прослоек не использую . Шансов что все это будет живое после возникновения исключения почти никаких. Даже стек сразу переопределяю.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я потерял нить :(

 

Итак, было сомнение в работе с оборудованием из обработчика событий - тут прояснили, что проблемы нет, потом что вызов только из panic

 

Сомнение в использовании HAL из panic - UART великолепно отрабатывает, потому что HAL это просто цепочка вызовов в данном случае не взаимодействующая с ОС видимо. В случае USB консоли - да, panic сообщение теряется. Это бы хотелось однажны побороть - так что хорошая идея завести тикет: https://sourceforge.net/p/rusefi/tickets/40/

 

По поводу chprintf в обработчкике: я пока не вижу причин его не использовать. Да, сейчас там что-то не так с перфомансом - ну так нужно взять и разобраться, почему именно. Я не вижу оснований, почему бы он был обязательно должен быть тормозным, когда дойдут руки - либо пофиксим перфоманс, либо когда точно будет понятно, что его не пофиксить - отойдём от chprintf. Тикет https://sourceforge.net/p/rusefi/tickets/35/ есть - значит проблема не забутиться.

 

Надеюсь это снимаем сомнения по текущим вопросам. Если есть желание и возможность собсвенно какие-то из этих открытых тикетов продвинуть вперёд - это бы было просто супер :) Я могу подсказать, какой провод на какой замкнуть на дев-плате, чтоб она сама себя начала стимулировать синтетическим сигналом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я потерял нить :(

 

Я говорил, что поинтер callbacks в обработчике прерывания указавает на функцию которая тоже использует chvprintf.

chvprintf в свою очередь работает с блокирующим! вызовом put.

 

Кстати, зачем метод put надо было так хитро завертывать в макрос? (это не вам, а создателю chibios ;) )

Очень неприятно когда макросы мимикрируют под функции. Усложняет исследование сорсов значительно.

 

Использование блокирующих вызовов в прерываниях - грубейшее нарушение принципов RTOS.

 

Я не накаляю, просто субъективные замечания по вашим исходникам.

Понимаю сколько сил надо было чтобы разобраться в этой chibios.

 

У меня кардинальное предложение.

А почему бы вам пока ваш проект достаточно маленький не перейти на другую платформу?

Я имею в виду микроконтроллеры серии K7x, например K70P256M150SF3.

Модуль так и быть, я бы вам нарисовал.

Получили бы гораздо более мощную бесплатную RTOS - MQX. Там и поддержка серьезней.

С портирвание вашего алгоритма помог бы.

 

 

Микроконтроллеры Freescale семейства Kinetis имеют такую замечательную фичу как аппаратный настраиваемый фильтр входных цифровых сигналов.

Такие интерфейсы как I2C, SPI, UART часто могут уходить в ступор при наличии глитчей на линиях. А Kinetis их успешно фильтрует.

Незаменимая вещь в условиях сильных помех. Сегодня меня буквально выручил. ;)

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я говорил, что поинтер callbacks в обработчике прерывания указавает на функцию которая тоже использует chvprintf.

chvprintf в свою очередь работает с блокирующим! вызовом put.

 

Не совсем понимаю, давай(те) уточним.

 

Я вижу chvprintf которому передаются разные имплементации потоков вывода через chSequentialStreamPut. Мне кажется, что в обработчиках (кроме ситуации panic) передаётся неблокирующая имплементация

 

static msg_t put(void *ip, uint8_t B) {

MemoryStream *msp = ip;

 

if (msp->size - msp->eos <= 0)

return RDY_RESET;

*(msp->buffer + msp->eos) = b;

msp->eos += 1;

return RDY_OK;

}

 

Я здесь ничего страшного не вижу. Я где-то заблуждаюсь?

 

Как я уже несколько раз пытался сказать - в важных местах логгинг идёт через мой буффер в памяти

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня кардинальное предложение.

А почему бы вам пока ваш проект достаточно маленький не перейти на другую платформу?

Незаменимая вещь в условиях сильных помех. Сегодня меня буквально выручил. ;)

 

Таки, момент истины. я предлагаю плату с TI Integra. Там просто Linux, и вообще все круто)

 

Чтото уважаемый AlexandrY стал нагнетать...

 

Микроконтроллеры Freescale семейства Kinetis имеют такую замечательную фичу как аппаратный настраиваемый фильтр входных цифровых сигналов. Такие интерфейсы как I2C, SPI, UART часто могут уходить в ступор при наличии глитчей на линиях. А Kinetis их успешно фильтрует. Незаменимая вещь в условиях сильных помех. Сегодня меня буквально выручил. ;)

 

Я конечно не великий гуру программирования. Но не объясните ли мне плз, как ето UART может перейти в ступор ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...