Перейти к содержанию
    

непонятность с Си

поднимаю модуль W5100, столкнулся с такой проблемой-

код

if ((RX_dataSize = IINCHIP_READ16 (Sn_RX_RSR0(0)))) {          
            recv (0, recv_IP, RX_dataSize);
            
              for (uint8_t i =8; i < RX_dataSize; i ++) {
              putchar (recv_IP [i]); 
              }
              putString ("   \r\n");
            }

            sendto(0, recv_IP, RX_dataSize, WIZ_DESTIP, 3000);

работает. Но стоит в нижнем вызове RX_dataSize заменить на любое число, например, 19, как оно и есть, программа начинает дурить ???

 

вот sendto

uint16 sendto(
    SOCKET s,         /**< socket index */
    const uint8 * buf,     /**< a pointer to the data */
    uint16 len,         /**< the data size to send */
    uint8 * addr,         /**< the peer's Destination IP address */
    uint16 port        /**< the peer's destination port number */
    )
{
    uint16 ret=0;
    
    putHEX (len);
    putString ("   len\r\n");

   if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
   else ret = len;

    if
        (
             ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
             ((port == 0x00)) ||(ret == 0)
        ) 
    {
       /* +2008.01 [bj] : added return value */
       ret = 0;
    }
    else
    {         
        IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
        IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
        IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
        IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
        IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
        IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));

          // copy data
          send_data_processing(s, (uint8 *)buf, ret);

        IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);  // тут он почему-то вваливается в прерывание ??? но массив I_STATUS каждый раз обновлен (приняли данные или отправили их)

        /* +20071122[chungs]:wait to process the command... */
                
        while( IINCHIP_READ(Sn_CR(s)) ) 
        ;                   
                
//#ifdef __DEF_IINCHIP_INT__
//       while ( (getISR(s) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )                  // делает тоже, что и нижняя ф-я
//       
//#else
       while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )  // Это работает, если из прерывания слать. Получили-отослали сразу в одном прерывании.                                                                                
//#endif                                                                        // т.к. в прерывании я после отправки данных не отправляю статус в массив I_STATUS, а делаю это только после прочтения. 
        {
//#ifdef __DEF_IINCHIP_INT__
//          if (getISR(s) & Sn_IR_TIMEOUT)
//#else
          if (IINCHIP_READ(Sn_IR(s)) & Sn_IR_TIMEOUT)
//#endif
            {

/* +2008.01 [bj]: clear interrupt */
//#ifdef __DEF_IINCHIP_INT__
//             putISR(s, getISR(s) & ~(Sn_IR_SEND_OK | Sn_IR_TIMEOUT));  /* clear SEND_OK & TIMEOUT */
//#else
             IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */
//#endif
            return 0;
            }
        }

/* +2008.01 bj */    
#ifdef __DEF_IINCHIP_INT__
         putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
#else
       IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
#endif

    }
    return ret;
}

 

вот еще

void send_data_processing(SOCKET s, uint8 *data, uint16 len)
{
    uint16 ptr;
    // ptr = IINCHIP_READ(Sn_TX_WR0(s));
    // ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_TX_WR0(s) + 1);
        ptr = IINCHIP_READ16 (Sn_TX_WR0(s));
        
    write_data(s, data, (uint8 *)(ptr), len);
    ptr += len;
    IINCHIP_WRITE(Sn_TX_WR0(s),(uint8)((ptr & 0xff00) >> 8));
    IINCHIP_WRITE((Sn_TX_WR0(s) + 1),(uint8)(ptr & 0x00ff));
}

а почему себя так ведет? Почему если RX_dataSize прсивоить значение, вписать RX_dataSize, то тоже глючит?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

переписываю драйвер полностью этот. Там еще глюков хватает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я не знаю, поможет ли это, но ошибку лучше исправить

if ((RX_dataSize = IINCHIP_READ16 (Sn_RX_RSR0(0)))) {

на

if ((RX_dataSize == IINCHIP_READ16 (Sn_RX_RSR0(0)))) {

 

Вы в условном операторе вместо сравнения == используете присвоение =. Условие всегда (тут я не очень уверен что всегда-всегда) верно. Или это такая задумка?

И что Вы имеете в виду под "программа начинает дурить"? Эти комментарии?

// тут он почему-то вваливается в прерывание ??? но массив I_STATUS каждый раз обновлен (приняли данные или отправили их)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы в условном операторе вместо сравнения == используете присвоение =. Условие всегда (тут я не очень уверен что всегда-всегда) верно. Или это такая задумка?

Это задумка. Считывается значение RX_dataSize и сразу сравнивается с нулём.

Чтобы было видно, что это задумка, она обрамлена двойными скобками.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это задумка. Считывается значение RX_dataSize и сразу сравнивается с нулём.

Чтобы было видно, что это задумка, она обрамлена двойными скобками.

 

Правильно, код который писался с трудом, должен и пониматься с трудом. Компилятор не ругается разве на такое присваивание ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Компилятор не ругается разве на такое присваивание ?

Имеет право, при соответствующих настройках предупреждений.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Компилятор может давать ворнинги в случае, если встретит

if (a = foo())

Поэтому принято такие конструкции обрамлять дополнительными скобками:

if ((a = foo()))

Таким образом компилятору и тому, кто будет читать код говорят, что это не опечатка, а так задумано.

 

Это нормальная практика. Я сейчас забежал греп на Кернел Линукс 2.6 - насчитал таких случаев 6932. Программистам следует этот прием если не использовать (некоторым религия не позволяет писать красивый код), то как минимум знать.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...