Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Re: Самопроизвольное изменение значения переменной

Пт мар 24, 2023 13:05:50

извините, но не вижу причины для споров.
после Вашего замечания я сделал оговорку, о том что моя фраза была по отношению к таймеру и не является призывом всегда глушить SR по любому поводу.
так же, не знаю какие еще события ждать от таймера после TIM_SR_UIF и на нем уже идет новый период и будет нужно "место" для новых событий.
в чем я вру?
наверно, я пишу маловато букавов, поэтому бываю понят неверно.

Re: Самопроизвольное изменение значения переменной

Пт мар 24, 2023 13:43:01

Нет, в таких случаях нужно явно читать весь пакет флагов в переменную, сразу сбрасывать все флаги

Это с какого перепуга?
Чем побитная обработка отличается от сохранения всего регистра флагов? Только не надо общих слов типа:
Потому как периферия в большинстве случаев живёт своей жизнью, и тактируется автономно. Пока чего-то там делаешь с одним флагом - срабатывают ещё несколько, после чего всё падает.

Что нибудь конкретное, что генерирует риски для целостности обработки. Работа с одним флагом НИКАК не влияет на остальные флаги. Влиять может только зазор между условием и сбросом. Для ОДНОГО флага это вообще непринципиально. Ибо события (тем более таймерные) генерирующие один тип флага не могут следовать с таким маленьким интервалом. В отличии от событий по разным флагам.

Re: Самопроизвольное изменение значения переменной

Пт мар 24, 2023 14:21:00

моя фраза была по отношению к таймеру и не является призывом всегда глушить SR по любому поводу

А мой призыв "глушить рыбу" - относится к разбору флагов больше одного. Когда флаги реально обрабатываются, а не просто висит условие от стандартного обработчика с пустыми скобками, с титрами от ST - "здесь ваш код".
Общий смысл очень простой: ожидаем один тип флага - значит всё остальное можно игнорировать.

КРАМ писал(а):Чем побитная обработка отличается от сохранения всего регистра флагов?

Вот именно этими общими словами и описывается ситуация - периферия живёт своей жизнью. Например прерывание от i2c датчика с собственным кварцем - обязано использовать цикл сохранения/сброса флагов. Иначе зависания гарантированы.

Re: Самопроизвольное изменение значения переменной

Пт мар 24, 2023 14:58:46

периферия живёт своей жизнью. Например прерывание от i2c датчика с собственным кварцем

И что? Назовите КОНКРЕТНЫЙ РИСК. Что может сработать в ИИЦ так, чтобы возник конфликт флагов? Вы тут чего то фантазируете изрядно. Конфликт флагов может возникнуть на СКОРОСТНОМ интерфейсе, когда установка двух РАЗНЫХ флагов этого интерфейса происходит (может происходить) с интервалом, который способен уместиться между условием и сбросом семафора обработчика. И всё. Никаких других "своей жизнью живет" там быть не может. Что касается самих событий, которые генерируют ЛЮБЫЕ ФЛАГИ прерываний, то они асинхронно работать не умеют ПО ОПРЕДЕЛЕНИЮ. То есть все эти внешние события ПРЕЖДЕ ВСЕГО проходят синхронизацию с тиками ядра и тогда NVIC им скажет "велкам".
Как то так, уважаемый.
Общий смысл очень простой: ожидаем один тип флага - значит всё остальное можно игнорировать.

Это очень прикольное условие... :)))
С чего бы мне чего то ожидать? Например, имеется ДВА ОЖИДАЕМЫХ В РАВНОЙ СТЕПЕНИ флага таймера. Флаг захвата и флаг апдейта. Они легко и непринужденно могут быть сгенерированы так, что один из них попадет между проверкой флага и сбросом флага. Если я работаю побитно, то позднее событие будет неизбежно обработано. Патамушта флаг его остается поднятым.

Re: Самопроизвольное изменение значения переменной

Пт мар 24, 2023 15:27:45

Никаких других "своей жизнью живет" там быть не может.

Ок, у вас два флага - обновление счётчика и сравнение. Первым у вас обрабатывается флаг обновления, вот прям сравнивается условие флага и выполняется код...
Вот тогда вам реально жизненно необходимо сбрасывать каждый флаг отдельно.
Но я на такое не подписывался.

Re: Самопроизвольное изменение значения переменной

Пт мар 24, 2023 15:34:56

Но я на такое не подписывался.

А не надо ни на что подписываться. Раздельная обработка флагов АВТОМАТИЧЕСКИ подпишет вас на все возможные комбинации. И код будет независимым для каждого флага. Словно это разные обработчики.
Код:
void TIM3_IRQHandler(void)
{
if ((TIM3->DIER&TIM_DIER_UIE)&&(TIM3->SR&TIM_SR_UIF))   // timeout 50 Hz
   {
      TIM3->SR = ~TIM_SR_UIF;

        // bla...bla...bla...

   }
if ((TIM3->DIER&TIM_DIER_CC1IE)&&(TIM3->SR&TIM_SR_CC1IF)) // capture 50 Hz
   {
      TIM3->SR = ~TIM_SR_CC1IF;

        // bla...bla...bla...

   }
   
}

Re: Самопроизвольное изменение значения переменной

Ср апр 05, 2023 18:49:54

Непонятно о чём спор. Работа с битами в Си
Код:
     var |= BIT;   // Установить бит
     var &= ~BIT;  // Сбросить бит
     var ^= BIT;   // Инвертировать бит
Всегда так было с момента появления Си. И так будет всегда, пока существует Си. Или нет?

Re: Самопроизвольное изменение значения переменной

Ср апр 05, 2023 20:05:45

Или нет?
Если речь про ARM-контроллеры, то нет. В RM на многие регистры периферии указан особый доступ, например, rc_w0, rc_w1, которые подразумевают атомарную запись для изменения состояния битов.

Re: Самопроизвольное изменение значения переменной

Чт апр 06, 2023 04:59:29

Или нет?
Если речь про ARM-контроллеры, то нет. В RM на многие регистры периферии указан особый доступ, например, rc_w0, rc_w1, которые подразумевают атомарную запись для изменения состояния битов.

Речь идёт о работе с битами в Си. Когда Си появился, про ARMы никто и слыхом не слыхивал. Поэтому, не вижу ничего криминального в том, чтобы для сброса определённого бита воспользоваться стандартным оператором Си. А то, что есть в ARM возможности атомарного доступа к регистрам, замечательно. Если знаете, как ими пользоваться, так и пользуйтесь на здоровье.

Re: Самопроизвольное изменение значения переменной

Чт апр 06, 2023 05:28:59

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

Re: Самопроизвольное изменение значения переменной

Чт апр 06, 2023 09:23:29

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

И какие "нестандартные" операторы Си в таких случаях нужно использовать?

Re: Самопроизвольное изменение значения переменной

Чт апр 06, 2023 10:28:11

Да операторы-то стандартные, просто использовать их надо очень аккуратно. Самый упоротый пример организации доступа, который я видел - регистры статуса конечных точек в stm32f103, называются EPnR: часть битов сбрасывается записью нуля, часть инвертируется записью единицы, часть просто read-only, а часть обычные. В результате работа с ними выглядит примерно так:
Код:
#define USB_EPx(num) (((volatile uint16_t*)USB)[(num)*2])

#define ENDP_STAT_RX(num, stat) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_RX | USB_EP_DTOG_TX | USB_EPTX_STAT)) | USB_EP_CTR_RX | USB_EP_CTR_TX) ^ stat; }while(0)
#define ENDP_STAT_TX(num, stat) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_RX | USB_EP_DTOG_TX | USB_EPRX_STAT)) | USB_EP_CTR_RX | USB_EP_CTR_TX) ^ stat; }while(0)
#define ENDP_DTOG_RX(num, dtog) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_TX | USB_EPRX_STAT | USB_EPTX_STAT)) | USB_EP_CTR_RX | USB_EP_CTR_TX) ^ dtog; }while(0)
#define ENDP_DTOG_TX(num, dtog) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_RX | USB_EPRX_STAT | USB_EPTX_STAT)) | USB_EP_CTR_RX | USB_EP_CTR_TX) ^ dtog; }while(0)
#define ENDP_CTR_RX_CLR(num) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_RX | USB_EP_DTOG_TX | USB_EPRX_STAT | USB_EPTX_STAT | USB_EP_CTR_RX)) | USB_EP_CTR_TX); }while(0)
#define ENDP_CTR_TX_CLR(num) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_RX | USB_EP_DTOG_TX | USB_EPRX_STAT | USB_EPTX_STAT | USB_EP_CTR_TX)) | USB_EP_CTR_RX); }while(0)

#define ENDP_TOG(num, tog) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_RX | USB_EP_DTOG_TX | USB_EPRX_STAT | USB_EPTX_STAT)) | USB_EP_CTR_RX | USB_EP_CTR_TX) | tog; }while(0)

Re: Самопроизвольное изменение значения переменной

Чт апр 06, 2023 10:41:49

Самый упоротый пример организации доступа, который я видел - регистры статуса конечных точек в stm32f103, называются EPnR: часть битов сбрасывается записью нуля, часть инвертируется записью единицы, часть просто read-only, а часть обычные.
Ох, вьетнамские флешбэки.

Re: Самопроизвольное изменение значения переменной

Чт апр 06, 2023 10:43:04

Да операторы-то стандартные, просто использовать их надо очень аккуратно. Самый упоротый пример организации доступа, который я видел - регистры статуса конечных точек в stm32f103, называются EPnR: часть битов сбрасывается записью нуля, часть инвертируется записью единицы, часть просто read-only, а часть обычные. В результате работа с ними выглядит примерно так:
Код:
#define USB_EPx(num) (((volatile uint16_t*)USB)[(num)*2])

#define ENDP_STAT_RX(num, stat) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_RX | USB_EP_DTOG_TX | USB_EPTX_STAT)) | USB_EP_CTR_RX | USB_EP_CTR_TX) ^ stat; }while(0)
#define ENDP_STAT_TX(num, stat) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_RX | USB_EP_DTOG_TX | USB_EPRX_STAT)) | USB_EP_CTR_RX | USB_EP_CTR_TX) ^ stat; }while(0)
#define ENDP_DTOG_RX(num, dtog) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_TX | USB_EPRX_STAT | USB_EPTX_STAT)) | USB_EP_CTR_RX | USB_EP_CTR_TX) ^ dtog; }while(0)
#define ENDP_DTOG_TX(num, dtog) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_RX | USB_EPRX_STAT | USB_EPTX_STAT)) | USB_EP_CTR_RX | USB_EP_CTR_TX) ^ dtog; }while(0)
#define ENDP_CTR_RX_CLR(num) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_RX | USB_EP_DTOG_TX | USB_EPRX_STAT | USB_EPTX_STAT | USB_EP_CTR_RX)) | USB_EP_CTR_TX); }while(0)
#define ENDP_CTR_TX_CLR(num) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_RX | USB_EP_DTOG_TX | USB_EPRX_STAT | USB_EPTX_STAT | USB_EP_CTR_TX)) | USB_EP_CTR_RX); }while(0)

#define ENDP_TOG(num, tog) do{USB_EPx(num) = ((USB_EPx(num) & ~(USB_EP_DTOG_RX | USB_EP_DTOG_TX | USB_EPRX_STAT | USB_EPTX_STAT)) | USB_EP_CTR_RX | USB_EP_CTR_TX) | tog; }while(0)
Это всё понятно. "Железо" надо знать! Только выше был пример - сброс флаг прерывания у таймера
TIM17->SR &= ~TIM_SR_UIF; - анафема.
А тут как нужно сделать?

Re: Самопроизвольное изменение значения переменной

Чт апр 06, 2023 10:49:08

А тут как нужно сделать?
Посмотреть в RM на регистр:
Изображение

Все биты имеют доступ rc_w0, что означает наличие возможность чтения и сброса бита путем записи нуля (запись 1, соответственно, никак не влияет на состояние бита). Таким образом, для сброса UIF достаточно записать число, где на соответствующей позиции ноль, то есть
Код:
TIM17->SR = ~TIM_SR_UIF;

Re: Самопроизвольное изменение значения переменной

Чт апр 06, 2023 11:15:34

А тут как нужно сделать?
Посмотреть в RM на регистр:
Изображение

Все биты имеют доступ rc_w0, что означает наличие возможность чтения и сброса бита путем записи нуля (запись 1, соответственно, никак не влияет на состояние бита). Таким образом, для сброса UIF достаточно записать число, где на соответствующей позиции ноль, то есть
Код:
TIM17->SR = ~TIM_SR_UIF;

Спасибо!!! Раньше как-то не обращал на это внимания. В общем, век учись - век живи!
Ответить