Very Hot Topic (More than 50 Replies) Микроконтроллер - как перспектива примочкостроения (Прочитано 128711 раз)
Ivana
Участник


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #280 - 03.11.2011 :: 13:01:34
Post Tools
Ну кто там писал
Код
Select All
Стр = Строка(Число); 

? Или, к примеру
Код
Select All
Стр = "" + Число; 

Я, кстати, всегда пишу
Код
Select All
Стр = СокрЛП(Число); 

, хотя результат одинаковый, но привычка использовать СокрЛП отсекает пробелы по сторонам, а часто это бывает нужно Улыбка
  

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


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

Сообщений: 1447
Местоположение: Кривой Рог, Украина
Зарегистрирован: 19.04.2005
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #281 - 03.11.2011 :: 13:28:01
Post Tools
Да-да, давай научим их как надо программировать Улыбка
  

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

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


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #282 - 03.11.2011 :: 13:36:52
Post Tools
Используя команду "РассчитатьРегистрыВ(....)" Улыбка Ведь логично, если есть "РассчитатьРегистрыНа(....)" и "РассчитатьРегистрыПо(....)" сделать и "В"  Смех
.... и "Через(.....)"  Смех
« Последняя редакция: 03.11.2011 :: 13:40:10 от »  

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


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #283 - 03.11.2011 :: 13:48:46
Post Tools
Кстати, хотел тут было убить 2-х зайцев - с помощью новой функции
Код
Select All
count_of_order(unsigned int *n, unsigned int order) 

считать не только порядки десятичных разрядов, но и выделять шестнадцатиричные разряды контрольной суммы Подмигивание Все вроде бы хорошо, но! Компилятор выдал не ошибку а предупреждение - указатель не на тот тип. У меня контрольная сумма типа char, а функция принимает указатель на int! Улыбка Если бы функция принимала САМ int, произошло бы преобразование типов, и все бы хорошо выполнилось Улыбка А так - вместо моего 8-битного char контрольной суммы в функцию попадет ещё и неизвестно какой рядом лежащий байт, и функция честно воспримет это как входящий int! Вот это, насколько я понимаю, уже настоящая ##па, хорошо что додумался Улыбка Резюме - преобразование типов дело хорошее, но с указателями такое проделывать нельзя  Круглые глаза
В результате пришлось завести фиктивную переменную типа int, присвоить ей посчитанный char и на этот int уже передать указатель...
  

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


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

Сообщений: 1619
Местоположение: Харків-city
Зарегистрирован: 22.03.2010
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #284 - 03.11.2011 :: 21:20:27
Post Tools
Цитата:
В результате пришлось завести фиктивную переменную типа int, присвоить ей посчитанный char и на этот int уже передать указатель...


Не понял. А сделать просто указатель на char вместо int?
  

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

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


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #285 - 03.11.2011 :: 22:11:08
Post Tools
Прикол в том, что моя вызываемая функция принимает в качестве параметра указатель на int. Можно написать её дубль, принимающий указатель на char Улыбка Просто при передаче параметра в лоб по значению, я бы принимал int а передавал int или char - а функция была бы одна... Неужели я ошибаюсь в своих мыслях?

ЗЫ или Вы про хитрый прием - принимать в функции указатель на char, а значение int получать сложением СЛЕДУЮЩЕГО адреса - как старшего байта в переменной int? Но имхо - это уже похоже на заход с черного хода Улыбка Так можно конечно передавать и long через указатель на char - младший байт, а старшие выгребать инкрементированием этого указателя - интересный прием, но не знаю насколько он устойчив Улыбка
« Последняя редакция: 03.11.2011 :: 22:15:59 от »  

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


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

Сообщений: 1619
Местоположение: Харків-city
Зарегистрирован: 22.03.2010
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #286 - 03.11.2011 :: 22:16:22
Post Tools
Я что-то запутался. Покажите весь код.
  

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

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


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #287 - 03.11.2011 :: 22:20:37
Post Tools
Функция count_of_order и вызов её с указателем на int
Код
Select All
//-----------------------------------------------------------------------------------------------

char count_of_order(unsigned int *n, unsigned int order)
{
	char res = 0;

	while (*n >= order)
	{
		*n = *n - order;
		res++;
	}

	return res;
}
//-----------------------------------------------------------------------------------------------


char *int_to_string(char *s, unsigned int n)
{
	char *begin = s;
	char digit;

	if((digit = count_of_order(&n, 10000))	|| s!=begin) *s++ = '0' + digit;
	if((digit = count_of_order(&n, 1000))	|| s!=begin) *s++ = '0' + digit;
	if((digit = count_of_order(&n, 100)) 	|| s!=begin) *s++ = '0' + digit;
	if((digit = count_of_order(&n, 10)) 	|| s!=begin) *s++ = '0' + digit;

	*s++ = '0' + n;

	return s;
}
//-----------------------------------------------------------------------------------------------
 


Нужна фактически та же функция, но для char
Код
Select All
//-----------------------------------------------------------------------------------------------


char *GPS_end_of_string(char *begin, char *end)
{
	char *d;
	char chek_summ = 0;
	unsigned int int_chek_summ;

	for(d=begin+1; d<end; d++) chek_summ = chek_summ^*d;
	int_chek_summ = chek_summ;

	*d++ = GPS_char_multiply;
	*d++ = '0' + count_of_order(&int_chek_summ, 16);
	*d++ = '0' + int_chek_summ;
	*d++ = GPS_char_enter;
	*d++ = GPS_char_return;
	*d++ = 0;

	return d;
}
//-----------------------------------------------------------------------------------------------
 

  

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


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

Сообщений: 1619
Местоположение: Харків-city
Зарегистрирован: 22.03.2010
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #288 - 03.11.2011 :: 22:25:06
Post Tools
Ааа, так Вы хотели одновременно с вместе со всей генерацией данных считать контрольную сумму? Зря. Хуже будет по итогам.
  

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

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


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #289 - 03.11.2011 :: 22:31:02
Post Tools
Вопрос подсчета контрольной суммы оказался случайно - просто пример, когда нужно вызвать одну функцию с аргументами разного типа. А так - да, я оба разряда 16-ричных контрольной суммы ЧАСТИ всей строки посылки помещаю в саму строку и даже enter и return в конце и 0 - для облегчения работы процедуры обработки прерывания посылки по USART-у. Наличие этих разрядов контрольной суммы в посылке требует формат протокола обмена данными с модулем GPS. И я да - сначала забиваю всю строку. а потом пробегаю по ней и считаю контрольную сумму. Имхо, это проще, чем считать её во всех вложенных функциях при заполнении строки.
  

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


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #290 - 04.11.2011 :: 09:15:39
Post Tools
Собственно, попытаюсь выразить свои мысли по этому поводу в следующей небольшой зарисовке под названием "Указатели и ОЗУ - уровни абстракций" Улыбка
Итак, ОЗУ. Для начала рассмотрим 8-битные AVR. Каждая ячейка ОЗУ - один байт, имеет некий адрес - физический и абсолютный, который, допустим, имеет длину 2 байта (зависит от размера ОЗУ), но в принципе это не главное - это имеет значение только когда мы этот адрес будем куда-то помещать и хранить-передавать. Для простоты будем писать адрес десятичным числом (хотя программисты привыкли к 16-ричному представлению Улыбка) Вот и все. При написании на asm можно как угодно это использовать.
Что же нам предлагает С? Вводится понятие указателя. Причем, на определенный тип. Что это значит? Имхо, это "всего навсего" значит - как извлекать значение и как инкрементировать указатель. Например, беру указатель некоей переменной типа char. Компилятор знает, что он положил эту переменную в ячейку ОЗУ (которая как раз 8-битная) с номером 915. Числовое значение указателя = 915 (тип int). Если я теперь пытаюсь получить значение переменной по этому указателю, компилятор запросит значение этой ячейки ОЗУ и выдаст её содержимое. Если я определяю переменную типа массив char, то компилятор располагает её в одной области ОЗУ, так что все элементы идут последовательно по адресам. В принципе, это не единственный способ определить массив в ОЗУ, но так с ним гораздо проще работать. В этом случае, если наш указатель на ячейку с номером 915 указывает на 0-й элемент массива, то прибавив к указателю 1-цу мы получим 916 - адрес 1-го элемента массива, и таким образом можем перебирать элементы (собственно, так это на самом деле и происходит Улыбка)
Теперь возьмем указатель на int. Int у нас лежит уже в 2-х ячейках ОЗУ. Но само числовое значение указателя будет то же самое по разрядности. Указатель (в своем числовом значении) будет хранить адрес младшего байта нашей переменной. А компилятор будет знать, что раз это указатель на int, то чтобы взять значение переменной, надо младший байт прочитать из ячейки с номером указателя - 915, а старший из следующей - 916. Хотя сам указатель будет хранить всегда числовое значение адреса одной ячейки ОЗУ. Если же мы определим указатель на массив int, то мы так же можем перебирать элементы массива, инкрементируя указатель - но в данном случае наш умный компилятор, зная что это указатель на int, будет инкрементировать его не на следующий байт ОЗУ а через байт - на ячейку 917, хотя мы указали инкрементирование на 1-цу! То же самое происходит и со структурами, и с массивами структур и вообще с любыми объектами в ОЗУ. Всего 2 вещи: указатель всегда содержит адрес одной ячейки и компилятор помнит насколько его надо увеличить, чтобы получить следующий элемент.

