Rst7 5 15 июня, 2011 Опубликовано 15 июня, 2011 · Жалоба Очень занятное поведение флага INTSTATUS_bit.RXDONEINT обнаружилось. Разрешено только прерывания RXDONEINT. Там такой код: void Ethernet_IRQHandler(void) { UREG i='0'; do { INTCLEAR=1UL<<3; //RxDoneInt i++; } while(INTSTATUS_bit.RXDONEINT); usart0_txc(i); NVIC_ClrPend(NVIC_ETHR); NVIC_SetPend(NVIC_RIT); //Ñòàðòóåì RIT_IRQHandler } Неспеша кормлю девайсу по одному пакету (дабы быть уверенным, что никакого переполнения не происходит). В результате в консоль сыпется: 122212112121121112122222222112112211212222222121111.... Пуристы для тестов могут заменить usart0_txc на ногодрыг и наблюдать осциллографом тот же результат - импульсов то 1, то 2. Если бы просто сделать void Ethernet_IRQHandler(void) { INTCLEAR=1UL<<3; //RxDoneInt NVIC_ClrPend(NVIC_ETHR); NVIC_SetPend(NVIC_RIT); //Ñòàðòóåì RIT_IRQHandler } то этот код часто (а то и вообще всегда) вызывается 2 раза - не сбрасывается флаг RxDoneInt, соответственно, сброс соответствующего бита в NVIC не помогает - не снят изначальный флаг, т.е. происходит опять поднятие флага в NVIC и последующее прерывание. Правда, на второй заход сброс таки происходит. Вот такой код вроде (ну ибо на обозримом отрезке времени мне не удалось наблюдать двойной вызов) всегда вызывается один раз: void Ethernet_IRQHandler(void) { INTSTATUS; __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); INTCLEAR=1UL<<3;//RxDoneInt NVIC_ClrPend(NVIC_ETHR); NVIC_SetPend(NVIC_RIT); //Ñòàðòóåì RIT_IRQHandler } Ересь какая-то в общем. Другие биты не проверял. Есть у кого какие мысли? В общем-то такое поведение и не особо страшно, но уж очень стремно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VslavX 0 15 июня, 2011 Опубликовано 15 июня, 2011 · Жалоба Очень занятное поведение флага INTSTATUS_bit.RXDONEINT обнаружилось. Мне кажется что у него какой-то внутренний сигнал, устанавливающий запрос RXDONEINT не успевает сняться. Если быстро заходите в прерывание и пытаетесь сбросить запрос, то внутренний "триггер" (не флип-флоп, а именно спусковой крючок) снова его ставит. А если немножко подождать - то внутренний "триггер" успевает сняться и все OK. У меня в прерывании с регистрами EMAC ничего не делается - просто ставится событие RTOS, поэтому до обработки собственно запроса в приоритетном потоке проходит некоторое время (явно больше чем Ваши NOPы), и такого поведения не наблюдается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 15 июня, 2011 Опубликовано 15 июня, 2011 · Жалоба Мне кажется что у него какой-то внутренний сигнал, устанавливающий запрос RXDONEINT не успевает сняться. Да вот там есть интересная фраза такая в мане, что Note that all bits are flip-flops with an asynchronous set in order to be able to generate interrupts if there are wake-up events while clocks are disabled. Какими они там сигналами асинхронно выставляются, я уж хз. Запросто эти сигналы могут быть заведены на вход S триггеров и быть по длительности хз какими. Вот и не сбрасывается. У меня в прерывании с регистрами EMAC ничего не делается - просто ставится событие RTOS Так тут тоже самое. NVIC_SetPend(NVIC_RIT) - это и есть запуск потока обработки. Только у него приоритет ниже, посему начинает обрабатывать позже. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 15 июня, 2011 Опубликовано 15 июня, 2011 · Жалоба А если dsb вставить после записи INTCLEAR? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 15 июня, 2011 Опубликовано 15 июня, 2011 (изменено) · Жалоба Разрешено только прерывания RXDONEINT. Там такой код: Я правильно понял - происходит двойной заход в обработчик? По моему NVIC должен запрещать двойные заходы. Только после полного выхода. Изменено 15 июня, 2011 пользователем GetSmart Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alag57 1 15 июня, 2011 Опубликовано 15 июня, 2011 · Жалоба while(INTSTATUS_bit.RXDONEINT); Посмотрите соответствующий код в ассемблере, нет ли там записи в INTSTATUS. У меня были какие-то неприятности с прерываниями от ЕМАС, когда я делал так: if (LPC_EMAC->IntStatus & (1 << INT_RX_DONE)) давненько было - не помню подробностей. Сделал так: unsigned int temp = LPC_EMAC->IntStatus; if (temp & INT_RX_DONE) { LPC_EMAC->IntClear = INT_RX_DONE; } И неприятностей больше не было. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 15 июня, 2011 Опубликовано 15 июня, 2011 · Жалоба А если dsb вставить после записи INTCLEAR? Барьеры не помогают (только как задержка вместо нопов). Я тоже сразу подумал о синхронизации всяких Load-Store конвейеров, но это не оно. Я правильно понял - происходит двойной заход в обработчик? Не двойной заход. Вход-выход и опять вход-выход. На втором входе все замечательно очищается. void Ethernet_IRQHandler(void) { INTCLEAR=1UL<<3;//RxDoneInt NVIC_ClrPend(NVIC_ETHR); ...тут например дрыгаем ножкой для теста } Такой код дрыгает ножкой два раза на один пакет. Без паузы. Посмотрите соответствующий код в ассемблере, нет ли там записи в INTSTATUS. Конечно нет. Код корректный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VslavX 0 15 июня, 2011 Опубликовано 15 июня, 2011 · Жалоба Так тут тоже самое. NVIC_SetPend(NVIC_RIT) - это и есть запуск потока обработки. Только у него приоритет ниже, посему начинает обрабатывать позже. Не совсем то же самое - Вы цупите INTCLEAR. Я прерывания от EMAC запрещаю через NVIC: void lw_lpc17_emac_handler( void) { tn_event_iset(&glw_lpc17_netif->event, MACEVT_MACIRQ); NVIC_IDCR0 = (1<<IRQ_EMAC); } Разбор чего там EMAC захотел и общение с его регистрами происходит позже в потоке Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 15 июня, 2011 Опубликовано 15 июня, 2011 · Жалоба Не совсем то же самое - Вы цупите INTCLEAR. Я прерывания от EMAC запрещаю через NVIC: Ну тогда похоже Вы не видите этих граблей, ибо очень долго до собственно сброса флага. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gladov 0 16 июня, 2011 Опубликовано 16 июня, 2011 · Жалоба void Ethernet_IRQHandler(void) { UREG i='0'; do { INTCLEAR=1UL<<3; //RxDoneInt i++; } while(INTSTATUS_bit.RXDONEINT); usart0_txc(i); NVIC_ClrPend(NVIC_ETHR); NVIC_SetPend(NVIC_RIT); //Ñòàðòóåì RIT_IRQHandler } void Ethernet_IRQHandler(void) { INTSTATUS; __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); INTCLEAR=1UL<<3;//RxDoneInt NVIC_ClrPend(NVIC_ETHR); NVIC_SetPend(NVIC_RIT); //Ñòàðòóåì RIT_IRQHandler } Я с EMAC плотно пока не работал, поэтому есть лишь догадка: в первом случае INTSTATUS вычитывается ПОСЛЕ первого обнуления в INTCLEAR, а во втором СНАЧАЛА читается статус, потом очищается прерывание. Может быть тот самый упомянутый выше "спусковой крючок" находится в INTSTATUS и сначала надо его прочитать (как в некоторых self-clear прерываниях), а потом уже принудительно прописать бит в INTCLEAR? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrewlekar 0 16 июня, 2011 Опубликовано 16 июня, 2011 · Жалоба Я в LPC1768 не смог победить их работу с прерыванием RxDone. По итогу сделал поллинг индекса в DMA. В других примерах (FreeRTOS например), сделано так же. Прерывание там используется только чтобы проснуться. Да, а заметили, что первые пара пакетов шлётся криво? В Errata описан такой баг. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 16 июня, 2011 Опубликовано 16 июня, 2011 · Жалоба поэтому есть лишь догадка Я так тоже думал. Нет, просто паузы достаточно для последующей нормальной очистки флага. Я в LPC1768 не смог победить их работу с прерыванием RxDone. А что его побеждать? Оно работает. Да, а заметили, что первые пара пакетов шлётся криво? В Errata описан такой баг. Хватило квалификации не наступить. Ибо изначально изучил Errata и закодил передачу пары пакетов заранее. И вообще, описанный баг превращается в фичу ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrewlekar 0 17 июня, 2011 Опубликовано 17 июня, 2011 · Жалоба А что его побеждать? Оно работает. А у меня не работает. Киньте что ли сюда код обработки прерывания - уберу у себя поллинг. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Slowhan 0 21 июля, 2011 Опубликовано 21 июля, 2011 · Жалоба Люди, а каких вы скоростей на Lpc17 достигаете по tcp? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 21 июля, 2011 Опубликовано 21 июля, 2011 · Жалоба Люди, а каких вы скоростей на Lpc17 достигаете по tcp? Смотря какую полезную нагрузку вкладывать. В принципе, при верном подходе утилизируется вся доступная полоса. Да, кстати, собственно по теме топика. Оказывается, у меня не была припаяна ножка RX- на PHY - работало по одному проводу. В результате после окончания пакета на 10МБит были еще дрыгания, которые интерпретировались PHY как начало нового фрейма. А MAC, как оказалось, даже такой в упор непакет все таки отбрасывает с установкой флага прерывания. В общем, имейте в виду, что может происходить и такая ересь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться