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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Интересное поведение EMAC на LPC17xx
Rst7
сообщение Jun 15 2011, 11:40
Сообщение #1


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Очень занятное поведение флага INTSTATUS_bit.RXDONEINT обнаружилось.

Разрешено только прерывания RXDONEINT. Там такой код:
CODE
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
}


Неспеша кормлю девайсу по одному пакету (дабы быть уверенным, что никакого переполнения не происходит). В результате в консоль сыпется:

CODE
122212112121121112122222222112112211212222222121111....


Пуристы для тестов могут заменить usart0_txc на ногодрыг и наблюдать осциллографом тот же результат - импульсов то 1, то 2.

Если бы просто сделать
CODE
void Ethernet_IRQHandler(void)
{
  INTCLEAR=1UL<<3; //RxDoneInt
  NVIC_ClrPend(NVIC_ETHR);
  NVIC_SetPend(NVIC_RIT); //Ñòàðòóåì RIT_IRQHandler
}

то этот код часто (а то и вообще всегда) вызывается 2 раза - не сбрасывается флаг RxDoneInt, соответственно, сброс соответствующего бита в NVIC не помогает - не снят изначальный флаг, т.е. происходит опять поднятие флага в NVIC и последующее прерывание. Правда, на второй заход сброс таки происходит.

Вот такой код вроде (ну ибо на обозримом отрезке времени мне не удалось наблюдать двойной вызов) всегда вызывается один раз:
CODE
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
}


Ересь какая-то в общем. Другие биты не проверял.

Есть у кого какие мысли?

В общем-то такое поведение и не особо страшно, но уж очень стремно biggrin.gif


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
VslavX
сообщение Jun 15 2011, 12:05
Сообщение #2


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Цитата(Rst7 @ Jun 15 2011, 14:40) *
Очень занятное поведение флага INTSTATUS_bit.RXDONEINT обнаружилось.

Мне кажется что у него какой-то внутренний сигнал, устанавливающий запрос RXDONEINT не успевает сняться.
Если быстро заходите в прерывание и пытаетесь сбросить запрос, то внутренний "триггер" (не флип-флоп, а именно спусковой крючок) снова его ставит. А если немножко подождать - то внутренний "триггер" успевает сняться и все OK.
У меня в прерывании с регистрами EMAC ничего не делается - просто ставится событие RTOS, поэтому до обработки собственно запроса в приоритетном потоке проходит некоторое время (явно больше чем Ваши NOPы), и такого поведения не наблюдается.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jun 15 2011, 12:41
Сообщение #3


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



QUOTE
Мне кажется что у него какой-то внутренний сигнал, устанавливающий запрос RXDONEINT не успевает сняться.


Да вот там есть интересная фраза такая в мане, что
QUOTE
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 триггеров и быть по длительности хз какими. Вот и не сбрасывается.

QUOTE
У меня в прерывании с регистрами EMAC ничего не делается - просто ставится событие RTOS


Так тут тоже самое. NVIC_SetPend(NVIC_RIT) - это и есть запуск потока обработки. Только у него приоритет ниже, посему начинает обрабатывать позже.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 15 2011, 13:00
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



А если dsb вставить после записи INTCLEAR?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 15 2011, 13:27
Сообщение #5


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(Rst7 @ Jun 15 2011, 16:40) *
Разрешено только прерывания RXDONEINT. Там такой код:

Я правильно понял - происходит двойной заход в обработчик?
По моему NVIC должен запрещать двойные заходы. Только после полного выхода.

Сообщение отредактировал GetSmart - Jun 15 2011, 13:58


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
alag57
сообщение Jun 15 2011, 13:46
Сообщение #6


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

Группа: Участник
Сообщений: 130
Регистрация: 26-06-06
Из: Березовский
Пользователь №: 18 355



Цитата
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;
}

И неприятностей больше не было.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jun 15 2011, 14:04
Сообщение #7


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



QUOTE
А если dsb вставить после записи INTCLEAR?


Барьеры не помогают (только как задержка вместо нопов). Я тоже сразу подумал о синхронизации всяких Load-Store конвейеров, но это не оно.

QUOTE
Я правильно понял - происходит двойной заход в обработчик?


Не двойной заход. Вход-выход и опять вход-выход. На втором входе все замечательно очищается.

CODE
void Ethernet_IRQHandler(void)
{
  INTCLEAR=1UL<<3;//RxDoneInt
  NVIC_ClrPend(NVIC_ETHR);
  ...тут например дрыгаем ножкой для теста
}


Такой код дрыгает ножкой два раза на один пакет. Без паузы.

QUOTE
Посмотрите соответствующий код в ассемблере, нет ли там записи в INTSTATUS.


Конечно нет. Код корректный.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
VslavX
сообщение Jun 15 2011, 14:13
Сообщение #8


embarrassed systems engineer
*****

Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038



Цитата(Rst7 @ Jun 15 2011, 15:41) *
Так тут тоже самое. 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 захотел и общение с его регистрами происходит позже в потоке
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jun 15 2011, 14:22
Сообщение #9


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



QUOTE
Не совсем то же самое - Вы цупите INTCLEAR. Я прерывания от EMAC запрещаю через NVIC:


Ну тогда похоже Вы не видите этих граблей, ибо очень долго до собственно сброса флага.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
gladov
сообщение Jun 16 2011, 04:29
Сообщение #10


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

Группа: Свой
Сообщений: 169
Регистрация: 10-11-05
Из: Воронеж
Пользователь №: 10 687



Цитата(Rst7 @ Jun 15 2011, 15:40) *
Код
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?
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Jun 16 2011, 05:32
Сообщение #11


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Я в LPC1768 не смог победить их работу с прерыванием RxDone. По итогу сделал поллинг индекса в DMA. В других примерах (FreeRTOS например), сделано так же. Прерывание там используется только чтобы проснуться. Да, а заметили, что первые пара пакетов шлётся криво? В Errata описан такой баг.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jun 16 2011, 05:56
Сообщение #12


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



QUOTE
поэтому есть лишь догадка


Я так тоже думал. Нет, просто паузы достаточно для последующей нормальной очистки флага.

QUOTE
Я в LPC1768 не смог победить их работу с прерыванием RxDone.


А что его побеждать? Оно работает.

QUOTE
Да, а заметили, что первые пара пакетов шлётся криво? В Errata описан такой баг.


Хватило квалификации не наступить. Ибо изначально изучил Errata и закодил передачу пары пакетов заранее. И вообще, описанный баг превращается в фичу wink.gif


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
andrewlekar
сообщение Jun 17 2011, 04:22
Сообщение #13


Знающий
****

Группа: Участник
Сообщений: 837
Регистрация: 8-02-07
Пользователь №: 25 163



Цитата
А что его побеждать? Оно работает.

А у меня не работает. Киньте что ли сюда код обработки прерывания - уберу у себя поллинг.
Go to the top of the page
 
+Quote Post
Slowhan
сообщение Jul 21 2011, 13:30
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 20-06-11
Из: Ленино
Пользователь №: 65 788



Люди, а каких вы скоростей на Lpc17 достигаете по tcp?
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jul 21 2011, 14:37
Сообщение #15


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



QUOTE
Люди, а каких вы скоростей на Lpc17 достигаете по tcp?


Смотря какую полезную нагрузку вкладывать. В принципе, при верном подходе утилизируется вся доступная полоса.

Да, кстати, собственно по теме топика. Оказывается, у меня не была припаяна ножка RX- на PHY - работало по одному проводу. В результате после окончания пакета на 10МБит были еще дрыгания, которые интерпретировались PHY как начало нового фрейма. А MAC, как оказалось, даже такой в упор непакет все таки отбрасывает с установкой флага прерывания.

В общем, имейте в виду, что может происходить и такая ересь.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 08:54
Рейтинг@Mail.ru


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