Например TDA7294

Форум РадиоКот • Просмотр темы - AVR GCC изменение переменной 8bit вне прерывания
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Чт фев 12, 2026 22:34:04

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 7 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: AVR GCC изменение переменной 8bit вне прерывания
СообщениеДобавлено: Вт дек 30, 2025 18:56:11 
Первый раз сказал Мяу!

Зарегистрирован: Пн дек 15, 2025 13:29:04
Сообщений: 23
Рейтинг сообщения: 0
Опять, без надобности, полез в глухие дебри - вроде и размер прошивки устраивает и отзывчатость, но решил посмотреть что получается при использовании структур.

Задача простая вне прерывания получать менять 8-битную переменную. Вроде как не нужно атомарный доступ. Решил глянуть, что выдаст асемблер.

Код:

typedef struct {
   bool test : 1;
   bool _unused1 : 1;
   bool _unused2 : 1;
   bool _unused3 : 1;
   bool _unused4 : 1;
   bool _unused5 : 1;
   bool _unused6 : 1;
   bool _unused7 : 1;
} compare_enabled_t;

typedef struct {
   ...
   compare_enabled_t is_enabled;
   byte_t x;
} clock_struct_t;



использование
Код:
volatile clock_struct_t clock = { ... , .test = {0}, .is_enabled = {.test = false}};
byte_t clock_x = 0;
void on_lo_press(void) {
   printf("on_lo_long\n");
   _NOP();
   clock.is_enabled.test = false;
   _NOP();
   clock.x &= ~_BV(0);
   _NOP();
   clock_x &= ~_BV(0);
   _NOP();
   clock.x &= 32;
   _NOP();
   clock_x = 32;
   _NOP();
}


Стандартная оптимизация по размеру, О2 оптимизация и О3 оптимизация дают здесь одинаковый ассемблерный код(хотя в общем размер бинарника Os/O2 отличается на 25%):
Код:
/* #APP */
 ;  30 "modules/buttons.c" 1
   nop
 ;  0 "" 2
/* #NOAPP */
   ldi r30,lo8(clock+10)
   ldi r31,hi8(clock+10)
   ld r24,Z
   andi r24,lo8(~(1<<0))
   st Z,r24
/* #APP */
 ;  32 "modules/buttons.c" 1
   nop
 ;  0 "" 2
/* #NOAPP */
   ldi r30,lo8(clock)
   ldi r31,hi8(clock)
   ldd r24,Z+11
   andi r24,lo8(-2)
   std Z+11,r24
/* #APP */
 ;  34 "modules/buttons.c" 1
   nop
 ;  0 "" 2
/* #NOAPP */
   lds r24,clock_x
   andi r24,lo8(-2)
   sts clock_x,r24
/* #APP */
 ;  36 "modules/buttons.c" 1
   nop
 ;  0 "" 2
/* #NOAPP */
   ldd r24,Z+11
   andi r24,lo8(32)
   std Z+11,r24
/* #APP */
 ;  38 "modules/buttons.c" 1
   nop
 ;  0 "" 2
/* #NOAPP */
   ldi r24,lo8(32)
   sts clock_x,r24
/* #APP */


В итоге вместо одного вопроса возникло целых два:
1) когда нельзя неатомарно менять переменную? Про аккуратность с некоторыми регистрами знаю(иногда лучше присвоение).
2) зачем такие костыли со структурами? Почему компилятор не может вычислить адрес относительно начала структуры? Выходит даже структуры - это зло. А я хотел в основном цикле много чего творить со сделанной атомарно копией структуры, а затем, если надо, атомарно менять оригинал(или не атомарно, если член 8bit). Что же тогда на ардуино где и классы присутствуют творится...

Добавлено after 36 minutes 6 seconds:
P.S. Работа по ссылке уже интересней:
Спойлер
Код:
/* #APP */
 ;  30 "modules/buttons.c" 1
   nop
 ;  0 "" 2
/* #NOAPP */
   ldd r24,Z+10
   andi r24,lo8(~(1<<0))
   std Z+10,r24
/* #APP */
 ;  32 "modules/buttons.c" 1
   nop
 ;  0 "" 2
/* #NOAPP */
   ldd r24,Z+11
   andi r24,lo8(-2)
   std Z+11,r24
/* #APP */
 ;  34 "modules/buttons.c" 1
   nop
 ;  0 "" 2
/* #NOAPP */
   lds r24,clock_x
   andi r24,lo8(-2)
   sts clock_x,r24
/* #APP */
 ;  36 "modules/buttons.c" 1
   nop
 ;  0 "" 2
/* #NOAPP */
   ldd r24,Z+11
   andi r24,lo8(32)
   std Z+11,r24
/* #APP */
 ;  38 "modules/buttons.c" 1
   nop
 ;  0 "" 2
/* #NOAPP */
   ldi r24,lo8(32)
   sts clock_x,r24
/* #APP */
 ;  40 "modules/buttons.c" 1
   nop
 ;  0 "" 2
/* #NOAPP */


А я много лет считал, что это для программиста отличается...

Добавлено after 4 hours 12 minutes 26 seconds:
P.P.S. Похоже я пере-перестраховался, так что испугался или наоборот :-) Счетчик и члены сравнения меняются из прерывания по таймеру, а читаются в основном цикле - тут нужно атомарное копирование, а все остальное настройки меняются и читаются только в основном цикле, так что пофиг сколько они занимают байт, всё должно быть OK.

Ну, а что касается структур - тут всё странно:
Код:
   clock_struct_t _approx_clock;
   const clock_struct_t * approx_clock;
   while(1) {
      _approx_clock = get_current_copy_atomic();
      approx_clock = &_approx_clock;
      ...
   }

и
Код:
   clock_struct_t approx_clock;
   while(1) {
      approx_clock = get_current_copy_atomic();
      ...
   }

Дают абсолютно одинаковый ассемблерный код. Причём, оптимальный.


Вернуться наверх
 
В сети
 Заголовок сообщения: Re: AVR GCC изменение переменной 8bit вне прерывания
СообщениеДобавлено: Вт дек 30, 2025 19:32:14 
Мудрый кот

Карма: 25
Рейтинг сообщений: 499
Зарегистрирован: Сб май 05, 2012 20:24:52
Сообщений: 1866
Откуда: KN34PC, Болгария
Рейтинг сообщения: 0
Дают абсолютно одинаковый ассемблерный код.

Нет информации где выполняете компиляцию. Отключите оптимизацию для анализа, если этого еще не сделали.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: AVR GCC изменение переменной 8bit вне прерывания
СообщениеДобавлено: Вт дек 30, 2025 20:21:45 
Первый раз сказал Мяу!

Зарегистрирован: Пн дек 15, 2025 13:29:04
Сообщений: 23
Рейтинг сообщения: 0
Дают абсолютно одинаковый ассемблерный код.

Нет информации где выполняете компиляцию. Отключите оптимизацию для анализа, если этого еще не сделали.


GNU AVR toolchain, IDE: Code::Blocks, OS: Gentoo

В том и дело что СО ВСЕМИ оптимизациями которые я знаю, непосредственная работа с глобальной переменной не давала нормального ASM-кода в определения адреса члена структуры, как только заменил на ссылку - адрес стал определяться за одну операцию. Но это в отдельных *.с файлах, где через заголовок было только объявление. Последний же случай в главном файле где эта структура определена. Возможно это каким-то образом повлияло.

Отключите оптимизацию для анализа, если этого еще не сделали.

Короче, уже наигрался со всеми возможными, вариантами и с оптимизацией и без. В принципе понятно, что лучше объявление глобальной ссылки на структруру, чем глобальной структуры. Пусть даже, благодаря объявлению, она могла бы быть видна везде, где нужно.

Добавлено after 7 minutes 43 seconds:
Со структурой код проще, всё сгруппировано вместе. Сложнее что-то пропустить.

Последний же случай в главном файле где эта структура определена. Возможно это каким-то образом повлияло.

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


Последний раз редактировалось Simon.S Вт дек 30, 2025 20:43:28, всего редактировалось 3 раз(а).

Вернуться наверх
 
В сети
 Заголовок сообщения: Re: AVR GCC изменение переменной 8bit вне прерывания
СообщениеДобавлено: Вт дек 30, 2025 20:26:25 
Мудрый кот

Карма: 25
Рейтинг сообщений: 499
Зарегистрирован: Сб май 05, 2012 20:24:52
Сообщений: 1866
Откуда: KN34PC, Болгария
Рейтинг сообщения: 0
Есть цель? Напр. небольшой объем данных/память или быстрый алгоритм, или просто экспериментируете? Для использования кода в других проектах было бы хорошо, если бы глобальные ресурсы (переменные, структуры и т. д.) действительно были глобальными, а все остальное - локальным, статик, external и т. д. Переключитесь на другой (неограниченный) MK (напр. ARM), там ситуация значительно сложнее.


Вернуться наверх
 
Эиком - электронные компоненты и радиодетали
Не в сети
 Заголовок сообщения: Re: AVR GCC изменение переменной 8bit вне прерывания
СообщениеДобавлено: Вт дек 30, 2025 20:32:15 
Первый раз сказал Мяу!

Зарегистрирован: Пн дек 15, 2025 13:29:04
Сообщений: 23
Рейтинг сообщения: 0
Есть цель: например, небольшой объем данных/память или быстрый алгоритм, или просто экспериментируете? Для использования кода в других проектах было бы хорошо, если бы глобальные ресурсы (переменные, структуры и т. д.) действительно были глобальными, а все остальное - локальным. Переключитесь на другой (неограниченный) MK (напр. ARM), там ситуация значительно сложнее.


Эксперементирую. Хотелось бы быстрый алгоритм, пока с недостатком памяти никогда не сталкивался, но пока ничего слишком серьёзного на AVR не кодил. Сейчас проект будет довольно сложный и довольно ответственный. Но думаю в размер всё равно впишусь.

Добавлено after 1 minute 49 seconds:
Когда закончу подготовительную часть (в основном учебно-эксперементальную) начну писать контроллер управления аквариумом: температура, насосы, свет.


Вернуться наверх
 
В сети
 Заголовок сообщения: Re: AVR GCC изменение переменной 8bit вне прерывания
СообщениеДобавлено: Вт дек 30, 2025 20:52:30 
Мудрый кот

Карма: 25
Рейтинг сообщений: 499
Зарегистрирован: Сб май 05, 2012 20:24:52
Сообщений: 1866
Откуда: KN34PC, Болгария
Рейтинг сообщения: 0
... писать контроллер управления аквариумом

В ATtiny13A все соберется :). Если нет, прежде чем сказать: не может, выбираем другой MK - это предпосылка для написания действительно сжатого кода. Не обязательно на ASM :).


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: AVR GCC изменение переменной 8bit вне прерывания
СообщениеДобавлено: Вт дек 30, 2025 21:28:57 
Первый раз сказал Мяу!

Зарегистрирован: Пн дек 15, 2025 13:29:04
Сообщений: 23
Рейтинг сообщения: 0
В ATtiny13A все соберется :)

В наличии только Attiny88 и пара Amega328P :twisted: . Сегодня STM32F405 получил, но в STM пока не умею :dont_know:


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 7 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 42


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y