Вопросы по С/С++ (СИ)
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
В своей теме я описывал, как поставить WinAVR посвежее и подключить к своему проекту, и даже снял видео в том числе про QtCreator.
Беглый взгляд на Ваш скриншот показывает, что линкер подключает в результирующий файл некий объектник gps_data_to_UART.o, который вообще-то в коде нигде не используется. Подозреваю, что у него большой размер, отсюда и результат. Вероятно, есть ещё какой-то файл gps_data_to_UART.c, который компилируется и линкуется в проект, хотя не используется.
P.S. Во вложении созданный мною шаблон для QtCreator для быстрого старта проекта.
Беглый взгляд на Ваш скриншот показывает, что линкер подключает в результирующий файл некий объектник gps_data_to_UART.o, который вообще-то в коде нигде не используется. Подозреваю, что у него большой размер, отсюда и результат. Вероятно, есть ещё какой-то файл gps_data_to_UART.c, который компилируется и линкуется в проект, хотя не используется.
P.S. Во вложении созданный мною шаблон для QtCreator для быстрого старта проекта.
- Вложения
-
- templates.7z
- (4.73 КБ) 141 скачивание
Re: Вопросы по С/С++ (СИ)
Попробую поставить чуть позже...
У меня еще один затык... (помоему AVRST+GCC сходит от меня сума... или я от него
)
Пробую сделать массив структур. Каждая структура состоит из указателя на текст и нескольких параметров...
Типа такого:
Если получаю указатель так или так:
то все нормально, получаю указатель на соответствующее текстовое поле...
а если делаю так:
в глобальных переменных назначаю номер текущей структуры (или передаю в функцию параметром, не важно)
то чтение указателя на поле
дает не предсказуемый результат.....
Вот пример в проте.
Если перед чтением указателя из структуры, еще раз присвоить значение смещению, то получаем в результате правильный адрес - 0х002C...
Если перед чтением закомментировать присваивание, (хотя оно выполнено глобально) получаем в результате 0x0000....
У меня еще один затык... (помоему AVRST+GCC сходит от меня сума... или я от него
Пробую сделать массив структур. Каждая структура состоит из указателя на текст и нескольких параметров...
Типа такого:
Код: Выделить всё
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....
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Проверил код, немного исправил объявления структур, т.к. у меня не компилировалось (я всегда включаю директивы -Wall и -Werror у компилятора, чтобы все предупреждения компилятора обрабатывались как ошибки - это помогает поддерживать код более чистым):
В терминал в Proteus выводится 0x002E, а если закомментировать строку MenuNum = 1 перед передачей в UART - то 0x002E. Т.е. работает код абсолютно одинаково в обоих случаях, как и ожидалось (то что разные значения - не важно, так как код разный, и в памяти всё это может в обоих случаях храниться по разным адресам).
Спойлер
Код: Выделить всё
#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. Т.е. работает код абсолютно одинаково в обоих случаях, как и ожидалось (то что разные значения - не важно, так как код разный, и в памяти всё это может в обоих случаях храниться по разным адресам).
Re: Вопросы по С/С++ (СИ)
Выходит - компилятор (AVRStudio4.19 + toolchain) глючит!?...
Я даже в студии6 проверял, та же петрушка.....
Кстати у меня даже предупреждений никаких не было, все чисто...
Попробовал объявить структуру как вы - результат тот же...
Я даже в студии6 проверял, та же петрушка.....
Кстати у меня даже предупреждений никаких не было, все чисто...
Попробовал объявить структуру как вы - результат тот же...
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
прежде чем обвинять компилято, вы бы изучили как следует язык Си. что это за объявление строк с фигурными скобками?! вы учитываете, что строки у вас в PROGMEM, а в структуре указатель на гште8_е в ОЗУ? принципиально тут проблемы нет, но она может появиться в месте, где вы к этому указателю обращаетесь. ну и еще ряд замечаний - перечислять лень.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
Кстати, до сих пор я так и не встречал неадекватного поведения со стороны компилятора, все трудности решались открытием для себя определенных правил, соглашений си, анси и т.д..... так что самому не охота кого бы то ни было обвинять... тем более такого уважаемого оппонента как компилятор...ARV писал(а):прежде чем обвинять компилято
Но я для того и текст примера показал, чтобы мне указали на мой "очередной" косяк... Пока что правка объявлений в структуре и убирание фигурных скобок не помогли... Надеюсь на дальнейшие рекомендации
Вы бы лучше поднапряглись, да все таки посоветовали что то дельное... ато про фигурные скобки - как то не серьезноARV писал(а):вы бы изучили как следует язык Си. что это за объявление строк с фигурными скобками?!
и еще ряд замечаний - перечислять лень.
А как по другому решить размещение массива структур в PROGMEM?ARV писал(а):вы учитываете, что строки у вас в PROGMEM, а в структуре указатель на гште8_е в ОЗУ? принципиально тут проблемы нет, но она может появиться в месте, где вы к этому указателю обращаетесь.
Вообще я думаю что указатель он и в африке указатель... не важно, с PROGMEM он записан, или без... думаю упоминание PROGMEM нужно только для того, чтобы компилятор мог контролировать правильность памяти, с которой будет работать указатель... Т.е. если указатель PROGMEM, а мы его используем чтобы работать с RAM, вот тут то и выскажется компилятор.....
Так что размещая в массиве указатель, который был объявлен с PROGMEM, компилятор об этом помнит, и дальше будет контролировать правильность используемой памяти...
В общем как ты и сказал -
тем более у WiseLord работает... Наверное он свой компиль чем то прикармливаетпринципиально тут проблемы нет
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Про хранение данных написано в мануале к avr-libc.
В любом случае, данные в такую структуру могут быть помещены только один раз, при компиляции программы и меняться они при её выполнении не могут. Отсюда и требования к объявлению таких данных как const.
P.S. А строки, хранимые во Flash-памяти, объявлять надо как-то так:
В любом случае, данные в такую структуру могут быть помещены только один раз, при компиляции программы и меняться они при её выполнении не могут. Отсюда и требования к объявлению таких данных как const.
Здесь фактически аргумент функции UartTransmInt - это некий адрес в ОЗУ, а вовсе не значение, которое лежит в структуре в поле pTxt. В принципе, это передаваемое число может быть любым. Чтобы добраться до адреса, хранимого в flash-памяти, надо выполнить что-то вродеUartTransmInt ((uint16_t)Menu[MenuNum].pTxt);
UartTransmInt (pgm_read_word(&Menu[MenuNum].pTxt));
P.S. А строки, хранимые во Flash-памяти, объявлять надо как-то так:
Код: Выделить всё
static const uint8_t labelSTBY[] PROGMEM = "Standby";Re: Вопросы по С/С++ (СИ)
ВОТ!!! конечно же... как это я так протупил...WiseLord писал(а):Чтобы добраться до адреса, хранимого в flash-памяти, надо выполнить что-то вродеUartTransmInt (pgm_read_word(&Menu[MenuNum].pTxt));
меня сбило с толку то, что мне в определенных случаях возвращался адрес размещения текста... (т.е. я вижу где размещен текст, и вижу что мне возвращается именно этот адрес).
но я только сейчас допер, что таким образом может возвращатся только адрес размещения указателя на текст, но не сам адрес текста... сейчас в голове более менее прояснилось...
В общем извиняюсь за очередной балаган, который я тут развел
(Хотя вопрос остался открытым, почему возвращаемый результат у меня в разных случаях был разный, хотя индекс по идее был всегда одинаковым (просто я его передавал разными способами))
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Наверное, потому что при комментировании кода его размер уменьшался - это становился уже другой код - оптимизатор мог его сделать ещё более различным - функции располагались уже по другим адресам, и выводиться могло уже что-то другое.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
shads писал(а):В общем извиняюсь за очередной балаган, который я тут развел.....
балаган начинается с "фигурных скобочек", где не надо, а заканчивается тем, что
после чего начинаются чудеса.shads писал(а):указатель он и в африке указатель... не важно, с PROGMEM он записан, или без...
поэтому я поднапрягаюсь и советую вам тщательно изучить Си, чтобы делать не тяп-ляп, а по правилам и с полным пониманием того, что делаешь. собственно, 90% моих советов только в этом и заключаются
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
Спасибо!!!ARV писал(а):cоветую вам тщательно изучить Си, чтобы делать не тяп-ляп, а по правилам и с полным пониманием того, что делаешь. собственно, 90% моих советов только в этом и заключаются
Именно этим сейчас и занимаюсь...
Я в принципе сразу сознался в своих грехах: viewtopic.php?p=2169843#p2169843
Но уже кой чего просветлело в голове
Re: Вопросы по С/С++ (СИ)
Здравствуйте, подскажите как разместить в структуре строки разного размера. Компилятор CodeVisionAvr
есть такая структура меню
Сделал пару пунктов меню по смотрел подумал что избыточно выделять на текстовую часть 40 байт
Захотел сделать такое что бы при инициализации выделялось место ровно по текстовой части т.е при таком варианте:
выделилось в озу 8-9 байт на указатели а в текстовой части нечего не было (следующая переменная )
а при таком варианте выделилось 8 байт на указатели и ещё массив со строкой "1234567"
Думал что вот такое изменение unsigned char Text[]; приведёт меня к желаемому результату но нет
после первой инициализации Null_Menu он создаёт массив нулевой размерностью и на все остальные строчки компилятор начинает ругаться "Error: ... included from: shaper.c: too many initializers"
есть такая структура меню
Код: Выделить всё
typedef struct PROGMEM{
void *Next;
void *Previous;
void *Parent;
void *Child;
unsigned char OK;
unsigned char ESC;
unsigned char ACTION_NEXT;
unsigned char ACTION_DOWN;
unsigned char Text[41];
} menuItem;Сделал пару пунктов меню по смотрел подумал что избыточно выделять на текстовую часть 40 байт
Захотел сделать такое что бы при инициализации выделялось место ровно по текстовой части т.е при таком варианте:
Код: Выделить всё
menuItem Null_Menu = {(void*)0, (void*)0, (void*)0, (void*)0,0,0,0,0, ""}; выделилось в озу 8-9 байт на указатели а в текстовой части нечего не было (следующая переменная )
Код: Выделить всё
menuItem Null_Menu2 = {(void*)0, (void*)0, (void*)0, (void*)0,0,0,0,0, "1234567"}; а при таком варианте выделилось 8 байт на указатели и ещё массив со строкой "1234567"
Думал что вот такое изменение unsigned char Text[]; приведёт меня к желаемому результату но нет
после первой инициализации Null_Menu он создаёт массив нулевой размерностью и на все остальные строчки компилятор начинает ругаться "Error: ... included from: shaper.c: too many initializers"
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
попробуйте использовать указатель на строку char *Text;
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- GARMIN
- Держит паяльник хвостом
- Сообщения: 952
- Зарегистрирован: Вс дек 02, 2012 16:58:33
- Откуда: от туда
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
делай в структуре ссылку на текстовую строку, а строки объявляй отдельно.
Re: Вопросы по С/С++ (СИ)
Благодарю за помощь. С указателем на строку получилось.
Re: Вопросы по С/С++ (СИ)
здраствуйте
что означает конструкция, где ADDRESS это допустим адрес микрухи.
например ADDRESS = 0b00000010, то получается что
0b00000010
0b00000001
__________
0b00000011 ?
что означает конструкция
Код: Выделить всё
ADDRESS | 1например ADDRESS = 0b00000010, то получается что
0b00000010
0b00000001
__________
0b00000011 ?
- ua1arn
- Встал на лапы
- Сообщения: 81
- Зарегистрирован: Вт май 08, 2012 23:15:45
- Откуда: Санкт - Петербург
Re: Вопросы по С/С++ (СИ)
Код: Выделить всё
0b00000011 ?Да.
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Будь там ADDRESS |= 1 - это бы означало установку 0-го бита ADDRESS в 1.
А так - это всего лишь незавершённое логическое выражение, в результате которого получится некий промежуточный результат - число, равное ADDRESS с точностью до последнего бита, который будет равен 1. А что дальше с этим числом делается - мы не знаем.
Ну, как если бы спросить, что означает ADDRESS + 1.
А так - это всего лишь незавершённое логическое выражение, в результате которого получится некий промежуточный результат - число, равное ADDRESS с точностью до последнего бита, который будет равен 1. А что дальше с этим числом делается - мы не знаем.
Ну, как если бы спросить, что означает ADDRESS + 1.
Re: Вопросы по С/С++ (СИ)
Доброго всем дня! Пишу тут прогу для МК с архитектурой 8051 на Си в Keil, увы, уровень владения языком невысок, но интересует такой вопрос: как ассоциировать с переменной какую-либо ячейку памяти данных? Делать ассемблерную вставку или можно как-то стандартными средствами кейловского си обойтись?
- Gudd-Head
- Друг Кота
- Сообщения: 20092
- Зарегистрирован: Чт сен 18, 2008 12:27:21
- Откуда: Столица Мира Санкт-Петербург
Re: Вопросы по С/С++ (СИ)
Аааа... зачем?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]