C для AVR -- пишем аккуратно.

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
drvlas
Родился
Сообщения: 14
Зарегистрирован: Пн апр 19, 2010 12:42:13

Re: C для AVR -- пишем аккуратно.

Сообщение drvlas »

Разочаровали.... Это скока же надо было наделать шуму на двух форумах, чтобы родить мышь!
Я читаю Ваши откровения и по-прежнему не вижу ни одного аргументированного возражения по сути приемов, предложенных коллегой avreal. Он просил (и очень справедливо) привести пример, когда его рекомендации могут привести к трудноуловимым глюкам или иным нежелательным последствиям. Конечно же, имелось в виду разумное использование рекомендаций, но Вам простилось бы даже передергивание. И я ожидал, что Вы, с огромным опытом в программировании, с высоты которого тут собралось стадо мартышек, приведете яркие примеры, а мы уж сможем научиться пользоваться калашом быть осторожными со столь непростыми приемами.
Но что же мы получаем:

- общий треп по поводу стадного чувства
- тривиальные замечания (да и то не свои) про goto. Оператор, которого avreal не касался вообще. Да ссылка на срач, разведенный на другом форуме. Очевидно, что ругань просто греет Вам душу.
- совсем уж примитивный пример бездумного программирования с зацикливанием программы на ожидании. Да, если бы Вы сподвигнулись написать что-нибудь конструктивное и включили подобную конструкцию в свой, безусловно эпический, труд, то она имела бы право быть упомянутой. Есть новички, могущие сесть в столь очевидную лужу. Это как раз на уровне мигания светодиодом и бывает. Но! Вам бросили вызов (напоминаю, Вас назвали треплом), а на него следует ответить. Или принять к сведению и задуматься о правилах поведения.

Поэтому Ваш выверт
HHIMERA писал(а):Предвкушая вопрос одиозных личностей "А к чему это всё?", напоминаю, тема называется "C для AVR -- пишем аккуратно."...
не катит. Вам нечего сказать по сути. Вы не можете ни уточнить предложенное автором, ни выдать сколь-нибудь вменяемые свои рекомендации.

Ну и Бог с Вами. Трепитесь далее.
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: C для AVR -- пишем аккуратно.

Сообщение HHIMERA »

drvlas писал(а):Разочаровали....

С твоими незнаниями и туповатой упёртостью??? :)))
Уже всё сказали... и здесь и на диахтунге... Ты или читать не умеешь, или делаешь вид...
Читай заново... раз пять... :)))

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

тривиальные замечания (да и то не свои) про goto. 

"Всё уже придумано до нас!" (С)
Было бы странно, если бы я заявил, что замечания мои, и goto тоже придумал я... :)))
Последний раз редактировалось HHIMERA Сб сен 22, 2012 10:54:08, всего редактировалось 1 раз.
"Я не даю готовых решений, я заставляю думать!"(С)
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: C для AVR -- пишем аккуратно.

Сообщение HHIMERA »

drvlas писал(а): Но! Вам бросили вызов (напоминаю, Вас назвали треплом), а на него следует ответить. Или принять к сведению и задуматься о правилах поведения.

Тогда напомню тебе... трепло здесь только ТЫ... т.к. абсолютно не владея предметом спора пытаешься расставить акценты и оценки... :)))
"Я не даю готовых решений, я заставляю думать!"(С)
led_fan
Встал на лапы
Сообщения: 142
Зарегистрирован: Вс фев 05, 2012 11:41:07

Re: C для AVR -- пишем аккуратно.

Сообщение led_fan »

ёпта.
пришел "парень с призрачным ником" и обосрал безусловно полезную образовательную работу....
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: C для AVR -- пишем аккуратно.

Сообщение HHIMERA »

Ничего в ней полезного нет...
Для новичков нужно писать более развёрнуто и с акцентом на возможные неприятности... и это не каждому под силу...
"Я не даю готовых решений, я заставляю думать!"(С)
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Re: C для AVR -- пишем аккуратно.

Сообщение avreal »

