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

Критерии совершенства в CubeMX?

2 часа назад, Arlleex сказал:

Более того: в некоторых микроконтроллерах размещение областей памяти может быть таким, что на 0-й адрес придется область ОЗУ и ничего не мешает разместить в этой области свои переменные. Например, в STM8S003 так.

Ничего страшного, максимум - потеря одного байта.

Гораздо хуже ситуация с указателями на члены структуры/класса. Вот тут да, могут быть проблемы.... Я даже сталкивался с таким в каком-то компиляторе (точно не помню), что компилятор, как только видел что в программе есть указатели на члены данной структуры, то добавлял лишний член в её начало. Неиспользуемый. Чтобы не было NULL-указателей на используемые.

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


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

1 час назад, mantech сказал:

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

У меня во всех проектах где есть Ethernet, то к нему приделано DMA. Обязательно.  :acute:

Портировал TCP-стеки (по ETHERNET) на МК 3-х разных вендоров: NXP, TI, Infineon - у всех эта периферия немного разная. В первый раз - сложно, потом всё проще и проще. На последний Infineon я уже потратил совсем немного времени. Потому что хоть периферия и разная, но это только внешне, по названиям регистров и расположением бит. А внутри у всех примерно одинаково. И когда один раз прошёл, дальше уже легко.

1 час назад, mantech сказал:

С УСБ тоже не все так однозначно, контроллеры разные бывают, особенно, если МК "осчастливит" программным УСБ контроллером, не EHCI и пр. то тоже не так все просто.. Хотя, это сугубо ИМХО, может для кого это и как дважды два :dirol:

Тоже тут справедлива поговорка "Глаза - боятся, руки - делают". Когда первый раз перетаскивал USB-стек на OMAP-L137, для которого не было вообще открытых примеров, было страшно при взгляде на число регистров. Но потом засел за мануалы, разобрался, и после этого казалось - дай в руки любой МК, за пару дней портирую и на него. :bb:

С тех пор конечно многое подзабылось, но так как дважды проходил этот путь успешно, то и ещё раз пройду.

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


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

2 hours ago, Arlleex said:

Вот о чем это может сказать? Ровно почти ни о чем.

Ну хипер при отсутствии обычно возращает нуль! Даже new можно об этом попросить. Как-бы формальная проверка, с которой просто чуть чуть спокойнее.

 

2 hours ago, scifi said:

Я думаю, все будут только благодарны.

Нет, пока не чувствую в себе для этого силы и желания. Но я не критиковал lwIP. Подтекст в моей речи был другой)

2 hours ago, one_eight_seven said:

Ну так линты предупреждают о потенциально опасном синтаксисе или семантике, а не о том, что код написан неверно.

Согласен. Если выполнять все рекомендации анализатора, то и код не всегда будет работать. Но иногда анализатор просто выдаёт ошибочные замечания, cppcheck не всегда уверенно работает со статическими переменными, объявленными внутри функций. Он просто не понимает, что у них есть "память".

2 hours ago, one_eight_seven said:

который - да, вряд ли есть смысл проверять на NULL

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

1 hour ago, mantech said:

а если приделывать ДМА

Гм, LPC2478/4337 не требуют этого. У них свой дма в маке, и его настройка (не помню точно) не требуется. Ну или минимально. С другими МК сеть не поднимал.

3 minutes ago, jcxz said:

Когда первый раз перетаскивал USB-стек

Не подскажите где взять?))) Или самописный?

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


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

29 минут назад, haker_fox сказал:
31 минуту назад, jcxz сказал:

Когда первый раз перетаскивал USB-стек

Не подскажите где взять?))) Или самописный?

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

Изменено пользователем mantech

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


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

40 минут назад, haker_fox сказал:

Не подскажите где взять?))) Или самописный?

Так в примерах IAR для LPC-шек есть. Я оттуда брал. Небольшой и вроде как нормально структурированный.

12 минут назад, mantech сказал:

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

Я взял из примеров IAR для LPC. Но затем так его переписал, что он практически стал самописным.  :wink:

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


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

6 minutes ago, jcxz said:

Я взял из примеров IAR для LPC

Понятно, т.е. вы его рекомендуете, как более-менее адекватный)

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


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

5 часов назад, haker_fox сказал:

Насколько я знаю, вы используете uc/OS-II. Её переделываете? Кстати, немного офф, но всё же... как эта оська в работе? Почему не свободная FreeRTOS, TNKernel, nuttx, mbed OS? Сертификаты важны?

Я полностью переписал её порт для CM4F. Во-первых: оптимизировал по скорости; во-вторых: переделал формат сохранения контекста задач так, что теперь и в задачах ОС и в ISR-ах можно использовать FPU без каких-либо ограничений и при этом размер сохранения контекста определяется в run-time (задачи которые не используют FPU едят меньше стека под контекст). Ранее в uCOS-II нужно было тем задачам, которые используют FPU, ставить флажок в свойствах при запуске, и после этого контекст FPU сохранялся, но сохранялся всегда и программно, вне зависимости о фактического использования. Почему-то они не сделали работу по флагу FPCA в FPU. Я переделал порт под использование этого флага.

Самое интересное, что уже после того как я переписал порт, я скачал последние версии uCOS-II и увидел там в комментах, что они в последних версиях тоже изменили формат сохранения контекста, и он у них стал точно такой же как у меня:wink:  Правда почему-то в этих последних версиях у них в комплект включён порт CM4F ещё для старого формата контекста (не соответствующий последним версиям ОС). Видимо забыли обновить. Так что не могу по коду сравнить - насколько похож мой порт на их.

Работает uCOS-II хорошо, никаких проблем. Но я её использую по-минимуму - никаких расширений, только ядро, да и из ядра использую только: запуск задач, изменение их приоритета, мэйлбоксы и семафоры. Этого мне хватает.

Когда (и если) будет нужно начальство сказало - купим её. А если будет слишком дорого - просто перепишу её да и всё.  :wink:

FreeRTOS я смотрел, но она мне показалась слишком тяжёлой по сравнению с uCOS-II. Не нужно тяжёлой. Да и всякие странности типа выделения стеков только в дин.памяти - я считаю это неадекватным поведением (знаю что в последних версиях можно задавать статически, но они ещё тяжелее стали). Смотрел также uCOS-III, но также - её (имхо) необоснованно и ненужно утяжелили. Одни только вызовы сервисов ОС чего стоят.

Цитата

Мне тоже так кажется. В целом MAC (на все не претендую, только LPC2478, LPC4337), условно конечно, не сложнее обычного UART. По-крайней мере задачи, которые они решают, отдалённо похоже.

Вот именно. После того как сконфигурили физику, остаётся только обслуживать прерывания да следить за очередями DMA. А это всё вместе (вместе с конфигурением физики), т.е. - вся работа с портами IO - у меня это всего один cpp-файл, объём которого составляет примерно 6% от объёма только сетевой части проекта.

Ну иногда нужно ещё со временем поработать если нужен IEEE 1588.

Цитата

Вот USB Device, с которым мне предстоит разобраться - это что-то. Хотя, возможно на первый взгляд. Я даже беру смелость попытаться сам написать стек USB Device CDC. Но это пока. Может быть чихну, и поищу что-то готовое...

Когда разберётесь, то поймёте, что "не так страшен чёрт как его малюют"  :wink:

24 минуты назад, haker_fox сказал:

Понятно, т.е. вы его рекомендуете, как более-менее адекватный)

Да. Но правда я в нём использовал или только само ядро (работу по эндпоинтам) или CDC. Больше ничего не использовал. И только Device. Т.е. - брал его из тех примеров, где только Device используется (вроде пример про виртуальный COM-порт).

Там у них удобно, что вся работа с периферией (насколько помню) вынесена в один файл. А всё остальное (middleware) - отделено от портов IO.

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


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

1 час назад, haker_fox сказал:

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

Это нормально. Но, имхо - лучше такую проверку сделать отключаемой. Типа:

#undef assert
#ifdef ASSERT
#define assert(test, extend) if (!(test)) trap(TRAP_ASSERT, (extend));
#else
#define assert(test, extend)
#endif
  
void DflashWrite16(u32 addr, u32 len, void const *data, uint pipe)
{
  assert(data && !(addr & 1), TRAPR_DFLASH);
...

И #define ASSERT - в глобальный .h.

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


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

2 часа назад, serglg сказал:

Я даже и браться не стал за  USB host

Поднимал недавно USB host (CDC, VCP) на STM32. Оказалось даже проще, чем device. Смотрел и в исходники куба и в "библиотеки из интернета". Везде находил ошибки. 

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


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

15 hours ago, jcxz said:

И #define ASSERT - в глобальный .h.

Поздравляю. Вы изобрели NDEBUG и assert() из <assert.h>. Больше велосипедов, хороших и разных :acute:

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


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

35 minutes ago, scifi said:

Поздравляю. Вы изобрели NDEBUG и assert() из <assert.h>. Больше велосипедов, хороших и разных :acute:

А "стандартный" ассерт позволит ошибку бросить не только в консоль, но и в журнал (на память), выполнить ещё какие-либо действия? Мой - может. И даже если прибор сбойнул на объекте, просмотр лога спасает.

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


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

22 часа назад, jcxz сказал:

Если USB-стек писать неохота - можно взять готовый.

Не спора ради, а какой готовый юсб стек независимый от переферии порекомендуете?

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


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

2 minutes ago, Kabdim said:

Не спора ради, а какой готовый юсб стек независимый от переферии порекомендуете?

Я уже задавал этот вопрос) Ответ был "из IAR" примеров.

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


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

Да, дочитал уже до того места. :) Вопрос писал читая вторую страницу. Дернулся удалить - пост уже не последний.

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


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

А у меня немножко по-другому

// stm8s003_nvm.c

...
#include "settings.h"

#if(COMPILATION_MODE__STM8S003_NVM_C == DEBUG)
  #define assert(x) if(x)
  #define trap(x)   else x
#elif(COMPILATION_MODE__STM8S003_NVM_C == RELEASE)
  #define assert(x)
  #define trap(x)
#endif

u8 nvm_WriteByteProgramMemory(const u16 ByteNumber, const u8 Byte, const u8 FixedTimeOperation)
{
  u8 ErrorCode = 0;
  
  assert(ByteNumber < NVM_PROGRAM_MEMORY_SIZE)
  {
    if(ByteNumber >= OB->UBCSR * NVM_PAGE_MEMORY_SIZE)
    {
      u8 *const PNVM = (u8 *)(PNVM_START_ADDRESS + ByteNumber);
      
      if(*PNVM != Byte)
      {
        NVM->PUKR = NVM_PUKR_UNLOCK_KEY1;
        NVM->PUKR = NVM_PUKR_UNLOCK_KEY2;
        
        if(bitset(NVM->SR, NVM_SR_PNVMUNLOCKED))
        {
          if(FixedTimeOperation)
            setbit(NVM->CR1, NVM_CR1_FIXBYTEPROGTIME);
          else
            resetbit(NVM->CR1, NVM_CR1_FIXBYTEPROGTIME);
          
          *PNVM = Byte;
          
          const u8 Status = NVM->SR;
          if(bitset(Status, NVM_SR_PROGPROTPAGE))
            ErrorCode = 4;
          else if(bitreset(Status, NVM_SR_ENDPROG))
            ErrorCode = 5;
          
          resetbit(NVM->SR,  NVM_SR_PNVMUNLOCKED);
          resetbit(NVM->CR1, NVM_CR1_FIXBYTEPROGTIME);
          
          if(ErrorCode == 0 && *PNVM != Byte)
            ErrorCode = 6;
        }
        else
          ErrorCode = 3;
      }
    }
    else
      ErrorCode = 2;
  }
  trap(ErrorCode = 1);
  
  return ErrorCode;
}

...

 

В settings.h определяю режим сборки для каждого модуля (файла) проекта.

В коде для входных параметров функции вызываю assert(), и назначаю ему соответствующий обработчик-ловушку trap().

В режиме DEBUG компиляции файла входной параметр будет проверяться. Таким образом, механизм assert-ов будет работать.

В режиме RELEASE компиляции файла входной параметр не будет проверяться, и из кода выкинется обработчик trap().

Аргументы проверяю по ходу выполнения программы, причем условие построено так, чтобы в большинстве случаев (в лучших случаях) мы попадали в тело условия, а не в его else. Связано это с внутренним чувством перфекто:biggrin: Так, мне кажется, DEBUG-сборка максимально ближе по итоговому коду и алгоритму к RELEASE.

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


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

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

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

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

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

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

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

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

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

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