Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

не влазит код в мегу8 - надо пожирнее мегу или от long long отказаться:
СпойлерИзображение
Последний раз редактировалось oleg110592 Вс ноя 09, 2014 16:13:00, всего редактировалось 1 раз.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Сообщение dosikus »

shads , в сети парсеров GPS как грязи . Смысл городить велосипед ?
Chip115 писал(а): хм. Думал об этом, но индусы из микрочипа не просто так же написали эту фигню?
В целом я правильно понял назначение этих строк?
Если пытаться в STM32 найти железо от MRF24J40, то никакие skill'ы не помогут. :)))
Реклама
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

oleg110592 писал(а):не влазит код в мегу8 - надо пожирнее мегу или от long long отказаться
Вах... я чет и не подумал что long long так убивает, и что причина может быть в этом :shock: ...

А как еще можно умножить 8-ми значное число на 0,01666666 т.е. на 1/60, с минимальными потерями ресурса?...
Пробовал так

Код: Выделить всё

	Parameter *= 16666666;
	Parameter /= 100000000;
Дык только эти 2 строчки кушают 5кб памяти...

dosikus писал(а):shads , в сети парсеров GPS как грязи . Смысл городить велосипед ?
Дык парсер то как раз не проблема...
Нужно перевести значение координат из - градусы, минуты - в значение в градусы...
Т.е. по сути то что делает этот калькулятор... http://goondel.ucoz.ru
ks0
Прорезались зубы
Аватара пользователя
Сообщения: 238
Зарегистрирован: Чт фев 28, 2013 14:16:10

Сообщение ks0 »

А че, просто поделить нельзя?!
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

не ради рекламы - интересно было, попробовал задачу shads решить на STM32F030K6T6 ARM Cortex M0, 48МГц, 32кб Flash, 4кб ОЗУ, корпус такой же TQFP32, цена у нас, такая же как и на ATMEGA8, компилятор Keil:

чистый main (только настройки тактовой частоты и стартап):
Program Size: Code=368 RO-data=208 RW-data=0 ZI-data=1024

программа shads
Program Size: Code=888 RO-data=208 RW-data=0 ZI-data=1024

получается эта же программа заняла всего то 520 байт против 9898 байт на AVR
СпойлерИзображение
Реклама
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

oleg110592 писал(а):решить на STM32F030K6T6 ARM Cortex M0
Ясный перец... архитектура 32 бита... я бы даже предположил бы, что должно получиться еще меньше чем 520 байт...

Не ну результат AVR меня просто сразил :)...
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Меня тоже сразил, и я не поверил, поэтому решил перепроверить:
Изображение
Так что это что-то у автора проблемы не так, а не у avr-gcc. Либо что-то ещё крупное к проекту подключено, чего мы не видим, а этот код является той каплей, что переполняет море.
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

WiseLord писал(а):это что-то у автора проблемы не так, а не у avr-gcc.
"Пол царства отдаю, и дочьку в жены" токма объясните, что нужно сделать чтобы такой размер получился?!...

И кстати проверьте пож, сколько покажет, если между первым и вторым циклами for, добавить две строчки:

Код: Выделить всё

Parameter *= 16666666;
Parameter /= 100000000;
И кстати что это у вас за оболочка такая прикольная?
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

да GCC AVR 4.9.2 нормально компилит
СпойлерИзображение
пробовал eclipse+AVR plugin+GCC AVR 4.9.2
выше оболочка, я так понял, Qt Creator+GCC AVR
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Пожалуйста:

Изображение

А так - да, в качестве IDE использую Qt Creator. Очень неплохой вариант для linux, всяко шустрее Eclipse.
shads писал(а):"Пол царства отдаю, и дочьку в жены" токма объясните, что нужно сделать чтобы такой размер получился?!...
Думаю, дело в тех аргументах avr-gcc, что на Ваших скриншотах полностью не видны: -Map=gps_data_to_UART....

Явно помимо предоставленного кода где-то в Makefile к проекту подцеплено ещё что-то тяжеловесное, и линковщик не может всё это вместить в 8 кБ.
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

WiseLord писал(а):Пожалуйста:.....
Усохни моя душенька... не верю своим глазам... надо пошшупать... ато ишшо вдруг оптицский обман здрения.....
WiseLord писал(а):Думаю, дело в тех аргументах avr-gcc, что на Ваших скриншотах полностью не видны: -Map=gps_data_to_UART....
Явно помимо предоставленного кода где-то в Makefile к проекту подцеплено ещё что-то тяжеловесное, и линковщик не может всё это вместить в 8 кБ.
Ануке просканируйте своим зорким взглядом...
СпойлерИзображение
WiseLord писал(а):в качестве IDE использую Qt Creator. Очень неплохой вариант для linux, всяко шустрее Eclipse.
А под винду такая игрушка шусествует?
Вложения
1.gif
(17.67 КБ) 550 скачиваний
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

похоже WinAVR это переварить не может - попробуйте сборку AVR GCC
Qt Creator под Windows есть, насчет AVR plugin для него не знаю - придется make файлы писать
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

В своей теме я описывал, как поставить WinAVR посвежее и подключить к своему проекту, и даже снял видео в том числе про QtCreator.

Беглый взгляд на Ваш скриншот показывает, что линкер подключает в результирующий файл некий объектник gps_data_to_UART.o, который вообще-то в коде нигде не используется. Подозреваю, что у него большой размер, отсюда и результат. Вероятно, есть ещё какой-то файл gps_data_to_UART.c, который компилируется и линкуется в проект, хотя не используется.

P.S. Во вложении созданный мною шаблон для QtCreator для быстрого старта проекта.
Вложения
templates.7z
(4.73 КБ) 152 скачивания
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

Попробую поставить чуть позже...

У меня еще один затык... (помоему AVRST+GCC сходит от меня сума... или я от него :shock: )
Пробую сделать массив структур. Каждая структура состоит из указателя на текст и нескольких параметров...
Типа такого:

Код: Выделить всё

PROGMEM uint8_t Txt1[] = {"text1"};	
PROGMEM uint8_t Txt2[] = {"TEXT2"};

PROGMEM struct{
	uint8_t *pTxt, UpLim, DnLim;
}Menu [] = {
	{Txt1, 	1,2},
	{Txt2,	3,4}
};
Если получаю указатель так или так:

Код: Выделить всё

Menu[0].pTxt
Menu[1].pTxt 
то все нормально, получаю указатель на соответствующее текстовое поле...


а если делаю так:
в глобальных переменных назначаю номер текущей структуры (или передаю в функцию параметром, не важно)

Код: Выделить всё

uint8_t shift = 0;
то чтение указателя на поле

Код: Выделить всё

Menu[shift ].pTxt
дает не предсказуемый результат.....



Вот пример в проте.
Если перед чтением указателя из структуры, еще раз присвоить значение смещению, то получаем в результате правильный адрес - 0х002C...
Если перед чтением закомментировать присваивание, (хотя оно выполнено глобально) получаем в результате 0x0000....
txt_struct.7z
(25.01 КБ) 225 скачиваний
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Проверил код, немного исправил объявления структур, т.к. у меня не компилировалось (я всегда включаю директивы -Wall и -Werror у компилятора, чтобы все предупреждения компилятора обрабатывались как ошибки - это помогает поддерживать код более чистым):
Спойлер

Код: Выделить всё

#define F_CPU 		8000000
#define UART_BAUD 	9600
#include <avr/pgmspace.h>
#include <avr/io.h>

//--------------------------------------------------------------------------------
//тексты и структура
PROGMEM const uint8_t Txt1[] = {"text1"};
PROGMEM const uint8_t Txt2[] = {"TEXT2"};

PROGMEM const struct{
	const uint8_t *pTxt;
	uint8_t UpLim, DnLim;
}Menu[] = {
	{Txt1, 	1,2},
	{Txt2,	3,4}
};

//--------------------------------------------------------------------------------
//Глобальные переменные
uint8_t MenuNum = 1;

//--------------------------------------------------------------------------------
//Передача байта по UART
void UartTransmByte (uint8_t byte)
{
	while (! (UCSRA & (1<<UDRE))){}			// Wait for empty transmit buffer
	UDR = byte;								// Put data into buffer, sends the data
}

//передача int значения по UART
void UartTransmInt (uint16_t word)
{
	uint8_t temp;
	UartTransmByte ('0');
	UartTransmByte ('x');
	temp = (word>>12) & 0x0f;
	if (temp < 10)		UartTransmByte (temp + 0x30);
	else				UartTransmByte (temp + 0x37);
	temp = (word>>8) & 0x0f;
	if (temp < 10)		UartTransmByte (temp + 0x30);
	else				UartTransmByte (temp + 0x37);
	temp = (word>>4) & 0x0f;
	if (temp < 10)		UartTransmByte (temp + 0x30);
	else				UartTransmByte (temp + 0x37);
	temp = word & 0x0f;
	if (temp < 10)		UartTransmByte (temp + 0x30);
	else				UartTransmByte (temp + 0x37);
	UartTransmByte (',');
}

//--------------------------------------------------------------------------------
int main (void)
{
	//Настройка UART
	uint16_t BaudRateTemp = (F_CPU / UART_BAUD / 16 - 1);//скорость работы UART
	UBRRH = (BaudRateTemp>>8);				
	UBRRL =  BaudRateTemp; 
	UCSRC = (1<<URSEL)|(1<<USBS)|			//2 стоп бита
			(1<<UCSZ1)|(1<<UCSZ0);			//формат посылки - 8 бит 
	UCSRB = (0<<RXEN)|(1<<TXEN);			//разрешена передача

	MenuNum = 1;
	UartTransmInt ((uint16_t)Menu[MenuNum].pTxt);

	while (1){}
}
 
//--------------------------------------------------------------------------------
В терминал в Proteus выводится 0x002E, а если закомментировать строку MenuNum = 1 перед передачей в UART - то 0x002E. Т.е. работает код абсолютно одинаково в обоих случаях, как и ожидалось (то что разные значения - не важно, так как код разный, и в памяти всё это может в обоих случаях храниться по разным адресам).
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

Выходит - компилятор (AVRStudio4.19 + toolchain) глючит!?...
Я даже в студии6 проверял, та же петрушка.....

Кстати у меня даже предупреждений никаких не было, все чисто...
Попробовал объявить структуру как вы - результат тот же...
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18788
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

прежде чем обвинять компилято, вы бы изучили как следует язык Си. что это за объявление строк с фигурными скобками?! вы учитываете, что строки у вас в PROGMEM, а в структуре указатель на гште8_е в ОЗУ? принципиально тут проблемы нет, но она может появиться в месте, где вы к этому указателю обращаетесь. ну и еще ряд замечаний - перечислять лень.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

ARV писал(а):прежде чем обвинять компилято
Кстати, до сих пор я так и не встречал неадекватного поведения со стороны компилятора, все трудности решались открытием для себя определенных правил, соглашений си, анси и т.д..... так что самому не охота кого бы то ни было обвинять... тем более такого уважаемого оппонента как компилятор...
Но я для того и текст примера показал, чтобы мне указали на мой "очередной" косяк... Пока что правка объявлений в структуре и убирание фигурных скобок не помогли... Надеюсь на дальнейшие рекомендации :)....
ARV писал(а):вы бы изучили как следует язык Си. что это за объявление строк с фигурными скобками?!
и еще ряд замечаний - перечислять лень.
Вы бы лучше поднапряглись, да все таки посоветовали что то дельное... ато про фигурные скобки - как то не серьезно :)...
ARV писал(а):вы учитываете, что строки у вас в PROGMEM, а в структуре указатель на гште8_е в ОЗУ? принципиально тут проблемы нет, но она может появиться в месте, где вы к этому указателю обращаетесь.
А как по другому решить размещение массива структур в PROGMEM?
Вообще я думаю что указатель он и в африке указатель... не важно, с PROGMEM он записан, или без... думаю упоминание PROGMEM нужно только для того, чтобы компилятор мог контролировать правильность памяти, с которой будет работать указатель... Т.е. если указатель PROGMEM, а мы его используем чтобы работать с RAM, вот тут то и выскажется компилятор.....
Так что размещая в массиве указатель, который был объявлен с PROGMEM, компилятор об этом помнит, и дальше будет контролировать правильность используемой памяти...
В общем как ты и сказал -
принципиально тут проблемы нет
тем более у WiseLord работает... Наверное он свой компиль чем то прикармливает :)..... Вот только не хочет сказать... чем.....
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Про хранение данных написано в мануале к avr-libc.

В любом случае, данные в такую структуру могут быть помещены только один раз, при компиляции программы и меняться они при её выполнении не могут. Отсюда и требования к объявлению таких данных как const.
UartTransmInt ((uint16_t)Menu[MenuNum].pTxt);
Здесь фактически аргумент функции UartTransmInt - это некий адрес в ОЗУ, а вовсе не значение, которое лежит в структуре в поле pTxt. В принципе, это передаваемое число может быть любым. Чтобы добраться до адреса, хранимого в flash-памяти, надо выполнить что-то вроде
UartTransmInt (pgm_read_word(&Menu[MenuNum].pTxt));
P.S. А строки, хранимые во Flash-памяти, объявлять надо как-то так:

Код: Выделить всё

static const uint8_t labelSTBY[]   PROGMEM = "Standby";
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

WiseLord писал(а):Чтобы добраться до адреса, хранимого в flash-памяти, надо выполнить что-то вроде
UartTransmInt (pgm_read_word(&Menu[MenuNum].pTxt));
ВОТ!!! конечно же... как это я так протупил...

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

В общем извиняюсь за очередной балаган, который я тут развел :).....

(Хотя вопрос остался открытым, почему возвращаемый результат у меня в разных случаях был разный, хотя индекс по идее был всегда одинаковым (просто я его передавал разными способами))
Ответить

Вернуться в «Разные вопросы по МК»