HHIMERA писал(а):Ничего в ней полезного нет...
Для новичков нужно писать более развёрнуто и с акцентом на возможные неприятности... и это не каждому под силу...
Да где уж мне, в лаптях да по паркету.
Вот уже «больше одного» знатока разродились на «акцент на возможные неприятности»: «напихивание static куда попало может привести» к каким-то химерным «трудноуловимым глюкам». Может, в их практике такое и было. И теперь гордятся тайным знанием.
Но я вечно что-то делаю не так и у меня таких глюков не было, видать, я сам тут начинающий и мне тоже нужно объяснить «более развернуто».
А вот это им уже «лениво» (трындеть — не мешки ворочать), так на реальный пример до сих пор и не разродились.
Чем глубокомысленнее и туманнее намёк на «возможные» опасности, после чего «с учёным видом знатока хранить молчанье в важном споре», тем легче прослыть знатоком, шаманом?
Проще напустить туману, «когда-нибудь вы все узнаете»?
Ну так скажите сейчас. (хлопая в ладоши) Просим, просим, просим!

p.s. Пассаж про «если привыкнуть ставить static к функциям, то начнёшь их лепить и к переменным» в теме на easyelectronics мне вообще понравился :))). Это ж насколько бездумно нужно писать, чтобы такое началось? Может, пора от них ножи и вилки прятать? А то, привыкнув тыкать ими в котлету, они ткнут ими в соседа за столом?
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: C для AVR -- пишем аккуратно.

Сообщение HHIMERA »

avreal
Тебе скучно... превирать потихоньку начал??? :)))
Не уподобляйся drvlas'у...
"Я не даю готовых решений, я заставляю думать!"(С)
led_fan
Встал на лапы
Сообщения: 142
Зарегистрирован: Вс фев 05, 2012 11:41:07

Re: C для AVR -- пишем аккуратно.

Сообщение led_fan »

avreal писал(а):Да где уж мне, в лаптях да по паркету.

не обращай внимания.

Вот уже «больше одного» знатока разродились на «акцент на возможные неприятности»: «напихивание static куда попало может привести» к каким-то химерным «трудноуловимым глюкам». Может, в их практике такое и было. И теперь гордятся тайным знанием.

Ну так скажите сейчас. (хлопая в ладоши) Просим, просим, просим!


p.s. Пассаж про «если привыкнуть ставить static к функциям, то начнёшь их лепить и к переменным» в теме на easyelectronics мне вообще понравился :))).

это все в мой огород. ;)
да, я "слегка" преувеличил. но делал это сознательно.
вон, на изиэлектрониксе drvlas буквально вчера спросил "горячий рестарт на авр - как?" и это после твоего более чем исчерпывающего объяснения. согласись, не дело.
и я эмоционально вовлекал собеседников с одной целью - чтобы отложилось в памяти хоть место, где обсуждалось. видно, не удалось, к сожалению...
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: C для AVR -- пишем аккуратно.

Сообщение shads »

Проектик на MEGA8 постепенно приближается к 8кб коду (ну пока 6092) но еще надо встроить несколько ресурсоемких вещей.
Поэтому начал уже сейчас кумекать, что можно подправить, чтобы места освободить..... Пришла идея (гдето раньше попадалось на глаза) переменные с флагами (т.к. к ним частое обращение в разных местах) перенести в область портов. У меня было 2 байта с флагами:

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

//ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
volatile char Flags1 = 0;                  //байт флагов №1
   #define b1DispFlash      (1<<0)            /*флаг включения мигающего режима дисплея*/
   #define b1OneWireStart   (1<<1)            /*флаг необходимости старта команды преобразования температуры в 1wire устройствах*/
   #define b1OneWireData   (1<<2)            /*флаг необходимости считать данные температуры*/
   #define b1ClockRead      (1<<3)            /*флаг чтения данных времени с МС часов 10 раз\сек*/
   #define b1ClockDot      (1<<4)            /*флаг включения мигающей точки часов*/
   #define b1BeepAlarmOn   (1<<5)            /*флаг включения зуммера*/
   #define b1StartDevice   (1<<6)            /*флаг необходимости внесения записи в EEPROM о подаче питания на устройство*/

volatile char BtnFlags = 0;                  //байт флагов кнопок
   #define ShortUp         (1<<0)            /*бит короткого нажатия кнопки вверх*/
   #define ShortLeft      (1<<1)            /*бит короткого нажатия кнопки вниз*/
   #define ShortDown      (1<<2)            /*бит короткого нажатия кнопки влево*/
   #define ShortRight      (1<<3)            /*бит короткого нажатия кнопки вправо*/
   #define LongUp         (1<<4)            /*бит длиного нажатия кнопки вверх*/
   #define LongLeft      (1<<5)            /*бит длиного нажатия кнопки вниз*/
   #define LongDown      (1<<6)            /*бит длиного нажатия кнопки влево*/
   #define LongRight      (1<<7)            /*бит длиного нажатия кнопки вправо*/

