|
Вопрос скорее по Си |
|
|
|
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
|
 |
Ответов
(30 - 44)
|
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
|
|
|