Обсуждаем контроллеры компании Atmel.
Ответить

Re: WinAvr в вопросах и ответах

Пт дек 13, 2024 14:22:52

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

Re: WinAvr в вопросах и ответах

Пт дек 13, 2024 14:29:21

Ну это же ваши проблемы.) А у меня свои. И не надо про верёвку, вроде как вы учитель.) Я, конечно, прислушиваюсь, но каждый сам находит что для себя оптимально.

Re: WinAvr в вопросах и ответах

Сб дек 14, 2024 23:49:23

ARV на самом деле у вас тоже есть чему поучиться. И я учусь. Но, у каждого свои недостатки. Или нет?

Re: WinAvr в вопросах и ответах

Вс дек 15, 2024 15:09:36

Это не тема форума

Добавлено after 5 hours 14 minutes 43 seconds:
Вспомнил, однако, когда мне пришлось делать динамическую индикацию в основном цикле...
Когда я делал собственную реализацию ScopeClock... из-за очень больших задержек на вход-выход от прерываний для этого пришлось отказаться, и весь векторный кадр пришлось рисовать в главном цикле при запрещенных прерываниях...

Re: WinAvr в вопросах и ответах

Вс дек 15, 2024 18:03:32

Ну если уже подходить к вопросу принципиально, то главный цикл может быть привязан к какому то "системному таймеру" и молотить строго через определенные интервалы времени. Тогда динамическую индикацию можно дергать и в основном цикле (при условии, что все подзадачи укладываются в период цикла)
Я встречала и противоположный подход - в основной программе только инициализация периферии. И все. А вся логика - в прерывании таймера.
В принципе, оба подхода имеют право на жизнь.
Но программа может стать сложночитаемой, когда одна большая простыня кода.

Re: WinAvr в вопросах и ответах

Пн дек 16, 2024 09:03:17

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

Именно так. Никаких простыней.)
Код:
  while (true) {
    while (!sys_tick());
    led();
   ...
}

Re: WinAvr в вопросах и ответах

Пн дек 16, 2024 09:54:25

Всё так, пока в главном цикле код линейный, либо пока из-за прерываний джиттер systick не станет неприемлемым

Re: WinAvr в вопросах и ответах

Пн дек 16, 2024 14:34:34

ARV, Если все задачи главного цикла выполняются заведомо быстрее периода систика, то джиттер будет в несколько тактов. Просто обновление дисплея нужно поставить в самом начале суперцикла. При частоте систика в 1-2-4 кГц - эти несколько тактов заметны не будут.
Но тогда нужно думать и дробить задачи. Так как даже запись в ЕЕПРОМ с блокирующим ожиданием флага готовности может все поломать.
Поэтому мой подход обычно - все тайминго-критичное ( динамическая индикация, отслеживание каких то периферийных процессов, критичных ко времени и т.д.; туда же обычно и кнопки уходят) - оно живет отдельно, в прерывании систика, со своими конечными автоматами, невидимыми из суперцикла. А в самом суперцикле - отслеживание флагов от периферии, а для вывода - заполнение видеопамяти.
Тогда можно себя не ограничивать в редких "долгоиграющих" задачах типа записи в ЕЕПРОМ.
Где то кто то писал (может даже и вы) - все медленное, отвечающее за работу с внешним миром - в основной программе, все критичное ко времени - на прерываниях. И взаимодействие с основным миром - через флаги.

OKF писал(а):Именно так. Никаких простыней.)
У меня так не получается )))
Поскольку любое состояние устройства - это как отдельный режим/подрежим.
И вся логика тут же дробится на кучку switch(mode) {}.... внутри суперцикла
Часть этих свичей уходят в функции....
Но в суперцикле у меня остается минимум два свича по режимам - один - это таймаут текущего режима и переход к следующему, второй - это загрузка/перезагрузка таймаута для текущего режима.
Спойлер
Код:
int main(void){
   init();
   modeType mode = mtInit;
   uint16_t modeTimeOut = TIMEOUT_INIT;
      
   
   while (1) {// super loop
      uint8_t ticks;
      do ticks = getSysClockInterval(); while(!ticks);
      
      //---------- переменные на один раз
      modeType newMode = mode;
      uint8_t reloadTimeOut = 0;
      
      //---------- exec peripherial


      
      //---------- Timeout
      if ( mode == newMode && modeTimeOut ) {
         modeTimeOut--;
         if ( !modeTimeOut) {
            switch (newMode) {
               case mtInit:
                  //newMode = mtShowTime;
                  break;
            } // switch newmode
         }   // if ( !modeTimeOut)
      }  // if modeTimeOut

      //---------- New or Reload timeout
      if (mode != newMode) reloadTimeOut = 1;
      
      if (reloadTimeOut) {
         switch (newMode) {
            case mtInit:
               modeTimeOut = 1;
               break;
         } // switch newmode
      }  //    if reloadTimeOut
      
      //---------- Mode change
      if (mode != newMode) {
         mode = newMode;
      }  // if (mode != newMode)
      
      
   } // while (1) - super loop

}
Зачастую еще в суперцикле живет обработчик нажатий на кнопки. Мне так удобнее.

Хотя в последнее время мне больше нравится концепция событий от периферии и от программных таймеров.
Тогда программа дробится на вагон мелких обработчиков событий.

Re: WinAvr в вопросах и ответах

Пн дек 16, 2024 15:52:05

Меня за фоновое выполнение динамической индикации агитировать не надо :))

Re: WinAvr в вопросах и ответах

Пн дек 16, 2024 17:57:54

:)
Не агитирую.
А аггрегирую знания и умные мысли.

Re: WinAvr в вопросах и ответах

Вт дек 17, 2024 10:16:13

Всё так, пока в главном цикле код линейный, либо пока из-за прерываний джиттер systick не станет неприемлемым

Код заведомо короче системного периода. Джиттера нет, потому что нет прерываний. И я не агитирую за индикацию в основном цикле, но зачастую так проще. Там же и кнопки и всё остальное. Конечно это для простых конструкций.
Да, и отладочный вывод на тот же индикатор почему не возможен? Это же быстро всё.

Re: WinAvr в вопросах и ответах

Вт дек 17, 2024 15:16:09

Я писал, что отладочный вывод невозможен для поиска причин зависания в главном цикле.

Re: WinAvr в вопросах и ответах

Вт дек 17, 2024 15:47:40

ОК. Всё решаемо). Индикатор можно выключать, а отлаживаться по UART, например.
Ладно, это уже так, болтовня.)

Re: WinAvr в вопросах и ответах

Ср янв 08, 2025 20:20:22

Кто-нибудь может сказать.
avr-gcc при работе с eeprom библиотечными функциями из eeprom.h (типа eeprom_update_byte() и т.п.) сам запрещает прерывания на время обновления? Что-то я задумался, посмотрел ассемблерный код и не могу сообразить, давно асмом не пользовался, а там все понамешано.... Вроде cli есть, а восстановление предыдущего состояния не вижу. Хотя программы всегда работали без вопросов.

Re: WinAvr в вопросах и ответах

Ср янв 08, 2025 20:26:03

ks0, обычно сначала куда то сохраняется SREG, потом CLI, потом защищенный блок и потом восстановление SREG - тогда вернется состояние запрета прерываний как было до входа в защищенный блок.
И вроде как eeprom_update_byte() не запрещает прерывания, там тупой блокирующий цикл ожидания готовности...
Ответить