Перейти к содержанию
    

Указатель на елемент структуры_подскажите

Програмировать в СИ только начинаю, так что если что не правильно сильно не бейте.

В процессе написание проги возникла не обходимость обращаться к элементам структуры через указатели. Предположим есть структура :

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 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}

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласно стандарту нельзя соэдать указатель на элемент структуры типа битовое поле.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Написано очень путанно, поэтому предложу простой совет - аккуратно это все детализировать. Отдельно определить два структурных типа в хидере, в теле инициализировать данными. Для начала обыграть это все непосредственно в RAM. Битовые поля вообще можно заметить битовыми масками одного бита.

В данном случае дожно выглядеть так :

flash set_sign signal_set[2]= {
{&mes22,&fl_sign.kabina,&punkt_zumer,&punkt_kuzov},
{&mes22,&fl_sign.kabina,&punkt_zumer,&punkt_kuzov}
};

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

union xxxx {

 

unsigned char xxx[xx];

 

struct xxxstr {

}

}

то есть в одной области памяти определить массив и структуру

А потом обращайся к массиву хоть через индекс или через указатель.

Недостаток придется вручную расписать все смещения на элементы структуры и присвоить им символические имена через define

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Програмировать в СИ только начинаю, так что если что не правильно сильно не бейте.

В процессе написание проги возникла не обходимость обращаться к элементам структуры через указатели. Предположим есть структура :

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 аналогично.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В CV так не прокатит,ему при обьявлении структуры нужно указывать тип памяти,при таком обьявлении

он сочтет,что это структтура в RAM и на TSygnalFlags flash signal_set[] = {.....} будет ругаться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В CV так не прокатит,ему при обьявлении структуры нужно указывать тип памяти,при таком обьявлении

он сочтет,что это структтура в RAM и на TSygnalFlags flash signal_set[] = {.....} будет ругаться.

Ну, и плохо это. Мы же можем писать

int i;

или

flash int i;

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

Изменено пользователем _Bill

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

 

 

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

}

 

 

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Програмировать в СИ только начинаю, так что если что не правильно сильно не бейте.

В процессе написание проги возникла не обходимость обращаться к элементам структуры через указатели. Предположим есть структура :

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}};

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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;

И дальше включить его в ваш массив структур во флэше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Большон спасибо всем за помощ.

Вариант OLD1 оказался самый правильный. В CV тоже работает отлично. Называется век живи век учись.

По поводу определителя типа структуры и класса памяти под него. В CV в операторе typedef сразу надо определять класс памяти и не подругому. Причем класс памяти вновь определяемой структуры должен совпадать с классом памяти объявленой в typedef. Так сделоно вCV.

Еще раз всем спасибо

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Большон спасибо всем за помощ.

Вариант OLD1 оказался самый правильный. В CV тоже работает отлично. Называется век живи век учись.

По поводу определителя типа структуры и класса памяти под него. В CV в операторе typedef сразу надо определять класс памяти и не подругому. Причем класс памяти вновь определяемой структуры должен совпадать с классом памяти объявленой в typedef. Так сделоно вCV.

Еще раз всем спасибо

 

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

 

2 prottoss В стандарте С про типы памяти нет ни слова,и это естественно,так-как на компе их и не

бывает.Соответственно,это всеотдано на откуп компиляторописателям.Но в принципе я с вами согласен,

в IARе этот момент сделан лучше-что есть,то есть.

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...