Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Зависает контроллер при работе с Ethernet
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
ZAA
Проблема в следующем. В основе - FreeRTOS 5.0.2. Контроллер AT91SAM7x256. В программе 2 задачи - Modbus (написана собственноручно), в которой идет опрос датчиков. и UIP (за основу взят стандартный сервер FreeRTOS). Есть флэш-ролик, который запускается из стандартного браузера или Flash-playerа. Ролик по ethernet посылает запросы (аналогичные стандартным фриртосовским - только вместо страниц index.shtml, io.shtml, tcp.shtml и т д - приходит запросы 172.210.10.25/123.txt?0*, 172.210.10.25/123.txt?1*, 172.210.10.25/123.txt?2* и т д, где ?0*, ?1*, ?2*). В ответ (после сравнения полученного s->filename) контроллер посылает строку s->file.data с длиной s->file.len. В стандартном сервере строки s->file.data константы, а в моей программе длина строки каждый раз разная в зависимости от пришедшего запроса. Пытаюсь выделять память для строки pvPortMalloc'ом, а потом удалять указатель, но контроллер после нескольких десятков-сотен запросов зависает.

понимаю. что на первый взгляд сложно определить причину проблемы, но все же жду от вас советов и помощи. Спасибо.
_dem
Удалять указатель - через pvPortFree или delete()/free() ?
aaarrr
Цитата(ZAA @ Nov 13 2008, 07:54) *
Пытаюсь выделять память для строки pvPortMalloc'ом, а потом удалять указатель, но контроллер после нескольких десятков-сотен запросов зависает.

Зависает, или падает в Abort? Во втором случае найти причину будет гораздо проще.
Начните с проверки выделения памяти, проверьте, нет ли утечки.
KonstantinT
Если уходит в аборт , по по lr узнайте из какой точки программы вылетает, по состоянию регистров можно понять (неправильный указатель чаще всего).
ZAA
Цитата(KonstantinT @ Nov 13 2008, 11:32) *
Если уходит в аборт , по по lr узнайте из какой точки программы вылетает, по состоянию регистров можно понять (неправильный указатель чаще всего).

К сожалению работаю без отладчика, поэтому никак не могу посмотреть состояние регистров...
Еще добавлю - подозреваю, что проблема может быть и в этом. У меня осуществляется обмен данными между потоками. Для этого я использую Mutex. Для доступа к общим данным использую следующую структуру:
Например в потоке modbus
if (xSemaphore != NULL)
{
if (xSemaphoreTake(.....) != NULL)
{
buffer1 = vTableSensorConfigure.xSensorConfigureStruct[index1]->Sensor_Value_Float;
buffer2 = vTableSensorConfigure.xSensorConfigureStruct[index1]->Sensor_Error;
xSemaphoreGive(xSemaphore);
}
} //Далее оперирую с локальными переменными buffer1 и buffer2
В потоке uip
if (xSemaphore != NULL)
{
if (xSemaphoreTake(.....) != NULL)
{
var1 = vTableSensorConfigure.xSensorConfigureStruct[index1]->Sensor_Value_Float;
var2 = vTableSensorConfigure.xSensorConfigureStruct[index1]->Sensor_Error;
xSemaphoreGive(xSemaphore);
}
}

Приоритеты и величины стеков у обоих потоков одинаковые...

Цитата(aaarrr @ Nov 13 2008, 10:39) *
Зависает, или падает в Abort? Во втором случае найти причину будет гораздо проще.
Начните с проверки выделения памяти, проверьте, нет ли утечки.

Подскажите плз несведующему, как можно эту самую утечку проверить...или ссылочку на тему в форуме, где есть unsure.gif Спасибо
aaarrr
Цитата(ZAA @ Nov 13 2008, 12:37) *
К сожалению работаю без отладчика, поэтому никак не могу посмотреть состояние регистров...

Для этого не обязательно пользоваться отладчиком. Разместите переходы на asm-обертки на векторах DataAbort и PrefetchAbort, а содержимое регистров выведите через UART, например.

Цитата(ZAA @ Nov 13 2008, 12:37) *
Подскажите плз несведующему, как можно эту самую утечку проверить...или ссылочку на тему в форуме, где есть unsure.gif Спасибо

Просто проверьте, не сползает ли постепенно адрес при вызове malloc.
Dron_Gus
А еще во FreeRTOS'е существует три метода работы с heap'ом. Один из них не подразумевает освобождение памяти.
_dem
При выводе страниц делайте на странице что-то в стиле

void * test = pvPortMalloc(16);
вывод значения (int)test ..
pvPortFree(16);

Если при нескольких обращения этот адрес будет изменяться - где-то утечка.
ZAA
Цитата(_dem @ Nov 13 2008, 14:06) *
Если при нескольких обращения этот адрес будет изменяться - где-то утечка.

Благодарю))) Завтра поэкспериментирую!!
ZAA
Цитата(aaarrr @ Nov 13 2008, 12:52) *
Для этого не обязательно пользоваться отладчиком. Разместите переходы на asm-обертки на векторах DataAbort и PrefetchAbort, а содержимое регистров выведите через UART, например.
Просто проверьте, не сползает ли постепенно адрес при вызове malloc.

У меня к вам вопрос возник другого плана. Может ли такая ситуация складываться (зависание) из-за того, что я не пользуюсь очередями??? Расставив кучу точек в программе, я увидела, что контроллер "умирает" неизменно в одном месте - после вызова функции Poll. В ней программа крутится в цикле, пока не сброшен глобальный флаг (он сбрасывается при истекании таймера на ожидание ответа от опрашиваемого, либо при приеме корректного ответа)
Код
char Poll(void)
{
   //В КАКОЙ_ТО МОМЕНТ ПРОГРАММА ПОПАДАЕТ СЮДА И ЗАВИСАЕТ (не заходя в while)
   while ( MYFLAG !=0 )
   {
      switch (MYF)
      {
    case EV_FRAME_RECEIVED:
    Poll1_status = RECEIVE_FRAME (&aa, &number);
    if (Poll1_status == ERR_OK)
    {
        if (byte_regs_received == 0x04)
        {
             *((char*)(&float_value))  =aa[6];     //собираем float из 4-х char
             *((char*)(&float_value)+1)=aa[5];
             *((char*)(&float_value)+2)=aa[4];
             *((char*)(&float_value)+3)=aa[3];
        }
        else if (byte_regs_received == 0x06)
        {
             for (i = 0; i < byte_regs_received; i++)
             {
             key_mass[i] = aa[i+3];
              }
              int_value1 = (unsigned short)(key_mass[0] << 8 | key_mass[1]);
              int_value2 = (unsigned short)(key_mass[2] << 8 | key_mass[3]);
              int_value3 = (unsigned short)(key_mass[4] << 8 | key_mass[5]);
         }
     }
     MYF=EV_EXECUTE;
    break;
    
            case EV_NO_REPLY:
    Poll1_status = ERR_NO_REPLY;
    MYF=EV_EXECUTE;
     break;
    
             case EV_FRAME_SENT:
     MYF=EV_EXECUTE;
     break;
                     
     case EV_EXECUTE:
    break;
    }
     }
        
     return Poll1_status;
}

Без взаимодействия с uipTask, т е без постоянных опросов с сервера modbus работает нормально. Обязательно ли использовать очереди при работе 2-х задач и прерываний или же можно обойтись другим способом? И еще - attribute ("ISR") служит для обозначения обработчика прерывания, которое возвращается после прерывания именно в ту задачу, в которой оно произошло?? Или я неправильно понимаю???
aaarrr
Цитата(ZAA @ Nov 27 2008, 21:45) *
Обязательно ли использовать очереди при работе 2-х задач и прерываний или же можно обойтись другим способом?

Не обязательно, но все от конкретных задач зависит.

Цитата(ZAA @ Nov 27 2008, 21:45) *
И еще - attribute ("ISR") служит для обозначения обработчика прерывания, которое возвращается после прерывания именно в ту задачу, в которой оно произошло?? Или я неправильно понимаю???

Если прерывание не вызывает переключение контекста и оформлено без portSAVE_CONTEXT/portRESTORE_CONTEXT, то его обработчик должен иметь этот атрибут.

