Страница 210 из 386
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн ноя 10, 2014 16:52:30
WiseLord
В
своей теме я описывал, как поставить WinAVR посвежее и подключить к своему проекту, и даже снял
видео в том числе про QtCreator.
Беглый взгляд на Ваш скриншот показывает, что линкер подключает в результирующий файл некий объектник gps_data_to_UART.o, который вообще-то в коде нигде не используется. Подозреваю, что у него большой размер, отсюда и результат. Вероятно, есть ещё какой-то файл gps_data_to_UART.c, который компилируется и линкуется в проект, хотя не используется.
P.S. Во вложении созданный мною шаблон для QtCreator для быстрого старта проекта.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт ноя 11, 2014 00:47:03
shads
Попробую поставить чуть позже...
У меня еще один затык... (помоему 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}
};
Если получаю указатель так или так:
то все нормально, получаю указатель на соответствующее текстовое поле...
а если делаю так:
в глобальных переменных назначаю номер текущей структуры (или передаю в функцию параметром, не важно)
то чтение указателя на поле
дает не предсказуемый результат.....
Вот пример в проте.
Если перед чтением указателя из структуры, еще раз присвоить значение смещению, то получаем в результате правильный адрес - 0х002C...
Если перед чтением закомментировать присваивание, (хотя оно выполнено глобально) получаем в результате 0x0000....
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт ноя 11, 2014 07:50:39
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. Т.е. работает код абсолютно одинаково в обоих случаях, как и ожидалось (то что разные значения - не важно, так как код разный, и в памяти всё это может в обоих случаях храниться по разным адресам).
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт ноя 11, 2014 08:21:41
shads
Выходит - компилятор (AVRStudio4.19 + toolchain) глючит!?...
Я даже в студии6 проверял, та же петрушка.....
Кстати у меня даже предупреждений никаких не было, все чисто...
Попробовал объявить структуру как вы - результат тот же...
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт ноя 11, 2014 09:07:18
ARV
прежде чем обвинять компилято, вы бы изучили как следует язык Си. что это за объявление строк с фигурными скобками?! вы учитываете, что строки у вас в PROGMEM, а в структуре указатель на гште8_е в ОЗУ? принципиально тут проблемы нет, но она может появиться в месте, где вы к этому указателю обращаетесь. ну и еще ряд замечаний - перечислять лень.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт ноя 11, 2014 10:48:29
shads
ARV писал(а):прежде чем обвинять компилято
Кстати, до сих пор я так и не встречал неадекватного поведения со стороны компилятора, все трудности решались открытием для себя определенных правил, соглашений си, анси и т.д..... так что самому не охота кого бы то ни было обвинять... тем более такого уважаемого оппонента как компилятор...
Но я для того и текст примера показал, чтобы мне указали на мой "очередной" косяк... Пока что правка объявлений в структуре и убирание фигурных скобок не помогли... Надеюсь на дальнейшие рекомендации

....
ARV писал(а):вы бы изучили как следует язык Си. что это за объявление строк с фигурными скобками?!
и еще ряд замечаний - перечислять лень.
Вы бы лучше поднапряглись, да все таки посоветовали что то дельное... ато про фигурные скобки - как то не серьезно

...
ARV писал(а):вы учитываете, что строки у вас в PROGMEM, а в структуре указатель на гште8_е в ОЗУ? принципиально тут проблемы нет, но она может появиться в месте, где вы к этому указателю обращаетесь.
А как по другому решить размещение массива структур в PROGMEM?
Вообще я думаю что указатель он и в африке указатель... не важно, с PROGMEM он записан, или без... думаю упоминание PROGMEM нужно только для того, чтобы компилятор мог контролировать правильность памяти, с которой будет работать указатель... Т.е. если указатель PROGMEM, а мы его используем чтобы работать с RAM, вот тут то и выскажется компилятор.....
Так что размещая в массиве указатель, который был объявлен с PROGMEM, компилятор об этом помнит, и дальше будет контролировать правильность используемой памяти...
В общем как ты и сказал -
принципиально тут проблемы нет
тем более у
WiseLord работает... Наверное он свой компиль чем то прикармливает

..... Вот только не хочет сказать... чем.....
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт ноя 11, 2014 11:07:07
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";
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт ноя 11, 2014 12:11:19
shads
WiseLord писал(а):Чтобы добраться до адреса, хранимого в flash-памяти, надо выполнить что-то вроде
UartTransmInt (pgm_read_word(&Menu[MenuNum].pTxt));
ВОТ!!! конечно же... как это я так протупил...
меня сбило с толку то, что мне в определенных случаях возвращался адрес размещения текста... (т.е. я вижу где размещен текст, и вижу что мне возвращается именно этот адрес).
но я только сейчас допер, что таким образом может возвращатся только адрес размещения указателя на текст, но не сам адрес текста... сейчас в голове более менее прояснилось...
В общем извиняюсь за очередной балаган, который я тут развел

.....
(Хотя вопрос остался открытым, почему возвращаемый результат у меня в разных случаях был разный, хотя индекс по идее был всегда одинаковым (просто я его передавал разными способами))
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт ноя 11, 2014 12:24:28
WiseLord
Наверное, потому что при комментировании кода его размер уменьшался - это становился уже другой код - оптимизатор мог его сделать ещё более различным - функции располагались уже по другим адресам, и выводиться могло уже что-то другое.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт ноя 11, 2014 13:01:12
ARV
shads писал(а):В общем извиняюсь за очередной балаган, который я тут развел

.....
балаган начинается с "фигурных скобочек", где не надо, а заканчивается тем, что
shads писал(а):указатель он и в африке указатель... не важно, с PROGMEM он записан, или без...
после чего начинаются чудеса.
поэтому я поднапрягаюсь и советую вам тщательно изучить Си, чтобы делать не тяп-ляп, а по правилам и с полным пониманием того, что делаешь. собственно, 90% моих советов только в этом и заключаются
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт ноя 11, 2014 13:08:15
shads
ARV писал(а):cоветую вам тщательно изучить Си, чтобы делать не тяп-ляп, а по правилам и с полным пониманием того, что делаешь. собственно, 90% моих советов только в этом и заключаются
Спасибо!!!
Именно этим сейчас и занимаюсь...
Я в принципе сразу сознался в своих грехах:
http://radiokot.ru/forum/viewtopic.php? ... 3#p2169843
Но уже кой чего просветлело в голове

.... Так глядишь и C++ штурмовать начну

.....
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт ноя 13, 2014 07:35:06
pokk
Здравствуйте, подскажите как разместить в структуре строки разного размера. Компилятор CodeVisionAvr
есть такая структура меню
Код: Выделить всё
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"
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт ноя 13, 2014 07:46:48
ARV
попробуйте использовать указатель на строку char *Text;
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт ноя 13, 2014 07:50:55
GARMIN
делай в структуре ссылку на текстовую строку, а строки объявляй отдельно.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт ноя 13, 2014 11:30:05
pokk
Благодарю за помощь. С указателем на строку получилось.
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб ноя 15, 2014 11:42:33
6Н23П
здраствуйте
что означает конструкция
, где ADDRESS это допустим адрес микрухи.
например ADDRESS = 0b00000010, то получается что
0b00000010
0b00000001
__________
0b00000011 ?
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб ноя 15, 2014 11:47:00
ua1arn
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб ноя 29, 2014 04:59:00
WiseLord
Будь там ADDRESS |= 1 - это бы означало установку 0-го бита ADDRESS в 1.
А так - это всего лишь незавершённое логическое выражение, в результате которого получится некий промежуточный результат - число, равное ADDRESS с точностью до последнего бита, который будет равен 1. А что дальше с этим числом делается - мы не знаем.
Ну, как если бы спросить, что означает ADDRESS + 1.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн дек 08, 2014 08:27:11
greenled
Доброго всем дня! Пишу тут прогу для МК с архитектурой 8051 на Си в Keil, увы, уровень владения языком невысок, но интересует такой вопрос: как ассоциировать с переменной какую-либо ячейку памяти данных? Делать ассемблерную вставку или можно как-то стандартными средствами кейловского си обойтись?
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн дек 08, 2014 09:56:19
Gudd-Head
Аааа... зачем?