реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
mdmitry
сообщение Oct 17 2008, 13:34
Сообщение #16


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



В каком виде надо MAC-адрес выводить? В зависимости от задачи и решение.
Можно сделать массив на 6 байт и в него записывать побайтно соответствующие значения и при необходимости побайтно выводить.

Есть проблемы с глобальной переменной: во время работы printf (функция очень медленная при выводе в порт) произошло прерывание и данные поменялись. Что выводим?

Необходимо задать значения по умолчанию (прерывания не было, а printf наступил).

P.S. Палыч чуть опередил.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
_dem
сообщение Oct 17 2008, 16:23
Сообщение #17


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



Studert, а разве приведенный мною код у Вас не работает ?
Go to the top of the page
 
+Quote Post
aesok
сообщение Oct 17 2008, 17:20
Сообщение #18


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(Kernigan @ Oct 17 2008, 16:04) *
Цитата
Нельзя разрешать прерывания перед выходом из прерывания, они сами разрештся при выполнении инструкции RETI


Можно конечно. Не запрещено.


1. Лишняя инструкция SEI, прерывания все равно будут разрешенны при выполнении инструкции RETI.

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

3. Специфично для GCC. Если функции нужно место в стеке, то нужно модифицировать регистр указателя стека. Пролог и эпилог обработчика прерывиня генерируеться из предположения что прерывания отключены и в них не выполняеться временное отключение прерываний при модификации указателя стека. Разрешая прерывания до эпилога возникают условия что обработчик прерывания может быть вызван когда указатель стека модифицирован только частично (старший байт уже изменен младший еще нет), что может привести к критическим последствиям.

Анатолй.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Oct 17 2008, 18:51
Сообщение #19


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(aesok @ Oct 17 2008, 21:20) *
Пролог и эпилог обработчика прерывиня генерируеться из предположения что прерывания отключены и в них не выполняеться временное отключение прерываний при модификации указателя стека.

На мой взляд такое предположение не совсем удачно. Компилятор ничего не должен предполагать - это прерогатива программиста.

Иногда просто необходимо разрешать прерывания внутри обработчика прерывания.
Выход видится такой:
Код
intX:
   прогол
   op1
   op2
   sei
   op3
   ....
   op333
   cli
   эпилог
   reti

Может есть другие, более изящные варианты?
Где в документации можно прочесть об этом нюансе?


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
aesok
сообщение Oct 17 2008, 19:14
Сообщение #20


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(demiurg_spb @ Oct 17 2008, 22:51) *
Иногда просто необходимо разрешать прерывания внутри обработчика прерывания.
Выход видится такой:
Код
intX:
   прогол
   op1
   op2
   sei
   op3
   ....
   op333
   cli
   эпилог
   reti


Это будет работать до того момента, пока кто нибудь не напишет:
{
sei()
...
if(...)
return;
...
cli()
}

Цитата
Где в документации можно прочесть об этом нюансе?


http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gc...tion-Attributes

Цитата
signal
Use this attribute on the AVR to indicate that the specified function is a signal handler. The compiler will generate function entry and exit sequences suitable for use in a signal handler when this attribute is present. Interrupts will be disabled inside the function.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Oct 17 2008, 20:44
Сообщение #21


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(demiurg_spb @ Oct 17 2008, 21:51) *
На мой взляд такое предположение не совсем удачно. Компилятор ничего не должен предполагать - это прерогатива программиста.
Если компилятор ничего не будет предполагать, он будет связан по рукам при оптимизации.
А прерогатива програмиста - управлять его предположениями.
Предполагает же он, что переменная не меняется, пока он сам её не поменяет? Предполагает. Пока программиcт не отобъёт эту предполагалку при помощи слова volatile.
С прерываниями - если нужно, чтобы данное прерывание всё выполнялось при разрешённых прерываниях, то
Код
ISR(INT0_vect,ISR_NOBLOCK)
{
}
и прерывания будут разрешены первой командой обработчика, потом будут если надо для модификаций указателя стека запрещаться на пару команд.

Цитата(demiurg_spb @ Oct 17 2008, 21:51) *
Иногда просто необходимо разрешать прерывания внутри обработчика прерывания.
Выход видится такой:
...
Может есть другие, более изящные варианты?
Где в документации можно прочесть об этом нюансе?
Если нужно разрешить на части обработчика, то других вариантов и нет. Чтобы не було проблем, обозначеннх aesok, надо глянуть <util/atomic.h>
Код
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/atomic.h>

volatile uint8_t a, b;

ISR(INT0_vect)
{
    ++a;
    NONATOMIC_BLOCK(NONATOMIC_FORCEOFF)
    { //+++ от сих
        PORTB |= 0x02;
        if( PINB & 0x01 ) return;  // а тут запретятся перед уходом на эпилог
        PORTB |= 0x04;        
    } //--- и до сих - прерывания разрешены
    ++b;
}


Это сделано на gcc-шном расширении C - атрибутах, приписывающих к переменным некие функции инициализации и очистки. По сути - конструкторы и деструкторы, выражаясь языком C++
Приведенный выше код эквивалентен С++ - ному
Код
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/atomic.h>

class noatomic_forceoff
{
public:
    noatomic_forceoff() { sei(); }
    ~noatomic_forceoff() { cli(); }
};

volatile uint8_t a, b;

ISR(INT0_vect)
{
    ++a;
    {
        noatomic_forceoff na;
        PORTB |= 0x02;
        if( PINB & 0x01 ) return;
        PORTB |= 0x04;        
    }
    ++b;
}
вплоть до сгенерированного компиляторами кода
avr-gcc -std=c99 -O2 -S -mmcu=atmega88
avr-g++ -O2 -S -mmcu=atmega88
CODE
__vector_1:
/* prologue: frame size=0 */
push __zero_reg__
push __tmp_reg__
in __tmp_reg__,__SREG__
push __tmp_reg__
clr __zero_reg__
push r24
/* prologue end (size=6) */
lds r24,a
subi r24,lo8(-(1))
sts a,r24
/* #APP */
sei
/* #NOAPP */
sbi 37-0x20,1
sbic 35-0x20,0
rjmp .L2
sbi 37-0x20,2
/* #APP */
cli
/* #NOAPP */
lds r24,b
subi r24,lo8(-(1))
sts b,r24
rjmp .L5
.L2:
/* #APP */
cli
/* #NOAPP */
.L5:
/* epilogue: frame size=0 */
pop r24
pop __tmp_reg__
out __SREG__,__tmp_reg__
pop __tmp_reg__
pop __zero_reg__
reti


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 17th July 2025 - 23:06
Рейтинг@Mail.ru


Страница сгенерированна за 0.01371 секунд с 7
ELECTRONIX ©2004-2016