-
Постов
4 027 -
Зарегистрирован
-
Посещение
-
Победитель дней
3
AHTOXA стал победителем дня 18 января
AHTOXA имел наиболее популярный контент!
Репутация
14 ХорошийИнформация о AHTOXA
-
Звание
фанат дивана
- День рождения 04.09.1970
Информация
-
Город
Array
Посетители профиля
-
портирование проекта (IAR-STM32IDE)
AHTOXA ответил addi II тема в Программирование
На VL (value line) отдельный RM, RM041. Это сильно урезанные контроллеры, без USB, и с частотой до 24МГц (пишу по памяти) Это STM32F10X_MD. -
Я судил по изменениям в inline-ассемблере IAR-а. Сейчас он выглядит вот так: __attribute__((__always_inline__)) inline void set_interrupt_state(status_reg_t status) { asm volatile ( "MSR PRIMASK, %0\n" : : "r"(status) :"memory" ); } Ну то есть один-в-один gcc. Этож-ж-ж неспроста? 🙂 Короче, мысль моя вот в чём: в 90% случаев должно хватить простого reg; или, для большей понятности (void)reg; Но на всякий случай лучше проверить дизассемблер.
-
Жуть какая! 🙂 Интересно, с 2010 года хоть какие-то из компиляторов, которые отбрасывают чтение volatile-переменной поменяли своё мнение? (Подозреваю, что IAR поменял, он же теперь вроде бы на LLVM сделан).
-
microSD, скорость чтения упала
AHTOXA ответил Freibier тема в В помощь начинающему
Я думаю, это изменение скорости (минус 100Кб/с). -
Плавный переход C -> C++ под МК
AHTOXA ответил Arlleex тема в Программирование
Это стили кодирования пишут для групп программистов. Когда в одном проекте несколько человек. Когда пишешь один - вообще пофиг как именуешь и форматируешь. Главное чтоб тебе самому было понятно. Но даже для себя одного полезно сформулировать эти правила, чтобы потом их придерживаться. Это поможет потом поддерживать проект, когда нужно будет вернуться к нему через год-другой. Из этого тоже можно извлечь пользу: сразу видно, что идёт вызов библиотечного кода 🙂 -
Плавный переход C -> C++ под МК
AHTOXA ответил Arlleex тема в Программирование
Ну да, блоком. Или вынести этот кусок в inline-функцию. -
Плавный переход C -> C++ под МК
AHTOXA ответил Arlleex тема в Программирование
А они редакторе подсвечиваются по-разному. (Я использую Eclipse для embedded-проектов, QtCreator для ПК-проектов). Префиксы мне не нравятся. Нет гарантий, что префикс соответствует реальному типу. Сменил тип - забыл про префикс. Гораздо надёжнее не полагаться на префиксы, а использовать возможности современных IDE. Навёл мышку на название типа - получил всплывающую подсказку с кусочком объявления. Если там doxigen- комментарий перед типом, то и он отобразится. Единственное место, где я оставил префиксы - это переменные-члены класса. Они у меня называются m_var; Если интересно, вот рекомендации по кодированию одного из моих старых проектов. Вот, кстати, идеальное место для применения RAII. Создаётся тип CriticalSection, в конструкторе вызываются cpu_alloc_critical_section_context(csc) и cpu_entry_critical_section(csc), а в деструкторе - cpu_leave_critical_section(csc). Тогда функция будет выглядеть так: inline void init() { CriticalSection cs(csc); SPI3->CR1 = SPI_CR1_PRESET_VAL; SPI3->CR2 = SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN; SPI3->SR = 0x0; SPI3->CRCPR = 0x0; SPI3->I2SCFGR = 0x0; SPI3->I2SPR = 0x0; __DSB(); } Это немного короче, но главное - нет шанса забыть освободить критическую секцию. Даже если где-то посреди функции сделать return; -
Плавный переход C -> C++ под МК
AHTOXA ответил Arlleex тема в Программирование
Если поместить конструкцию using namespace в функцию, то область её действия заканчивается в конце функции: namespace Test { struct Foo { int flag }; } auto makeFoo() { using namespace Test; return Foo {1}; } int main() { auto foo = makeFoo(); // здесь не действует using namespace Test } А в целом, идеологически, все эти пространства имён для того и делались, чтобы виртуально "удлиннить" идентификаторы. Поэтому логично, что запись получается более многословной. Можно от этого огорчаться, можно пытаться сократить запись, а можно просто принять это, и использовать. Запись вида sGPIOCmdDesc descriptor = {sGPIOCmdDesc::GPIO_CTRL, sGPIOCmdDesc::SET_EN_DISPLAY}; не выглядит ужасной, зато сразу видно, что мы не перепутали enum-ы. А если вместо enum использовать enum class, то мы также можем быть уверены, что мы не перепутали местами аргументы. -
Это если он не нагружен. Если же нагружен, то при обесточивании он может остаться в том положении, в котором он был на момент обесточивания (типа, на 3/16 шага). В этом случае при возобновлении подачи питания он может сместиться в положение полного шага, которое ему даст драйвер при включении. Но даже в этом случае пара двигателей скорее всего сместится синхронно, потому что в момент обесточивания она с большой вероятностью была в одинаковом положении. У меня у 3D-принтера на оси Z такая конструкция - два мотора. Ничего вроде не перекашивается.
-
Плавный переход C -> C++ под МК
AHTOXA ответил Arlleex тема в Программирование
Это всё понятно. Но всё же, реальная-то память под эти элементы массива где-то выделена? То есть, по сути, мы "наводим" наш "безразмерный массив" на лежащий где-то реальный массив. Поэтому я предложил два варианта: либо вместо массива без указания размера указать его максимальный размер (да хоть стопиццот, нам без разницы, потому что реальная длина указана в структуре), либо использовать современный класс span, специально заточенный для таких целей (по сути это и есть указатель + длина). то есть или так: struct sUDPAckReadFIFOCAN1{ Header header; size_t frameSize; sCANFrame frame[100500]; }; или так: struct sUDPAckReadFIFOCAN1{ Header header; std::span<sCANFrame> frames; }; ЗЫ. Во втором случае, конечно не удастся просто привести указатель на буфер приёма/передачи к этой структуре. Это может быть как минусом, так и плюсом, в зависимости от обстоятельств. -
Плавный переход C -> C++ под МК
AHTOXA ответил Arlleex тема в Программирование
А зачем "псевдо"? Ведь данные всё равно лежат в реальном массиве. Его и используйте. Если есть несколько таких структур, различающихся только размерами массивов, можно приводить к максимальному. Ну или взять std::span из c++20. Хотя это не отменяет надобности в массиве для собственно хранения данных. -
Плавный переход C -> C++ под МК
AHTOXA ответил Arlleex тема в Программирование
Тут согласен, иногда хочется иметь какой-то базовый класс со значениями по умолчанию. В принципе, можно сделать вот так: struct CommandInfoTwoParam { struct Params { uint32_t param1; uint32_t param2; }; }; template <> struct CommandInfo<Command::SendData> : public CommandInfoTwoParam {}; Это почти идеально: лишнее дублирование (почти) отсутствует, но тем не менее каждая команда явно описана. -
Плавный переход C -> C++ под МК
AHTOXA ответил Arlleex тема в Программирование
То, что вы описали, почти всегда не нужно. А нужно - чёткое и консистентное описание протокола обмена. Можно составить документ, таблицу, типа код команды - структура параметров запроса - структура параметров ответа. И потом надеяться, что не забудешь внести в неё изменения при добавлении/изменении команды. А можно сделать самодокументирующийся код, как я описал выше. Там всё сразу в одном месте. И никак не получится при добавлении команды "забыть" добавить реализацию шаблона. Будет ошибка компиляции. Меня такой подход многократно выручал. Особенно он удобен, когда приходится возвращаться к проекту после длительного перерыва, и всё уже полностью выветрилось из головы. -
Плавный переход C -> C++ под МК
AHTOXA ответил Arlleex тема в Программирование
Я как раз и агитирую за отдельные структурки. Чтобы для каждой команды было чётко указано, какова структура параметров. Всё это можно вынести в один *.h - файл, и получить самодокументированный код. Кстати, и в этом подходе можно вынести одинаковые структуры "за скобки": struct OneParam { uint32_t param1; } template <> struct CommandInfo<Command::GetInfo> { using Params = OneParam; }; -
Плавный переход C -> C++ под МК
AHTOXA ответил Arlleex тема в Программирование
Почему "нет конечно". Конечно да:) Потому что потом, при необходимости изменить структуру sTxSendCAN не придётся искать все её псевдонимы и дорабатывать их. Лучше уж сразу для каждой команды прописать подходящую структуру. Можно использовать плюсовый механизм traits. Типа такого: // перечень всех команд enum Command : uint32_t { Reset = 0, GetInfo = 1, SendData = 2, }; // шаблон структуры, содержащей информацию о команде template<Command cmd> struct CommandInfo; // специализации шаблона для каждой команды (можно туда добавлять всё что угодно: тайм-аут обработки, структуры-параметры и так далее) template <> struct CommandInfo<Command::Reset> { struct Params {}; }; template <> struct CommandInfo<Command::GetInfo> { struct Params { uint32_t param1; }; }; template <> struct CommandInfo<Command::SendData> { struct Params { uint32_t param1; uint32_t param2; }; }; void send(...) { } // и вот как будет выглядеть выбор нужной структуры для заданной команды: void sendData() { using CommandData = CommandInfo<Command::SendData>; using Params = typename CommandData::Params; Params params; send(Command::SendData, ¶ms, sizeof(Params)); } При добавлении новой команды для неё сразу же создаём специализацию шаблона, содержащего инфу о команде. И далее оперируем этой информацией (на обоих концах протокола обмена).