Большой Воронежский Форум
» Программирование>Глючит структура.
-=Женек=- 22:01 21.07.2013
Господа, есть программа для STM32F103 под KEIL, использует USB.
По USB передаются байты, которые заливаются в массив структур.
Код:
 struct tPoint
 {
	unsigned char room;
   unsigned int number;
   unsigned int time;
   char LQI;
   unsigned char passed;
   unsigned char caption[40];
 } POINTS_LIST[];
Вот цикл, в котором происходит чтение из USB и заполнение структуры:
Код:
while(1)
{
if (POINTS_LIST[1].room==111) LED3_ON;else LED3_OFF; // СТРОКА - "МАЯЧОК", пояснение ниже.
						
if ( USB_ReceiveFlg == TRUE) // Если есть данные, то...
		{
		  if (Receive_Buffer[0]==48) // проверка сигнатуры пакета
		   {
		    packet_number=Receive_Buffer[2]; // номер элемента массива, для которого пришли данные
		    POINTS_LIST[packet_number].room=Receive_Buffer[3]; // запись в элемент массива данных
						 
		   UserToPMABufferCopy(Transi_Buffer, ENDP2_TXADDR, nReportCnt); // Подготовка ответа
		   SetEPTxValid(ENDP2); 
		   TimeCount = 0x00;
		   USB_ReceiveFlg=FALSE;
					
		 }	  
		 }
}
Обнаружилось, что элемент №1 массива битый. Поставил строку-"маячок", прицепил на нее светодиод - он моргает, то есть в POINTS_LIST[i] данные сначала записываются, а потом затираются. Грешил на глюки USB, думал, что в один и тот же приемный массив пишутся данные от двух посылок, оказалось что нет - если сразу передавать обратно в компьютер пришедшие данные, то все ОК.
Отладка, расстановка различных флажков показали, что данные портятся позже - ровно через двадцать холостых (если USB_ReceiveFlg=FALSE) циклов while(1) . Хотя я их не трогаю.

Дальнейший метод тыка (убил целый день) показал, что глюк исчезает, если убрать из структуры tPoint все элементы unsigned int. Если есть хотя бы один int - глюк имеет место быть.

В чем тут может быть дело? [Ответ]
Hopkroft 22:57 21.07.2013
Код:
 
if ( USB_ReceiveFlg == TRUE) // Если есть данные, то...
}
Кхм...достаточно просто написать if (USB_ReceiveFlg) ...

Код:
 
 packet_number=Receive_Buffer[2]; // номер элемента массива, для которого пришли данные
Может ли иметь место ситуация когда, вышли за пределы массива?
Если судить по приведённому примеру, то структура не используется. Однако я вижу функции, и не измвестно что они могут вызывать в своём коде.
Код:
UserToPMABufferCopy(Transi_Buffer, ENDP2_TXADDR, nReportCnt); 
SetEPTxValid(ENDP2);
Код:
 Дальнейший метод тыка (убил целый день) показал, что глюк исчезает, если убрать из структуры tPoint все элементы unsigned int. Если есть хотя бы один int - глюк имеет место быть.
Тип изменил, или просто элементы убрал?
Если просто убрал элементы, то соответственно убрал код, который к ним обращается. Может дело в нём? [Ответ]
-=Женек=- 23:04 21.07.2013

Сообщение от :
Может ли иметь место ситуация когда, вышли за пределы массива?

Возможна лишь теоретически. На практике я использую всего 5 элементов, каждый раз результат один.

Сообщение от :
Если судить по приведённому примеру, то структура не используется. Однако я вижу функции, и не измвестно что они могут вызывать в своём коде.

Вот это не понял...

Сообщение от :
Тип изменил, или просто элементы убрал?
Если просто убрал элементы, то соответственно убрал код, который к ним обращается. Может дело в нём?

Как видите из кода, я к переменным типа unsigned int не обращаюсь. ДОстаточно лишь объявить их в структуре, чтобы появился глюк.
ЧТобы он исчез, необязательно убирать переменные, достаточно изменить их тип.

Хм... наверное конфликт и с USB тоже - убрал USB, сделал принудительное заполнение массива по таймеру - все ОК. Как будто бы эта структура и элементы библиотеки USB где-то друг с другом конфликтуют. [Ответ]
Hopkroft 23:48 21.07.2013

Сообщение от -=Женек=-:
Вот это не понял...

Форум заглючил, не успел попровить. Смысл в том, что у меня была мысль что эта структура использовалась в коде, которого нету в примере.

Сообщение от -=Женек=-:
Хм... наверное конфликт и с USB тоже - убрал USB, сделал принудительное заполнение массива по таймеру - все ОК. Как будто бы эта структура и элементы библиотеки USB где-то друг с другом конфликтуют.

Я так понял, это идея, о том что имена пересекаются. Но в данном случае, компилятор бы заругался.

Минуточку, а что за библиотека доступа к USB? [Ответ]
Spectator 23:49 21.07.2013
программа выполняется на ПК?
если да, то надо не раздумывая ставить breakpoint на адресе переменной, которая изменяется, и смотреть что к этому приводит. [Ответ]
-=Женек=- 05:34 22.07.2013
Spectator,
Программа выполняется на контроллере (ядро Cortex M3).

Hopkroft,

Сообщение от :
Я так понял, это идея, о том что имена пересекаются. Но в данном случае, компилятор бы заругался.

Как оказалось, действительно, разные переменные не могут что-то поделить в памяти - добавил еще одну переменную в структуру, так после этого левые данные появились еще в одном массиве, в который я временно вообще ничего не пишу.

Проблема временно решилась после того, как я указал размерность POINTS_LIST явно.

Сообщение от :
Минуточку, а что за библиотека доступа к USB?

Со стороны ПК - JvHIDController из пакета JEDI. В контроллере - USB аппаратный с библиотекой от производителя.

Сообщение от :
то надо не раздумывая ставить breakpoint на адресе переменной

Так я после этого и понял, что что-то не то с дележкой памяти. И убедился, что в самом протоколе обмена ошибок нет, то есть мои кривые руки сами эту структуру не трут.
Вот только как и рыбку съесть (сделать POINTS_LIST безразмерным) и при этом данные не испортить - не знаю. Все-таки программа для микроконтроллера, а его ресурсы более ограничены, нежели ресурсы ПК и на компилятор это накладывает отпечаток. С компилятором C на ПК таких проблем не возникало. [Ответ]
-=Женек=- 05:48 22.07.2013
Хотя... в принципе черт с ней с безразмерностью - при установке 500 элементов программа все еще компилируется, а мне столько не надо. Так что поставлю 50 и успокоюсь. [Ответ]
Hopkroft 08:00 22.07.2013

Сообщение от -=Женек=-:
Хотя... в принципе черт с ней с безразмерностью - при установке 500 элементов программа все еще компилируется, а мне столько не надо. Так что поставлю 50 и успокоюсь.

Блин, я тоже упустил из виду этот момент...нужно срочно в отпуск
Получаем обращение за границы массива.

Код:
 struct tPoint
 {
	unsigned char room;
   unsigned int number;
   unsigned int time;
   char LQI;
   unsigned char passed;
   unsigned char caption[40];
 } POINTS_LIST[];
[Ответ]
Spectator 11:01 22.07.2013
я вообще не очень понимаю как компилятор у тебя это обрабатывает, вставил для эксперимента в C++ Builder

Код:
 struct tPoint
 {
	unsigned char room;
   unsigned int number;
   unsigned int time;
   char LQI;
   unsigned char passed;
   unsigned char caption[40];
 } POINTS_LIST[];
он мне совершенно честно и справедливо сказал что

[C++ Error] UnitLink.cpp(128): E2449 Size of 'POINTS_LIST' is unknown or zero [Ответ]
Hopkroft 11:18 22.07.2013

Сообщение от Spectator:
я вообще не очень понимаю как компилятор у тебя это обрабатывает, вставил для эксперимента в C++ Builder

Там есть такая багафича. В зависимости от настроек компилятора он может такие "форты" выполнять.
Поэтому приходится, ставить вещи по типу EurekaLog, и устанавливать компилятор в "параноидальный режим".

Версия студии какая(неужели 2007)? Хотелось бы эту вещь на заметку взять. [Ответ]
Spectator 11:37 22.07.2013

Сообщение от Hopkroft:
Версия студии какая(неужели 2007)? Хотелось бы эту вещь на заметку взять.

неужели 6
да, 2002 года выпуска.

самая православная на мой взгляд. Codegear'ом я так и не проникся. [Ответ]
Вверх