|
Вопрос скорее по Си |
|
|
|
Jun 1 2007, 15:17
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
В программе объявлен такой тип данных Код #define MAX_DATA_SIZE 128 struct TStructure { unsigned char DataSize;// размер данных unsigned char Data[MAX_DATA_SIZE]; }; Соответственно есть переменные такого типа: Код struct TStructure st1={ 3, {1,2,3} }; struct TStructure st1={ 1, {1} }; Структуры должны хранится в программной памяти и загружаться в ОЗУ соответственно ситуации. Проблема в том, что Data может быть разной длины (от 1 до 128), то есть программная память зря расходуется. Как определить структуру, чтобы поле Data имела размер не больше чем требуется?
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 44)
|
Jun 1 2007, 15:28
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
ИМХО, забейте на эту структуру!  Объявите одномерный массив Код unsigned char Data[MAX_DATA_SIZE+1]; И интерпретируйте его первый элемент (Data[0]) как валидный размер текущего массива. Соответственно ваши данные располагайте, начиная со второго элемента массива (Data[1]). P.S. я понимаю, когда в структуру объединяют разнотипные данные, но зачем для однотипных структуру-то создавать? Если только для того чтобы "красиво" в тексте исходника выглядело, дык дефайны для этого имеются, типа Код #define DataSize Data[0]
|
|
|
|
|
Jun 1 2007, 15:44
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(rezident @ Jun 1 2007, 18:28)  P.S. я понимаю, когда в структуру объединяют разнотипные данные, но зачем для однотипных структуру-то создавать? Если только для того чтобы "красиво" в тексте исходника выглядело, дык дефайны для этого имеются, типа Код #define DataSize Data[0] Данные разнотипные (пример неудачный). В Паскале я бы написал так: Код type Tstructure=record A: Byte; B: array of TDateTime;// TDateTime для примера end; На Си что-то не придумывается (хотя преложенный вариант в принципе подходит).
|
|
|
|
|
Jun 1 2007, 16:23
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
IMHO, лучше массивы не пытаться укладывать в структуры, ибо их размер должен быть определен. Лучше уж примерно так:
typedef struct TStructure { unsigned char DataSize;// размер данных unsigned char * pData; //указатель на начало массива }TStructure;
unsigned char Data[]={1,2,3,4}; unsigned char Data1[]={1,2,3,4,5,6,7};
TStructure mystr = {sizeof(Data), &Data[0])}; TStructure mystr1 = {sizeof(Data1), &Data1[0])};
--------------------
aka Vit
|
|
|
|
|
Jun 1 2007, 17:17
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(rezident @ Jun 1 2007, 18:28)  ИМХО, забейте на эту структуру!  Совершенно неразумный совет. Цитата И интерпретируйте его первый элемент (Data[0]) как валидный размер текущего массива. Ну зачем, о Господи! Если совершенно естественно именуется поле структуры а уж его "интерпретацией" должен заниматься компилятор. Зачем забивать себе и другим лишними знаниями, соглашениями и потенциальными ошибками. Цитата(_Артём_ @ Jun 1 2007, 19:49)  Пожалуй остановлюсь на массиве. И, простите, как, это поможет проблеме??? Внимательно читайте пост defunct - Ваш вариант это динамическое выделение памяти.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 1 2007, 17:50
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Наверное присоединюсь к defunct и zltigo. И структура здесь не мешает. Хотя я бы всёже в структуру вводил ссылку на массив и его длину. Со строками пример приведу, а массив ничем по сути не отличается. Код struct AddrKom_e { uint8_t Name; // Имя команды uint16_t TimeStart; // Время начала исполнения команды uint8_t TimeRealH; // Время реальное часы uint8_t TimeRealM; // Время реальное минуты } *Kom_e;
struct AddrKomT { uint8_t Name; // Имя команды uint16_t TimeStart; // Время начала исполнения команды uint8_t TimeMashtabTek, // Текущее значение масштаба для времени исполнения TimeMashtab; // Масштаб для времени исполнения uint16_t TimeLife; // Время исполнения команды с учётом масштаба int16_t BegX,BegY; // Начало объекта (X,Y) int8_t VecX,VecY; // вектор перемещения объекта (X,Y) uint8_t text[10]; // Текст сообщения } *KomT;
struct AddrKomR { uint8_t Name; // Имя команды uint16_t TimeStart; // Время начала исполнения команды uint8_t TimeMashtab; // Изменение масштаба для времени исполнения uint16_t TimeLife; // Изменение времени исполнения команды с учётом масштаба int16_t BegX,BegY, // Изменение начала объекта (X,Y) SizeX,SizeY; // Изменение размеров объекта (X,Y) int8_t VecX,VecY; // Изменение вектора перемещения объекта (X,Y) uint8_t NAktive; // Номер изменяемого объекта } *KomR;
..... А применяю так Код KomXx = (struct AddrKomXx*) AdrActiveKom[i]; // Прочитать адрес текущей активной команды if(KomXx->TimeStart>Status.TekTime) continue; // Если не подошло время для исполнения команды, то пропустить данную команду switch (KomXx->Name) { /* Команда "END" - "Ролик завершить" */ case 'E': ...... case 'e': Kom_e = (struct AddrKom_e*) AdrActiveKom[i];// Прочитать адрес текущей активной команды if((Kom_e->TimeRealH>Status.Hour)&&(Kom_e->TimeRealM>Status.Minute)){ .....
|
|
|
|
|
Jun 1 2007, 18:20
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(defunct @ Jun 1 2007, 18:48)  Как вариант - использовать "open array" и динамическое выделение памяти: Вот только с выделением облом - автор хотел эти структуры во флеше хранить. Т.е. если использовать "incomplete arrays" (в терминологии стандарта), то должно получиться: Код typedef struct { uint8_t size; uint8_t data[] } my_struct_type; my_struct_type const __flash Struct = { 2, { 1, 2} }; Только надо помнить четыре вещи: 1)такой массив может располагаться только в конце структуры 2)sizeof() будет выдавать размер такой структуры без учета массива, т.е. в данном случае 1 и сделать массив из таких структур уже не получится, а также арифметика указателей на этих структурах будет работать некорректно. 3) не все компиляторы поддерживают incomplete arrays (ИАР поддерживает) 4) В С++ такое уже не прокатит.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 1 2007, 18:43
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(zltigo @ Jun 1 2007, 23:17)  Совершенно неразумный совет. Вы как всегда категоричны  Чем же он неразумен в применении к структуре однотипных переменных? Структура это всего лишь абстракция, предназначенная для удобства человека. Чтобы человек-программист мог на привычном для него объектном уровне изложить компилятору свою точку зрения на вид, размерность и порядок расположения переменных. Данные в памяти будут все равно в виде байтов, 16-ти или 32-разрядных слов располагаться, в соответствии со способом организации типа памяти конкретного МК. Цитата(zltigo @ Jun 1 2007, 23:17)  Ну зачем, о Господи! Если совершенно естественно именуется поле структуры а уж его "интерпретацией" должен заниматься компилятор. Собственно я об этом же, только без обращения к Творцу  Только зачем она в приведенном автором топика примере? Цитата(zltigo @ Jun 1 2007, 23:17)  Зачем забивать себе и другим лишними знаниями, соглашениями и потенциальными ошибками. Тогда нужно на Паскале писать, а не на Си. Делов-то! Цитата(zltigo @ Jun 1 2007, 23:17)  Внимательно читайте пост defunct - Ваш вариант это динамическое выделение памяти. Читайте пост Сергея Борщ о том, какие проблемы бывают с незавершенными массивами.
|
|
|
|
|
Jun 1 2007, 21:24
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(rezident @ Jun 1 2007, 21:43)  Читайте пост Сергея Борщ о том, какие проблемы бывают с незавершенными массивами. Вам бы тоже не помешало прочитать его пост и сравнить два термина "open array" и "incomplete array". Проблемы перечисленные Сергеем не распространяются на open array, кроме одной - Цитата 1)такой массив может располагаться только в конце структуры Ну а то что нельзя разместить во флеш - да.. Но в контексте AVR - флеша ведь в разы больше чем RAM'а, для чего могла потребоваться такая экономия?! Цитата(Сергей Борщ @ Jun 1 2007, 21:20)  Вот только с выделением облом - автор хотел эти структуры во флеше хранить. Во флеш можно хранить в удобном и нормальном для этого виде, также как у автора ветки - структуры фиксированной длинны. Экономия на мой взгляд может потребоваться во второй части задачи - "загружаться в ОЗУ соответственно ситуации." Вот тут как раз сэкономить поможет способ с дин. выделением памяти.
|
|
|
|
|
Jun 1 2007, 22:15
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(_Артём_ @ Jun 1 2007, 19:17)  Структуры должны хранится в программной памяти и загружаться в ОЗУ соответственно ситуации. Проблема в том, что Data может быть разной длины (от 1 до 128), то есть программная память зря расходуется. Может быть я конечно не все понял, но в чем вобще проблема ? Копирование из флеш в рам в вашей ситуации все равно придется делать "ручками" Ну дык и кто мешает просто забить в памяти кусок максимального объема типа Код #define MAX_DATA_SIZE 128 struct { unsigned char DataSize;// размер данных unsigned char Data[MAX_DATA_SIZE]; } currStruct; и по необходимости переносить в нее из флеш. Ну или просто, если уж у Вас структуры хранятся в флеш то это наверное константы ? тогда просто организуйте доступ к ним без копирования в память
|
|
|
|
|
Jun 1 2007, 22:33
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(singlskv @ Jun 2 2007, 01:15)  Может быть я конечно не все понял, но в чем вобще проблема ? Копирование из флеш в рам в вашей ситуации все равно придется делать "ручками" Ну дык и кто мешает просто забить в памяти кусок максимального объема типа Код #define MAX_DATA_SIZE 128 struct { unsigned char DataSize;// размер данных unsigned char Data[MAX_DATA_SIZE]; } currStruct; и по необходимости переносить в нее из флеш. Ну или просто, если уж у Вас структуры хранятся в флеш то это наверное константы ? тогда просто организуйте доступ к ним без копирования в память Проблема в том, что программной памяти жалко (и так не хватает), это обстоятельство и не позволяет "просто забить в памяти кусок максимального объема типа".
|
|
|
|
|
Jun 2 2007, 08:43
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(defunct @ Jun 2 2007, 00:24)  сравнить два термина "open array" и "incomplete array". Стоп. Термин "incomplete array" приведен в стандарте С. Термина open array там нет, поэтому я решил что rezident ошибся в термине и поправил его, чтобы интересующийся ответом мог дальше искать информацию по правильным ключевым словам. Ваша фраза наталкивает на мысль, что open array это совершенно иная (хоть и похожая) конструкция. Но ладно стандарт, даже гугля на первых двух страницах не дает ни одной тематической ссылки на запрос "c open array" (дальше не искал). Поэтому объясните, что же такое "open array". Судя по вашей реплике, они есть в С++, с ними дружит sizeof и из них можно делать массивы? Цитата(defunct @ Jun 2 2007, 00:24)  Ну а то что нельзя разместить во флеш - да.. Но в контексте AVR - флеша ведь в разы больше чем RAM'а, для чего могла потребоваться такая экономия?! Как раз для размещения во флеш в этой задаче incomplete arrays подходят как нельзя лучше. А вот при работе в ОЗУ - да, динамическое выделение памяти выглядит красиво, но не в каждой задаче имеет смысл его использовать. Тогда можно по ситуации - или дин. память или присваивать указателю на такую структуру адрес заранее выделенного буфера и дальше работать с буфером как со структурой этого типа.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 2 2007, 12:40
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Сергей Борщ @ Jun 2 2007, 11:43)  Стоп. Термин "incomplete array" приведен в стандарте С. Термина open array там нет, поэтому я решил что rezident ошибся в термине и поправил его Вы поправляли меня. Под open array, я привел конструкцию: char A[1]; а не char A[] т.е. это обычный массив объявленный с количеством элементов = 1. Но ничто не мешает нам обращаться к элементам A[1], A[2] и т.д., необходимо лишь быть уверенным, что обращаясь к этим элементам мы не затрем ничего лишнего. При дин. выделении памяти - мы определяем границу массива количеством выделенной под него памяти. Цитата , чтобы интересующийся ответом мог дальше искать информацию по правильным ключевым словам. По ключевому слову incomplete он бы нашел не то, что я имел в виду. Цитата Поэтому объясните, что же такое "open array". Судя по вашей реплике, они есть в С++, с ними дружит sizeof и из них можно делать массивы? Отличие выше, с sizeof он конечно же тоже не дружит, т.к. будет возвращена длина 1. Но sizeof не был перечислен в Вашем списке проблем, либо я невнимательно смотрел. В C++ нично не препятствует использованию таких конструкций. Цитата Как раз для размещения во флеш в этой задаче incomplete arrays подходят как нельзя лучше. Согласен.
|
|
|
|
|
Jun 2 2007, 12:41
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Цитата присваивать указателю на такую структуру адрес заранее выделенного буфера и дальше работать с буфером как со структурой этого типа А что, преобразование типа через void * не годится или имеется в виду то же? Если массивы есть, то кто им мешает располагаться во FLASH? Вроде этого и хотели. Добавить модификаторы const __flash ко всем элементам (кроме typedef), т.е. к массивам и структурам, в вариант http://electronix.ru/forum/index.php?showt...32479&st=0# и свободно пользоваться - массивы нужной длины во FLASH, структуры для работы с ними - тоже, "лишнего" места - аж по одному указателю на 1 массив. Просто не очень понятно, зачем для const массивов создавать что-то динамическое? Если нужно копировать, то всё-равно будет нужно куда-то положить. Если не обязательно, то можно взять по указателю в любое время.
--------------------
aka Vit
|
|
|
|
|
Jun 2 2007, 13:52
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(defunct @ Jun 2 2007, 15:40)  Под open array, я привел конструкцию: char A[1]; а не char A[]; т.е. это обычный массив объявленный с количеством элементов = 1. ... Отличие выше, с sizeof он конечно же тоже не дружит, т.к. будет возвращена длина 1. Но sizeof не был перечислен в Вашем списке проблем, либо я невнимательно смотрел. Не вижу принципиальных отличий. К char A[]с тем же успехом можно обращаться через A[1], A[2] и так далее, "необходимо лишь быть уверенным" и далее по тексту. Точно так же не дружит с sizeof(), только для char A[1] надо ptr = malloc( sizeof(struct header) + data_len - 1); а для char A[] надо ptr = malloc( sizeof(struct header) + data_len); что несколько более логично. Т.е. разницы с точки зрения применения - нет. Фактически, char A[1]; - это старый добрый программистский трюк, основанный на том, что поля структуры расположены в памяти в том же порядке, в котором записаны в структуре (кстати, в C++ это не гарантируется, если я правильно помню). char A[]; - это стандартизованный способ. Кстати, GNU-тое расширение позволяло писать char A[0];
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Jun 2 2007, 16:42
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(ReAl @ Jun 2 2007, 16:52)  Т.е. разницы с точки зрения применения - нет. В контексте вопроса этой ветки разница есть, и очень существенная. Так как struct { char A[]; } просто не воспримится многими компиляторами.
|
|
|
|
|
Jun 2 2007, 18:24
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Сергей Борщ @ Jun 2 2007, 00:20)  3) не все компиляторы поддерживают incomplete arrays (ИАР поддерживает) Кстати, Сергей, откуда ты взял, что ИАР поддерживает? Помнится у меня была подобная проблема, когда в зависимости от конкретной прикладной задачи прибора, нужно было хранить в сегменте INFO MSP430 наряду с определенным количеством констант еще произвольное описание масок для данных. Так вот предлагаемый тобой способ с incompete array не прокатил. Хотя я располагал массив как и положено в конце структуры констант. Пришлось определять его отдельно как константный байтовый массив с одновременной инициализацией его. А в самой программе писать свою функцию, разбирающую этот массив на данные нужной размерности. Код //описание масок для обработки буфера данных, сетевых и локальных // кол-во байт описания - смещение для переменной в буфере - маска1[, маска2, маска3, ...]; 0 - завершение описания #pragma pack(1) #pragma location=(0x1000+sizeof(InfoSeg)) const unsigned char MaskLedOut[]= { 0, //описание для LED1 0, //описание для LED2 0, //описание для LED3 0, //описание для LED4 1, MAIN_LOC_BUF_OFF, 0x10, 0, //описание для LED5 1, MAIN_LOC_BUF_OFF, 0x20, 0, //описание для LED6 1, MAIN_LOC_BUF_OFF, 0x40, 0, //описание для LED7 1, MAIN_LOC_BUF_OFF, 0x80, 0, //описание для LED8 1, MAIN_LOC_BUF_OFF+1, 0x01, 0, //описание для LED9 1, MAIN_LOC_BUF_OFF+1, 0x02, 0, //описание для LED10 1, MAIN_LOC_BUF_OFF+1, 0x04, 0, //описание для LED11 1, MAIN_LOC_BUF_OFF+1, 0x08, 0, //описание для LED12 0, //описание для LED13 1, MAIN_NET_BUF_OFF(5)+3, 0x80, 0, //описание для LED14 4, MAIN_NET_BUF_OFF(5), 0x5E, 0x60, 0x00, 0x03, 0,//описание для LED15 1, MAIN_NET_BUF_OFF(6), 0x06, 0 //описание для LED16 }; #pragma pack() Ах да! Пользовался я ИАР ЕВ430 3.30А.
|
|
|
|
|
Jun 2 2007, 19:00
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(rezident @ Jun 2 2007, 21:24)  Кстати, Сергей, откуда ты взял, что ИАР поддерживает? Поддерживает. Практически используется, ну и родной документ по IAR EW430: Код Incomplete arrays at end of structs The last element of a struct may be an incomplete array. This is useful because one chunk of memory can be allocated for the struct itself and for the array, regardless of the size of the array. Цитата Так вот предлагаемый тобой способ с incompete array не прокатил Невероятно, разве только если не пытались совсем грубо: Код The array may not be the only member of the struct. If that was the case, then the size of the struct would be zero, which is not allowed in ISO/ANSI C.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 2 2007, 19:16
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(zltigo @ Jun 3 2007, 01:00)  The array may not be the only member of the struct. If that was the case, then the size of the struct would be zero, which is not allowed in ISO/ANSI C. Эта цитата означает что структура не может состоять только из одного incomplete array, я правильно понял? Нет, у меня была структура из разных переменных в конце которой я пытался вставить этот incomplete array. Не получилось. ИАР выдавал ошибку. Кстати, могла ли быть эта ошибка вызвана тем, что объявлял я структуру с одновременной инициализацией ее в одном модуле, а использовал еще и в двух других. Естественно, что в других модулях был описан ее прототип с квалификатором extern.
|
|
|
|
|
Jun 2 2007, 19:27
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата Эта цитата означает что... Да. Цитата(rezident @ Jun 2 2007, 22:16)  Не получилось. ИАР выдавал ошибку. Подтверждаю, что использую без всяких проблем.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 2 2007, 19:52
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(rezident @ Jun 2 2007, 21:24)  Кстати, Сергей, откуда ты взял, что ИАР поддерживает? Из хелпа. Да и тут вопрос задавал, когда в плюсах попробовал использовать и не прошло. Мне тут ответили, что все работает. Переключил в режим С, действительно скомпилилось. А в плюсах - никак. Долго думал. Потом понял, что сама идеология классов (и структур как частных случаев классов) из-за полиформизма такое не допускает. Меня интересовало именно в ОЗУ. Сделал через динамическое выделение байтового массива и накладывание структуры. Кстати (!) структуру описал как open array. Насчет использования incomplete array в разных файлах - тоже наталкивался, но не на ошибку а на варнинг, но сейчас не вспомню какой точно. Если есть интерес - могу попытаться воспроизвести. Если я правильно понял ваш исходник, вы пытались сделать массив из структур, содержащих incomplete array. А поскольку размер такой структуры неизвестен, то и массив из нее сделать никак. P.S. вот читаешь всякие умные книжки, и так у них красиво все получается. Массив нужен из таких структур - пожалуйста: получите массив указателей на такие структуры. И писать можно data = Mystruct[1].data[3]. А вдумаешься - для этой "красоты" на каждую структуру лишний указатель. Выглядит красиво, но в нашей области в бОльшей части реальных задач неприменимо. Или динамическое выделение памяти - с ним задача из примера решается легко и естественно. А оно мне на меге8 с 1К ОЗУ как серпом по... И так практически с каждым примером. Снова порой ощущаю себя как когда с ассемблера на С переползал - "блин, какой тупой компилятор, здесь можно было команду сэкономить, здесь регистр, здесь такт". Может это пройдет, а может в этом есть и положительное - заставляет мозгами активнее шевелить.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 2 2007, 20:37
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(zltigo @ Jun 2 2007, 23:11)  А какие проблемы? Для простейшего менеджера памяти накладные расходы можно свести к паре-тройке байтов на блок. А кто тут пугал всех ужасами фрагментации в "простейших менеджерах памяти"? Как там было в классике? "Настоящий программист экономит 30 тактов в цикле, который выполняется один раз при запуске программы". Жаба душит заводить кучу чтобы попользоваться ей только один раз. А насчет менеджера памяти надо пообщаться - актуально. Нужны две кучи - в "набортном" быстром ОЗУ для объектов и во внешнем для данных. Насколько я разобрался в ИАРе - он умеет только одну. По вашим сообщениям я понял, что у вас есть наработки на эту тему. P.S. Хотя, насчет кучи у меня действительно предубеждение, надо его побороть. На ARMах уже использую, но еще не "почувствовал" настолько, чтобы и в мелких контроллерах применять не задумываясь. Все время гложет вопрос - что делать, если память кончится. Оператора ведь нет, некому плакаться.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 2 2007, 21:38
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Jun 2 2007, 23:37)  А кто тут пугал всех ужасами фрагментации в "простейших менеджерах памяти"?  Я пугал, но в большинстве микроконтроллерных случаев от менеджера достаточно получить экономное распределение памяти в зависимости от текущей конфигурации и возможность хотя-бы последовательного выделения-освобождения-выделения-.... Цитата А насчет менеджера памяти надо пообщаться - актуально. Нужны две кучи - в "набортном" быстром ОЗУ для объектов и во внешнем для данных. Естественное желание. Цитата Насколько я разобрался в ИАРе - он умеет только одну. Даже не разбирался  Цитата По вашим сообщениям я понял, что у вас есть наработки на эту тему. Ага, менеджер слегка навороченный - вызывается инициализация c указанием подконтрольного блока памяти. Количество вызовов не ограничено  , что позволяет иметь любое количество областей. Я его использую в том числе и для создания внутри выделенного блока памяти еще одного менеджируемого набора блоков фиксированного размера для беспорядочного использования без побочных проблем с дефрагментацией. Цитата P.S. Хотя, насчет кучи у меня действительно предубеждение, надо его побороть Обязательно. Цитата Все время гложет вопрос - что делать, если память кончится. Оператора ведь нет, некому плакаться. Разбираться и прибивать нежизненноважные задачи.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 4 2007, 08:03
|
Частый гость
 
Группа: Свой
Сообщений: 151
Регистрация: 21-02-06
Пользователь №: 14 561

|
Цитата(_Артём_ @ Jun 2 2007, 01:33)  Проблема в том, что программной памяти жалко (и так не хватает), это обстоятельство и не позволяет "просто забить в памяти кусок максимального объема типа". ...непонятно, предполагается что структура размещается в ОЗУ, а не в программной памяти и данные в нее заносятся из flash... у вас нехватка какой памяти программ или ОЗУ данных?
|
|
|
|
|
Jun 4 2007, 21:14
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(tag @ Jun 4 2007, 11:03)  ...непонятно, предполагается что структура размещается в ОЗУ, а не в программной памяти и данные в нее заносятся из flash... у вас нехватка какой памяти программ или ОЗУ данных? Нехватка у меня памяти программ(это к слову). Вариант Сергея Борща почему-то в С++ глючит (то работает, то нет). Наверное буду использовать другие варианты (скорее всего двоичный массив нужной длины). Пожалуй, тему пора закрывать - сказано более, чем достаточно... Всем спасибо.
|
|
|
|
|
Jun 5 2007, 08:14
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
А про С++ в вопросе не было! Цитата(_Артём_ @ Jun 5 2007, 00:14)  Вариант Сергея Борща почему-то в С++ глючит (то работает, то нет). Как заставить Американца прыгнуть с моста? Встретить его на мосту и убедить, что он разорен. Как заставить француза прыгнуть с моста? Встретить его на мосту и убедить, что жена ему изменяет. Как заставить русского прыгнуть с моста? Встретить его на мосту и сказать "А вы знаете, здесь прыгать с моста запрещено!" Цитата(Сергей Борщ @ Jun 1 2007, 21:20)  4) В С++ такое уже не прокатит. В С++ такое не работает по простой причине: при наследовании данные производной структуры (которая в С++ есть частный случай класса) располагаются вслед за данными родителя. А если размер родителя неизвестен, компилятор не сможет иметь доступ к данным производного класса. А сказать "от этого класса наследников не будет никогда" возможности нет. Как сделать на С++ то, что вы хотите, да еще с инициализацией через {} - не знаю  Могу предложить два варианта - 1) массив структур сам по себе, структура из размера и указателя на массив. Да, лишний указатель, зато можно писать a = pArray[n].member; 2) не указывать размер, а в конце масива добавлять элемент с каким-либо признаком конца структуры (например если одно из полей - указатель, то он равен нулю. Код class terminal_t { public: terminal_t() {}; static void process(); private: static bool read_input(char c); public:
private: ................ struct dictionary_t { char Name[10]; void (*Action)(void); uint8_t StackRequired; } static const __flash Dictionary[]; } static Terminal;
#define TERMINAL_DICTIONARY \ terminal_t::dictionary_t const __flash terminal_t::Dictionary[] = \ { \ { "HEX", ns_terminal::SetHex, 0}, \ { "DECIMAL", ns_terminal::DECIMAL, 0}, \ { ".", ns_terminal::UDOT, 1}, \ { "@", ns_terminal::Reference, 1}, \ { "!", ns_terminal::Dereference, 2}, \ {"DUMP", ns_terminal::DUMP, 2}, \
#define TERMINAL_DICTIONARY_END \ {0, 0 } \ };
TERMINAL_DICTIONARY {"v", readADC, 0}, {"IDUMP", RAM_DUMP, 2}, {"RDUMP", XROM_DUMP, 3}, {"XDUMP", XRAM_DUMP, 2}, {"X!", writeRAM, 2}, {"X@", readRAM, 1}, {"RB!", writeROM_byte, 3}, {"R!", writeROM, 3}, {"R@", readROM, 2}, {"SN", SN, 0}, TERMINAL_DICTIONARY_END Да, на каждую структуру лишний элемент, но не нужно вручную перед компиляцией считать количество элементов, а значит и ошибиться невозможно. И те же самые Dictionary[n].Action();
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 5 2007, 10:17
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(Сергей Борщ @ Jun 5 2007, 10:14)  В С++ такое не работает по простой причине: при наследовании данные производной структуры (которая в С++ есть частный случай класса) располагаются вслед за данными родителя. А если размер родителя неизвестен, компилятор не сможет иметь доступ к данным производного класса. Более того, даже без учёта incomplete array порядок размещения полей гарантируется только если у класса нет чередования модификаторов доступа (public/protected/private), нет виртуальных функций и базовых классов. Т.е. тут порядок в памяти будет как написано class foo { int i; int j; int k; }; а тут уже "не гарантируется", хотя и, вероятнее всего, будет всё нормально. struct moo { int i; protected: int j; public: int k; }; gcc без ключа полного соответствия стандарту (--pedantic) пропускает incomplete arrays и вроде бы всё нормально компилирует... Но при этом не ругается даже если вывести потомка. На мой взгляд, если уж припёрло, лучше бы такое выделить в отдельный чисто-С-шный модуль и обернуть в вызовы (чтобы сами структуры наружу даже не блестели). Или таки разориться на указатели в структурах а массивы держать отдельно.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Jun 5 2007, 20:20
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(zltigo @ Jun 5 2007, 00:27)  Ой! Очем это? "Глючит"  . Поросто не компилится в принципе. Что однако не мешает его использовать, поскольку никто не обязывает весь проект на С++ писать. Привожу код: Код struct my_struct_type { unsigned long TL; unsigned short Tmp; unsigned char size; unsigned char data[5]; };
my_struct_type const __flash Struct = { 100, 10, 3, { 1, 2, 5, 7} }; struct TTT { volatile unsigned char A; void SomeFunc(unsigned char b); };
struct TTT TT;
void TTT::SomeFunc(unsigned char b) { A+=b; }
typedef const __flash my_struct_type *my_struct_type_p; void TestStruct(unsigned char *ptr) { FlashPointer ff; my_struct_type_p pp;
//ff=&Struct.data[0]; //unsigned char i, k=Struct.size+Struct.Tmp; unsigned long i, k=Struct.size+Struct.Tmp+Struct.TL; unsigned char b; //pp=&Struct; for (i=0; i<k; i++) { b=*ptr; TT.SomeFunc(b); *ptr++=*ff++; } } Использую IAR3.10С.
|
|
|
|
|
Jun 5 2007, 20:30
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(_Артём_ @ Jun 5 2007, 23:20)  Привожу код: Код struct my_struct_type { unsigned long TL; unsigned short Tmp; unsigned char size; unsigned char data[5]; }; Ну и причем здесь Ваши слова: Цитата Вариант Сергея Борща почему-то в С++ глючит (то работает, то нет). Когда у Сергея речь шла о: Код struct my_struct_type { unsigned long TL; unsigned short Tmp; unsigned char size; unsigned char data[]; };
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 5 2007, 21:22
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(zltigo @ Jun 5 2007, 23:30)  Ну и причем здесь Ваши слова: Когда у Сергея речь шла о: Код struct my_struct_type { unsigned long TL; unsigned short Tmp; unsigned char size; unsigned char data[]; }; Беру свои слова обратно... Видно под вечер глаз замылился.. слона не заметил. В ходе экспериментов наверное заменил data[] на data[5] и забыл. Сейчас вижу: Вы правы - такой вариант компилятором не компилируется. Спасибо что поправили.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|