Перенес эти 2 байта флагов в регистры работы с внутренней EEPROM - EEARL, EEDR (внутренняя у меня не используется т.к. имеется внешня флэш на 8Кб - 24C64) получилось так:

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

//ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
#define Flags1 EEARL                            /*байт флагов №1 будет размещатся в регистре EEARL (т.к. внутренняя EEPROM не исп-ся)*/
    #define b1DispFlash        (1<<0)                /*флаг включения мигающего режима дисплея*/
    #define b1OneWireStart    (1<<1)                /*флаг необходимости старта команды преобразования температуры в 1wire устройствах*/
    #define b1OneWireData    (1<<2)                /*флаг необходимости считать данные температуры*/
    #define b1ClockRead        (1<<3)                /*флаг чтения данных времени с МС часов 10 раз\сек*/
    #define b1ClockDot        (1<<4)                /*флаг включения мигающей точки часов*/
    #define b1BeepAlarmOn    (1<<5)                /*флаг включения зуммера*/
    #define b1StartDevice    (1<<6)                /*флаг необходимости внесения записи в EEPROM о подаче питания на устройство*/

#define BtnFlags EEDR                            /*байт флагов кнопок будет размещатся в регистре EEDR (т.к. внутренняя EEPROM не исп-ся)*/
    #define ShortUp            (1<<0)                /*бит короткого нажатия кнопки вверх*/ 
    #define ShortLeft        (1<<1)                /*бит короткого нажатия кнопки вниз*/ 
    #define ShortDown        (1<<2)                /*бит короткого нажатия кнопки влево*/ 
    #define ShortRight        (1<<3)                /*бит короткого нажатия кнопки вправо*/ 
    #define LongUp            (1<<4)                /*бит длиного нажатия кнопки вверх*/ 
    #define LongLeft        (1<<5)                /*бит длиного нажатия кнопки вниз*/ 
    #define LongDown        (1<<6)                /*бит длиного нажатия кнопки влево*/ 
    #define LongRight        (1<<7)                /*бит длиного нажатия кнопки вправо*/ 

Flags1 = 0;                           //флаговые байты - инициализация
BtnFlags = 0; 

Что вы думаете..... сразу 300 байт высвободилось..... стало 5774 байта

Кто нибудь такое вытворял? Интересно, какие еще регистры портов можно задействовать.....
Можно было бы и другие часто используемые переменные туда ныкать.....
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: C для AVR -- пишем аккуратно.

Сообщение Kavka »

shads, во втором варианте у вас нет атрибута volatile.
Как результат - уменьшился код прошивки, так как компилятор смог что-то оптимизировать.
Можно было и в исходном коде убрать volatile - прошивка тоже бы уменьшилась.
Если вам volatile реально нужен и вы его вернёте в варианте с регистрами EEPROM, то размер может вырасти опять.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: C для AVR -- пишем аккуратно.

Сообщение shads »

Kavka писал(а):Можно было и в исходном коде убрать volatile - прошивка тоже бы уменьшилась.

В исходном коде низя убирать volatile, т.к. флаги еще в прерывании используются. А вообще (ради чтобы проверить) пробовал убрать volatile, код уменьшился всего на 70 байт.....

Kavka писал(а):Если вам volatile реально нужен и вы его вернёте в варианте с регистрами EEPROM, то размер может вырасти опять.

Помоему к регистрам портов нет смысла указывать volatile, т.к. они итак в волатильном режиме работают.....
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Re: C для AVR -- пишем аккуратно.

Сообщение ibiza11 »

регистры периферии везде объявлены как volatile
Ставим плюсы: )
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: C для AVR -- пишем аккуратно.

Сообщение Kavka »

Про volatile и регистры в/в - да, тут я дал маху. Признаю.
Был повод повторно проштудировать sfr_defs.h. :)
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: C для AVR -- пишем аккуратно.

Сообщение shads »

Сейчас проверил, одинаково нормально работает со следующими регистрами В/В.
Это конечно при условии, что не используются соответствующие модули.....

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

EEARL -    EEPROM регистр адреса
EEDR -    EEPROM регистр данных
UBRRL -    USART регистр скорости интерфейса
TWBR -   TWI регистр скорости передачи
TWAR -    TWI регистр адреса
Аватара пользователя
IM1
Грызет канифоль
Сообщения: 268
Зарегистрирован: Вт фев 16, 2010 12:10:38
Откуда: Воронеж, Россия

Re: C для AVR -- пишем аккуратно.

Сообщение IM1 »

Ув. avreal с удовольствием читаю Ваш мастер-класс по C, правда хочу сделать маленькое, но как мне кажется полезное замечание по работе с EEPROM:
avreal писал(а):Не ленимся и пишем свои функции, принимающие 8-битный номер ячейки. Тоже NOINLINE, так как иначе некоторые версии компилятора их встраивают (особенно Read, она совсем короткая).
Ваша функция записи в EEPROM:

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

static void EEWrite(uint8_t addr, uint8_t data)
{
    while (EECR & (1<<EEPE)) ;
    EECR = (0 << EEPM1) | (0 << EEPM0);
    EEAR = addr;
    EEDR = data;
    // Теперь уже в запись может влезть прерывание, запрещаем на время запуска
    CLI();
    EECR |= (1 << EEMPE);
    EECR |= (1 << EEPE);
    SEI();
}
Функция разрешает прерывания независимо от того были они запрещены до этого или нет. Т.е. она справедлива для частного случая, где прерывания разрешены всегда.
Предлагаю немного измененный вариант для универсального применения:

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

static void EEWrite(uint8_t addr, uint8_t data)
{
   while (EECR & (1<<EEWE));
   EECR = (0 << EEPM1) | (0 << EEPM0);
   EEAR = addr;
   EEDR = data;
   // Теперь уже в запись может влезть прерывание, запрещаем на время запуска
   uint8_t srbuf = SREG;
   cli();
   EECR |= (1 << EEMWE);
   EECR |= (1 << EEWE);
   SREG = srbuf;
}
ПС
Ваш код взят из download/file.php?id=118730
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: C для AVR -- пишем аккуратно.

Сообщение shads »

А для чего перед
int main(void)
пишется
__attribute__((OS_main))

что делает этот атрибут?.....
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: C для AVR -- пишем аккуратно.

Сообщение Kavka »

http://gcc.gnu.org/onlinedocs/gcc-4.7.3 ... Attributes
OS_main/OS_task
On AVR, functions with the OS_main or OS_task attribute do not save/restore any call-saved register in their prologue/epilogue.

The OS_main attribute can be used when there is guarantee that interrupts are disabled at the time when the function is entered. This will save resources when the stack pointer has to be changed to set up a frame for local variables.

The OS_task attribute can be used when there is no guarantee that interrupts are disabled at that time when the function is entered like for, e.g. task functions in a multi-threading operating system. In that case, changing the stack pointer register will be guarded by save/clear/restore of the global interrupt enable flag.
OS_main и OS_task указывают компилятору, что процедура не сохраняет и не восстанавливает регистры. Это можно сделать, так как main ниоткуда не вызывается и из процедуры никогда не "выходиться" (так как внутри "вечный" цикл). Обычная процедура должна это делать. В итоге экономиться чуть-чуть памяти.
OS_main - если гарантируется, что прерывания запрещены. Иначе OS_task.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: C для AVR -- пишем аккуратно.

Сообщение HHIMERA »

shads писал(а):А для чего перед
int main(void)
пишется
__attribute__((OS_main))

что делает этот атрибут?.....

Склероз???
viewtopic.php?p=1399164#p1399164
viewtopic.php?p=1400279#p1400279
"Я не даю готовых решений, я заставляю думать!"(С)
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: C для AVR -- пишем аккуратно.

Сообщение shads »

Да..... старею постепенно.....
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: C для AVR -- пишем аккуратно.

Сообщение Kavka »

Вложенные прерывания, avr-gcc, avr-libc.
Часто видел запись такого вида.

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

ISR(PCINT0_vect) {
   sei();
..........
}
Команда разрешения прерывания будет после пролога.
Но там где надо задержку сделать минимальной есть лучший способ, с меньшей задержкой.
Тактов на 5-6 минимум (avr-gcc 4.7). Не много, но кому-то может пригодиться.

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

ISR_NOBLOCK ISR(PCINT0_vect) {
..........
}
ISR_NOBLOCK определено в avr/interrupt.h из avr-libc (WinAVR или AVR toolchain) как __attribute__((interrupt))
В этом случае команда разрешения прерывания будет вставлена компилятором, и она будет первой в прологе процедуры.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Ответить

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