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

 
 
 
Reply to this topicStart new topic
> непонятность с Си, под АВР
Метценгерштейн
сообщение Sep 14 2013, 06:48
Сообщение #1


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

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



поднимаю модуль 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, то тоже глючит?
Go to the top of the page
 
+Quote Post
Marto
сообщение Sep 14 2013, 17:44
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 103
Регистрация: 17-05-09
Из: Ижевск
Пользователь №: 49 190



Оптимизатор?
volatile int RX_dataSize; // ??????


--------------------
Шизоидный холерик
Go to the top of the page
 
+Quote Post
Метценгерштейн
сообщение Sep 15 2013, 12:50
Сообщение #3


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

Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079



переписываю драйвер полностью этот. Там еще глюков хватает.
Go to the top of the page
 
+Quote Post
Sergey_Aleksandr...
сообщение Oct 8 2013, 17:04
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 168
Регистрация: 8-10-08
Из: РФ Смоленск
Пользователь №: 40 764



Я не знаю, поможет ли это, но ошибку лучше исправить
Код
if ((RX_dataSize = IINCHIP_READ16 (Sn_RX_RSR0(0)))) {

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


Вы в условном операторе вместо сравнения == используете присвоение =. Условие всегда (тут я не очень уверен что всегда-всегда) верно. Или это такая задумка?
И что Вы имеете в виду под "программа начинает дурить"? Эти комментарии?
Цитата
// тут он почему-то вваливается в прерывание ??? но массив I_STATUS каждый раз обновлен (приняли данные или отправили их)
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 8 2013, 18:30
Сообщение #5


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



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

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


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
RED_BULLok
сообщение Oct 10 2013, 09:49
Сообщение #6


Участник
*

Группа: Свой
Сообщений: 58
Регистрация: 27-03-08
Из: Беларусь, Минск
Пользователь №: 36 275



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


Правильно, код который писался с трудом, должен и пониматься с трудом. Компилятор не ругается разве на такое присваивание ?
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Oct 10 2013, 12:42
Сообщение #7


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



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

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


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
igorle
сообщение Oct 10 2013, 13:00
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753



Компилятор может давать ворнинги в случае, если встретит
Код
if (a = foo())

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

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

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

Go to the top of the page
 
+Quote Post

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

 


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


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