|
Еще раз про powerdown, нужен совет |
|
|
|
Apr 16 2008, 07:32
|
Гуру
     
Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446

|
С чего возник вопрос. Есть прибор, который с периодичностью 1 с просыпается и контролирует два параметра с помощью АЦП. Приборчик должен быть автономный и долгоиграющий. Чтобы знать, что приборчик работает и батарейки не сдохли предусмотрена индикация каждые 10 с, т.е. каждый десятый раз просыпания. Теперь сам вопрос. На http://www.gaw.ru/html.cgi/txt/doc/micros/avr/arh128/4.htm прочитал: Выход из режима сна происходит при возникновении разрешенного прерывания. В этом случае, помимо времени старта микроконтроллер приостанавливается на 4 машинных цикла, выполняет процедуру обработки прерывания и продолжает выполнять команды следующие за SLEEP. Содержимое файла регистров и статического ОЗУ остается неизменным после выхода из режима сна. Если во время действия режима сна возникает условие сброса, то микроконтроллер пробуждается и исполняет код программы по вектору сброса. Можно ли использовать регистр ОЗУ под счетчик к-ва "пробуждений" и как это сделать программно? Желательно уходить в power-down, а просыпаться по WDT. Использую С, WinAVR. Спасибо!
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
|
Apr 17 2008, 14:55
|
Местный
  
Группа: Свой
Сообщений: 234
Регистрация: 30-03-07
Из: Одесса
Пользователь №: 26 621

|
Цитата(smk @ Apr 16 2008, 10:32)  Можно ли использовать регистр ОЗУ под счетчик к-ва "пробуждений" и как это сделать программно? Желательно уходить в power-down, а просыпаться по WDT. Использую С, WinAVR. Спасибо! Просыпание по WDT есть два варианта - использовать прерывание (мега48, 88, 168) или сброс по WDT. Первый вариант типа возможен, но ввиду глюка прерывания от собаки работает не всегда. Если уходить в сброс, то необходимо счетчик засунуть в неинициализируемые данные. Если мне не изменяет память, в WinAVR необходимо объявить секцию с требуемыми атрибутами. (директива SECTION вроде). Тогда при сбросе эта секция перетираться не будет. Для инициализации первого включения после установки новых батарей необходимо будет добавить проверку на валидность значения этого счетчика - или CRC, или просто проинвертированное значение этого счетчика.
|
|
|
|
|
Apr 17 2008, 16:35
|
Гуру
     
Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446

|
Цитата после установки новых батарей В этой ситуации счет спокойно можно начинать с нуля. Суть в том, чтоб не утомлять пользователя частыми сигналами о работоспособности. Цитата в WinAVR необходимо объявить секцию с требуемыми атрибутами. Начинаю читать. Если кто-то знает как это делается - поделитесь опытом и (если можно) примером кода. Я так понял речь об этгом?: 9.3.3 The .bss Section Uninitialized global or static variables end up in the .bss section. Как объявить такую переменную и как потом с ней обращаться?
Сообщение отредактировал smk - Apr 17 2008, 16:56
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
|
Apr 17 2008, 18:21
|
Частый гость
 
Группа: Участник
Сообщений: 169
Регистрация: 31-08-05
Из: New York
Пользователь №: 8 118

|
Цитата(smk @ Apr 17 2008, 12:35)  В этой ситуации счет спокойно можно начинать с нуля. Суть в том, чтоб не утомлять пользователя частыми сигналами о работоспособности. Начинаю читать. Если кто-то знает как это делается - поделитесь опытом и (если можно) примером кода.
Я так понял речь об этгом?: 9.3.3 The .bss Section Uninitialized global or static variables end up in the .bss section.
Как объявить такую переменную и как потом с ней обращаться? 7.7.5 The .noinit Section This sections is a part of the .bss section. What makes the variables which are defined as such: int foo __attribute__ ((section (".noinit")));
--------------------
ASB
|
|
|
|
|
Apr 17 2008, 21:25
|
Частый гость
 
Группа: Участник
Сообщений: 169
Регистрация: 31-08-05
Из: New York
Пользователь №: 8 118

|
Цитата(smk @ Apr 17 2008, 15:54)  Если я правильно понял, то так будет работать:
int my_variable __attribute__ ((section (".noinit"))); //объявляем глобальной . . .
if (my_variable==10) { //показываем, что прибор работает my_variable=0; } Все правильно? Вот, что написано в мануале: The .noinit SectionThis sections is a part of the .bss section. What makes the .noinit section special is that variables which are defined as such: int foo __attribute__ ((section (".noinit"))); will not be initialized to zero during startup as would normal .bss data. Only uninitialized variables can be placed in the .noinit section. Thus, the following code will cause avr-gcc to issue an error: int bar __attribute__ ((section (".noinit"))) = 0xaa; It is possible to tell the linker explicitly where to place the .noinit section by adding -Wl,--section-start=.noinit=0x802000 to the avr-gcc command line at the linking stage. For example, suppose you wish to place the .noinit section at SRAM address 0x2000: $ avr-gcc ... -Wl,--section-start=.noinit=0x802000 ... Note: Because of the Harvard architecture of the AVR devices, you must manually add 0x800000 to the address you pass to the linker as the start of the section. Otherwise, the linker thinks you want to put the .noinit section into the .text section instead of .data/.bss and will complain.
--------------------
ASB
|
|
|
|
|
Apr 17 2008, 21:49
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(smk @ Apr 17 2008, 19:35)  Uninitialized global or static variables ... Как объявить такую переменную и как потом с ней обращаться? Как это в WinAVR не скажу, а в других компиляторах предельно просто. Есть расширение в виде ключевого слова. В ИАР это: __no_initВ HiTech: persistentДобавляется к любой переменной. Эта переменная попадает в секцию, которая не обнуляется после рестарта. Больше никаких отличий нет. Пример: __no_init unsigned char Counter; У меня в приборах с батарейным питанием половина переменных __no_init Например регистры часов. Иначе любой случайный сброс - и время 00:00
|
|
|
|
|
Apr 18 2008, 06:39
|
Гуру
     
Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446

|
Цитата Вот, что написано в мануале:
The .noinit Section This sections is a part of the .bss section. What makes the .noinit section special is that variables which are defined as such: int foo __attribute__ ((section (".noinit"))); will not be initialized to zero during startup as would normal .bss data.
Only uninitialized variables can be placed in the .noinit section. Thus, the following code will cause avr-gcc to issue an error: int bar __attribute__ ((section (".noinit"))) = 0xaa;
It is possible to tell the linker explicitly where to place the .noinit section by adding -Wl,--section-start=.noinit=0x802000 to the avr-gcc command line at the linking stage. For example, suppose you wish to place the .noinit section at SRAM address 0x2000:
$ avr-gcc ... -Wl,--section-start=.noinit=0x802000 ...
Note: Because of the Harvard architecture of the AVR devices, you must manually add 0x800000 to the address you pass to the linker as the start of the section. Otherwise, the linker thinks you want to put the .noinit section into the .text section instead of .data/.bss and will complain. А как Вы сами это пользуете? Спасибо! Вот это место не совсем понял: Note: Because of the Harvard architecture of the AVR devices, you must manually add 0x800000 to the address you pass to the linker as the start of the section. Otherwise, the linker thinks you want to put the .noinit section into the .text section instead of .data/.bss and will complain. Перевод: Примечание: Из-за Гарвардской архитектуры устройств AVR, вы должны вручную добавить 0x800000 по адресу, который вы передаете редактору связей как запуск секции. Иначе, редактор связей думает, что вы хотите поместить .noinit секцию в .text секцию вместо .data/.bss и будете жаловаться.
Сообщение отредактировал smk - Apr 18 2008, 07:10
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
|
Apr 18 2008, 07:15
|

Местный
  
Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035

|
Цитата(smk @ Apr 17 2008, 23:54)  Если я правильно понял, то так будет работать:
int my_variable __attribute__ ((section (".noinit"))); //объявляем глобальной
Все правильно? Да правильно. Сам использую также: uint8_t resetReason __attribute__ ((section (".noinit"))); Сохраняю там значение, если контроллер ресетнули программно. После ресета считываю то же значение, которое записал перед ресетом. Спесиально эти секции в скрипте линкера не описываю, потому что WinAvr использует скрипты, где всё уже описанно. После сборки проекта, можете сделать map карту проекта линкером и убедиться, что всё слинковалось куда надо.
|
|
|
|
|
Apr 18 2008, 07:36
|
Гуру
     
Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446

|
Цитата Да правильно. Спасибо! В студии работает как и было задумано. Интересно теперь как в железе будет... И еще нужна консультация. Я правильно отправляю в power-down? MCUCR=SLEEP_MODE_PWR_DOWN; sleep_enable (); sleep_mode (); Спасибо!
Сообщение отредактировал smk - Apr 18 2008, 07:47
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
|
Apr 18 2008, 08:41
|

Местный
  
Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035

|
Вы какую мегу юзаете? В меге 1281, которую я использую есть регистр: SMCR – Sleep Mode Control Register. Вот его и пользую. В даташите приведены кода всех энергосберегающих режимов. В режим power down вхожу так: Код SMCR = (1 << SM1) | (1 << SE); // power-down asm volatile ("sleep"); А MCUCR - MCU Control Register, что вы с помощью него хотите сделать?
|
|
|
|
|
Apr 18 2008, 08:47
|
Гуру
     
Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446

|
Цитата Вы какую мегу юзаете? tiny13 Цитата А MCUCR - MCU Control Register, что вы с помощью него хотите сделать? Там есть биты SE - sleep_enable; SM(1,0) - sleep_mode. А Ваш пример явно мне интересен. Спасибо!
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
|
Apr 18 2008, 08:58
|

Местный
  
Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035

|
Цитата(smk @ Apr 18 2008, 12:47)  Там есть биты SE - sleep_enable; SM(1,0) - sleep_mode.  Тогда наверное правильно. Надо смотреть что представляют из себя макросы и функции: SLEEP_MODE_PWR_DOWN sleep_enable () sleep_mode ()
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|