Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема при копировании 2-х массивов [GCC-AVR, C++]
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
kurtis
Здравствуйте!

Столкнулся с проблемой которая завела меня в тупик, не могу понять в каком месте ошибся.
Суть проблемы в том что контроллер иногда работает совершенно непредсказуемым образом - случайным образом нажимаются кнопки, причем кнопки нажимаются программно, т.к. клавиатура физически отключена. За нажатия кнопок отвечает массив в ОЗУ с именем key_data. Начал разбираться и методом исключений пришел к выводу что проблема в этой функции
Код
140 void Work_drv()
141 {
142     //void *memcpy(void *dest, const void *src, size_t n);
143
144     uint8_t index;
145
146     for (index=0; index < 15; index++) {netForDpu.cond1[index] = netOutCond[0].devs_net_stat[index];}
147     for (index=0; index < 15; index++) {netForDpu.cond2[index] = netOutCond[1].devs_net_stat[index];}
148     for (index=0; index < 15; index++) {netForDpu.cond3[index] = netOutCond[2].devs_net_stat[index];}
149     for (index=0; index < 15; index++) {netForDpu.cond4[index] = netOutCond[3].devs_net_stat[index];}
150     for (index=0; index < 15; index++) {netForDpu.cond5[index] = netOutCond[4].devs_net_stat[index];}
151
152     //memcpy(netForDpu.cond1, netOutCond[0].devs_net_stat, 15);
153     //memcpy(netForDpu.cond2, netOutCond[1].devs_net_stat, 15);
154     //memcpy(netForDpu.cond3, netOutCond[2].devs_net_stat, 15);
155     //memcpy(netForDpu.cond4, netOutCond[3].devs_net_stat, 15);
156     //memcpy(netForDpu.cond5, netOutCond[4].devs_net_stat, 15);
157
158 }
Изначально были функции memcpy(), но потом для понятности переписал через цикл.

Вот как массивы лежат в ОЗУ:
Код
619 008007b2 0000002f B lcd_data
620 008007e1 00000005 B key_data
621 008007e6 00000008 B netFromDpu
622 008007ee 00000069 B netForDpu
623 00800857 00000078 B netOutCond
624 008008cf 0000002a B netInCond
625 008008f9 00000020 B LCD_str
626 00800919 00000001 B tech_fl

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

http://dl.dropbox.com/u/2632562/file.txt - вот дизассемблированный код функции.

Версия avr-gcc 4.3.3, с поддержкой С++.

Спасибо за помощь!
demiurg_spb
Цитата(kurtis @ Apr 30 2010, 14:21) *
Изначально были функции memcpy(), но потом для понятности переписал через цикл...
...
Обычно, когда я выходил за пределы массива...
Ржу - не могу!:) Жванецкий отдыхает!

Из конкретных предположений:
А кнопки-то ведь действительно могут нажиматься самостоятельно и с клавиатурой и без оной, если вход сканирования кнопок висит не притянутым в воздухе.
kurtis
Цитата
если вход сканирования кнопок висит не притянутым в воздухе.

Состояния нажатых кнопок получаются от удаленного устройства по сети.

Возможно я не совсем правильно выразился. Если удалить вызов этой функции из программы, то спонтанного нажатия кнопок не происходит.
Палыч
Цитата(kurtis @ Apr 30 2010, 14:21) *
Начал разбираться и методом исключений пришел к выводу что проблема в этой функции
Может, все-таки, проблема не в этой функции, а в том, что стек "наезжает" на netOutCond и портит его?
kurtis
Цитата
Может, все-таки, проблема не в этой функции, а в том, что стек "наезжает" на netOutCond и портит его?

Не думаю. Если бы наезжал стек, то он бы еще много чего портил. Да и ОЗУ заполнено процентов на 70, так что теоретически, запас еще есть.

Если заменить условие, в 150й строке, с 15 на 13, то такой проблемы не возникает.
Код
148     for (index=0; index < 15; index++) {netForDpu.cond3[index] = netOutCond[2].devs_net_stat[index];}
149     for (index=0; index < 15; index++) {netForDpu.cond4[index] = netOutCond[3].devs_net_stat[index];}
150     for (index=0; index < 15; index++) {netForDpu.cond5[index] = netOutCond[4].devs_net_stat[index];}
151
152     //memcpy(netForDpu.cond1, netOutCond[0].devs_net_stat, 15);
Палыч
Цитата(kurtis @ Apr 30 2010, 15:59) *
Не думаю. Если бы наезжал стек, то он бы еще много чего портил. Да и ОЗУ заполнено процентов на 70, так что теоретически, запас еще есть.
А, при описании netOutCond и netForDpu с числом элементов в массивах у Вас всё верно?
kurtis
Да.

Это netOutCond:
CODE
typedef struct
{
HEAD_NET_STRUCT head;
uint8_t devs_net_stat[15];
uint8_t status;
uint8_t foo;
}
NET_COND_OUT_STRUCT;

а это netForDpu:
CODE
typedef struct
{
HEAD_NET_STRUCT head;
uint8_t network_state;
uint8_t lamps[10];

uint8_t zasl1[5];
uint8_t zasl2[5];

uint8_t net_state[6];

uint8_t cond1[15];
uint8_t cond2[15];
uint8_t cond3[15];
uint8_t cond4[15];
uint8_t cond5[15];
}
NET_FOR_IO_DPU;
Палыч
Вам лень было привести ещё две строки? Что-то типа
Код
NET_COND_OUT_STRUCT netOutCond[5];
NET_FOR_IO_DPU netForDpu;

Да и HEAD_NET_STRUCT можно было бы привести... Надеюсь, что число элементов netOutCond у Вас указано - пять (как это сделано у меня)?
kurtis
Код
LCD_OUTPUT_STRUCT lcd_data;
LCD_INPUT_STRUCT  key_data;

NET_FROM_IO_DPU netFromDpu;
NET_FOR_IO_DPU netForDpu;

NET_COND_OUT_STRUCT netOutCond[6];
NET_COND_IN_STRUCT netInCond[6];


CODE
typedef struct
{
uint8_t size;
uint8_t adr;
uint8_t cmd;
}
HEAD_NET_STRUCT;

typedef struct
{
HEAD_NET_STRUCT head;
uint8_t out_lcd[44];
}
LCD_OUTPUT_STRUCT;

typedef struct
{
HEAD_NET_STRUCT head;
uint8_t key[2];
}
LCD_INPUT_STRUCT;
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.