|
Динамическое создание массивов и ошибки при работе с ними, Косяк, но не понимаю почему |
|
|
|
Jun 7 2009, 12:12
|
Местный
  
Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512

|
Смысл в том, что данные приходящие по UART сбрасываю в буфер RS232_RX_BUFFER. Потом при его заполнении выставляю флаг. Главная программа если видит флаг, то создает динамический массив того же размера что и RS232_RX_BUFFER и начинает его декодировать. Зачем сделана двойная буферизация? - Отвечаю: так надо В коде происходит так: Код uint8 *buf1; .....
if(RS232_RX_BUFFER_OVERFLOW) { buf1 = (uint8*) malloc(RS232_RX_BUFFER_SIZE * sizeof(uint8)); // Сообразили 2-й буфер //if (buf==0) break; // Тут надо придумать обработчик если памяти на буфер не дали buf1 = (uint8*) memcpy((uint8*)buf1,(uint8*)RS232_RX_BUFFER,RS232_RX_BUFFER_SIZE); RS232_RX_BUFFER_OVERFLOW=0; // Обнулим флаг переполнения приемного буфера RS232 RS232_RX_BUFFER_INDEX=0; if(UART_Decode_Package((uint8*)buf1,RS232_RX_BUFFER_SIZE)==0) RS232_TX_BUILD_MESSAGE_PACKAGE(30); // Пакет битый free(buf1); } если же динамический массив не использовать то проверка на валидность пакета проходит без проблем. Вот так работает: Код if(RS232_RX_BUFFER_OVERFLOW) { if(UART_Decode_Package((uint8*)RS232_RX_BUFFER,RS232_RX_BUFFER_SIZE)==0) RS232_TX_BUILD_MESSAGE_PACKAGE(30); RS232_RX_BUFFER_OVERFLOW=0; // Обнулим флаг переполнения приемного буфера RS232 RS232_RX_BUFFER_INDEX=0; } Вот обработчик пакета: Код uint8 UART_Decode_Package(uint8 *rs232_rx_buf,uint8 Len) { uint16 crc16;
crc16 = (uint16) CRC16((uint8*) rs232_rx_buf,Len-2);
if (crc16!=((((uint16) rs232_rx_buf[Len-2])<<8) | rs232_rx_buf[Len-1])) { // Если пришёл битый пакет return 0; // Контрольная сумма не прошла } ....... return 1; } Вот считалка контрольной суммы. Функция - табличная. Код uint16 CRC16(uint8 *data, uint16 len) { uint16 crc = 0xFFFF; while (len--) crc = (crc << 8) ^ Crc16Table[(crc >> 8) ^ *data++]; return crc; } В общем если кто может сказать почему у меня возникли проблемы при обработки динамич. массивов - заранее огромное спасибо!!! P.S. Контроллер: AT90USB162, у него RAM 512 байт.
Сообщение отредактировал Halfback - Jun 7 2009, 12:12
|
|
|
|
|
Jun 7 2009, 15:30
|
Местный
  
Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512

|
sergeeffЦитата Складывается ощущение, что вы должны уложиться со всеми этими копированиями-декодированием за время от момента возникновения сигнала overflow до прихода следующего символа по rs232 (не так уж много). Пакеты с ПК я выдаю вручную. Так что копирование-перекодирование успевает 100 пудов. Тут явно проблема либо с нехваткой ОЗУ (которую я попытаюсь явно выявить) либо глупая ошибка при передачи массива по указателю в функцию. Цитата Кстати о двойной буфферизации. А кто мешает второй буфер сделать статическим, если он уж очень нужен? Ничего не мешает. Причем опытные железячные программисты так и советуют сделать (в случае избежания случая если ОЗУ не хватит, а если делать статически - то компилятор хотя бы выдаст ошибку переполнения ОЗУ) - но тем не менее не понятно почему так происходит. Еще одна причина - у меня не только буфер по УАРТу но и по другим интерфейсам - поэтому в теле main была идея использовать один динамический массив чем несколько статических под каждый буфер. zltigoЦитата Заодно всякую ненужную галиматью типа buf1 = memcpy() уберите. Да, ну так расскажите где тут "галиматья"? Или знаете как по-другому и по-быстрее скопировать один массив в другой (при одинаковых размерах)? Цитата правильная работа с флагами работаю последовательно. так что пальцы гните перед другими!
Сообщение отредактировал Halfback - Jun 7 2009, 15:40
|
|
|
|
|
Jun 7 2009, 15:47
|

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

|
Цитата(Halfback @ Jun 7 2009, 18:30)  Да, ну так расскажите где тут "галиматья"? Галиматья специально отцитирована "buf1 =" она и есть родная. Цитата(Halfback @ Jun 7 2009, 18:30)  работаю последовательно... Да хоть зигзагами, только думать и обрабатывать ошибки возвращаемые malloc() по любому надо. Цитата ..так что пальцы гните перед другими!
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 7 2009, 16:15
|
Местный
  
Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512

|
zltigoЦитата обрабатывать ошибки возвращаемые malloc() по любому надо согласен. но на тот момент обработчика не придумал. malloc(), кстати, возращает одну ошибку - это 0. щас напишу обработчик malloc() и посмотрю что он возвращает. Дополнил код вот так: Код if(RS232_RX_BUFFER_OVERFLOW) { buf1 = (uint8*) malloc(RS232_RX_BUFFER_SIZE * sizeof(uint8)); // Сообразили 2-й буфер if(buf1==0) { // Тут надо придумать обработчик если памяти на буфер не дали RS232_TX_BUILD_MESSAGE_PACKAGE(99); } else { buf1 = (uint8*) memcpy((uint8*)buf1,(uint8*)RS232_RX_BUFFER,RS232_RX_BUFFER_SIZE); if(UART_Decode_Package((uint8*)buf1,RS232_RX_BUFFER_SIZE)==0) RS232_TX_BUILD_MESSAGE_PACKAGE(30); free(buf1); } RS232_RX_BUFFER_OVERFLOW=0; // Обнулим флаг переполнения приемного буфера RS232 RS232_RX_BUFFER_INDEX=0; По УАРТу когда отослал пакет в контроллер вернулся код 99. Т.е. malloc() память не выдел.  При компиляции вот что выдается: Bit variables area: 2h to 2h Bit variables size: 1 byte(s)
Data Stack area: 100h to 17Fh Data Stack size: 128 byte(s) Estimated Data Stack usage: 42 byte(s)
RAM Global variables area: 180h to 1D4h RAM Global variables size: 85 byte(s)
Hardware Stack area: 1D5h to 2FFh Hardware Stack size: 299 byte(s)
Heap size: 0 byte(s)
EEPROM usage: 0 byte(s), 0,0% of EEPROM Program size: 2927 words (5854 bytes), 35,7% of FLASHСлабо вериться что в ОЗУ не нашлось куска в 10 байт.
Сообщение отредактировал Halfback - Jun 7 2009, 16:16
|
|
|
|
|
Jun 7 2009, 16:29
|
Местный
  
Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512

|
sergeeffЦитата А куча (heap) вообще-то существует? И размер ее? не знаю что это такое но после компиляциии и линковки пишет что Код Heap size: 0 byte(s)
|
|
|
|
|
Jun 7 2009, 16:42
|

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

|
Цитата(Halfback @ Jun 7 2009, 19:15)  malloc(), кстати, возращает одну ошибку - это 0. Вообще-то он возвращает NULL, что в 'C' (void *)0. Цитата щас напишу обработчик malloc() и посмотрю что он возвращает. Это и так ясно было с самого начала. Цитата buf1 = (uint8*) memcpy((uint8*)buf1,(uint8*)RS232_RX_BUFFER,RS232_RX_BUFFER_SIZE); Ну и зачм по прежнему болтается это присвоение buf1  и ненужные письмена для явного преобразования buf1 и чего-то (зачем-то коcящего под макрос) к указателю на байт, хотя он buf1 сам по жизни такой, а аргументы memcpy() вообще универсальные void * Цитата(sergeeff @ Jun 7 2009, 19:21)  А куча (heap) вообще-то существует? И размер ее? Написано-же, что не существует, как класс: Цитата Heap size: 0 byte(s)
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 7 2009, 18:53
|

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

|
Цитата(sergeeff @ Jun 7 2009, 19:52)  Раз не знаешь.... Ну все когда-то чего-то не знали... Динамическее выделение памяти во многих случаях весьма эффективно в том числе и для экономии памяти, однако делить остатки микроскопических 512 байт стандартым неуклюжим менеждером требующим и ресурсов и, что еще более неприятно, требующим явного резервировния хипа, сколее всего очень неудачная идея. При необдуманом использовании предстоит познакомится и со словом дефрагментация  . Для микроскопических контроллеров в большинстве проще и много эффективнее размещать (при необходимости) динамические объекты в стеке. Ну недостаток, конечно, отсутствие штатных средств конроля, но зато минимум накладных и равноправный доступ к столь ограниченным ресурсам, как память.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 7 2009, 19:46
|
Местный
  
Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512

|
Жаль что тут никто реальным советом не помог. "Раз не знаешь - то мол не трогай" - это ко мне не относиться и к подобным высказываниям в свой адрес отношусь негативно т.к. не учился на домохозяку. А раз так то пришлось разобраться самому с этим heap. Heap - как я понял почитав пару статей в инете - это и есть область памяти где работает malloc и смежные ей функции при динамическом распределении ОЗУ. Но чтобы было всё хорошо её надо определить в компоновщике. В своем компиляторе (CAVR) я ей (свалке) выделил 20 байт - и вуаля, всё заработало!!! malloc теперь NULL не возвращает. Другое мне не понятно - почему компилятор на счет примененного мной malloc() ничего не вякнул. Код Hardware Stack area: 1D5h to 2EBh Hardware Stack size: 279 byte(s)
Heap area: 2ECh to 2FFh Heap size: 20 byte(s) Отсюда следует - что 20 байт компоновщик отнял от области памяти стека. ВОт это уже интересно!
Сообщение отредактировал Halfback - Jun 7 2009, 19:50
|
|
|
|
|
Jun 7 2009, 20:00
|

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

|
Цитата(Halfback @ Jun 7 2009, 22:46)  Жаль что тут никто реальным советом не помог. Вы так считаете  . Тогда Вы зря чрезмерно дистанциируетесь от домохозяйки  Цитата Heap - как я понял почитав пару статей в инете ....  Цитата Другое мне не понятно - почему компилятор на счет примененного мной malloc() ничего не вякнул.  Потому, что Вы описали сегмент heap, хотя и нулевого размера. Уберите сегмент и будет вякать. Цитата Но чтобы было всё хорошо её надо определить в компоновщике. Cюрприз, если, конечно не читали предыдущий пост. Впрочем, Вы можете и сами реализовать свой менеджер памяти сгладив особо мешающие Вам лично недостатки. Цитата Отсюда следует - что 20 байт компоновщик отнял от области памяти стека. ВОт это уже интересно! А Вы полагали, что он материализует их из окружающего пространства  . 20 байтовый heap это точно профанация идеи, может создаваться ну разве только для нужд библиотечных функций типа time().
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|