Страница 5 из 6
Re: C для AVR -- пишем аккуратно.
Добавлено: Сб сен 22, 2012 08:55:17
drvlas
Разочаровали.... Это скока же надо было наделать шуму на двух форумах, чтобы родить мышь!
Я читаю Ваши откровения и по-прежнему не вижу ни одного аргументированного возражения по сути приемов, предложенных коллегой
avreal. Он просил (и очень справедливо) привести пример, когда его рекомендации могут привести к трудноуловимым глюкам или иным нежелательным последствиям. Конечно же, имелось в виду разумное использование рекомендаций, но Вам простилось бы даже передергивание. И я ожидал, что Вы, с огромным опытом в программировании, с высоты которого тут собралось стадо мартышек, приведете яркие примеры, а мы уж сможем научиться
пользоваться калашом быть осторожными со столь непростыми приемами.
Но что же мы получаем:
- общий треп по поводу стадного чувства
- тривиальные замечания (да и то не свои) про goto. Оператор, которого
avreal не касался вообще. Да ссылка на срач, разведенный на другом форуме. Очевидно, что ругань просто греет Вам душу.
- совсем уж примитивный пример бездумного программирования с зацикливанием программы на ожидании. Да, если бы Вы сподвигнулись написать что-нибудь конструктивное и включили подобную конструкцию в свой, безусловно эпический, труд, то она имела бы право быть упомянутой. Есть новички, могущие сесть в столь очевидную лужу. Это как раз на уровне мигания светодиодом и бывает. Но! Вам бросили вызов (напоминаю, Вас назвали треплом), а на него следует ответить. Или принять к сведению и задуматься о правилах поведения.
Поэтому Ваш выверт
HHIMERA писал(а):Предвкушая вопрос одиозных личностей "А к чему это всё?", напоминаю, тема называется "C для AVR -- пишем аккуратно."...
не катит. Вам нечего сказать по сути. Вы не можете ни уточнить предложенное автором, ни выдать сколь-нибудь вменяемые свои рекомендации.
Ну и Бог с Вами. Трепитесь далее.
Re: C для AVR -- пишем аккуратно.
Добавлено: Сб сен 22, 2012 10:39:51
HHIMERA
drvlas писал(а):Разочаровали....
С твоими незнаниями и туповатой упёртостью???
Уже всё сказали... и здесь и на диахтунге... Ты или читать не умеешь, или делаешь вид...
Читай заново... раз пять...
Код: Выделить всё
тривиальные замечания (да и то не свои) про goto.
"Всё уже придумано до нас!" (С)
Было бы странно, если бы я заявил, что замечания мои, и goto тоже придумал я...

Re: C для AVR -- пишем аккуратно.
Добавлено: Сб сен 22, 2012 10:47:18
HHIMERA
drvlas писал(а): Но! Вам бросили вызов (напоминаю, Вас назвали треплом), а на него следует ответить. Или принять к сведению и задуматься о правилах поведения.
Тогда напомню тебе... трепло здесь только ТЫ... т.к. абсолютно не владея предметом спора пытаешься расставить акценты и оценки...

Re: C для AVR -- пишем аккуратно.
Добавлено: Вт сен 25, 2012 10:12:11
led_fan
ёпта.
пришел "парень с призрачным ником" и обосрал безусловно полезную образовательную работу....
Re: C для AVR -- пишем аккуратно.
Добавлено: Вт сен 25, 2012 10:51:59
HHIMERA
Ничего в ней полезного нет...
Для новичков нужно писать более развёрнуто и с акцентом на возможные неприятности... и это не каждому под силу...
Re: C для AVR -- пишем аккуратно.
Добавлено: Ср сен 26, 2012 09:39:15
avreal
HHIMERA писал(а):Ничего в ней полезного нет...
Для новичков нужно писать более развёрнуто и с акцентом на возможные неприятности... и это не каждому под силу...
Да где уж мне, в лаптях да по паркету.
Вот уже «больше одного» знатока разродились на «акцент на возможные неприятности»: «напихивание static куда попало может привести» к каким-то химерным «трудноуловимым глюкам». Может, в их практике такое и было. И теперь гордятся тайным знанием.
Но я вечно что-то делаю не так и у меня таких глюков не было, видать, я сам тут начинающий и мне тоже нужно объяснить «более развернуто».
А вот это им уже «лениво» (трындеть — не мешки ворочать), так на реальный пример до сих пор и не разродились.
Чем глубокомысленнее и туманнее намёк на «возможные» опасности, после чего «с учёным видом знатока хранить молчанье в важном споре», тем легче прослыть знатоком, шаманом?
Проще напустить туману, «когда-нибудь вы все узнаете»?
Ну так скажите сейчас. (хлопая в ладоши) Просим, просим, просим!
p.s. Пассаж про «если привыкнуть ставить static к функциям, то начнёшь их лепить и к переменным» в теме на easyelectronics мне вообще понравился

. Это ж насколько бездумно нужно писать, чтобы такое началось? Может, пора от них ножи и вилки прятать? А то, привыкнув тыкать ими в котлету, они ткнут ими в соседа за столом?
Re: C для AVR -- пишем аккуратно.
Добавлено: Ср сен 26, 2012 10:39:08
HHIMERA
avreal
Тебе скучно... превирать потихоньку начал???
Не уподобляйся drvlas'у...
Re: C для AVR -- пишем аккуратно.
Добавлено: Ср сен 26, 2012 12:22:23
led_fan
avreal писал(а):Да где уж мне, в лаптях да по паркету.
не обращай внимания.
Вот уже «больше одного» знатока разродились на «акцент на возможные неприятности»: «напихивание static куда попало может привести» к каким-то химерным «трудноуловимым глюкам». Может, в их практике такое и было. И теперь гордятся тайным знанием.
Ну так скажите сейчас. (хлопая в ладоши) Просим, просим, просим!
p.s. Пассаж про «если привыкнуть ставить static к функциям, то начнёшь их лепить и к переменным» в теме на easyelectronics мне вообще понравился

.
это все в мой огород.

да, я "слегка" преувеличил. но делал это сознательно.
вон, на изиэлектрониксе drvlas буквально вчера спросил "горячий рестарт на авр - как?" и это после твоего более чем исчерпывающего объяснения. согласись, не дело.
и я эмоционально вовлекал собеседников с одной целью - чтобы отложилось в памяти хоть место, где обсуждалось. видно, не удалось, к сожалению...
Re: C для AVR -- пишем аккуратно.
Добавлено: Вс дек 16, 2012 11:27:33
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 байта
Кто нибудь такое вытворял? Интересно, какие еще регистры портов можно задействовать.....
Можно было бы и другие часто используемые переменные туда ныкать.....
Re: C для AVR -- пишем аккуратно.
Добавлено: Вс дек 16, 2012 12:34:29
Kavka
shads, во втором варианте у вас нет атрибута volatile.
Как результат - уменьшился код прошивки, так как компилятор смог что-то оптимизировать.
Можно было и в исходном коде убрать volatile - прошивка тоже бы уменьшилась.
Если вам volatile реально нужен и вы его вернёте в варианте с регистрами EEPROM, то размер может вырасти опять.
Re: C для AVR -- пишем аккуратно.
Добавлено: Вс дек 16, 2012 14:48:25
shads
Kavka писал(а):Можно было и в исходном коде убрать volatile - прошивка тоже бы уменьшилась.
В исходном коде низя убирать volatile, т.к. флаги еще в прерывании используются. А вообще (ради чтобы проверить) пробовал убрать volatile, код уменьшился всего на 70 байт.....
Kavka писал(а):Если вам volatile реально нужен и вы его вернёте в варианте с регистрами EEPROM, то размер может вырасти опять.
Помоему к регистрам портов нет смысла указывать volatile, т.к. они итак в волатильном режиме работают.....
Re: C для AVR -- пишем аккуратно.
Добавлено: Вс дек 16, 2012 15:11:46
ibiza11
регистры периферии везде объявлены как volatile
Re: C для AVR -- пишем аккуратно.
Добавлено: Пн дек 17, 2012 08:00:20
Kavka
Про volatile и регистры в/в - да, тут я дал маху. Признаю.
Был повод повторно проштудировать sfr_defs.h.

Re: C для AVR -- пишем аккуратно.
Добавлено: Пн дек 17, 2012 11:04:00
shads
Сейчас проверил, одинаково нормально работает со следующими регистрами В/В.
Это конечно при условии, что не используются соответствующие модули.....
Код: Выделить всё
EEARL - EEPROM регистр адреса
EEDR - EEPROM регистр данных
UBRRL - USART регистр скорости интерфейса
TWBR - TWI регистр скорости передачи
TWAR - TWI регистр адреса
Re: C для AVR -- пишем аккуратно.
Добавлено: Пт май 03, 2013 22:43:03
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;
}
ПС
Ваш код взят из
http://radiokot.ru/forum/download/file.php?id=118730
Re: C для AVR -- пишем аккуратно.
Добавлено: Ср май 15, 2013 18:46:44
shads
А для чего перед
int main(void)
пишется
__attribute__((OS_main))
что делает этот атрибут?.....
Re: C для AVR -- пишем аккуратно.
Добавлено: Ср май 15, 2013 20:16:03
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.
Re: C для AVR -- пишем аккуратно.
Добавлено: Ср май 15, 2013 20:23:52
HHIMERA
shads писал(а):А для чего перед
int main(void)
пишется
__attribute__((OS_main))
что делает этот атрибут?.....
Склероз???
http://radiokot.ru/forum/viewtopic.php? ... 4#p1399164
http://radiokot.ru/forum/viewtopic.php? ... 9#p1400279
Re: C для AVR -- пишем аккуратно.
Добавлено: Ср май 15, 2013 20:32:54
shads
Да..... старею постепенно.....
Re: C для AVR -- пишем аккуратно.
Добавлено: Ср май 15, 2013 21:09:54
Kavka
Вложенные прерывания, avr-gcc, avr-libc.
Часто видел запись такого вида.
Команда разрешения прерывания будет после пролога.
Но там где надо задержку сделать минимальной есть лучший способ, с меньшей задержкой.
Тактов на 5-6 минимум (avr-gcc 4.7). Не много, но кому-то может пригодиться.
Код: Выделить всё
ISR_NOBLOCK ISR(PCINT0_vect) {
..........
}
ISR_NOBLOCK определено в avr/interrupt.h из avr-libc (WinAVR или AVR toolchain) как __attribute__((interrupt))
В этом случае команда разрешения прерывания будет вставлена компилятором, и она будет первой в прологе процедуры.