Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

 
Опции темы
Непрочитано 22.03.2010, 20:53  
neiver
Временная регистрация
 
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
neiver на пути к лучшему
По умолчанию Re: О программировании AVR на C++.

Немного отвлечёмся от потров и проблем универсальности.
Предлагаю интересный и удобный способ для обеспечения атомарности блока кода.
Оычно для этих целей используют код вида:

Код:
cli();
….
//блок кода, выполняющийся атомарно
….
sei();
Однако, если в этом блоке встречаются конструкции типа return, break, continue, или goto, то надо перед ними не забыть разрешить прерывания.
А не плохо было бы писать так:
Код:
ATOMIC
{
//блок кода, выполняющийся атомарно
}
или так:
ATOMIC атомарный_оператор;
Чтобы прерывания запрещались при входе в блок и разрешались (если при входе они были разрешены) привыходе, причем независимо от наличия в этом блоке операторов return, break, continue, или goto.
Такой синтаксис несложно реализовать если вспомнить про симметричность вызовов конструкторов и деструкторов классов.

Код:
class DisableInterrupts
{
public:
	DisableInterrupts()
	{
		_sreg = SREG;
		cli();
	}
	~DisableInterrupts()
	{
		SREG = _sreg;
	}
	operator bool()
	{return false;}
private:
	uint8_t _sreg;
};

#define ATOMIC if(DisableInterrupts di = DisableInterrupts()){}else
Реклама:
neiver вне форума  
Сказали "Спасибо" neiver
kot-69 (22.03.2010)
Непрочитано 22.03.2010, 21:44  
kison
Почётный гражданин KAZUS.RU
 
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
kison на пути к лучшему
По умолчанию Re: О программировании AVR на C++.

Сообщение от neiver Посмотреть сообщение
Однако, если в этом блоке встречаются конструкции типа return, break, continue, или goto, то надо перед ними не забыть разрешить прерывания.
Ну вот Вам пример из обычного С
Код:
#include ‹inttypes.h›
#include ‹util/atomic.h›

volatile uint8_t a = 55;
uint8_t array[10] = {0,0,55,77,55};

int main(void)
{
sei();
 ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
    {
    for(uint8_t i=0; i‹sizeof(array); i++) 
        {
        if(array[i] == a) 
            {
            array[i] = 0; goto L1;
            }
        array[0] = 0;
        }
    }
L1:
a = 100;
while(1)
    {
    asm volatile("nop");
    };
}
Это высосано из пальца ес-но. Перед goto прерывания не разрешал. Меня ждут проблемы?
kison вне форума  
Непрочитано 22.03.2010, 22:03  
neiver
Временная регистрация
 
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
neiver на пути к лучшему
По умолчанию Re: О программировании AVR на C++.

Сообщение от kison Посмотреть сообщение
Ну вот Вам пример из обычного С
ATOMIC_RESTORESTATE в AVR GCC реализован через нестандартный аттрибут.
__attribute__((__cleanup__(__iRestore)))
который эквивалентен вызову деструктора.
neiver вне форума  
Непрочитано 22.03.2010, 22:51  
SasaVitebsk
Гражданин KAZUS.RU
 
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
SasaVitebsk на пути к лучшему
По умолчанию Re: О программировании AVR на C++.

Сообщение от kison Посмотреть сообщение
Я ничего такого не хотел. Возможности инструмента не безграничны. А такая оптимизация вообще посильна только для мозга человека.

Вот именно. Это я не вам писал. А к вам обратился, так как то что вы считаете излишне универсальным, neiver считает недостаточно универсальным. Вот и угоди всем.
SasaVitebsk вне форума  
Непрочитано 22.03.2010, 23:22  
kison
Почётный гражданин KAZUS.RU
 
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
kison на пути к лучшему
По умолчанию Re: О программировании AVR на C++

neiver
Последний пример Вам удался. Если не принимать во внимание такие вот хитрые аттрибуты, то действительно Ваш способ удобней. Хотя ложка дегтя все же есть
Способ удобен в случае кривого стиля программинга. Ведь критическая секция должна быть как можно короче - например только на время считывания многобайтовай volatile переменой. Никаких условных операторов там быть не должно в принципе! Так что если подумать - Ваш пример очень вредный Когда человек дойдет до понимания что такое неявный вызов конструктора/деструктора, он обычно уже умеет применять критические секции правильно. А тут Вы даете готовое решение позволяющее наплевательски относиться к критическим секциям и оборачивать ими что угодно.
kison вне форума  
Непрочитано 24.03.2010, 19:33  
neiver
Временная регистрация
 
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
neiver на пути к лучшему
По умолчанию Re: О программировании AVR на C++

Продолжаем разговор. Как я и обещал, выкладываю универсальный (в статике) способ, пока только вывода в порты.
Во первых, для пинов добавлены псевдонимы вида Pa0,...,Pa7;.... Pg0,...,Pg7.
Если кому мало - можно ещё добавить.
Во вторых добавлен класс PinList, которым можно пользоваться так:

Код:
           typedef PinList‹Pa0, Pb1, Pc2, Pa3, Pb3, Pc3› pins;
	pins::Write(someValue);
В качестве параметров ему можно передать до 16 любых пинов на любом порте. Номер бита из записываемого значения соответствует номеру пина в списке. При выводе пины группируются по портам и в порт записывается сразу значение группы пинов.

Пример находится в прикреплённом архиве.
Предлагаю всем заинтересованным посмотреть этот пример и высказаться по поводу удобства использования и качества генерируемого кода.

Напоминаю, полную версию исходников можно найти здесь.


ЗЫ. Класс PinList реализован с помощью злой и очень чёрной шаблонной магии

ЗЗЫ. проект AVR Studio/WinAVR.
Вложения:
Тип файла: zip AvrCppProjects.zip (8.9 Кб, 132 просмотров)
neiver вне форума  
Эти 2 пользователя(ей) сказали Спасибо neiver за это сообщение:
look22 (05.06.2011), sspivak (29.03.2010)
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
AVR JTAGICE MKII - проблемы firmware... Luxurious AVR 25 20.10.2014 10:50
Ищу книги по AVR rocky7 Микроконтроллеры, АЦП, память и т.д 9 17.03.2010 12:43
AVR. Как правильно совместить LCD и ISP на PORTB? Serg3621 Микроконтроллеры, АЦП, память и т.д 8 04.02.2010 14:03


Часовой пояс GMT +4, время: 21:20.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot