Какой-то капризный компилятор, cvavr в этом отношении проще
он не капризный, он просто не любит, когда не соблюдают правила языка Си.
И какое же правило языка СИ я нарушил?
Я объявил глобальную переменную
Код:
unsigned int last_millis=0;
куда уж глобальнее?
До winavr я использовал cvavr (возьмите мой код и прогоните через cvavr и он будет работать в таком состоянии в котором есть), с тем проблем не было, не удивительно что с этим вы используете wdt_enable с wdt_reset.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Вы сами указали в настройках компилятора определённый уровень оптимизации (предположу, -O3). Тем самым дав команду компилятору уменьшать размер кода, потребление RAM и т.д. Так что это ваша задача теперь - объявлять глобальные переменные volatile, если они могут измениться в прерывании, и это всё оговорено в документации.
Ну ОК, не то чтобы указали, а просто либо не знали, либо забыли. Но, по большому счёту, какая разница?
P.S. "На пальцах", как это работает (может, где-то упрощённо, но главное - суть):
Есть глобальная переменная - где-то в RAM. Как работает обычная функция (та же main) - переменная вытаскивается из RAM в какой-то из регистров, и там с нею уже все арифметические операции производятся. По выходу из функции изменённая переменная возвращается в RAM.
Соответственно, если МК уйдёт в прерывание, в котором его обработчик внезапно поменяет в памяти эт у переменную, то функция по возврату к ней управления продолжит работать с тем значением, что сохранено в регистре. И по окончании вернёт в память значение, невзирая на то, что там уже "постарался" обработчик прерывания.
Аналогичное явление происходит в многопоточных приложениях, когда несколько потоков, работая с одной глобальной переменной фактически (за счёт оптимизации компилятором) работают каждый с временной локальной копией.
Это нормальное поведение при включенной оптимизации для большинства переменных (ведь в прерывании их не так много меняется обычно). Если такое не нужно для конкретной переменной - объявляем её volatile, после чего при любых попытках работать с ней она будет "обновляться" из памяти. На это нужны, соответственно, лишние операции и такты процессора.
То что CVAVR так делает даже не с volatile переменными может говорить лишь о том, что он генерирует не самый оптимальный код. То есть, даже обычные глобальные переменные, которые в прерываниях не участвуют, вероятно, постоянно "синхронизированы" с RAM при работе с ними. А это уже лишнее
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Можно было бы рассказать еще об атомарности и зачем она нужна, но подождем пока человек наступит на очередные грабли и прибежит жаловаться на неправильные компиляторы. Документацию ведь для дураков пишут.
Я думаю, просто надо грамотно писать программу, и оно само получится. А если размер скомпилированной проги вылезет за 6кб - чем поможет makefile ? "Утопчет" байты кода или отрежет "ненужные", по его мнению ? Полученный hex всегда можно посмотреть текстовым редактором, и если он вылез за размер, то это видно, и его не надо заливать в МК.
А если размер скомпилированной проги вылезет за 6кб - чем поможет makefile ? "Утопчет" байты кода или отрежет "ненужные", по его мнению ?
Если размер проги вылазит за пределы, компилятор предупреждает об этом. В данном случае если 8меги не хватит, есть 168 и 328меги. Просто думал, что makefile есть способ сказать что не 8кБ а 6кБ всего.
Может уже было - искать по ветке долго... Установил на новый ноутбук (Win7) WinAVR20100110. При открытии нотепейджем исходника русские комментарии читаются как крякозяблики. На старом ноутбуке (WinXP) всё было нормально. Подскажите путь решения проблемы. Спасибо!
Dimon456: P.S. "На пальцах", как это работает (может, где-то упрощённо, но главное - суть):
Есть глобальная переменная - где-то в RAM. Как работает обычная функция (та же main) - переменная вытаскивается из RAM в какой-то из регистров, и там с нею уже все арифметические операции производятся. По выходу из функции изменённая переменная возвращается в RAM.
Соответственно, если МК уйдёт в прерывание, в котором его обработчик внезапно поменяет в памяти эт у переменную, то функция по возврату к ней управления продолжит работать с тем значением, что сохранено в регистре. И по окончании вернёт в память значение, невзирая на то, что там уже "постарался" обработчик прерывания.
Аналогичное явление происходит в многопоточных приложениях, когда несколько потоков, работая с одной глобальной переменной фактически (за счёт оптимизации компилятором) работают каждый с временной локальной копией.
Это нормальное поведение при включенной оптимизации для большинства переменных (ведь в прерывании их не так много меняется обычно). Если такое не нужно для конкретной переменной - объявляем её volatile, после чего при любых попытках работать с ней она будет "обновляться" из памяти. На это нужны, соответственно, лишние операции и такты процессора.
То что CVAVR так делает даже не с volatile переменными может говорить лишь о том, что он генерирует не самый оптимальный код. То есть, даже обычные глобальные переменные, которые в прерываниях не участвуют, вероятно, постоянно "синхронизированы" с RAM при работе с ними. А это уже лишнее
Заголовок сообщения: Re: WinAvr в вопросах и ответах
Добавлено: Вс фев 12, 2017 05:59:32
Собутыльник Кота
Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2694 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
WiseLord писал(а):
Есть глобальная переменная - где-то в RAM. Как работает обычная функция (та же main) - переменная вытаскивается из RAM в какой-то из регистров, и там с нею уже все арифметические операции производятся. По выходу из функции изменённая переменная возвращается в RAM.
Соответственно, если МК уйдёт в прерывание, в котором его обработчик внезапно поменяет в памяти эт у переменную, то функция по возврату к ней управления продолжит работать с тем значением, что сохранено в регистре. И по окончании вернёт в память значение, невзирая на то, что там уже "постарался" обработчик прерывания.
Следует добавить, что volatile не дает атомарности и при работе с многобайтными переменными, в некоторых случаях, нужно запрещать прерывания.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Скорее всего придётся редактировать сами исходники - у "старых" атмег (8, 16, 32) регистры расположены не так, как у более новых. А если всё совпадает - искать в Makefile параметр target и подставлять туда идентификатор контроллера.
_________________ Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 27
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения