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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Динамическое создание массивов и ошибки при работе с ними, Косяк, но не понимаю почему
Halfback
сообщение Jun 7 2009, 12:12
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512



Смысл в том, что данные приходящие по UART сбрасываю в буфер RS232_RX_BUFFER. Потом при его заполнении выставляю флаг. Главная программа если видит флаг, то создает динамический массив того же размера что и RS232_RX_BUFFER и начинает его декодировать. Зачем сделана двойная буферизация? - Отвечаю: так надо rolleyes.gif

В коде происходит так:
Код
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
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 7 2009, 12:46
Сообщение #2


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Складывается ощущение, что вы должны уложиться со всеми этими копированиями-декодированием за время от момента возникновения сигнала overflow до прихода следующего символа по rs232 (не так уж много). Это так, или com порт у вас с fifo? В любом случае попробуйте на время обработки буфера запретить прерывания и посмотреть, есть ли разница.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 7 2009, 13:35
Сообщение #3


Гуру
******

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



Цитата(Halfback @ Jun 7 2009, 15:12) *
....у него RAM 512 байт.
......
//if (buf==0) break; // Тут надо придумать обработчик если памяти на буфер не дали

Когда придумаете smile.gif, тогда и пишите программы с менеджерами памяти для контроллеров с 512B
Заодно всякую ненужную галиматью типа buf1 = memcpy() уберите. Ну а дальше пойдут времена, правильная работа с флагами, критичесими секциями....


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 7 2009, 14:25
Сообщение #4


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Кстати о двойной буфферизации. А кто мешает второй буфер сделать статическим, если он уж очень нужен?
Go to the top of the page
 
+Quote Post
Halfback
сообщение Jun 7 2009, 15:30
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512



sergeeff
Цитата
Складывается ощущение, что вы должны уложиться со всеми этими копированиями-декодированием за время от момента возникновения сигнала overflow до прихода следующего символа по rs232 (не так уж много).

Пакеты с ПК я выдаю вручную. Так что копирование-перекодирование успевает 100 пудов.

Тут явно проблема либо с нехваткой ОЗУ (которую я попытаюсь явно выявить) либо глупая ошибка при передачи массива по указателю в функцию.

Цитата
Кстати о двойной буфферизации. А кто мешает второй буфер сделать статическим, если он уж очень нужен?

Ничего не мешает. Причем опытные железячные программисты так и советуют сделать (в случае избежания случая если ОЗУ не хватит, а если делать статически - то компилятор хотя бы выдаст ошибку переполнения ОЗУ) - но тем не менее не понятно почему так происходит. Еще одна причина - у меня не только буфер по УАРТу но и по другим интерфейсам - поэтому в теле main была идея использовать один динамический массив чем несколько статических под каждый буфер.

zltigo
Цитата
Заодно всякую ненужную галиматью типа buf1 = memcpy() уберите.

Да, ну так расскажите где тут "галиматья"? Или знаете как по-другому и по-быстрее скопировать один массив в другой (при одинаковых размерах)?

Цитата
правильная работа с флагами

работаю последовательно. так что пальцы гните перед другими!

Сообщение отредактировал Halfback - Jun 7 2009, 15:40
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 7 2009, 15:47
Сообщение #6


Гуру
******

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



Цитата(Halfback @ Jun 7 2009, 18:30) *
Да, ну так расскажите где тут "галиматья"?

Галиматья специально отцитирована "buf1 =" она и есть родная.
Цитата(Halfback @ Jun 7 2009, 18:30) *
работаю последовательно...

Да хоть зигзагами, только думать и обрабатывать ошибки возвращаемые malloc() по любому надо.
Цитата
..так что пальцы гните перед другими!

smile.gif smile.gif smile.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Halfback
сообщение Jun 7 2009, 16:15
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 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() память не выдел. wacko.gif При компиляции вот что выдается:
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 байт. blink.gif

Сообщение отредактировал Halfback - Jun 7 2009, 16:16
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 7 2009, 16:21
Сообщение #8


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



А куча (heap) вообще-то существует? И размер ее?
Go to the top of the page
 
+Quote Post
Halfback
сообщение Jun 7 2009, 16:29
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512



sergeeff
Цитата
А куча (heap) вообще-то существует? И размер ее?

не знаю что это такое но после компиляциии и линковки пишет что
Код
Heap size: 0 byte(s)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 7 2009, 16:42
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 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 sad.gif и ненужные письмена для явного преобразования buf1 и чего-то (зачем-то коcящего под макрос) к указателю на байт, хотя он buf1 сам по жизни такой, а аргументы memcpy() вообще универсальные void *

Цитата(sergeeff @ Jun 7 2009, 19:21) *
А куча (heap) вообще-то существует? И размер ее?

Написано-же, что не существует, как класс:
Цитата
Heap size: 0 byte(s)


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 7 2009, 16:52
Сообщение #11


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Раз не знаешь, что такое heap, не пользуйся функциями выделения/освобождения памяти или разберись с этим вопросом. Похоже, что динамический массив в данной задачи на фиг не нужен, как, впрочем, и двойная буферизация, особенно учитывая дефицит RAM.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 7 2009, 18:53
Сообщение #12


Гуру
******

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



Цитата(sergeeff @ Jun 7 2009, 19:52) *
Раз не знаешь....

Ну все когда-то чего-то не знали... Динамическее выделение памяти во многих случаях весьма эффективно в том числе и для экономии памяти, однако делить остатки микроскопических 512 байт стандартым неуклюжим менеждером требующим и ресурсов и, что еще более неприятно, требующим явного резервировния хипа, сколее всего очень неудачная идея. При необдуманом использовании предстоит познакомится и со словом дефрагментация sad.gif. Для микроскопических контроллеров в большинстве проще и много эффективнее размещать (при необходимости) динамические объекты в стеке. Ну недостаток, конечно, отсутствие штатных средств конроля, но зато минимум накладных и равноправный доступ к столь ограниченным ресурсам, как память.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jun 7 2009, 19:39
Сообщение #13


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Что-то у меня про эффективность динамической памяти не сильно язык поворачивается так сказать. Я бы сказал, что это компромиссное решение, когда программных модулей много, а свободных ресурсов памяти - не очень. И как обычно бывает за такой компромисс приходится расплачиваться накладными расходами на резервирование/освобождение памяти и ее фрагментацию.
Go to the top of the page
 
+Quote Post
Halfback
сообщение Jun 7 2009, 19:46
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512



Жаль что тут никто реальным советом не помог. "Раз не знаешь - то мол не трогай" - это ко мне не относиться и к подобным высказываниям в свой адрес отношусь негативно т.к. не учился на домохозяку. А раз так то пришлось разобраться самому с этим heap.
Heap - как я понял почитав пару статей в инете - это и есть область памяти где работает malloc и смежные ей функции при динамическом распределении ОЗУ. Но чтобы было всё хорошо её надо определить в компоновщике. В своем компиляторе (CAVR) я ей (свалке) выделил 20 байт - и вуаля, всё заработало!!! malloc теперь NULL не возвращает. Другое мне не понятно - почему компилятор на счет примененного мной malloc() ничего не вякнул. unsure.gif

Код
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
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 7 2009, 20:00
Сообщение #15


Гуру
******

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



Цитата(Halfback @ Jun 7 2009, 22:46) *
Жаль что тут никто реальным советом не помог.

Вы так считаете sad.gif. Тогда Вы зря чрезмерно дистанциируетесь от домохозяйки smile.gif
Цитата
Heap - как я понял почитав пару статей в инете ....

smile.gif
Цитата
Другое мне не понятно - почему компилятор на счет примененного мной malloc() ничего не вякнул. unsure.gif

Потому, что Вы описали сегмент heap, хотя и нулевого размера. Уберите сегмент и будет вякать.
Цитата
Но чтобы было всё хорошо её надо определить в компоновщике.

Cюрприз, если, конечно не читали предыдущий пост. Впрочем, Вы можете и сами реализовать свой менеджер памяти сгладив особо мешающие Вам лично недостатки.
Цитата
Отсюда следует - что 20 байт компоновщик отнял от области памяти стека. ВОт это уже интересно!

А Вы полагали, что он материализует их из окружающего пространства smile.gif. 20 байтовый heap это точно профанация идеи, может создаваться ну разве только для нужд библиотечных функций типа time().


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

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

 


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


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