реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Указатель на елемент структуры_подскажите
SergSit
сообщение Jun 19 2006, 07:43
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 173
Регистрация: 9-12-05
Пользователь №: 12 031



Програмировать в СИ только начинаю, так что если что не правильно сильно не бейте.
В процессе написание проги возникла не обходимость обращаться к элементам структуры через указатели. Предположим есть структура :
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. Перепробывал много вариантов, не хватает опыта и глубокого знания СИ.
Может кто сталкивался с такой проблемой?
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jun 19 2006, 08:01
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Зачем в описании структуры указывать тип памяти?


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}

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


--------------------
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jun 19 2006, 08:06
Сообщение #3


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Согласно стандарту нельзя соэдать указатель на элемент структуры типа битовое поле.
Go to the top of the page
 
+Quote Post
SergSit
сообщение Jun 19 2006, 08:33
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 173
Регистрация: 9-12-05
Пользователь №: 12 031



Такой вариант не катит. Сразу выдает ошибку: структуру можно хранить только в том типе памяти в котором определена. Если в операторе 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 есть операция обращения к элементу массива и поэтому выдает ошибку.


Цитата(IgorKossak @ Jun 19 2006, 11:06) *
Согласно стандарту нельзя соэдать указатель на элемент структуры типа битовое поле.



Тоже самое происходит если структуру определить без полей битов. Вот таким образом

eeprom struct flagi_signal
{unsigned char kabina;
unsigned char kuzov;
unsigned char revun;
unsigned char zumer;
}fl_sign={1,1,1,1};
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Jun 19 2006, 09:02
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Написано очень путанно, поэтому предложу простой совет - аккуратно это все детализировать. Отдельно определить два структурных типа в хидере, в теле инициализировать данными. Для начала обыграть это все непосредственно в RAM. Битовые поля вообще можно заметить битовыми масками одного бита.
В данном случае дожно выглядеть так :
Код
flash set_sign signal_set[2]= {
{&mes22,&fl_sign.kabina,&punkt_zumer,&punkt_kuzov},
{&mes22,&fl_sign.kabina,&punkt_zumer,&punkt_kuzov}
};

В массив укладываются не структуры, а их адреса.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
maegg
сообщение Jun 19 2006, 09:04
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 129
Регистрация: 22-06-04
Из: S. Peterburg
Пользователь №: 103



можно выкрутится через union
union xxxx {

unsigned char xxx[xx];

struct xxxstr {
}
}
то есть в одной области памяти определить массив и структуру
А потом обращайся к массиву хоть через индекс или через указатель.
Недостаток придется вручную расписать все смещения на элементы структуры и присвоить им символические имена через define
Go to the top of the page
 
+Quote Post
_Bill
сообщение Jun 19 2006, 09:28
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



Цитата(SergSit @ Jun 19 2006, 10:43) *
Програмировать в СИ только начинаю, так что если что не правильно сильно не бейте.
В процессе написание проги возникла не обходимость обращаться к элементам структуры через указатели. Предположим есть структура :
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 аналогично.
Go to the top of the page
 
+Quote Post
WHALE
сообщение Jun 19 2006, 13:11
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



В CV так не прокатит,ему при обьявлении структуры нужно указывать тип памяти,при таком обьявлении
он сочтет,что это структтура в RAM и на TSygnalFlags flash signal_set[] = {.....} будет ругаться.


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post
_Bill
сообщение Jun 19 2006, 13:42
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



Цитата(WHALE @ Jun 19 2006, 16:11) *
В CV так не прокатит,ему при обьявлении структуры нужно указывать тип памяти,при таком обьявлении
он сочтет,что это структтура в RAM и на TSygnalFlags flash signal_set[] = {.....} будет ругаться.

Ну, и плохо это. Мы же можем писать
int i;
или
flash int i;
Через typedef просто объявляется новый тип данных, не более. А тип памяти, в которой располагаются данные этого типа, указывается при объявлении данных. В IAR сделано именно так, и это логично, по-моему.

Сообщение отредактировал _Bill - Jun 19 2006, 13:44
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jun 19 2006, 13:45
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Хочу еще раз подчеркнуть то что я говорил выше: в описателе структуры не надо объявлять тип памяти, ведь вы можете создать структуру как во флэш, так и в еепроме, или в статической памяти. Тип памяти указывается при объявлении переменной. Естественно, что и все члены структуры будут расположенны в том типе памяти, в котором созданна переменная с данным типом структуры. Но никто вам не запрещает через переопределение типов обратится через одного из членов структуры (если это указатель) к другому типу памяти. Немного запутанно, но я пытаюсь сказать то что пытаюсь))))



Ну вот вам еще пример, правда, работающий на 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

}




Такое проще конечно вытворять в Си++, где для структуры можно написать методы работы с членами структуры для разных типов памяти.

Вот о чем я хотел сказать)))


--------------------
Go to the top of the page
 
+Quote Post
Old1
сообщение Jun 19 2006, 18:22
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 697
Регистрация: 26-07-05
Из: Могилев
Пользователь №: 7 095



Цитата(SergSit @ Jun 19 2006, 10:43) *
Програмировать в СИ только начинаю, так что если что не правильно сильно не бейте.
В процессе написание проги возникла не обходимость обращаться к элементам структуры через указатели. Предположим есть структура :
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}};
Go to the top of the page
 
+Quote Post
WHALE
сообщение Jun 19 2006, 19:19
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



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;
И дальше включить его в ваш массив структур во флэше.


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post
SergSit
сообщение Jun 19 2006, 19:20
Сообщение #13


Частый гость
**

Группа: Свой
Сообщений: 173
Регистрация: 9-12-05
Пользователь №: 12 031



Большон спасибо всем за помощ.
Вариант OLD1 оказался самый правильный. В CV тоже работает отлично. Называется век живи век учись.
По поводу определителя типа структуры и класса памяти под него. В CV в операторе typedef сразу надо определять класс памяти и не подругому. Причем класс памяти вновь определяемой структуры должен совпадать с классом памяти объявленой в typedef. Так сделоно вCV.
Еще раз всем спасибо
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jun 19 2006, 22:34
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(SergSit @ Jun 20 2006, 03:20) *
Большон спасибо всем за помощ.
Вариант OLD1 оказался самый правильный. В CV тоже работает отлично. Называется век живи век учись.
По поводу определителя типа структуры и класса памяти под него. В CV в операторе typedef сразу надо определять класс памяти и не подругому. Причем класс памяти вновь определяемой структуры должен совпадать с классом памяти объявленой в typedef. Так сделоно вCV.
Еще раз всем спасибо


Если обувь тесная, пора срочно ее менять))) ИМХО в ИАРе лучше работается со всеми видами памяти...

Цитата(WHALE @ Jun 20 2006, 03:19) *
2 prottoss В стандарте С про типы памяти нет ни слова,и это естественно,так-как на компе их и не
бывает.Соответственно,это всеотдано на откуп компиляторописателям.Но в принципе я с вами согласен,
в IARе этот момент сделан лучше-что есть,то есть.


Что есть структура? Это попытка описать и упорядочить область памяти, где каждая ячейка будет что то означать. Это шаблон, накладывая который на ЛЮБОЙ участок памяти (ЛЮБОЙ памяти), мы будем знать что и за что отвечает. Структура описывает ТИП ДАННЫХ, а не ТИП ПАМЯТИ. Следовательно, ИМХО, компиляторы, которые путают два совершенно разных понятия кривые)))

В "компе", как Вы выразились, кстати, типы памяти есть, если копнуть немного глубже. Я имею ввиду сегменты... К тому же поцессор "компа" и МК AVR различаются архитектурой памяти, первый имеет архитектуру фон Неймана, когда у второго Гарвардская


--------------------
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 20:21
Рейтинг@Mail.ru


Страница сгенерированна за 0.01492 секунд с 7
ELECTRONIX ©2004-2016