Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту

AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR...

 
Опции темы
Непрочитано 19.06.2014, 19:43  
qweentet
Частый гость
 
Регистрация: 17.06.2014
Сообщений: 30
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
qweentet на пути к лучшему
Злость Выяснить причину затирания данных

Что имею:
Структура для реализации динамического массива:
Код:
typedef struct {
    uchar * data;
    unsigned char size;    
} ByteArray;
Периферия для обслуживания:
Код:
void BA_pushback(ByteArray * array,uchar data){
    if(array-›size==0){
        free(array-›data);
        array-›data = calloc(1,sizeof(ByteArray));
    }else{        
        array-›data = realloc(array-›data,(array-›size+1)*sizeof(uchar));
    }
    array-›data[array-›size]=data;
    array-›size++;        
}
void BA_clear(ByteArray * array){
    free(array-›data);
    array-›size=0;
}
И адское место, в котором происходит неясные для меня вещи:
Код:
if(sendID003Cmd(ID003_GET_STATUS,0,answer)){
                        convertAnswerData(ID003_CCNET,answer,data);
//Комманда выше, возвращает правильные данные, она вернула мне индекс переданный устройством, что я проверил способом ниже
                        BA_clear(answer);
                        DDRC=0xFF;
                        PORTC=data-›data[0];
//Теперь погружаемся в процедуру  getCCNetAnswPack                                 
                        if(getCCNetAnswPack(CCNET_POLL, answer, data)){   
                            return 0x1;                                   
                        }
                    }
Вот эта процедура
Код:
bool getCCNetAnswPack(uchar cmd, ByteArray * answPack, ByteArray * answData){
    ushort crc;
// Здесь данные по прежнему целые...
    BA_pushback(answPack,CCNET_PREFIX);  //Префикс пакета
    BA_pushback(answPack,CCNET_BV_ADD);  //Адресс устройства
    BA_pushback(answPack,0x0); //Готовим место для размера пакета
// А уже здесь они поврежденные
    DDRD|=(0xFF‹‹2);
    PORTD=(answData-›data[0]‹‹2);
    switch(cmd){
.....
Где я допустил косяк, в чем моя ошибка?
Реклама:
qweentet вне форума  
Непрочитано 19.06.2014, 21:49  
uk8amk
Вид на жительство
 
Регистрация: 05.07.2006
Адрес: Tashkent
Сообщений: 454
Сказал спасибо: 24
Сказали Спасибо 67 раз(а) в 44 сообщении(ях)
uk8amk на пути к лучшему
По умолчанию Re: Выяснить причину затирания данных

Реализация конечно красивая, но насколько помню в ID003 размер типичного пакета исчисляется длиной в несколько байт и игры с динамическим выделением памяти скорее усложняют задачу. По этой причине может просто выделить буфер фиксированной длины?
uk8amk вне форума  
Непрочитано 19.06.2014, 23:15  
vynt
Почётный гражданин KAZUS.RU
 
Аватар для vynt
 
Регистрация: 02.03.2011
Адрес: Россия, КБР
Сообщений: 629
Сказал спасибо: 108
Сказали Спасибо 596 раз(а) в 334 сообщении(ях)
vynt на пути к лучшему
По умолчанию Re: Выяснить причину затирания данных

Сообщение от qweentet Посмотреть сообщение
Структура для реализации динамического массива:
Код:
typedef struct {
uchar * data;
unsigned char size;
} ByteArray;
лучше так, на мой взгляд
Код:
typedef struct {
 unsigned char size;
 uchar * data;
} ByteArray;
а ещё лучше сделать как написал uk8amk
какой камень? может ОЗУ кончилось...
vynt вне форума  
Непрочитано 20.06.2014, 00:10  
Raptor1
Прописка
 
Регистрация: 18.01.2006
Сообщений: 268
Сказал спасибо: 81
Сказали Спасибо 476 раз(а) в 127 сообщении(ях)
Raptor1 на пути к лучшему
По умолчанию Re: Выяснить причину затирания данных

Сообщение от qweentet Посмотреть сообщение
Что имею:
Структура для реализации динамического массива:
Код:
typedef struct {
    uchar * data;
    unsigned char size;    
} ByteArray;
Периферия для обслуживания:
Код:
void BA_pushback(ByteArray * array,uchar data){
    if(array-›size==0){
        free(array-›data);
        array-›data = calloc(1,sizeof(ByteArray));
    }else{        
        array-›data = realloc(array-›data,(array-›size+1)*sizeof(uchar));
    }
    array-›data[array-›size]=data;
    array-›size++;        
}
void BA_clear(ByteArray * array){
    free(array-›data);
    array-›size=0;
}
И адское место, в котором происходит неясные для меня вещи:
Код:
if(sendID003Cmd(ID003_GET_STATUS,0,answer)){
                        convertAnswerData(ID003_CCNET,answer,data);
//Комманда выше, возвращает правильные данные, она вернула мне индекс переданный устройством, что я проверил способом ниже
                        BA_clear(answer);
                        DDRC=0xFF;
                        PORTC=data-›data[0];
//Теперь погружаемся в процедуру  getCCNetAnswPack                                 
                        if(getCCNetAnswPack(CCNET_POLL, answer, data)){   
                            return 0x1;                                   
                        }
                    }
Вот эта процедура
Код:
bool getCCNetAnswPack(uchar cmd, ByteArray * answPack, ByteArray * answData){
    ushort crc;
// Здесь данные по прежнему целые...
    BA_pushback(answPack,CCNET_PREFIX);  //Префикс пакета
    BA_pushback(answPack,CCNET_BV_ADD);  //Адресс устройства
    BA_pushback(answPack,0x0); //Готовим место для размера пакета
// А уже здесь они поврежденные
    DDRD|=(0xFF‹‹2);
    PORTD=(answData-›data[0]‹‹2);
    switch(cmd){
.....
Где я допустил косяк, в чем моя ошибка?
вот это жесть, давно не видел такого, ну во первых
Код:
void BA_pushback(ByteArray * array,uchar data){
    if(array-›size==0){
        free(array-›data);
...
это что, освобождаем то, чего нет? А вообще, не слишком ли расточительно, при добавлении каждого байта перевыделять память, выделение памяти длительная процедура, и количество ее вызовов желательно минимизировать. В общем ваш динамический массив не годится для практического использования, возможные направления улучшения - выделять память блоками по 64 байта например, или на 25% больше чем уже использовано (как в stl) и хранить размер буфера и количество данных в нем.
Raptor1 вне форума  
Непрочитано 20.06.2014, 02:06  
Yurkin2014
Заблокирован
 
Регистрация: 21.01.2014
Сообщений: 589
Сказал спасибо: 7
Сказали Спасибо 267 раз(а) в 206 сообщении(ях)
Yurkin2014 на пути к лучшему
По умолчанию Re: Выяснить причину затирания данных

Вот у Вас два указателя answer и data. Должно быть ещё также 2 места в памяти зарезервировано за двумя структурами типа ByteArray, и потом начальные адреса этих областей памяти записаны в указатели соответственно. Из приведённых фрагментов программы этого не видно. Можно посмотреть как инициализируются переменные answer и data?

Последний раз редактировалось Yurkin2014; 20.06.2014 в 02:10.
Yurkin2014 вне форума  
Непрочитано 20.06.2014, 09:57  
qweentet
Частый гость
 
Регистрация: 17.06.2014
Сообщений: 30
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
qweentet на пути к лучшему
По умолчанию Re: Выяснить причину затирания данных

Самое первое - камень ATMega8 работает на 8 MHz

Сообщение от Raptor1 Посмотреть сообщение
вот это жесть, давно не видел такого, ну во первых
Код:
void BA_pushback(ByteArray * array,uchar data){
    if(array-›size==0){
        free(array-›data);
...
это что, освобождаем то, чего нет? А вообще, не слишком ли расточительно, при добавлении каждого байта перевыделять память, выделение памяти длительная процедура, и количество ее вызовов желательно минимизировать. В общем ваш динамический массив не годится для практического использования, возможные направления улучшения - выделять память блоками по 64 байта например, или на 25% больше чем уже использовано (как в stl) и хранить размер буфера и количество данных в нем.
Код:
void BA_pushback(ByteArray * array,uchar data){
    if(array-›size==0){
        free(array-›data);
...
Это я вставил тогда, когда уже не знал что делать, и лепил самые не разумные вещи. На счет размерности учту ,спасибо!=)

Цитата:
Реализация конечно красивая, но насколько помню в ID003 размер типичного пакета исчисляется длиной в несколько байт и игры с динамическим выделением памяти скорее усложняют задачу. По этой причине может просто выделить буфер фиксированной длины?
При среднестатистических командах до 14 байт, НО, также присутсвует работа с 256 байтами у ID003 и 64к у CCNet (по документации), Это сделано для передачи пакетов данных (прошивка или статистика) а не команд. Вот я и пытался предусмотреть все нюансы...

Цитата:
Вот у Вас два указателя answer и data. Должно быть ещё также 2 места в памяти зарезервировано за двумя структурами типа ByteArray, и потом начальные адреса этих областей памяти записаны в указатели соответственно. Из приведённых фрагментов программы этого не видно. Можно посмотреть как инициализируются переменные answer и data?
Вот весь процесс:
Код:
void main(void){
    ByteArray tmpPackage,tmpAnswer,tmpData;     
    SUART_Init();   //Инициализация софтового UART
    USART_Init();   //Инициализация физического USART
while(1){
    BA_clear(&tmpPackage);
    BA_clear(&tmpAnswer);
    BA_clear(&tmpData);
     if(collectCCNetPackage(&tmpPackage)){
     if(convertAndSend(CCNET_ID003,&tmpPackage,&tmpData,&tmpAnswer)){
     SUART_Transmit(&tmpAnswer);   
            }   
        }
    }
}
Код:
bool convertAndSend(uchar direct,ByteArray * package,ByteArray * data,ByteArray * answer){
    uchar status=0;
    BA_clear(data);
    BA_clear(answer);
    switch(direct){
        case CCNET_ID003:   //Направление конвертации от CCNet к ID003
            switch(package-›data[3]){
                case CCNET_RESET:  
                    if(sendID003Cmd(ID003_RESET,0,answer)){
                        if(answer-›data[2]==ID003_ACK){
                            BA_clear(answer);
                            if(getCCNetAnswPack(CCNET_ACK, answer, 0))
                                status=1;                               
                        }
                    }
                    break;
                case CCNET_GET_STATUS:  //Получить статус. По версии CCNet в ответе должны прийты таблица номиналов 
                //и уровни безопасности к ним, в ID003 это два запроса
                    if(sendID003Cmd(ID003_GET_BILL_TABLE,0,answer)){
                        BA_pushback(data,0);
                        BA_pushback(data,~(uchar)answer-›data[3]);
                        BA_pushback(data,~(uchar)answer-›data[4]);
                        BA_clear(answer);           
                    }
                    else{
                        break;
                    }
                    if(sendID003Cmd(ID003_GET_SECURITY,0,answer)){
                        BA_pushback(data,0);
                        BA_pushback(data,answer-›data[3]);
                        BA_pushback(data,answer-›data[4]);
                        BA_clear(answer);          
                    }
                    else{
                        break;
                    }
                    if(getCCNetAnswPack(CCNET_GET_STATUS, answer, data)){
                        status=1;                                   
                    }
                    break;
                case CCNET_SET_SECURITY:    //По версии CCNet в ответ приходит ACK
                    // PR - ADD - LNG - CMD - D1 - D2 - D3
                    //  0     1    2     3    4    5    6
                    BA_pushback(data,package-›data[5]); 
                    BA_pushback(data,package-›data[6]);
                    if(sendID003Cmd(ID003_SET_SECURITY,data,answer)){
                        BA_clear(answer);
                        BA_clear(data);
                        if(getCCNetAnswPack(CCNET_ACK, answer, 0))
                            status=1;       
                    }        
                    break;
                case CCNET_POLL:
                    if(sendID003Cmd(ID003_GET_STATUS,0,answer)){
                        convertAnswerData(ID003_CCNET,answer,data);
                        BA_clear(answer);
                        DDRC=0xFF;
                        PORTC=data-›data[0];                                  
                        if(getCCNetAnswPack(CCNET_POLL, answer, data)){   
                            return 0x1;                                   
                        }
                    }   
                    break;
                default:
                    return 0;   
            }             
            break;
        case ID003_CCNET:
        
            break;
        default:
            return 0;
    } 
    BA_clear(data);
    if(!status)
        BA_clear(answer);
    return status;
};
//Вот откуда берутся answer и data
//Раньше data брала свое начало в функции выше, но я подумал, может проблема из-за того, что данные не в той области видимости, и решил вынести наверх - нифига не помогло...
Вот такие вот дела,если проблему не решу, то буду пытатсья со статикой работать, хотя не хотелось бы=(
qweentet вне форума  
Непрочитано 20.06.2014, 10:44  
MaxiMuz79
Гражданин KAZUS.RU
 
Аватар для MaxiMuz79
 
Регистрация: 06.04.2010
Адрес: Санкт-Петербург - Волжский
Сообщений: 529
Сказал спасибо: 74
Сказали Спасибо 56 раз(а) в 45 сообщении(ях)
MaxiMuz79 на пути к лучшему
По умолчанию Re: Выяснить причину затирания данных

ATMega8 - 1kb SRAM , не стал бы я использовать на таком камне команды подобные calloc. Не забывайте что есть еще стек, и неизвестно как его насилует ваша программа.
Код:
void BA_pushback(ByteArray * array,uchar data){
    if(array-›size==0){
        free(array-›data);
        array-›data = calloc(1,sizeof(ByteArray));
    }else{        
        array-›data = realloc(array-›data,(array-›size+1)*sizeof(uchar));
    }
    array-›data[array-›size]=data;
    array-›size++;        
}
+ После распределения памяти рекомендуют делать проверку:
Код:
 if(array-›size==0){
        free(array-›data);
        array-›data = calloc(1,sizeof(ByteArray));
        if (array-›data ==NULL) return 0;
    }
MaxiMuz79 вне форума  
Непрочитано 20.06.2014, 10:58  
Boba_spb
Почётный гражданин KAZUS.RU
 
Регистрация: 08.06.2008
Сообщений: 1,394
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
Boba_spb на пути к лучшему
По умолчанию Re: Выяснить причину затирания данных

Вот как бы во "взрослом " C/C++ память добавляется, но не переписывается. Она ж из кучи берется . Надо ручками переписывать из старого в новое


Prototype
void *calloc(size_t nitems, size_t size);
Description

Allocates main memory.
calloc provides access to the C memory heap. The heap is available for dynamic allocation of variable-sized blocks of memory. Many data structures, such as trees and lists, naturally employ heap memory allocation.

calloc allocates a block of size nitems * size. The block is initialized to 0.

Иль у Вас С/C++ какой иной?
Boba_spb вне форума  
Непрочитано 20.06.2014, 11:17  
Boba_spb
Почётный гражданин KAZUS.RU
 
Регистрация: 08.06.2008
Сообщений: 1,394
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
Boba_spb на пути к лучшему
По умолчанию Re: Выяснить причину затирания данных

Прощу прпощения, погорячился. Все корректно.
Boba_spb вне форума  
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
FAQ (ЧаВО) по PROTEUS для начинающих и не только dosikus Proteus 221 07.03.2024 22:45
Беспроводная передача данных 1кб/с , 3км. Как и чем? Zemlyanov Микроконтроллеры, АЦП, память и т.д 5 29.01.2015 10:02
Поток данных 44Мбит/сек.Нужно снять лог пару секунд. Как? Zemlyanov Микроконтроллеры, АЦП, память и т.д 4 15.11.2010 23:46
Помогите выяснить причину шума Big_Digger Видеотехника 7 26.12.2009 16:13
Упаковка данных (сжатие данных) satnettv Proteus, KiCAD и другие ECAD 4 06.09.2007 20:15


Часовой пояс GMT +4, время: 07:20.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot