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

 
 
> Компилятор ниоса самодурствует?
alexPec
сообщение Dec 21 2012, 11:33
Сообщение #1


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

Группа: Свой
Сообщений: 1 284
Регистрация: 9-04-06
Пользователь №: 15 968



Всем добрый день.

Возникла такая проблема. Прикручиваю готовый стек TCPIP к ниосу. Там есть структура:

Код
typedef struct _ARP_PACKET
{
    WORD        HardwareType;
    WORD        Protocol;
    BYTE        MACAddrLen;
    BYTE        ProtocolLen;
    WORD        Operation;
    MAC_ADDR    SenderMACAddr;
    IP_ADDR     SenderIPAddr;
    MAC_ADDR    TargetMACAddr;
    IP_ADDR     TargetIPAddr;
}  ARP_PACKET;

Здесь MAC_ADDR это:
Код
typedef struct _MAC_ADDR
{
    BYTE v[6];
} MAC_ADDR;

IP_ADDR это DWORD_VAL, а DWORD_VAL это:
Код
typedef union _DWORD_VAL
{
    DWORD Val;
    WORD w[2];
    BYTE v[4];
    struct
    {
        WORD LW;
        WORD HW;
    } word;
    struct
    {
        BYTE LB;
        BYTE HB;
        BYTE UB;
        BYTE MB;
    } byte;
} DWORD_VAL;


В коде подразумевается, что байты каждого поля идут по порядку друг за другом, без промежутков. В реальности выходит, что байты полей до SenderIPAddr располагаются в памяти как надо, по порядку, а вот поле SenderIPAddr располагается в памяти через 2 байта от SenderMACAddr и оказывается выровненным по 32-битной границе. Подозреваю, ниосу удобней стало расположить DWORD выровненным по 32-битной границе, а не разделять DWORD по двум адресам, и он пропустил 2 байта.

Вопрос:
1.Допускается ли такое (по правилам С, в коде из-за этого проблемы)?
2.Лечится ли как-нибудь? (указать бы ему явно, что брать байты надо по порядку, а не выравнивать DWORD по границе 32 бита)
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Serhiy_UA
сообщение Dec 21 2012, 12:25
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 721
Регистрация: 23-10-08
Из: next to Odessa
Пользователь №: 41 112



Писал свой усеченный TCP/IP стек для NiosII, все работало.
Использовал структуры, что в приложении. Для ARP на второй странице структура ETHERARP...
Сравните со своими....
Go to the top of the page
 
+Quote Post
alexPec
сообщение Dec 21 2012, 13:21
Сообщение #3


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

Группа: Свой
Сообщений: 1 284
Регистрация: 9-04-06
Пользователь №: 15 968



Спасибо Serhiy_UA и Артем!

Оба варианта лечат проблему, все работает!
Go to the top of the page
 
+Quote Post
alexPec
сообщение Dec 23 2012, 12:32
Сообщение #4


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

Группа: Свой
Сообщений: 1 284
Регистрация: 9-04-06
Пользователь №: 15 968



Возникла еще такая проблема: есть код вычисления контрольной суммы:
Код
unsigned short checksum(void *b, int len)
{
    unsigned short *buf = b, result;
    unsigned int sum=0;
    for ( sum = 0; len > 1; len -= 2 ) /* Sum all 16b words */
    {
        result=*buf;
        sum += *buf++;
    }
    if ( len == 1 )
    /* If any stray bytes, */
    sum += *(unsigned char*)buf;
    /* add to sum */
    sum = (sum >> 16) + (sum & 0xFFFF);
    /* Add the carry */
    sum += (sum >> 16);
    /* (again) */
    result = ~sum;
    /* Take the one's complement */
    return result;
    /* Return 16b value */
}


Так вот работает он корректно только когда адрес входного буфера четный. В случае нечетного адреса unsigned short выбирается из памяти неправильно, со смещением на 1 назад (в сторону меньшего адреса).
Как такое лечить, наверняка какой-то прагмой?
Или как-то ремапить его (буфер) перед подсчетом?
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 20:16
Рейтинг@Mail.ru


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