|
Почему под отладчиком работает а без него не хочет? |
|
|
|
Dec 31 2007, 13:52
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Всех с наступающим Новым Годом! Проблема такова: С ARM работаю недавно. Имеется код, который нормально работал с AVR и платформенно не зависим. Перенес сей код на ARM - все, затык. Кoд такой: Код В хедере:
#define MAKEUINT16(byte_h, byte_l) ((UINT16)(((UINT16)byte_h << 8)|(UINT16)byte_l)) #define HIBYTE(word) ((UCHAR)((UINT16)word >> 8)) #define LOBYTE(word) ((UCHAR)((UINT16)word & 0xff))
#define MAKEUINT32(word_h, word_l) ((UINT32)(((UINT32)word_h << 16)|(UINT32)word_l)) #define HIWORD(longv) ((UINT16)((UINT32)longv >> 16)) #define LOWORD(longv) ((UINT16)((UINT32)longv & 0xffff))
#define SWAP16(n16) (MAKEUINT16(LOBYTE(n16), HIBYTE(n16))) #define SWAP32(n32) (MAKEUINT32(SWAP16(LOWORD(n32)), SWAP16(HIWORD(n32)))) в модуле: Код ... if(hTCP->flags & TCP_FLAG_ACK) { /* Jup, use it as our seq */ socket->send_unacked = SWAP32(hTCP->ackno); socket->hTCP.flags = TCP_FLAG_RESET; socket->receive_next = SWAP32(hTCP->seqno); } else { socket->send_unacked = 0; socket->hTCP.flags = TCP_FLAG_RESET | TCP_FLAG_ACK; socket->receive_next = SWAP32(hTCP->seqno) + 1; } Если ставлю точку останова на строку с SWAP32 и потом, при попадании программы в эту точку, стартую программу - все нормально, код выполняется. Если точку останова не ставлю - программа виснет:-( Если строки с SWAP32 удаляю - программа работает нормально... Переменные send_unacked и receive_next 32-битные. IAR C/C++ Compiler for ARM 4.42A Evaluation (4.42.1.201) Помогите разобраться, в чем прикол...
--------------------
|
|
|
|
|
Jan 1 2008, 13:53
|

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

|
1. При всем обилии матрешек, лишних масок и преобразований типов завешивать и не работать там нечему, особенно, если все параметры макросов в скобочки заключить (а делать это всегда обязательно!!!): Код #define MAKEUINT16( byte_h, byte_l ) ( ( (UINT16)(byte_h) << 8) | (byte_l) ) #define HIBYTE(word) ( (UCHAR)((word) >> 8) ) #define LOBYTE(word) ( (UCHAR)(word) ) #define MAKEUINT32( word_h, word_l ) ( ( (UINT32)(word_h) << 16) | (word_l) ) #define HIWORD(longv) ( (UINT16)((longv) >> 16) ) #define LOWORD(longv) ( (UINT16)(longv) ) Ищите ошибку в другом месте. 2. Функции выполняющие вышеописанное "правильно" называются htonl() / ntohl() Network-TO-Host-Long / Host-TO-Network-Long сответственно и встречаются в большинстве библиотек. 3. Для ARM достаточно приличный код получается: Код #define ntohl(x) htonl(x) #pragma inline=forced __arm ulong htonl( ulong n ); __arm ulong htonl( ulong n ) { ulong tmp;
tmp = n ^ ( (n << 16) | (n >> 16) ); tmp &= ~0x00FF0000; n = ( n << 24 )|( n >> 8 ); n ^= ( tmp >> 8 );
return( n ); }
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 1 2008, 16:57
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(zltigo @ Jan 1 2008, 20:53)  3. Для ARM достаточно приличный код получается: Код #define ntohl(x) htonl(x) #pragma inline=forced __arm ulong htonl( ulong n ); __arm ulong htonl( ulong n ) { ulong tmp;
tmp = n ^ ( (n << 16) | (n >> 16) ); tmp &= ~0x00FF0000; n = ( n << 24 )|( n >> 8 ); n ^= ( tmp >> 8 );
return( n ); } Если смотреть с точки зрения меньших затрат на понятие кода  проще вот так Код UINT32 swap32(UINT32 n32) { UINT8 *dest = (UINT8 *)&n32; UINT8 src[sizeof(UINT32)/sizeof(UINT8)]; src[0] = dest[3]; src[1] = dest[2]; src[2] = dest[1]; src[3] = dest[0];
return (*(UINT32 *)&src); } ...но подставив ЭТО вместо SWAP32 имею ту же проблему.... в Ассемблерном виде выгдядит вот так: Код \ In segment CODE, align 4, keep-with-next 18 UINT32 swap32(UINT32 n32) 19 { \ swap32: \ 00000000 01B4 PUSH {R0} \ 00000002 81B0 SUB SP,SP,#+4 20 UINT8 *dest = (UINT8 *)&n32; \ 00000004 01A8 ADD R0,SP,#+4 \ 00000006 0100 MOVS R1,R0 21 UINT8 src[sizeof(UINT32)/sizeof(UINT8)]; 22 23 src[0] = dest[3]; \ 00000008 6846 MOV R0,SP \ 0000000A CA78 LDRB R2,[R1, #+3] \ 0000000C 0270 STRB R2,[R0, #+0] 24 src[1] = dest[2]; \ 0000000E 6846 MOV R0,SP \ 00000010 8A78 LDRB R2,[R1, #+2] \ 00000012 4270 STRB R2,[R0, #+1] 25 src[2] = dest[1]; \ 00000014 6846 MOV R0,SP \ 00000016 4A78 LDRB R2,[R1, #+1] \ 00000018 8270 STRB R2,[R0, #+2] 26 src[3] = dest[0]; \ 0000001A 6846 MOV R0,SP \ 0000001C 0A78 LDRB R2,[R1, #+0] \ 0000001E C270 STRB R2,[R0, #+3] 27 28 return (*(UINT32 *)&src); \ 00000020 6846 MOV R0,SP \ 00000022 0068 LDR R0,[R0, #+0] \ 00000024 02B0 ADD SP,SP,#+8 \ 00000026 7047 BX LR ;; return Забыл добавить  Код пишется под ucOS-II. Самое интересное, что остальные задачи не зависают, только TCPIP, имеющая вышеприведенный код Цитата(zltigo @ Jan 1 2008, 20:53)  2. Функции выполняющие вышеописанное "правильно" называются htonl() / ntohl() Network-TO-Host-Long / Host-TO-Network-Long сответственно и встречаются в большинстве библиотек. А что, мои функции выполняют ЭТО не правильно???
--------------------
|
|
|
|
|
Jan 1 2008, 17:18
|

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

|
Цитата(prottoss @ Jan 1 2008, 18:57)  Если смотреть с точки зрения меньших затрат на понятие кода  проще вот так Взгяд неверный  Для открытия чакр, рекомендую сравнить результат "понятного кода" с "кодом дающим приличный результат" Код 462 cmd->cmdcode = htonl( cmd->cmdcode ); \ 0000006C 000094E5 LDR R0,[R4, #+0]
\ 00000070 601820E0 EOR R1,R0,R0, ROR #+16 \ 00000074 FF18C1E3 BIC R1,R1,#0xFF0000 \ 00000078 2114A0E1 LSR R1,R1,#+8 \ 0000007C 600421E0 EOR R0,R1,R0, ROR #+8
\ 00000080 000084E5 STR R0,[R4, #+0] Цитата А что, мои функции выполняют ЭТО не правильно??? Читайте внимательно первый пункт - я не утверждал, что они в даном контексте работают неправильно - а утверждал прямо противоположное. Читаем: Цитата При всем обилии матрешек, лишних масок и преобразований типов завешивать и не работать там нечему.... Ищите ошибку в другом месте. Но название они имеют неправильное, при этом само слово было употреблено в кавычках. В чем я не прав? При всем при этом Ваши макросы сломаются вдребезги при вызове типа: c = HIWORD( a & b ); Это к "вопросу о скобочках". Ну и тем более странно на фоне отсутствия жизненно необходимого смотрятся многочисленые излишества ввиде явных преобразований типов и масок.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 1 2008, 18:06
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(zltigo @ Jan 2 2008, 00:18)  ОК, оставив вопрос о птичках, вопрашаю Вас, пАчему под JTAG SAM-ICE и на AVR ВСЕ ЭТО работает, а без JTAG SAM-ICE + на ARM не хочет????????????????????????????????? Кстати о птичках - при переносе кода были другие , о котрых я умолчал... Хотя беспокоится надо было уже там... В том же проекте для AVR, пристуствует структура, Вам, думаю, понятная Код /* IP datagram header fields */ typedef struct __IP_Header { UINT8 vihl; /* Version & Header Length field */ UINT8 tos; /* Type Of Service */ UINT16 tlen; /* Total Length */ UINT16 id; /* IP Identification number */ UINT16 frags; /* Flags & Fragment offsett */ UINT8 ttl; /* Time to live */ UINT8 protocol; /* Protocol over IP */ UINT16 checksum; /* Header Checksum */ UINT32 src_ip; /* Source IP address */ UINT32 dest_ip; /* Destination IP address */ } IP_Header_t; Так ВОТ, пока я не переделал поля UINT32 src_ip и UINT32 dest_ip в UINT8 src_ip[4] и UINT8 dest_ip[4] програ в ARM не читайло:-) их правильно, то бишь дело не в коде, компилеру скармиливаемом, думаю я.... Как ВЫ думаете??? НУ:-) естественно, переделал процедуры, работающие с данными полями Еще добавлю Код /******************************************************************************* File: stdafx.h Creted by PROTTOSS Mail to [email="PROTTOSS@mail.ru"]PROTTOSS@mail.ru[/email]
Std def's
26.09.2005 *******************************************************************************/
#ifndef STDAFX_H #define STDAFX_H
/******************************************************************************* *******************************************************************************/
/******************************************************************************* Types def's *******************************************************************************/
/* byte */ #define CHAR char #define SCHAR signed char #define UCHAR unsigned char
#define INT8 CHAR #define UINT8 UCHAR #define SINT8 SCHAR #define MAXUINT8 ((UINT8)(-1))
/* word */ #define INT16 short #define SINT16 signed short #define UINT16 unsigned short #define MAXUINT16 ((UINT16)(-1))
/* double word */ #define INT32 long #define SINT32 signed long #define UINT32 unsigned long #define MAXUINT32 ((UINT32)(-1))
/* quad word */ #define INT64 long long #define SINT64 signed long long #define UINT64 unsigned long long
#define BOOL UCHAR
#ifndef FALSE #define FALSE 0 #endif /* #ifndef FALSE */
#ifndef TRUE #define TRUE 1 #endif /* #ifndef TRUE */
/* function pointers */ typedef void (*FNCT_VOID)(void); typedef void (*FNCT_PTR )(void *);
/* utils */ #define MAKEUINT16(byte_h, byte_l) ((UINT16)(((UINT16)byte_h << 8)|(UINT16)byte_l)) #define HIBYTE(word) ((UCHAR)((UINT16)word >> 8)) #define LOBYTE(word) ((UCHAR)((UINT16)word & 0xff))
#define MAKEUINT32(word_h, word_l) ((UINT32)(((UINT32)word_h << 16)|(UINT32)word_l)) #define HIWORD(longv) ((UINT16)((UINT32)longv >> 16)) #define LOWORD(longv) ((UINT16)((UINT32)longv & 0xffff))
#define SWAP16(n16) ((UINT16)(MAKEUINT16(LOBYTE(n16), HIBYTE(n16)))) #define SWAP32(n32) ((UINT32)(MAKEUINT32(SWAP16(LOWORD(n32)), SWAP16(HIWORD(n32)))))
UINT16 swap16(UINT16 n16); UINT32 swap32(UINT32 n32);
/* NULL define */ #ifndef NULL #define NULL 0 #endif
/******************************************************************************* *******************************************************************************/ #endif//STDAFX_H
--------------------
|
|
|
|
|
Jan 1 2008, 18:25
|

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

|
Цитата(prottoss @ Jan 1 2008, 20:06)  ... вопрашаю Вас, пАчему под JTAG SAM-ICE и на AVR ВСЕ ЭТО работает, а без JTAG SAM-ICE + на ARM не хочет????????????????????????????????? ... Так ВОТ, пока я не переделал поля UINT32 src_ip и UINT32 dest_ip в UINT8 src_ip[4] и UINT8 dest_ip[4] програ в ARM не читайло:-) их правильно, то бишь дело не в коде, компилеру скармиливаемом, думаю я.... ПАтАмучтА ошибки есть. Я, например, могу только догадыватся, что написано выше Вами, вроде на русском языке. Так и компилятору зачастую очень трудно понимать написанное на "вроде на C"  . Постарайтесь более ясно мысли выражать. При портировании с 8bit, есть две проблемы явные - пренебрежение паковкой структур (90% Ваш случай) и честные 32bit, но big/littleendian. И одна неявная - изобилие где непопадя (неестественных для большинства 32bit платформ) восьмибитовых переменных, вместо естественных int. P.S. По поводу прилагаемого *.h файла - кроме пренебрежения скобками, налицо пренебрежение #typedef - тоже может сыграть "веселые" шутки в определенных обстоятельствах. Ну NULL, в "C", а не "C++" правильный другой - как-никак указатель.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 1 2008, 18:59
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(zltigo @ Jan 2 2008, 01:25)  При портировании с 8bit, есть две проблемы явные - пренебрежение паковкой структур (99% Ваш случай) Поясните пожалуйста И интересно, при чем здесь отладчик  Цитата(zltigo @ Jan 2 2008, 01:25)  P.S. По поводу прилагаемого *.h файла - кроме пренебрежения скобками, налицо пренебрежение #typedef - тоже может сыграть "веселые" шутки в определенных обстоятельствах. Ну NULL, в "C", а не "C++" правильный другой - как никак указатель. Пробовал вместо #define в определении типов ставит typedef - код ни на байт не изменился... 2 zltigoПосле вот такого объявления Код
/* TCP header */ #pragma pack(1) typedef struct __TCP_Header { UINT16 src_port; /* Source port */ UINT16 dest_port; /* Destination port */ UINT32 seqno; /* Sequence number */ UINT32 ackno; /* Acknowledgement number */ UINT8 hlen; /* Header length an 32 bits oktets */ UINT8 flags; /* Flags */ UINT16 window; /* Size of window */ UINT16 checksum; /* TCP packet checksum */ UINT16 urgent; /* Urgent pointer */
} TCP_Header_t; Все заработало... Появилось сообщение компилятора: Цитата Warning[Pa039]: use of address of unaligned structure member ...tcp.c 1311
--------------------
|
|
|
|
|
Jan 1 2008, 19:22
|

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

|
Цитата(prottoss @ Jan 1 2008, 20:59)  И интересно, при чем здесь отладчик  Нет желания разбираться, тем более, что я как-то уже давно без него обхожусь.... Цитата Пробовал вместо #define в определении типов ставит typedef - код ни на байт не изменился... Не изменился, но мог. Далеко уже первый раз http://electronix.ru/forum/index.php?showt...5962&st=50:Цитата не вижу принципиальной разницы между: typedef unsigned char uint8; и #define uint8 unsigned char
Насколько я мог заметить Вам вообще многое, что без разницы [AD], но это не есть объективная реальность. #define и typedef по разному обрабатываются - один препроцессором, а второй компилятором. Компилятор (или дополнительные утилиты типа lint) могут дополнительно заниматься котролем типов, а препроцессор - нет. Кроме того попробуйте ответить на вопрос есть-ли разница между, например, типами переменных bt и bd:
str_t at, bt; str_d ad, bd;
если:
typedef char *str_t; // Правильный подход к делу #define str_d char * // Дурной стиль без всякой на то надобности да и еще с побочными эффектами
Даже, если Вы "не увидите принципиальной разницы", то смею Вас заверить, что разница есть и фатальная. Никогда не делайте чего-либо через заднепроходное отверстие, если есть прямые пути. А все результат и потенциальные разговоры о глюках компиляторы гарантированны Цитата После вот такого объявления /* TCP header */ #pragma pack(1) .... Все заработало... Что и предполагалось. Цитата Появилось сообщение компилятора: Это IAR-овскя фишка - кричать, на элемент пакованой структуры, даже если он при паковке выровнен оказался. Не лечится. Придется задавить прагмой.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 1 2008, 19:58
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(zltigo @ Jan 2 2008, 02:22)  Насколько я мог заметить Вам вообще многое, что без разницы [AD], но это не есть объективная реальность. надеюсь - ЭТО не мне:-) Цитата(zltigo @ Jan 2 2008, 02:22)  #define str_d char * // Дурной стиль без всякой на то надобности да и еще с побочными эффектами А кто сказал, что указатели будем через #define делать??? Цитата(zltigo @ Jan 2 2008, 02:22)  Что и предполагалось. С меня пиво...при встрече...или чегойто там еще
--------------------
|
|
|
|
|
Jan 1 2008, 20:21
|

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

|
Цитата(prottoss @ Jan 1 2008, 21:58)  надеюсь - ЭТО не мне:-) Нет - там спецально кроме цитаты еще и ссылка дана. Цитата А кто сказал, что указатели будем через #define делать??? А не в этом дело - НИКАКИЕ типы не надо никогда через #define извращаться, поскольку #typedef есть для этих целей, а "глюк" c указателем не единственная причина - в цитате еще помянуты. P.S. И про скобки и NULL не забудьте
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 2 2008, 12:05
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(zltigo @ Jan 1 2008, 21:22)  Это IAR-овскя фишка - кричать, на элемент пакованой структуры, даже если он при паковке выровнен оказался. Не лечится. Придется задавить прагмой. Не уверен что член, на который идет ругань, на самом деле выровнен. Давить предупреждение - последнее дело, тем более что тут оно справедливо. Поскольку IAR не имеет расширения в виде указателей на упакованные данные, надо переделывать исходник - либо передавать значение, либо завести новый тип - упакованная структура из одного члена нужного размера и передавать указатель на нее. По основному вопросу - что значит "программа виснет? У вас стоят ловушки на DataAbort? Не в DataAbort ли сваливается ядро? Andy Mozzhevilov писал тут на форуме, что отладчик ИАРа в пошаговом режиме на LPC выполняет чтение невыровненных данных, в то время как ядро LPC "на всем скаку" при таком чтении игнорирует младшие биты адреса. А ядро SAM7, насколько помню, вообще сваливается в DataAbort.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 2 2008, 12:54
|

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

|
Цитата(Сергей Борщ @ Jan 2 2008, 14:05)  Не уверен что член, на который идет ругань, на самом деле выровнен. Может и подправили в свежайшем, но по крайней мере раньше IAR, к сожелению, тупо включал предупрежение и для выровненых членов пакованных структур. Обсуждалось на форуме неоднократно, как и пути обхода. Цитата .. тем более что тут оно справедливо. Где "тут" надо смотреть конкретно, но для "конкретно" вообще нет информации. Но у меня в исходниках, например в протоколе LAPD, несколько таких мест с подавленными warnig есть  .
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 2 2008, 13:49
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(zltigo @ Jan 2 2008, 14:54)  Может и подправили в свежайшем, но по крайней мере раньше IAR, к сожелению, тупо включал предупрежение и для выровненых членов пакованных структур. Обсуждалось на форуме неоднократно, как и пути обхода. Не хочу затевать спор. Я себе ситуацию представляю так: в выровненных структурах каждый член выровнен априори. Для невыровненных же, судить о выровненности конкретного члена можно лишь на этапе линковки, а иногда и на этапе исполнения. Да, программист может заранее знать о выровненности конкретного члена (и только в этом случае можно давить предупреждение на конкретном участке кода), но компилятору такой анализ не под силу. Возможно именно поэтому предупреждение выдается всегда.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0
|
|
|