Цитата(ZAA @ Nov 27 2008, 21:45) *
В КАКОЙ_ТО МОМЕНТ ПРОГРАММА ПОПАДАЕТ СЮДА И ЗАВИСАЕТ (не заходя в while)

Так все уже в Ваших руках - неужели не получается найти непосредственную причину зависания?
ZAA
Цитата(aaarrr @ Nov 27 2008, 23:15) *
Так все уже в Ваших руках - неужели не получается найти непосредственную причину зависания?

Я похоже опять возвращаюсь к тому, с чего все начиналось((( Последней точкой где контроллер выводит в DBGU, является запрет прерываний по Tx и разрешение по Rx(c portENTER_Critical и PortEXIT_CRITICAL).
ZAA
Цитата(aaarrr @ Nov 27 2008, 23:15) *
Не обязательно, но все от конкретных задач зависит.
Так все уже в Ваших руках - неужели не получается найти непосредственную причину зависания?

А можно ли объединить 2 задачи в одну - опрос датчиков + вебсервер? чтобы не использовать общие данные и семафоры для доступа к ним...Корректно ли так делать?
И еще вывалился глюк (когда 2 задачи объединили) - спустя небольшое время (после пары десятков-сотен запросов, приходящих на контроллер) контроллер сам сбрасывается (не виснет) и начинает работать заново... Вроде Watchdog с самого начала в LowLewelInit функции отключен 05.gif
И еще, мне не очень понятен смысл vSemaphoreGiveFromISR, которая вызывается в обработчике прерывания по EMAC... unsure.gif
scifi
Я бы всё-таки посоветовал наладить внутрисхемную отладку. Трудно переоценить возможность ставить точки останова и просматривать содержимое переменных.
Пока Вы не сузите круг поиска, маловероятно, что Вам форум поможет. Это всё равно, что пытаться поставить больному диагноз по телефону. Надо точно установить причину проблемы, а через интернет это сложно сделать.
ZAA
Цитата(scifi @ Nov 30 2008, 19:45) *
Я бы всё-таки посоветовал наладить внутрисхемную отладку. Трудно переоценить возможность ставить точки останова и просматривать содержимое переменных.

К сожалению, отладчика нет и не предвидится crying.gif Да и с ассемблером я не очень дружу и времени разбираться с ним тоже нет 05.gif
aaarrr
Цитата(ZAA @ Nov 30 2008, 18:40) *
А можно ли объединить 2 задачи в одну - опрос датчиков + вебсервер? чтобы не использовать общие данные и семафоры для доступа к ним...Корректно ли так делать?

Трудно что-либо ответить, не зная Ваших задач. Но лучше такие "упрощения" не делать, ИМХО.

Цитата(ZAA @ Nov 30 2008, 18:40) *
И еще вывалился глюк (когда 2 задачи объединили) - спустя небольшое время (после пары десятков-сотен запросов, приходящих на контроллер) контроллер сам сбрасывается (не виснет) и начинает работать заново... Вроде Watchdog с самого начала в LowLewelInit функции отключен 05.gif

Посмотрите, хватает ли стеков, нет ли наложения данных на стек и т.п.

Цитата(ZAA @ Nov 30 2008, 18:40) *
И еще, мне не очень понятен смысл vSemaphoreGiveFromISR, которая вызывается в обработчике прерывания по EMAC... unsure.gif

Смысл разбудить основной процесс vuIP_Task и только.

P.S. Внутрисхемная отладка тут ни разу не поможет. Прежде всего нужно разобраться в методах синхронизации задач, работе со стеками и т.д. Без этих знаний пытаться заставить систему работать - шаманство. И тут уже никто помочь не сможет.
zltigo
Цитата(scifi @ Nov 30 2008, 19:45) *
Трудно переоценить возможность ставить точки останова и просматривать содержимое переменных.

Довольно муторное занятие для отладки чего-либо сложнее 2+2= smile.gif тем более, если речь идет обрушении операционки... Банальная консолька для данного случая много эффективнее, тем более, что во FreeRTOS уже заложены некоторые средства для отладки системы.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.