Very Hot Topic (More than 50 Replies) Микроконтроллер - как перспектива примочкостроения (Прочитано 128829 раз)
Peratron
Гуру
*****
Вне Форума


GTLab - forever!

Сообщений: 13579
Зарегистрирован: 16.08.2009
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #240 - 12.10.2011 :: 07:29:36
Post Tools
Цитата:
Через отдельную функцию, которая при старте запрещает нужные прерывания, читает переменную а потом возвращает прерывания?
Нормальная подпрограмма сама заботится об исключении подобных коллизий - если в С функция написана через пень колоду, то боржом пить поздно...

Цитата:
Я понимаю что эта коллизия может произойти раз в 1000 лет...
При нормальном кодировании такая коллизия должна быть подавлена в зародыше.
Во всяком случае при написании мониторов для РК-86, а потом и для самоспроектированного PCХТ в любой вызываемой функции я ставил и запреты на прерывания, и отслеживание стека, и прочие причиндалы, исключающие сбои...
  

(Вложенный файл удалён)

Схемотехническая мантра: титцешенкохоровицехилл. Повторять до просветления...
Наверх
 
IP записан
 
Ivana
Участник


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #241 - 12.10.2011 :: 08:03:48
Post Tools
Значит я не зря озадачился этим вопросом. Но поскольку с ним должны были сталкиваться почти все, то скорее всего есть уже наработанные людьми методы решения, которые хочется узнать и изучить. Хотя я и свои придумать могу (пару уже предложил), но имхо неразумно и самонадеянно исключать возможность того, что есть красивые варианты до которых я не додумался  Круглые глаза
  

(Вложенный файл удалён)
Наверх
 
IP записан
 
Rst7
Гуру
*****
Вне Форума


Мимо проходил...

Сообщений: 1619
Местоположение: Харків-city
Зарегистрирован: 22.03.2010
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #242 - 12.10.2011 :: 08:57:39
Post Tools
Цитата:
Получается, что если мы на С читаем в локальную переменную из глобальной, а это выполняется за много ASM команд, то у нас запросто может прийти прерывание которое пишет эту же глобальную переменную и в результате мы можем прочитать начало старого значения а конец нового?


При любом многопоточном коде такое возможно - наличие разрешенных прерываний - это один из видов многопоточности.

Естественно, что доступ к объектам, который осуществляется неатомарным способом из нескольких потоков (например, за несколько команд) надо обрамлять в критические секции (вид этих критических секций может разнится от среды выполнения).

Следует понимать, что неатомарность доступа бывает везде. И если, например, на AVR на неатомарность можно наступить уже при работе с int (т.к. 16 бит), то на ARM это обычно проявляется при работе со структурами как с целыми объектами.

Обычно в среде различных RTOS есть специальные примитивы, которые позволяют обеспечивать быструю блокировку многопоточности для такого доступа. Следует, однако, иметь в виду, что блокировать шедуллер следует только на минимально возможное время - иначе могут возникнуть совершенно нежелательные задержки в работе других потоков. Если надо монополизировать доступ к какому-либо объекту на длительное время, то в средах RTOS рекомендуется использовать более продвинутые примитивы синхронизации - мьютексы и тому подобное.

Теперь о простом способе красивого написания атомарного кода (на Си). Я обычно пользуюсь таким макросом (пример для IAR'а в инкарнации ARM Cortex-M3)
Код
Select All
//Содержимое подходящего .h-файла
#pragma inline=forced
static __istate_t get_INTERRUPT_and_CLI() {__istate_t s=__get_interrupt_state(); __disable_interrupt(); return s; }

#define ATOMIC_CODE()   for(__istate_t __temp=get_INTERRUPT_and_CLI(),iter=0; iter<1; iter++,__set_interrupt_state(__temp))


//Использование
void foo(void)
{
  ...
  ATOMIC_CODE()
  {
    //Этот код в пределах скобок будет выполнен с запрещенными прерываниями. После выхода из блока состояние прерываний будет восстановлено.
    a++; //Кстати, если а - глобальная переменная, такой инкремент нифига не атомарен
  }
  ...
}
 



Что делают функции __get_interrupt_state, __disable_interrupt и __set_interrupt_state, думаю, понятно само за себя. На самом деле пара __get/__set представляет из себя минимально возможный способ получить и восстановить состояние прерываний - обычно это одна-две команды на любой архитектуре.

Цикл в макросе оптимизатор полностью вычищает, т.к. его работа полностью предсказуема и представляет из себя одну итерацию.

Ну а в общем намного выше я рассказывал о прелестях регистровой архитектуры и правильным способом работы с переменными на процессорах с такой архитектурой - загрузили из ОЗУ в регистры, потрудились, выгрузили. Так вот в таком случае часто обеспечение атомарности упрощается - один атомарный блок в начале, один - в конце.

Цитата:
Во всяком случае при написании мониторов для РК-86


Господин Peratron, Вам абы слово вставить? На РК-86 сигнал прерывания на процессор не приходил никогда, ибо железно сидел на +5. А на вывод сигнализации о разрешении/запрете прерываний вообще был подвешен матюгальник. Ни о какой многопоточности из-за этого там не могло быть и речи, а следовательно никакие примитивы для синхронизации там были не нужны.
  

(Вложенный файл удалён)

"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредствен
Наверх
WWW  
IP записан
 
Ivana
Участник


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #243 - 12.10.2011 :: 10:25:03
Post Tools
Сижу у заказчиков, интенсивно работаю и уже второй час не могу детально прочитать и обдумать вышенаписанное - а чувствую, что там есть над чем подумать!  Круглые глаза Позже дома проанализирую. Спасибо!  Круглые глаза

ЗЫ вообще, имхо часть постов из этого топика надо в меморис и на винт - как ценную информацию.
  

(Вложенный файл удалён)
Наверх
 
IP записан
 
Ivana
Участник


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #244 - 13.10.2011 :: 12:26:19
Post Tools
Насчет анализа вышеприведенного примера и общей философии по поводу что хорошо что регистры восстанавливаются после завершения прерывания а хотя бы область ОЗУ - нет, я возьму таймаут ещё на подумать  Круглые глаза

А комментарии по ходу боя - у меня устройство шлет по USARTу регулярно немалый объем информации, мне из неё нужно максимум процентов 5 (в худшем случае). Хотел повесить на процедуру обработки прерывания приема небольшой анализатор принятого сообщения и дублирования его куда надо если оно ценное - но политика общего проекта такова, что мы USART максимально не нагружаем - а значит придется записывать ВСЁ ПОДРЯД что он пришлет в длинный буфер (причем, придется рассчитать его максимально необходимую длину), а потом долгими зимними вечерами (и только вечерами, а днем делать другое Улыбка ) сидеть и разгребать - что же он нам там наприсылал и выискивать в этом крупицы ценных данных... Да ещё и думать - как это красиво организовать Улыбка
  

(Вложенный файл удалён)
Наверх
 
IP записан
 
Rst7
Гуру
*****
Вне Форума


Мимо проходил...

Сообщений: 1619
Местоположение: Харків-city
Зарегистрирован: 22.03.2010
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #245 - 01.11.2011 :: 14:26:30
Post Tools
Новость  для тех, кто до сих пор живет в прошлом веке и кроме DIP-корпусов ничего не переваривает.

http://www.mt-system.ru/index.php?id=93243

  

(Вложенный файл удалён)

"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредствен
Наверх
WWW  
IP записан
 
Ivana
Участник


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #246 - 01.11.2011 :: 21:47:26
Post Tools
Покидайтесь плиз помидорами - мне самому кажется что весьма коряво, но красивее минимизорованнее по ОЗУ придумать не могу...

Код
Select All
void GPS_send_command_RMC_call_freq(char call_freq)
{
	//$PMTK314,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2D<CR><LF>

	char i, j;

	i = 0;
	GPS_command_buffer[i++] = '$';
	GPS_command_buffer[i++] = 'P';
	GPS_command_buffer[i++] = 'M';
	GPS_command_buffer[i++] = 'T';
	GPS_command_buffer[i++] = 'K';
	GPS_command_buffer[i++] = '3';
	GPS_command_buffer[i++] = '1';
	GPS_command_buffer[i++] = '4';
	GPS_command_buffer[i++] = ',';
	GPS_command_buffer[i++] = '0';
	GPS_command_buffer[i++] = ',';

	j = call_freq;
	if (j >= 100)
	{
		GPS_command_buffer[i++] = '0' + j/100;
		j = j - 100*(j/100);
		GPS_command_buffer[i++] = '0' + j/10;
		j = j - 10*(j/10);
	}
	else if (j >= 10)
	{
		GPS_command_buffer[i++] = '0' + j/10;
		j = j - 10*(j/10);
	}
	GPS_command_buffer[i++] = '0' + j;

	for (j=0; j<17; j++)
	{
		GPS_command_buffer[i++] = ',';
		GPS_command_buffer[i++] = '0';
	}
	GPS_command_buffer[i++] = 0;

	j = 0;
	i = 1;
	while (GPS_command_buffer[i]) j = j^GPS_command_buffer[i++];

	GPS_command_buffer[i++] = GPS_char_multiply;
	GPS_command_buffer[i++] = '0' + j/16;
	GPS_command_buffer[i++] = '0' + (j - 16*(j/16));
	GPS_command_buffer[i++] = GPS_char_enter;
	GPS_command_buffer[i++] = GPS_char_return;
	GPS_command_buffer[i++] = 0;
}	 

  

(Вложенный файл удалён)
Наверх
 
IP записан
 
Rst7
Гуру
*****
Вне Форума


Мимо проходил...

Сообщений: 1619
Местоположение: Харків-city
Зарегистрирован: 22.03.2010
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #247 - 01.11.2011 :: 22:34:04
Post Tools
Ну во-первых... Конечно, обычно компиляторы переделывают при возможности работу с массивами на работу с указателями, но более верно было бы
Код
Select All
char *d=GPS_command_buffer;

*d++='$';
*d++='P';
*d++=....;
*d++=....;
....
 



Второе - это, конечно, преобразование числа в строку. Есть масса вариантов. Например, для ARM'а ниче так смотрится такое:
Код
Select All
typedef unsigned long UREG32;
typedef unsigned long UREG;

char *i2a(char *s, UREG32 n)
{
  UREG c;
  char *res;
  char *d=s;
  do
  {
    UREG b=n%10; /* get next digit */
    *s++=b+'0';
  }
  while ((n/=10)>0);     /* delete it */
  res=s;
  while(c=*--s,d<s)
  {
    *s=*d;
    *d++=c;
  }
  return res;
}
 



Функция печатает число в строку и возвращает указатель на следующий символ, т.е. в Вашем случае ее можно использовать так:
Код
Select All
char *d=GPS_command_buffer;

*d++='$';
*d++='P';
*d++=....;
*d++=....;

d=i2a(d,call_freq);

...
 



Вообще, вопрос оптимизации процедуры печати десятичных чисел очень обширный. Я так, на вскидку, знаю еще пару более быстрых способов.
  

(Вложенный файл удалён)

"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредствен
Наверх
WWW  
IP записан
 
Ivana
Участник


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #248 - 02.11.2011 :: 09:36:50
Post Tools
Как всегда спасибо за помощь и советы Улыбка С указателями (и даже страшными указателями на функции  Круглые глаза) чувствую, придется разбираться поплотнее, чтобы не просто думать что их "более менее понял", а активно использовать - иначе без них совсем как без рук Улыбка Кстати, на каждую строку типа
Код
Select All
GPS_command_buffer[i++] = '$'; 


компилятор (почему-то) выдает мне warning, попробую Ваш вариант с указателями.
Прожую дома Ваши примеры Улыбка

ЗЫ этот код как раз пишется для AVR, иначе вспомогательные переменные индексов я бы делал не char а разрядности регистров, например 32.

ЗЗЫ а преобразование числа в строку мне в этой задаче придется делать множество раз, поэтому было бы совсем хорошо иметь для этого одну красивую функцию  Круглые глаза
  

(Вложенный файл удалён)
Наверх
 
IP записан
 
Rst7
Гуру
*****
Вне Форума


Мимо проходил...

Сообщений: 1619
Местоположение: Харків-city
Зарегистрирован: 22.03.2010
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #249 - 02.11.2011 :: 09:48:14
Post Tools
Цитата:
ЗЫ этот код как раз пишется для AVR
...
поэтому было бы совсем хорошо иметь для этого одну красивую функцию


А, для AVR самый годный способ немного другой. Вечером положу пример. Правда, компилятор с оптимизацией справился не полностью, посему код был изготовлен полувручную - сначала был скомпилен сишный исходник, а потом допилен его асм-листинг.

Кстати, какой компилятор используете?
  

(Вложенный файл удалён)

"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредствен
Наверх
WWW  
IP записан
 
Ivana
Участник


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #250 - 02.11.2011 :: 09:54:03
Post Tools
Спасибо за возню с моими блохами Улыбка Компилятор WinAVR с официального сайта. Предпоследняя версия вроде, напишу как посмотрю её. Работаю в AVR Studio (но не последней, а предыдущей 4-й версии по моему - дома на компе посмотрю точнее, ибо в последней версии нет поддержки внутренним симулятором нужного камня - ....USB162..... четатам, дома уточню опять же Улыбка )
  

(Вложенный файл удалён)
Наверх
 
IP записан
 
Rst7
Гуру
*****
Вне Форума


Мимо проходил...

Сообщений: 1619
Местоположение: Харків-city
Зарегистрирован: 22.03.2010
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #251 - 02.11.2011 :: 10:03:12
Post Tools
Цитата:
Компилятор WinAVR с официального сайта.


Ну тогда сами регистры переименуете согласно соглашениям GCC о передаче параметров.
  

(Вложенный файл удалён)

"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредствен
Наверх
WWW  
IP записан
 
Ivana
Участник


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #252 - 02.11.2011 :: 10:17:37
Post Tools
Улыбка Я конечно буду признателен за допиленный ASM код этой функции для AVR, но на текущий момент я хотел бы отложить разбирательство в GCC соглашениях и использовании регистров, и ограничиться может не такой оптимизированной, но C - функцией, с которой надеюсь этот вопрос будет за кадром  Круглые глаза

ЗЫ Я не то чтобы хочу Вашими руками и мозгами сделать свои задачи, конечно я хочу и буду писать сам и это и многое другое Улыбка Вот Вы мне дали листинг этой функции для ARM, мне уже есть пища для подумать, и может дошлифовать её под AVR - насколько хватит ума, перед этим разобравшись в указателях и особенно методах её вызова  Круглые глаза А если для сравнения дадите С функцию для AVR, да ещё если она будет отличаться сильно - будет ещё веселее Улыбка

ЗЫ я подозреваю, что есть стандартные библиотеки типа std/io, где такие функции уже есть. Но по разным причинам хочется написать её самому (или разобраться с предложенной)  Круглые глаза
  

(Вложенный файл удалён)
Наверх
 
IP записан
 
Rst7
Гуру
*****
Вне Форума


Мимо проходил...

Сообщений: 1619
Местоположение: Харків-city
Зарегистрирован: 22.03.2010
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #253 - 02.11.2011 :: 10:27:17
Post Tools
Цитата:
А если для сравнения дадите С функцию для AVR, да ещё если она будет отличаться сильно - будет ещё веселее


Сильно по другому. Там другой алгоритм.
  

(Вложенный файл удалён)

"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредствен
Наверх
WWW  
IP записан
 
Ivana
Участник


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #254 - 02.11.2011 :: 10:34:03
Post Tools
Другой алгоритм - это не страшно Улыбка Я пока в восторге от лаконичности вызова
Код
Select All
d=i2a(d,call_freq); 


при том, что я пока не понимаю детально совсем как он работает (сижу программирую у заказчиков на 1С, не могу даже отвлечься и вдуматься по уму)  Круглые глаза Если метод вызова будет такой же или подобный, тоже удобный, то внутренний алгоритм получения разрядов может быть разным - он с точки зрения внешнего вызова за кадром Улыбка
  

(Вложенный файл удалён)
Наверх
 
IP записан
 
Ivana
Участник


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #255 - 02.11.2011 :: 14:48:11
Post Tools
Перед осмыслением вышенаписанных функций - лирическое отступление - сказка/фантазияна тему "Как мы делили ОЗУ - много нас а оно одно!"  Смех

Есть ОЗУ. Адрес/значение. Когда программировал на ASM - сам составлял модель разбиения его на блоки/сектора, время их заполнения, время когда они нужны и время когда их можно использовать под другие задачи - и при этом не был ограничен никакими рамками  Круглые глаза
Есть C. Переменная/значение. И адрес, конечно. Или регистр  Смех Ну допустим, условимся что адрес. Глобальные переменные сразу при определении отрезают у нас щедрый ломоть ОЗУ, который потом программа не сможет использовать ни подо что другое (если она конечно находится в здравом уме и светлой памяти, а не бежит, к примеру, по массиву когда он уже закончился  Круглые глаза ). То есть, глобальные переменные сразу уменьшают свободный объем ОЗУ, которым может оперировать.... ээээээ.... компилятор - ведь мы же при программировании на С редко опускаемся до абсолютных значений адресов ОЗУ! Далее - локальные переменные. В оставшемся месте ОЗУ выделяется для них память, все хорошо. В любом месте функции я могу обратиться к ним по имени! Вызываю вложенную функцию... Формально это что? Rcall и ret? Однако, при этом вроде как сохраняются в стек регистры(?) и ТЕРЯЕТСЯ связь с переменными исходной функции по их именам! Но что делает компилятор если я во вложенной функции определяю новые переменные? Он нарезает для них место в ОЗУ, которое НЕ ЗАНЯТО переменными вызывающей функции - чтобы последние остались теми же после возвращения вызова! Однако, они есть - но обратиться к ним по именам мы не можем! (или я неправ?) А через указатели?..... Не знаю, надо думать  Улыбка  Далее - что может моя вызываемая функция сделать полезного, кроме как вернуть значение БАЗОВОГО типа и поменять глобальную переменную? Тот же пример с числом в строку = массив символов. Функция не может вернуть массив. Хорошо, может заполнить массив и вернуть указатель на его начало! Но после выполнения функции её локальные переменные считаются очищенными - и этот массив тут же может затереться при последующих действиях в вызывающей функции! Может тогда определить в вызывающей функции локальную переменную - массив, и вызвать функцию, куда передать указатель на его начало, чтобы та функция его заполнила весь? Это то по крайней мере мне понятно, похоже на аналогию с глобальными переменными...

ЗЫ сумбурная лирика, понимаю.... Но мне все никак не удается сформировать у себя в голове красивую абстракцию, называемую "язык C"!  Смущённый

ЗЗЫ такая ПРОСТЕЙШАЯ задача - преобразовать число в строку! У Керригана-Ритчи это азы букваря!.... С неё начинаются первые шаги!.... А я все никак не постигну  Печаль .....
  

(Вложенный файл удалён)
Наверх
 
IP записан
 
TylerDurden
Разбирающийся
****
Вне Форума


Вы знакомы с
м-ром Дерденом?

Сообщений: 1447
Местоположение: Кривой Рог, Украина
Зарегистрирован: 19.04.2005
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #256 - 02.11.2011 :: 15:12:21
Post Tools
OFF
// Хорошо нам, тупым 1С-никам Улыбка
Стр=Строка(Число); 
// И свего делов-то
  

(Вложенный файл удалён)

Кто спер мою подпись? &&&&
Наверх
 
IP записан
 
Ivana
Участник


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #257 - 02.11.2011 :: 15:42:44
Post Tools
Да, всегда хорошо пользоваться инструментом, которым владеешь Улыбка...

ЗЫ Будда в свое время был настолько целеустремленный, серьезный и бескомпромиссный, что однажды почувствовал суть и сказал - вот сейчас сяду под это дерево боддхи и буду сидеть до тех пор, пока не постигну суть!  Круглые глаза И постиг! (По разным данным, сидя под деревом от 100 дней до 6-10 лет!) А я через полчаса собираюсь на каток опробовать новые коньки - а способ вызова и работу той функции с указателями из нескольких строчек так пока и не постиг  Круглые глаза Куда уж тут на просветление рассчитывать....

ЗЗЫ Решился открыть К&R - глава "5.2 Указатели и аргументы функций" - и забрезжили первые признаки понимания.... Наверное, надо дальше почитать!  Смех
« Последняя редакция: 02.11.2011 :: 15:59:17 от »  

(Вложенный файл удалён)
Наверх
 
IP записан
 
Ivana
Участник


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #258 - 02.11.2011 :: 19:56:03
Post Tools
Понял! Улыбка Параметры в функцию передаются по значению, но мы всегда можем передать в функцию любое количество указателей на заранее объявленные переменные (как глобальные, так и в вызывающей функции, и даже в N-й функции уровня выше - транзитом через несколько функций  Круглые глаза ), а в самой функции по этим указателям и читать и записывать значения соответствующих переменных! Улыбка И +- от этих указателей вверх/вниз - имея в виду что это массивы и существуют (определены) соответствующие элементы! Улыбка

Тогда предложенная строка вызова функции делает следующее - принимает текущий указатель на последний+1 элемент массива (который у нас глобальная переменная, но мог быть и локальной в вызывающей функции), добивает это массив дальше нужным количеством элементов и возвращает новое значение указателя последнего+1 элемента массива, который и присваивается переменной указателя в вызывающей функции! Кто-то скажет - просто! А я скажу - круто!  Круглые глаза

ЗЫ если было бы надо добивать элементами 2 массива, надо было бы вернуть 2 новых указателя, а через возвращаемое значение это невозможно - но мы бы создали переменную в вызывающей функции, передали бы указатель на неё, в функции установили значение а после вызова прочитали бы в ней то что установила вызываемая функция! Победа разума над косной материей!  Круглые глаза По этому поводу прошу поставить душевную песню - http://www.youtube.com/watch?v=X64Xw_avLLw ;  Улыбка
  

(Вложенный файл удалён)
Наверх
 
IP записан
 
KMG
Гуру
*****
Вне Форума



Сообщений: 3773
Местоположение: Санкт-Петербург
Зарегистрирован: 06.06.2008
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #259 - 02.11.2011 :: 20:08:40
Post Tools
Передавать в функцию указатели на стековые пременные считается дурным тоном.
  

(Вложенный файл удалён)
Наверх
IP записан
 
 
  « Главная ‹ Раздел Наверх этой страницы