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

Кто любит RISC в жизни, заходим, не стесняемся.
a797945
Мучитель микросхем
Сообщения: 446
Зарегистрирован: Вс ноя 01, 2015 09:15:16
Откуда: 69.Ржев

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

Сообщение a797945 »

извините, но не вижу причины для споров.
после Вашего замечания я сделал оговорку, о том что моя фраза была по отношению к таймеру и не является призывом всегда глушить SR по любому поводу.
так же, не знаю какие еще события ждать от таймера после TIM_SR_UIF и на нем уже идет новый период и будет нужно "место" для новых событий.
в чем я вру?
наверно, я пишу маловато букавов, поэтому бываю понят неверно.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25123
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

Сообщение КРАМ »

[uquote="AVI-crak",url="/forum/viewtopic.php?p=4390411#p4390411"]Нет, в таких случаях нужно явно читать весь пакет флагов в переменную, сразу сбрасывать все флаги[/uquote]
Это с какого перепуга?
Чем побитная обработка отличается от сохранения всего регистра флагов? Только не надо общих слов типа:
[uquote="AVI-crak",url="/forum/viewtopic.php?p=4390411#p4390411"]Потому как периферия в большинстве случаев живёт своей жизнью, и тактируется автономно. Пока чего-то там делаешь с одним флагом - срабатывают ещё несколько, после чего всё падает.[/uquote]
Что нибудь конкретное, что генерирует риски для целостности обработки. Работа с одним флагом НИКАК не влияет на остальные флаги. Влиять может только зазор между условием и сбросом. Для ОДНОГО флага это вообще непринципиально. Ибо события (тем более таймерные) генерирующие один тип флага не могут следовать с таким маленьким интервалом. В отличии от событий по разным флагам.
Аватара пользователя
AVI-crak
Прорезались зубы
Сообщения: 202
Зарегистрирован: Сб янв 09, 2016 15:51:17
Контактная информация:

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

Сообщение AVI-crak »

[uquote="a797945",url="/forum/viewtopic.php?p=4390414#p4390414"]моя фраза была по отношению к таймеру и не является призывом всегда глушить SR по любому поводу[/uquote]
А мой призыв "глушить рыбу" - относится к разбору флагов больше одного. Когда флаги реально обрабатываются, а не просто висит условие от стандартного обработчика с пустыми скобками, с титрами от ST - "здесь ваш код".
Общий смысл очень простой: ожидаем один тип флага - значит всё остальное можно игнорировать.
КРАМ писал(а):Чем побитная обработка отличается от сохранения всего регистра флагов?
Вот именно этими общими словами и описывается ситуация - периферия живёт своей жизнью. Например прерывание от i2c датчика с собственным кварцем - обязано использовать цикл сохранения/сброса флагов. Иначе зависания гарантированы.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25123
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

Сообщение КРАМ »

[uquote="AVI-crak",url="/forum/viewtopic.php?p=4390436#p4390436"]периферия живёт своей жизнью. Например прерывание от i2c датчика с собственным кварцем[/uquote]
И что? Назовите КОНКРЕТНЫЙ РИСК. Что может сработать в ИИЦ так, чтобы возник конфликт флагов? Вы тут чего то фантазируете изрядно. Конфликт флагов может возникнуть на СКОРОСТНОМ интерфейсе, когда установка двух РАЗНЫХ флагов этого интерфейса происходит (может происходить) с интервалом, который способен уместиться между условием и сбросом семафора обработчика. И всё. Никаких других "своей жизнью живет" там быть не может. Что касается самих событий, которые генерируют ЛЮБЫЕ ФЛАГИ прерываний, то они асинхронно работать не умеют ПО ОПРЕДЕЛЕНИЮ. То есть все эти внешние события ПРЕЖДЕ ВСЕГО проходят синхронизацию с тиками ядра и тогда NVIC им скажет "велкам".
Как то так, уважаемый.
[uquote="AVI-crak",url="/forum/viewtopic.php?p=4390436#p4390436"]Общий смысл очень простой: ожидаем один тип флага - значит всё остальное можно игнорировать.[/uquote]
Это очень прикольное условие... :)))
С чего бы мне чего то ожидать? Например, имеется ДВА ОЖИДАЕМЫХ В РАВНОЙ СТЕПЕНИ флага таймера. Флаг захвата и флаг апдейта. Они легко и непринужденно могут быть сгенерированы так, что один из них попадет между проверкой флага и сбросом флага. Если я работаю побитно, то позднее событие будет неизбежно обработано. Патамушта флаг его остается поднятым.
Аватара пользователя
AVI-crak
Прорезались зубы
Сообщения: 202
Зарегистрирован: Сб янв 09, 2016 15:51:17
Контактная информация:

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

Сообщение AVI-crak »

[uquote="КРАМ",url="/forum/viewtopic.php?p=4390440#p4390440"]Никаких других "своей жизнью живет" там быть не может.[/uquote]
Ок, у вас два флага - обновление счётчика и сравнение. Первым у вас обрабатывается флаг обновления, вот прям сравнивается условие флага и выполняется код...
Вот тогда вам реально жизненно необходимо сбрасывать каждый флаг отдельно.
Но я на такое не подписывался.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25123
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

Сообщение КРАМ »

[uquote="AVI-crak",url="/forum/viewtopic.php?p=4390460#p4390460"]Но я на такое не подписывался.[/uquote]
А не надо ни на что подписываться. Раздельная обработка флагов АВТОМАТИЧЕСКИ подпишет вас на все возможные комбинации. И код будет независимым для каждого флага. Словно это разные обработчики.

Код: Выделить всё

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...

	}
	
}
Bill_
Открыл глаза
Сообщения: 60
Зарегистрирован: Вс ноя 13, 2022 14:58:17

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

Сообщение Bill_ »

Непонятно о чём спор. Работа с битами в Си

Код: Выделить всё

     var |= BIT;   // Установить бит
     var &= ~BIT;  // Сбросить бит
     var ^= BIT;   // Инвертировать бит
Всегда так было с момента появления Си. И так будет всегда, пока существует Си. Или нет?
Аватара пользователя
azhel12
Встал на лапы
Сообщения: 145
Зарегистрирован: Пн апр 02, 2012 15:56:23

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

Сообщение azhel12 »

[uquote="Bill_",url="/forum/viewtopic.php?p=4396799#p4396799"]Или нет?[/uquote]Если речь про ARM-контроллеры, то нет. В RM на многие регистры периферии указан особый доступ, например, rc_w0, rc_w1, которые подразумевают атомарную запись для изменения состояния битов.
Bill_
Открыл глаза
Сообщения: 60
Зарегистрирован: Вс ноя 13, 2022 14:58:17

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

Сообщение Bill_ »

[uquote="azhel12",url="/forum/viewtopic.php?p=4396835#p4396835"][uquote="Bill_",url="/forum/viewtopic.php?p=4396799#p4396799"]Или нет?[/uquote]Если речь про ARM-контроллеры, то нет. В RM на многие регистры периферии указан особый доступ, например, rc_w0, rc_w1, которые подразумевают атомарную запись для изменения состояния битов.[/uquote]
Речь идёт о работе с битами в Си. Когда Си появился, про ARMы никто и слыхом не слыхивал. Поэтому, не вижу ничего криминального в том, чтобы для сброса определённого бита воспользоваться стандартным оператором Си. А то, что есть в ARM возможности атомарного доступа к регистрам, замечательно. Если знаете, как ими пользоваться, так и пользуйтесь на здоровье.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

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

Сообщение VladislavS »

ARM тут, действительно, не причём. А вот правила работы с битами в регистрах могут быть ой какими причудливыми. И работа с ними стандартными операторами языка С может быть от неправильной до ошибочной. Про каждый регистр надо смотреть как с ним правильно работать.
Bill_
Открыл глаза
Сообщения: 60
Зарегистрирован: Вс ноя 13, 2022 14:58:17

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

Сообщение Bill_ »

[uquote="VladislavS",url="/forum/viewtopic.php?p=4396990#p4396990"]ARM тут, действительно, не причём. А вот правила работы с битами в регистрах могут быть ой какими причудливыми. И работа с ними стандартными операторами языка С может быть от неправильной до ошибочной. Про каждый регистр надо смотреть как с ним правильно работать.[/uquote]
И какие "нестандартные" операторы Си в таких случаях нужно использовать?
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

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

Сообщение COKPOWEHEU »

Да операторы-то стандартные, просто использовать их надо очень аккуратно. Самый упоротый пример организации доступа, который я видел - регистры статуса конечных точек в 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)
Аватара пользователя
azhel12
Встал на лапы
Сообщения: 145
Зарегистрирован: Пн апр 02, 2012 15:56:23

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

Сообщение azhel12 »

[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=4397063#p4397063"]Самый упоротый пример организации доступа, который я видел - регистры статуса конечных точек в stm32f103, называются EPnR: часть битов сбрасывается записью нуля, часть инвертируется записью единицы, часть просто read-only, а часть обычные.[/uquote]Ох, вьетнамские флешбэки.
Bill_
Открыл глаза
Сообщения: 60
Зарегистрирован: Вс ноя 13, 2022 14:58:17

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

Сообщение Bill_ »

[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=4397063#p4397063"]Да операторы-то стандартные, просто использовать их надо очень аккуратно. Самый упоротый пример организации доступа, который я видел - регистры статуса конечных точек в 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)
[/uquote]Это всё понятно. "Железо" надо знать! Только выше был пример - сброс флаг прерывания у таймера
TIM17->SR &= ~TIM_SR_UIF; - анафема.
А тут как нужно сделать?
Аватара пользователя
azhel12
Встал на лапы
Сообщения: 145
Зарегистрирован: Пн апр 02, 2012 15:56:23

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

Сообщение azhel12 »

[uquote="Bill_",url="/forum/viewtopic.php?p=4397071#p4397071"]А тут как нужно сделать?[/uquote]Посмотреть в RM на регистр:
Изображение

Все биты имеют доступ rc_w0, что означает наличие возможность чтения и сброса бита путем записи нуля (запись 1, соответственно, никак не влияет на состояние бита). Таким образом, для сброса UIF достаточно записать число, где на соответствующей позиции ноль, то есть

Код: Выделить всё

TIM17->SR = ~TIM_SR_UIF;
Bill_
Открыл глаза
Сообщения: 60
Зарегистрирован: Вс ноя 13, 2022 14:58:17

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

Сообщение Bill_ »

[uquote="azhel12",url="/forum/viewtopic.php?p=4397074#p4397074"][uquote="Bill_",url="/forum/viewtopic.php?p=4397071#p4397071"]А тут как нужно сделать?[/uquote]Посмотреть в RM на регистр:
Изображение

Все биты имеют доступ rc_w0, что означает наличие возможность чтения и сброса бита путем записи нуля (запись 1, соответственно, никак не влияет на состояние бита). Таким образом, для сброса UIF достаточно записать число, где на соответствующей позиции ноль, то есть

Код: Выделить всё

TIM17->SR = ~TIM_SR_UIF;
[/uquote]
Спасибо!!! Раньше как-то не обращал на это внимания. В общем, век учись - век живи!
Ответить

Вернуться в «ARM»