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

    

Nixon

Админы
  • Публикаций

    2 807
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о Nixon

  • Звание
    Гуру
  • День рождения 29.04.1974

Контакты

  • Сайт
    http://

Информация

  • Город
    Киев

Посетители профиля

21 095 просмотров профиля
  1. Не поможет. Точнее поможет только в примитивных случаях.
  2. А я приведу. Несколько абстрактный пример, но sapienti sat struct FOO { int A; int B; }; struct BAR { const FOO* foo; const int sum; }; constexpr int sum (const FOO foo) { return foo.A + foo.B; } constexpr FOO foo1 {1,2}; constexpr FOO foo2 {2,4}; const BAR bar1 {&foo1, sum(foo1)}; const BAR bar2 {&foo2, sum(foo2)}; void main ( void ) { int X = bar1.sum + bar2.sum; while(1); } Чтоб было понятнее - скриншотик Или вы будет утверждать что никогда не возникало потребности выполнить кучу действий на этапе компиляции? P.S. Я кстати современный С++ и рассматриваю только в плане улучшения "препроцессинга".
  3. template <typename T, int aLDA> class MDA2 { enum : int { LDA = aLDA }; public: T *A; MDA2(T *aA) : { A=aA; }; T &operator()(int i1, int i2) { return A[i2+LDA*i1]; }; T *operator()(int i1) { return A+LDA*i1; }; }; Если вы конечно не используете экземпляр класса повторно с переинициализацией LDA Чой то я, там enum вообще не нужен - используйте параметр шаблона напрямую
  4. Да, вы правы. Универсальное решение в таком случае - дамп с последующим анализом. Жаль, хотелось бы немножко автоматизировать сей процесс
  5. Меня скорее всего спасает то, что функции имеющие assert довольно тяжелые, и потому они имеют только вариант завершения с POP. P.S. Особенность проблемы в том, что ошибка возникает ОЧЕНЬ редко, на объекте и оперативно просмотреть дамп нет возможности. Коррекция самой ошибки производится сбросом с последующим восстановлением переменных всех машин состояний. В принципе как бы и решена проблема. Но хотелось бы разобраться в чем ее истоки. Проект довольно большой, многоуровневый (писали его с полдесятка человек) и потому дамп нужно хранить очень большой, а места очень мало. Вот и хотелось обойтись только стеком вызовов.
  6. Да, спасибо, нашел такое. Добавил еще поиск такого способа выхода
  7. Была такая функция подсчета битов, я ее тупо скопипастил. А какая разница что считать - сохраненные регистры или восстановленные? Разве что искать вверх придется только команды коррекции стека и PUSH. Но их тоже может не быть. Я честно говоря надеялся, что существует что-то стандартное для раскрутки стека вызовов.
  8. Сохранить верхушку стека недостаточно. Функция FOO() в которой возник assert вызывается из многих мест, цепочка вызовов достаточно длинная, и нужно знать на каком именно этапе произошло формирование ошибочного набора параметров для FOO(). Кроме того место для логгирования сбоев ограничено. Но как вариант просто сохранять кадр стека (побольше) имеет место быть. В любом случае нужна ручная работа. По поводу возврата из функции не через POP - тоже верно, такое возможно, можно учесть и этот случай, но я в своем проекте такого не встречал (возможно это зависит от уровня оптимизации).
  9. Задача по обратной раскрутке стека вызовов у меня возникает регулярно. Понятно, что в режиме отладки за вас это делает отладчик, но часто нужно делать пост-анализ сбоев в рантайме. Ничего готового я не нашел, хотя возможно все лежит на поверхности. Сейчас я реализовал это через одно место (жутко процессоро- и компиляторо- зависисимо - IAR и Thumb-2). void assertSave ( void) { uint32_t sp; uint16_t * pc; uint32_t report[8]; uint32_t count; __ASM volatile ("mov %0, sp" : "=r" (sp) ); __ASM volatile ("mov %0, pc" : "=r" (pc) ); memset(report, 0, sizeof(report)); for (uint32_t i = 0; i < 8; i++) { while (1) { // check pc if (((uint32_t)pc < IFLASH_START_ADDRESS) || ((uint32_t)pc > IFLASH_END_ADDRESS)) break; // check sp if (((uint32_t)sp < IRAM_START_ADDRESS) || ((uint32_t)sp > IRAM_END_ADDRESS)) break; // find POP or POP.W if (((*pc & 0xFF00) == 0xBD00) || (*pc == 0xE8BD)) { // count = number of registers to be restored by POP command if (*pc == 0xE8BD) { count = (uint32_t)(*(pc + 1) & 0x1FFF); } else { count = (uint32_t)(*pc & 0x00FF); } count = count - ((count >> 1) & 0x55555555); count = (count & 0x33333333) + ((count >> 2) & 0x33333333); count = (((count + (count >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; // checking previous command is ADD SP,SP,XX if ((*(pc - 1) & 0xFF00) == 0xB000) { // count += size of the stack correction before POP count += (uint8_t)(*(pc - 1) & 0x00FF); } // getting stack frame of previous function sp += count << 2; // getting continue address of previous function pc = (uint16_t *)(*(uint32_t *)sp & 0xFFFFFFFE); sp += 4; // save address of CALLSTACK report[i] = (uint32_t)pc - 4; break; } pc += 1; } } // write to blackbox blackBoxWrite(report, sizeof(report)); } По сути я просматриваю от текущего PC до ближайшего возврата через POP или POP.W. По коррекции стека перед выходом определяю размер текущего фрейма стека с предположением что первым в стек компилятор кладет адрес возврата. Ну и дальше рекурсия. Возможно у кого-то есть более грамотное решение.
  10. Критерии совершенства в CubeMX?

    Да. Но это специфика очень большой компании с подразделениями по всему миру. Бамбук выполняет кроме сборки кучу дополнительной работы по фиксации релиза.
  11. Критерии совершенства в CubeMX?

    Все же такой подход видится мне несколько ограниченным. Не всё поведение объектов классов (шаблонных и обычных) стоит определять сугубо параметрами шаблонов или конструкторов. Все же поддержка, например, глобальных дефайнов типа NDEBUG иногда здорово облегчает жизнь (например в автоматических системах сборки типа Bamboo и т.п.).
  12. Подписи перетянулись из базы старого движка. В новом движке подписи разрешены для групп "Свой" и выше. Остальным подписи недоступны. Получается парадокс - подписи у вас есть, но редактировать их вы не можете. Разрешил подписи группе "Участник" с ограничением на количество строк и ссылок (по одной). Увидите слева под "Display Name" строку редактора подписи
  13. Использование __no_init

    Некоторые микроконтроллеры имеют домен ОЗУ, питаемый отдельно от Vbat.
  14. Критерии совершенства в CubeMX?

    Для этого вам нужно как минимум знать какой вектор используется и т.д. Я приведу другой пример. Микроконтроллер, 6 уартов. Шаблонный класс уарта, который в зависимости от параметров шаблона при создании экземпляра класса сам автоматически подключит в качестве обработчика прерывания по приему/передаче функцию данного класса, которая осуществляет прием, буферизацию, разбор пакетов и т.д. 2 @Forger - ответили одновременно
  15. Критерии совершенства в CubeMX?

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