AlexandrY 3 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба 2 hours ago, haker_fox said: Чтобы прийти к такому выводу вам наверняка понадобилось всё же исследовать код, созданный кодогенератором матлаба? А если в нём ошибка? Как отлаживать и править? Архитектура - это то как построена стэйт диаграмма. Для нее симулинк генерирует безошибочный код и самый быстрый для этой диаграммы, потому как он точно следует диаграмме. Программист на C++ такое же задание делал бы с привлечением избыточных классов и делегатов, они у них как узелки на память. Но слишком много узелков опять создают проблему обозримости. Но главное то что на диаграмме делается одним переносом мышкой блока на другой уровень в C++ делается ломкой интерфейсов и наследований, т.е по сути личной маленькой трагедией программера. Обсуждать возможные ошибки генерации кода симулинком не имеет смысла, как не имеет смысла обсуждать как вы защищаетесь от метеоритов. Т.е. события с крайне малой вероятностью не стоят внимания. Как отлаживать стэйт диаграммы (не путать с машинами состояний, это разные домены знаний) отдельная большая и увлекательная тема. Может создам ее позже. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 6 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба 3 минуты назад, AlexandrY сказал: отдельная большая и увлекательная тема. Не менее интересна тема что делать с контролем версий этих чрезвычайно удобных и понятных картинок-комиксов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба 31 minutes ago, alexunder said: Я понимаю, моя реплика была в поддержку Вашего комментария Это я понял, спасибо :) Quote Можно узнать детали Вашего тулчейна? Да все самый настоящий самопал. Из qt заимствована идея slot/signal, но на базе делегатов. Все началось с этих несчастных обработчиков прерываний - голых C-функций, заглушки на которые идут "комплектом" в startup.asm. Проблема в том, что в обработчиках нужно работать с конкретными объектами данных, т.е. приходится очень многое делать видим глобально. А это сильно нарушает структуру проекта и создает значительные трудности при его дальнейшем развитии. Короче, сделал, понравилось, обратно возвращаться уже нет как-то желания. По реализации: под каждое семейство процов есть свой Vectors.cpp (он же startup) создан массив делегатов в зависимости того, сколько обработчиков вообще есть в этом семейств (по максимому). Вот, например, как я реализую и использую обработчик прерываний, например, под таймер: // Некий модуль class xxxxx : public Module { .... private: // объявляем задачу (можно тут же создать ее экземпляр) class Thread : public OS::Thread<xxxxx_STACK_SIZE> { private: virtual void initialize(); virtual void body(); void handler(); private: OS::Semaphore semaphore; Hardware::TimerTIM2 timer; ... } thread; }; // настройка объектов задачи void ..... ::Thread::initialize() { .... auto vector = DELEGATE(&Thread::handler, this); timer.installVector(vector); timer.initialize(); timer.setOnePulseMode(); timer.setGranularityUs(1); // timer clock frequency = 1 MHz (1us granularity) .... } // Тело задачи void BacklightsLib::Thread::body() { semaphore.waitForever(); .... // реагируем на прерывание от таймера } // И собственно сам обработчик прерываний от таймера: void ... ::Thread::handler() { if (timer.irqUpdate.isPending()) { timer.irqUpdate.clearPending(); semaphore.signal(); } } Quote Как Вы используете Qt в эмбеде? Надеюсь, разработчики Qt выпустят наконец свое решение под baremetal. А пока колхозим свое )) 9 minutes ago, AlexandrY said: в C++ делается ломкой интерфейсов и наследований, т.е по сути личной маленькой трагедией программера. Не стоить судить по себе или своему возможно не очень удачному опыту Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nixon 4 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба 1 час назад, Forger сказал: Дык, у меня через делегаты реализованы аж прерывания (!) - некая таблица делегатов. Если в двух словах и грубо - это указатели на void(void) метод ЛЮБОГО класса, а не на обычную С-функцию, как "по-дефолту". Конечно, ходил по disasm, сравнивал оверхед, но криминала не обнаружил - компилятор свое дело знает Удобство применения и другие полезности с лихвой перевалили даже тот маленький оверхед, который в данном случае безусловно есть (добавляется несколько тактов на вход и выход из прерывания). Делаю так же. //// part of startup_xxx.cpp // delegates for IRQ handlers Delegate<void(void)> IRQ_NonMaskableInt = [](void){ while (1); }; // -14 Cortex-M3 Non Maskable Interrupt ... // IRQs handlers extern "C" __weak void NMI_Handler(void) { IRQ_NonMaskableInt(); } ... // Vectors table extern "C" const void * const __vector_table[] = { &CSTACK$$Limit, (void *) Reset_Handler, /* 1 - Reset (start instruction) */ (void *) NMI_Handler, /* 2 - NMI */ ... } Некоторый оверхед все же присутствует, поэтому оставлена возможность использования чистых "С" функций для обработчиков прерываний через __week. P.S. Это IAR, но по сути применимо везде Кстати, вместо while(1) для ARM при отладке лучше использовать __BKPT(0) из core_cmInstr.h - когда влетишь в неопределенное прерывание сразу видно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба 10 minutes ago, Forger said: Не стоить судить по себе или своему возможно не очень удачному опыту Эт не мой опыт, а стандартный путь в текстовой нотации. Ну хорошо не трагедия, а потеря времени раз в 10. 11 minutes ago, SSerge said: Не менее интересна тема что делать с контролем версий этих чрезвычайно удобных и понятных картинок-комиксов. Никто не делает проблему из контроля версий в Altium или другой EDA. Вот так и с Simulink, как нибудь привыкнут. Контроль версий не влияет напрямую на производительность программирования. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба 5 minutes ago, AlexandrY said: Эт не мой опыт, а стандартный путь в текстовой нотации. Ну хорошо не трагедия, а потеря времени раз в 10. Дык, так я и говорю - аминь! Ведь нет ничего плохого в том, чтобы рисовать, как тут уже выразились, "картинки-комиксы" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба У меня по сути используется таблица из делегатов, вызываемых каждый из своей статической функции. Вот так: static struct DummyClass { void vector() {} } dummyClass; static stm32f1::Interrupt::Vector __attribute__((used)) vectorTable[IRQ_VECTOR_TABLE_SIZE] = { DELEGATE(&DummyClass::vector, &dummyClass) }; Шаблон статической функции - аналог обработчиков из starup.s (они отличают для DEBUG и RELEASE версий): template<unsigned VECTOR> static void interruptHandler() { vectorTable[VECTOR](); } Ну и собственно сама таблица этих функций: static void (* const __vectors[])() __attribute__((section("RESET"))) __attribute__((used)) = { 0, // SP has to be setup into the "ResetHandler" ResetHandler, NMI_Handler, // NMI, HardFault_Handler, // HardFault 0, // Reserved 0, // Reserved 0, // Reserved 0, // Reserved 0, // Reserved 0, // Reserved 0, // Reserved SVC_Handler, // Keil RTX RTOS Vector 0, // Reserved 0, // Reserved PendSV_Handler, // Keil RTX RTOS Vector SysTick_Handler, // Keil RTX RTOS Vector interruptHandler<0>, interruptHandler<1>, interruptHandler<2>, interruptHandler<3>, .... interruptHandler<64>, interruptHandler<65>, interruptHandler<66>, interruptHandler<67> }; Такая схема позволяет подключать/отключать обработчики когда душе угодно. Правда, необходимость в отключении - все же сомнительна, я не использую ее. Quote Кстати, вместо while(1) для ARM при отладке лучше использовать __BKPT(0) из core_cmInstr.h - Полезный совет! Спасибо! У меня в DEBUG версии формируется соотв. сообщение (через RTT) перед входом в бесконечность. Quote когда влетишь в неопределенное прерывание сразу видно. У меня нету неопределенных прерываний, все по-умолчанию ведут в DummyClass::vector() {}, правда, он до сих пор у меня пустой ... непорядок! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nixon 4 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба Только что, Forger сказал: Полезный совет! Спасибо! У меня в DEBUG версии формируется соотв. сообщение (через RTT) перед входом в бесконечность. Только не забудьте проверять подключенный отладчик, а то... if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) { __BKPT(0); ... } 5 минут назад, Forger сказал: У меня нету неопределенных прерываний, все по-умолчанию ведут в DummyClass::vector() {}, Не неопределенные - лучше сказать неиспользуемые пользовательским софтом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба 7 минут назад, Forger сказал: Правда, необходимость в отключении - все же сомнительна, я не использую ее Тогда в чем смысл применения второй таблицы? Почему не вставить DELEGATE(&DummyClass::vector, &dummyClass) сразу в __vectors[]? И покажите определение DELEGATE(), а то мне пока непонятен смысл всей этой затеи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nixon 4 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба Вектора находятся стандартно во флеши. Чтобы динамически при создании компонентов можно было использовать функции-члены классов как обработчики прерываний и используется вторая таблица, которая находится в ОЗУ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 26 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба 28 minutes ago, Сергей Борщ said: Тогда в чем смысл применения второй таблицы? Почему не вставить DELEGATE(&DummyClass::vector, &dummyClass) сразу в __vectors[]? Nixon уже ответил исчерпывающе ) Quote И покажите определение DELEGATE(), а то мне пока непонятен смысл всей этой затеи. #define DELEGATE(foo, thisPrt) (makeDelegate(foo).bind<foo>(thisPrt)) template<typename T, typename RET, typename... PARAMS> DelegateMaker<T, RET, PARAMS... > makeDelegate(RET (T::*)(PARAMS...)) { return DelegateMaker<T, RET, PARAMS...>(); } Реализацию делегатов по C++11 честно стырил с просторов интернетов. Немного причесал, добавил "ловушку" против попытки вызова пустых делегатов (в версии DEBUG). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба Смотрю я на такой код, и как в универе на матане: "буквы буквы буквы... О, цифра!!!". Так и тут - где циферки? Где работа с железом? Эх, надо открыть книжку по C++, видимо, и зубрить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба 6 minutes ago, Arlleex said: Так и тут - где циферки? Где работа с железом? Эх, надо открыть книжку по C++, видимо, и зубрить. +1))) @Nixon, @Forger, недавно читал статейку о том, чтобы делать стартапы не на ассемблере, классически, а описывать прямов в *.cpp файлах. Тогда ещё подумал - странная идея. Сейчас уже начинаю менять своё мнение. А ещё пару недель назад я думал, что это невозможно, или, как миниму, не нужно. Спасибо вам за то, что добавили опыт и в мою, в том числе, копилку знаний! P.S. А тема, однако, славно развивается!))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nixon 4 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба Да стартап у нас и описан на C++. Вот вам для примера для EFM32LG. Сделать его для любого другого семейства - час делов. startup_efm32lg.cpp startup_efm32lg.hpp Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 14 января, 2019 Опубликовано 14 января, 2019 · Жалоба 1 hour ago, AlexandrY said: симулинк генерирует безошибочный код Кстати, а код этот читаемый? Если не секретный, можете дать хотя бы фрагмент для общего обозрения? 1 minute ago, Nixon said: Вот вам для примера Спасибо!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться