Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: непонятность с Си
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Метценгерштейн
поднимаю модуль 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, то тоже глючит?
Marto
Оптимизатор?
volatile int RX_dataSize; // ??????
Метценгерштейн
переписываю драйвер полностью этот. Там еще глюков хватает.
Sergey_Aleksandrovi4
Я не знаю, поможет ли это, но ошибку лучше исправить
Код
if ((RX_dataSize = IINCHIP_READ16 (Sn_RX_RSR0(0)))) {

на
Код
if ((RX_dataSize == IINCHIP_READ16 (Sn_RX_RSR0(0)))) {


Вы в условном операторе вместо сравнения == используете присвоение =. Условие всегда (тут я не очень уверен что всегда-всегда) верно. Или это такая задумка?
И что Вы имеете в виду под "программа начинает дурить"? Эти комментарии?
Цитата
// тут он почему-то вваливается в прерывание ??? но массив I_STATUS каждый раз обновлен (приняли данные или отправили их)
AHTOXA
Цитата(Sergey_Aleksandrovi4 @ Oct 8 2013, 23:04) *
Вы в условном операторе вместо сравнения == используете присвоение =. Условие всегда (тут я не очень уверен что всегда-всегда) верно. Или это такая задумка?

Это задумка. Считывается значение RX_dataSize и сразу сравнивается с нулём.
Чтобы было видно, что это задумка, она обрамлена двойными скобками.
RED_BULLok
Цитата(AHTOXA @ Oct 8 2013, 21:30) *
Это задумка. Считывается значение RX_dataSize и сразу сравнивается с нулём.
Чтобы было видно, что это задумка, она обрамлена двойными скобками.


Правильно, код который писался с трудом, должен и пониматься с трудом. Компилятор не ругается разве на такое присваивание ?
mdmitry
Цитата(RED_BULLok @ Oct 10 2013, 13:49) *
Компилятор не ругается разве на такое присваивание ?

Имеет право, при соответствующих настройках предупреждений.
igorle
Компилятор может давать ворнинги в случае, если встретит
Код
if (a = foo())

Поэтому принято такие конструкции обрамлять дополнительными скобками:
Код
if ((a = foo()))

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

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

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.