А теперь самое интересное - возможные следствия этого  Круглые глаза Абсолютное значение любого указателя - одно и то же по типу и разрядности - наши пресловутые 915. Но с этого адреса мы можем извлечь из памяти и char, и int, и вообще любое значение любого типа Улыбка Весь вопрос в том - осознанно ли мы это делаем или нет Улыбка Например, определив указатель на массив типа int, мы можем присвоить его значение (те же 915) другому указателю на char. И получить по значению этого указателя младший байт переменной int. А при последовательном инкрементировании этого указателя мы возьмем старший байт (из ячейки 916), потом младший байт следующего элемента (917) и т.д. Улыбка Потому что наш умный компилятор будет знать, что раз это указатель на char, то инкрементировать его надо на 1-цу а не через байт Улыбка Или, например, мы взяли указатель на переменную char, присвоили его значение указателю на int и читаем по нему. Младший байт прочитается из ячейки char а старший - из следующей, где в это время может лежать совершенно что угодно. Это все упирается в философский вопрос о том, знаем ли мы что находится в ОЗУ когда читаем оттуда по адресам.
Когда же может произойти "переопределение типа" указателя? При прямом присваивании значения указателя одного типа другому, при передаче в качестве параметра в функцию, при чтении значения указателя из переменной и т.д., подозреваю что способов много. Неприятные последствия этого очевидны - мы читаем из ОЗУ или пишем в него совсем не то и не по тем адресам, что мы думаем там находится. Выше приведенный пример с вроде бы красивым обращением к разным байтам длинных переменных по указателям char с одной стороны подкупает своей стильностью, но я бы не советовал пользоваться такими методами. Потому что, например, при переносе кода на 32-разрядные системы, все может поломаться совсем Улыбка Потому что там char и int могут храниться в одной и той же 32-разрядной ячейке ОЗУ. А если система позволяет, то компилятор может вообще засовывать переменные char в разные группы разрядов 32-битной ячейки ОЗУ - хоть 4 в одну, имея в виду векторный адрес переменной (адрес ячейки + адрес байта: 0,1,2,3).
Проще говоря - заранее не зная, между какими структурами ОЗУ будет переноситься ваш код, подобные хитрости с указателями лучше не применять. Да и вообще, имхо их лучше не применять - чтобы жизнь была проще!  Круглые глаза

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

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



Сообщений: 3773
Местоположение: Санкт-Петербург
Зарегистрирован: 06.06.2008
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #291 - 04.11.2011 :: 09:49:34
Post Tools
Цитата:
А при последовательном инкрементировании этого указателя мы возьмем старший байт (из ячейки 916), потом младший байт следующего элемента (917) и т.д.

Забыл еще одни грабли endianness или порядок упаковки байтов, даже при одной разрядности системы.
Intel/Motorola little-endian/big-endian.
http://en.wikipedia.org/wiki/Endianness
  

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


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #292 - 04.11.2011 :: 09:52:15
Post Tools
Точно, блин - ещё же и little-endian/big-endian!  Улыбка В общем, хватает особенностей разных ОЗУ, чтобы не лезть туда напрямую а оставить это компилятору, но при этом не вводить его в заблуждение переопределением типов указателей  Круглые глаза
  

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



Сообщений: 3773
Местоположение: Санкт-Петербург
Зарегистрирован: 06.06.2008
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #293 - 04.11.2011 :: 10:26:50
Post Tools
Также, разрядность int зависит от среды программирования, может быть любая, от 8 (забыли про 4х битные процессоры) и до ...!
Для конкретной разрядности пользуйся типами
int8_t/uint8_t
int16_t/uint16_t
int32_t/uint32_t...
  

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


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #294 - 04.11.2011 :: 10:42:26
Post Tools
Спасибо, я в конце концов так и хотел потом сделать - дошлифовать код напильником (в нормальном текстовом редакторе, где есть автозамена, групповое назначение-снятие комментариев, автоформатирование и т.п. - например, 1С Улыбка ), добавить везде unsigned, где надо - static и т.п. Но оказалось (на примере функции перевода числа в строку), что unsigned надо добавлять сразу, а то работает до половины int  Круглые глаза Так что, действительно, наверное лучше сразу по возможности писать всё как надо Улыбка
  

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


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #295 - 04.11.2011 :: 12:45:27
Post Tools
Вести с полей с граблями  Улыбка
В результате определенной исследовательской работы выяснилось, что в таблице символов заглавные латинские буквы 'A', 'B' и т.д. идут не сразу за символами цифр '8', '9' а через некоторое расстояние, в связи с чем функцию преобразования числа в шестнадцатиричное строковое представление придется таки написать отдельно и сделать немножко поинтеллектуальнее амебы  Круглые глаза

ЗЫ хорошо ещё, что 1-2-3 и А-B-C по порядку идут и 0 перед 1 а не после 9 - а то от этих.... таблиц всего ожидать можно  Круглые глаза
« Последняя редакция: 04.11.2011 :: 12:45:57 от »  

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


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #296 - 04.11.2011 :: 18:46:26
Post Tools
Продолжение прогулки по граблям... Из-за своего упрямства и тупости потерял много времени выискивая ошибки - а у меня почти везде не было написано unsigned - и переменные залезали в минус, причем не всегда, а непредсказуемо! Уколебался выискивать эти моменты!  Злой Впредь будет мне идиоту наука - писать сразу правильно, как советуют добрые люди!... Вот дебил-то, блин!...
  

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


Re: Микроконтроллер - как перспектива примочкостроения
Ответ #297 - 05.11.2011 :: 09:53:47
Post Tools
Очередная сказка - "Про статическое и динамическое распределение ОЗУ."  Круглые глаза
Глобальные и статические переменные с боем отвоевали свое право жить вечно в своих областях ОЗУ. Динамические переменные рождаются и умирают - совсем как мы с вами. В любом месте итогового hex кода у нас используется определенное количество ОЗУ. Начнем с гипотетического примера - пусть у меня в задаче есть только 2 функции, которые делают абсолютно никак друг с другом не связанные вещи. Одна для своей работы забирает 250 байт ОЗУ под локальные переменные, вторая - тоже 250. Вопрос - каковы мои максимальные претензии на ОЗУ? Если они вызываются по очереди, то это будет: глобальные переменные (допустим 16 байт) + все регистры (поскольку они сохранятся в ОЗУ при вызове функции), допустим, 64 байта + 250 байт = 330 байт. Я прав? Ничего не забыл? Ничего там больше компилятор без моего ведома внутреннего/служебного/закадрового/для облегчения себе работы не создаст и не затребует под это ОЗУ? Если мои предположения верны, то функция занятого ОЗУ от времени (хода кода) буде выглядеть так: 16 - 16 -330 - 330 - 16 -.... Если же я вдруг внутри одной функции решу вызвать вторую, то уже мои максимальные претензии на ОЗУ будут 16 + (64 + 250) + (64 + 250) = 644 байта. А функция использованного ОЗУ примерно будет такая: 16 - 330 - 330 - 644 - 644 - 330 - 16 - .... Очевидная жо следствие: если у нас аппаратно всего 512 байт ОЗУ то в первом случае все хорошо, а во втором мы не вписываемся в аппаратные ограничения.
Это был простейший пример. В реальности функций гораздо больше, но сути это не меняет - в каждый момент времени (шага кода) у нас однозначно определена функция количества требуемого ОЗУ. И мы можем всегда посчитать её максимальное значение чтобы гарантировано знать что влезем в ОЗУ при любых раскладах? Хрен там!  Улыбка Тут на сцену выходят 2 засады - рекурсия и прерывания  Круглые глаза

Рекурсия - крутая вещь. Но количество вложенных вызовов при выполнении кода определяется входными данными и компилятор заранее при компиляции не может их посчитать! Поэтому не знает, сколько раз вызовется рекурсивно функция (в общем случае это количество ничем не ограничено!) и соответственно, определить максимальные претензии по ОЗУ. А мы как люди сами можем? В принципе да, принимая во внимание самый худший вариант входных данных, которые приведут к вызову рекурсии и будучи уверенными, что у нас никогда не встретятся данные, которые вызовут рекурсию большее количество вложенных раз. Но в нетривиальном коде сделать это также нетривиально, особенно учитывая неявные рекурсии - когда функция вызывает себя не напрямую, а через несколько других функций.

Прерывания - отличная вещь! Но при вызове сохраняются регистры в стек + процедура обработки прерывания запросто может предъявить претензии на ОЗУ. Учитывая многообразие прерываний, их возможную вложенность (!, правда не везде) и т.д., можно ли определить их максимальные претензии на ОЗУ? Не знаю! Правда, не знаю. Может и можно, допустив, что все они произошли условно одновременно, но только единожды (где это возможно), или произошло максимально требовательное к ОЗУ (где нет вложенности прерываний) - тут наверное можно рассуждать так. Хотя ощущения гарантии НЕ превышения некоего определенного количества затребованного ОЗУ при любом случае внешних прерываний у меня нет!....  Смущённый

К чему весь этот очередной длинный монолог? У меня мало ОЗУ, я вынужден об этом думать. Точнее, в итоговом проекте будет камень с бОльшим ОЗУ, но командир сказал - мне надо, чтобы твоя задача гарантированно укладывалась в ХХХ ОЗУ! Потому что у него таких задач много, и он должен быть уверен, что запустив, к примеру, одновременно а не последовательно задачи получения GPS координат и отправки их же по SMS через GSM модуль - он не упрется в ограничение по ОЗУ. И я его хорошо понимаю  Круглые глаза
Собственно, вопросы Улыбка Мой компилятор при билде проекта показывает количество используемого ОЗУ и проценты от общего. Он это делает корректно? Как я написал выше? Но не учитывая рекурсии и прерывания? Есть ли у меня гарантия, что если он написал - 95%, то всё будет хорошо всегда, если у меня нет рекурсий (явных и неявных) а максимально прожорливое прерывание требует 4% ОЗУ?
И конечно, как всегда, общий вопрос - что делать и кто виноват что скажете на эту тему, господа доктора?  Круглые глаза

ЗЫ и ещё вопрос - я ещё не заколебал вас всех обоих своими монологами и вопросами? Просто я нахожусь в этом потоке и хочется делиться мыслями и слушать в ответ  Круглые глаза
« Последняя редакция: 05.11.2011 :: 10:03:17 от »  

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


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

Сообщений: 1619
Местоположение: Харків-city
Зарегистрирован: 22.03.2010
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #298 - 05.11.2011 :: 12:33:18
Post Tools
Цитата:
Мой компилятор при билде проекта показывает количество используемого ОЗУ и проценты от общего. Он это делает корректно? Как я написал выше? Но не учитывая рекурсии и прерывания?


GCC показывает только суммарный размер сегментов данных. Остальное в GCC отводится на стек (и на кучу, но ею Вы вряд ли пользуетесь). Попытки посчитать макс. размеры стека он не делает.

Цитата:
Есть ли у меня гарантия, что если он написал - 95%, то всё будет хорошо всегда, если у меня нет рекурсий (явных и неявных) а максимально прожорливое прерывание требует 4% ОЗУ?


Нет, конечно. Использование стека собственно функциями не учитывается.
« Последняя редакция: 05.11.2011 :: 12:34:38 от Rst7 »  

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

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


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

Сообщений: 1619
Местоположение: Харків-city
Зарегистрирован: 22.03.2010
Re: Микроконтроллер - как перспектива примочкостроения
Ответ #299 - 05.11.2011 :: 12:37:53
Post Tools
Цитата:
ЗЫ и ещё вопрос - я ещё не заколебал вас всех обоих своими монологами и вопросами? Просто я нахожусь в этом потоке и хочется делиться мыслями и слушать в ответ


Так мы тут вроде отвечаем Улыбка Значит, пока терпим  Смех
  

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

"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредствен
Наверх
WWW  
IP записан
 
 
  « Главная ‹ Раздел Наверх этой страницы