SergSit 0 19 июня, 2006 Опубликовано 19 июня, 2006 · Жалоба Програмировать в СИ только начинаю, так что если что не правильно сильно не бейте. В процессе написание проги возникла не обходимость обращаться к элементам структуры через указатели. Предположим есть структура : eeprom struct flagi_signal {unsigned char kabina:1; unsigned char kuzov:1; unsigned char revun:1; unsigned char zumer:1; }fl_sign={1,1,1,1}; Теперь хочу создать массив структур в котором один из элементов должен ссылать на елементы сртукткры fl_sign, причем новая структура должна (если это возможно) храниться во Flash. Моя версия не работает flash struct set_sign {flash unsigned char *mas; eeprom unsigned char *pun;---> елемент который должен ссылать на елемент структуры fl_sign unsigned int punkt_up; unsigned int punkt_down; }signal_set[]={{mes22,fl_sign.kabina,punkt_zumer,punkt_kuzov}, {mes22,fl_sign.kabina,punkt_zumer,punkt_kuzov}}; Прогу пишу в CodeVision. Перепробывал много вариантов, не хватает опыта и глубокого знания СИ. Может кто сталкивался с такой проблемой? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prottoss 0 19 июня, 2006 Опубликовано 19 июня, 2006 · Жалоба Зачем в описании структуры указывать тип памяти? typedef struct set_sign_type { unsigned char *mas; unsigned char *pun; unsigned int punkt_up; unsigned int punkt_down; } set_sign __flash set_sign signal_set[]= {{mes22,fl_sign.kabina,punkt_zumer,punkt_kuzov} когда Вы обращаетесь к элементам структуры, вот тогда и преобразуете тип данных к нужному Вам типу памяти. И компилятору становится ясно, от куда брать данные. Может быть такой вариант катит? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 19 июня, 2006 Опубликовано 19 июня, 2006 · Жалоба Согласно стандарту нельзя соэдать указатель на элемент структуры типа битовое поле. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SergSit 0 19 июня, 2006 Опубликовано 19 июня, 2006 · Жалоба Такой вариант не катит. Сразу выдает ошибку: структуру можно хранить только в том типе памяти в котором определена. Если в операторе Typedef указываеш тип памяти flash, то эта ошибка пропадает. Но появляется другая: указатель на разные типы памяти. Это из-за того что mas храниться во flash. Когда ставиш flash unsigned char *mas- ошибка по указателю пропадает и происходит новая ошибка указавающая на строку flash set_sign signal_set[2]= {{mes22,fl_sign.kabina,punkt_zumer,punkt_kuzov},<---- сюда показывает {mes22,fl_sign.kabina,punkt_zumer,punkt_kuzov}}; И пишет: non adress/- constant initializer. Т.е. возвращается к тому от чего я пытаюсь уйти(((( Мне кажется это из-за того что при инициализации данных необходимо указывать константные выражения. А fl_sign.kabina есть операция обращения к элементу массива и поэтому выдает ошибку. Согласно стандарту нельзя соэдать указатель на элемент структуры типа битовое поле. Тоже самое происходит если структуру определить без полей битов. Вот таким образом eeprom struct flagi_signal {unsigned char kabina; unsigned char kuzov; unsigned char revun; unsigned char zumer; }fl_sign={1,1,1,1}; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
beer_warrior 0 19 июня, 2006 Опубликовано 19 июня, 2006 · Жалоба Написано очень путанно, поэтому предложу простой совет - аккуратно это все детализировать. Отдельно определить два структурных типа в хидере, в теле инициализировать данными. Для начала обыграть это все непосредственно в RAM. Битовые поля вообще можно заметить битовыми масками одного бита. В данном случае дожно выглядеть так : flash set_sign signal_set[2]= { {&mes22,&fl_sign.kabina,&punkt_zumer,&punkt_kuzov}, {&mes22,&fl_sign.kabina,&punkt_zumer,&punkt_kuzov} }; В массив укладываются не структуры, а их адреса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
maegg 0 19 июня, 2006 Опубликовано 19 июня, 2006 · Жалоба можно выкрутится через union union xxxx { unsigned char xxx[xx]; struct xxxstr { } } то есть в одной области памяти определить массив и структуру А потом обращайся к массиву хоть через индекс или через указатель. Недостаток придется вручную расписать все смещения на элементы структуры и присвоить им символические имена через define Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bill 0 19 июня, 2006 Опубликовано 19 июня, 2006 · Жалоба Програмировать в СИ только начинаю, так что если что не правильно сильно не бейте. В процессе написание проги возникла не обходимость обращаться к элементам структуры через указатели. Предположим есть структура : eeprom struct flagi_signal {unsigned char kabina:1; unsigned char kuzov:1; unsigned char revun:1; unsigned char zumer:1; }fl_sign={1,1,1,1}; Теперь хочу создать массив структур в котором один из элементов должен ссылать на елементы сртукткры fl_sign, причем новая структура должна (если это возможно) храниться во Flash. Моя версия не работает flash struct set_sign {flash unsigned char *mas; eeprom unsigned char *pun;---> елемент который должен ссылать на елемент структуры fl_sign unsigned int punkt_up; unsigned int punkt_down; }signal_set[]={{mes22,fl_sign.kabina,punkt_zumer,punkt_kuzov}, {mes22,fl_sign.kabina,punkt_zumer,punkt_kuzov}}; Прогу пишу в CodeVision. Перепробывал много вариантов, не хватает опыта и глубокого знания СИ. Может кто сталкивался с такой проблемой? Лучше (и проще всего) делать так: typedef struct { // Определить тип данных в виде структуры unsigned char kabina:1; unsigned char kuzov:1; unsigned char revun:1; unsigned char zumer:1; } TSygnalFlags; Далее, можно опеределить переменные этого типа: TSygnalFlags flash signal_set[] = {.....}; // Массив в программной flash памяти TSygnalFlags eeprom signal; // Переменная в EEPROM памяти данных И, соответственно, указатели на них: TSygnalFlags flash *sfPtr; // Указатель в ОЗУ, указывает на данные во flash flash TSygnalFlags flash *ffPtr = signal_set; // Указатель во flash памяти, укзывает на данные во flash C EEPROM аналогично. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
WHILE 0 19 июня, 2006 Опубликовано 19 июня, 2006 · Жалоба В CV так не прокатит,ему при обьявлении структуры нужно указывать тип памяти,при таком обьявлении он сочтет,что это структтура в RAM и на TSygnalFlags flash signal_set[] = {.....} будет ругаться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bill 0 19 июня, 2006 Опубликовано 19 июня, 2006 (изменено) · Жалоба В CV так не прокатит,ему при обьявлении структуры нужно указывать тип памяти,при таком обьявлении он сочтет,что это структтура в RAM и на TSygnalFlags flash signal_set[] = {.....} будет ругаться. Ну, и плохо это. Мы же можем писать int i; или flash int i; Через typedef просто объявляется новый тип данных, не более. А тип памяти, в которой располагаются данные этого типа, указывается при объявлении данных. В IAR сделано именно так, и это логично, по-моему. Изменено 19 июня, 2006 пользователем _Bill Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prottoss 0 19 июня, 2006 Опубликовано 19 июня, 2006 · Жалоба Хочу еще раз подчеркнуть то что я говорил выше: в описателе структуры не надо объявлять тип памяти, ведь вы можете создать структуру как во флэш, так и в еепроме, или в статической памяти. Тип памяти указывается при объявлении переменной. Естественно, что и все члены структуры будут расположенны в том типе памяти, в котором созданна переменная с данным типом структуры. Но никто вам не запрещает через переопределение типов обратится через одного из членов структуры (если это указатель) к другому типу памяти. Немного запутанно, но я пытаюсь сказать то что пытаюсь)))) Ну вот вам еще пример, правда, работающий на IARe: typedef struct MBS_Data_Block_Type { UCHAR Ext_Type; UCHAR Int_Type; UINT Ext_Addr; UINT Int_Addr; UINT Size; } MBS_Data_Block; __flash MBS_Data_Block Coil_Array[]; __flash MBS_Data_Block Input_Array[]; __flash MBS_Data_Block Hold_Array[]; __flash MBS_Data_Block Reg_Array[]; __flash MBS_Data_Block __flash *DB_Array[4] = { Coil_Array, Input_Array, Hold_Array, Reg_Array, }; Обратите внимание на объявление массива DB_Array - первый __flash указывает, что массив расположен в о флэше, второй __flash говорит что указатели содержат адерса структур, расположенных во флэше. Возмем структуру MBS_Data_Block. В ней адреса представленны вообще как integer. Но с помощью преобразований я в коде могу указать компилятору как работать с данным адерсом, и на какой тип памяти он указывает...Допустим: void main(void) { MBS_Data_Block db; (UCHAR *)db.Ext_Addr = 5;// пишем в SRAM (__eeprom UCHAR *) db.Ext_Addr = 5; // пишем в EEPROM } Такое проще конечно вытворять в Си++, где для структуры можно написать методы работы с членами структуры для разных типов памяти. Вот о чем я хотел сказать))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Old1 0 19 июня, 2006 Опубликовано 19 июня, 2006 · Жалоба Програмировать в СИ только начинаю, так что если что не правильно сильно не бейте. В процессе написание проги возникла не обходимость обращаться к элементам структуры через указатели. Предположим есть структура : eeprom struct flagi_signal {unsigned char kabina:1; unsigned char kuzov:1; unsigned char revun:1; unsigned char zumer:1; }fl_sign={1,1,1,1}; Теперь хочу создать массив структур в котором один из элементов должен ссылать на елементы сртукткры fl_sign, причем новая структура должна (если это возможно) храниться во Flash. Моя версия не работает flash struct set_sign {flash unsigned char *mas; eeprom unsigned char *pun;---> елемент который должен ссылать на елемент структуры fl_sign unsigned int punkt_up; unsigned int punkt_down; }signal_set[]={{mes22,fl_sign.kabina,punkt_zumer,punkt_kuzov}, {mes22,fl_sign.kabina,punkt_zumer,punkt_kuzov}}; Прогу пишу в CodeVision. Перепробывал много вариантов, не хватает опыта и глубокого знания СИ. Может кто сталкивался с такой проблемой? Указатели на битовые поля, как уже говорилось выше, создать нельзя. Если структуру flagi_signal определить так: eeprom struct flagi_signal {unsigned char kabina; unsigned char kuzov; unsigned char revun; unsigned char zumer; }fl_sign={1,2,3,4}; То вот такой вариант работает (проверял правда в ИАРе): __flash struct set_sign {unsigned char __flash *mas; unsigned char __eeprom *pun; unsigned int punkt_up; unsigned int punkt_down; }signal_set[]={{mes22,&fl_sign.kabina,punkt_zumer,punkt_kuzov}, {mes22,&fl_sign.kuzov,punkt_zumer,punkt_kuzov}}; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
WHILE 0 19 июня, 2006 Опубликовано 19 июня, 2006 · Жалоба 2 prottoss В стандарте С про типы памяти нет ни слова,и это естественно,так-как на компе их и не бывает.Соответственно,это всеотдано на откуп компиляторописателям.Но в принципе я с вами согласен, в IARе этот момент сделан лучше-что есть,то есть. 2 SergSit А если так: eeprom struct flagi_signal {unsigned char kabina:1; unsigned char kuzov:1; unsigned char revun:1; unsigned char zumer:1; }fl_sign={1,1,1,1}; struct flagi_signal flash *ptr_fl_sign=&fl_sign; И дальше включить его в ваш массив структур во флэше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SergSit 0 19 июня, 2006 Опубликовано 19 июня, 2006 · Жалоба Большон спасибо всем за помощ. Вариант OLD1 оказался самый правильный. В CV тоже работает отлично. Называется век живи век учись. По поводу определителя типа структуры и класса памяти под него. В CV в операторе typedef сразу надо определять класс памяти и не подругому. Причем класс памяти вновь определяемой структуры должен совпадать с классом памяти объявленой в typedef. Так сделоно вCV. Еще раз всем спасибо Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prottoss 0 19 июня, 2006 Опубликовано 19 июня, 2006 · Жалоба Большон спасибо всем за помощ. Вариант OLD1 оказался самый правильный. В CV тоже работает отлично. Называется век живи век учись. По поводу определителя типа структуры и класса памяти под него. В CV в операторе typedef сразу надо определять класс памяти и не подругому. Причем класс памяти вновь определяемой структуры должен совпадать с классом памяти объявленой в typedef. Так сделоно вCV. Еще раз всем спасибо Если обувь тесная, пора срочно ее менять))) ИМХО в ИАРе лучше работается со всеми видами памяти... 2 prottoss В стандарте С про типы памяти нет ни слова,и это естественно,так-как на компе их и не бывает.Соответственно,это всеотдано на откуп компиляторописателям.Но в принципе я с вами согласен, в IARе этот момент сделан лучше-что есть,то есть. Что есть структура? Это попытка описать и упорядочить область памяти, где каждая ячейка будет что то означать. Это шаблон, накладывая который на ЛЮБОЙ участок памяти (ЛЮБОЙ памяти), мы будем знать что и за что отвечает. Структура описывает ТИП ДАННЫХ, а не ТИП ПАМЯТИ. Следовательно, ИМХО, компиляторы, которые путают два совершенно разных понятия кривые))) В "компе", как Вы выразились, кстати, типы памяти есть, если копнуть немного глубже. Я имею ввиду сегменты... К тому же поцессор "компа" и МК AVR различаются архитектурой памяти, первый имеет архитектуру фон Неймана, когда у второго Гарвардская Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться