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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Баг ядра LPC2368?
GetSmart
сообщение Nov 12 2009, 10:43
Сообщение #1


.
******

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



Проц LPC2368. Отладчик MT-Link v6.0. Прога под FreeRTOS. Компилятор CW 1.7 build 9

В майне всё как полагается - регистрируются треды и в конце вызывается vTaskStartScheduler(). Собственно во все треды управление залетает, до тех пор пока не встретится vTaskDelay(). Далее управление больше не возвращается. Баг возникает очень редко, но долговременно. Часто до выключения питания. Перепрограммирование проца баг не снимает.

Во всех тредах IRQ и FIQ разрешены (CPSR = x000001f). Расследование показывает, что не вызываются IRQ вообще, хотя FIQи прекрасно работают. Настройки таймера FreeRTOS правильные. Все регистры в норме, таймер тикает до установленного MATCH, потом опять с нуля. В VIC корректный адрес обработчика TIMER0 и приоритет = 1 (проверено). Все остальные регистры VIC тоже в порядке, причём в VICIRQStatus и VICRawIntr установлен запрос на прерывание от TIMER0, но оно туда не идёт. Брейкпоинт на 0x18 и на первой команде прерывания (IRQ) TIMER0 не срабатывает. IRQ реально не вызывается. Не могу выяснить проблему. Кстати, в начале майна стоит запрет прерываний в CPSR и команда VICIntEnClr = ~0;

ЗЫ. Одну странность заметил. В регистре VICRawIntr наблюдается включённый бит 3 (ARM Core Embedded ICE, DbgCommTX), причём этого же бита нет ни в VICIRQStatus ни в VICFIQStatus. Состояние первых 16-ти регистров VIC на картинке.

Забыл указать - прога без конца крутится в цикле for (;;) из функции static portTASK_FUNCTION( prvIdleTask, pvParameters ) периодически залетая в FIQ. В ней аналогично CPSR = x000001f.

В течении ближайшего часа могу продемонстрировать баг "вживую" на "телевизоре" TeamViewer. Реальным пацанам smile.gif

Сообщение отредактировал GetSmart - Nov 12 2009, 10:36
Эскизы прикрепленных изображений
Прикрепленное изображение
 


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
KRS
сообщение Nov 12 2009, 11:36
Сообщение #2


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Ну то что прерывание по DCC TX разрешено - так может это отладчик его использует, для debug_printf или еще для чего.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 12 2009, 11:40
Сообщение #3


.
******

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



-----------------
Есть предположение, что это не баг, а фича под названием RealMonitor, прошитая в bootloader.

Цитата из User Manual 23xx.pdf
Код
While user application is running, RMTarget typically uses IRQs generated by the DCC.
This means that if user application also wants to use IRQs, it must pass any
DCC-generated interrupts to RealMonitor.

Кто-нибудь с этим сталкивался? Как это точно переводится?
Когда пользовательская прога работает, RMTarget-у тоже требуются запросы IRQ. Это значит что если пользовательская прога юзает IRQ, то она же должна перенаправлять прерывания от DCC в RealMonitor ?
Я правильно перевёл?

Цитата(KRS @ Nov 12 2009, 17:36) *
Ну то что прерывание по DCC TX разрешено - так может это отладчик его использует, для debug_printf или еще для чего.

Проверил. debug_printf не используется в моём проекте.

Сообщение отредактировал GetSmart - Nov 12 2009, 11:51


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
KRS
сообщение Nov 12 2009, 11:40
Сообщение #4


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(GetSmart @ Nov 12 2009, 14:37) *
-----------------
Есть предположение, что это не баг, а фича под названием RealMonitor, прошитая в bootloader.

Так его надо включить вызовом соответствующим!
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 12 2009, 12:13
Сообщение #5


.
******

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



Может кто-нибудь знает, как сбрасываются запросы от Embedded ICE, DbgCommRx и Embedded ICE, DbgCommTX или сиё тайна NXP?

Поставил в начале main() вот это
Код
        VICVectAddr = 0;
        VICVectAddr = 0;
        VICVectAddr = 0;
        VICVectAddr = 0;
        VICVectAddr = 0;
        VICVectAddr = 0;
        VICVectAddr = 0;

И всё заработало smile.gif

Всвязи с этим возник вопрос - как при рестарте проги (программно или по JTAG) правильно сбрасывать VIC ? Чтобы ещё и счётчик приоритетов обнулялся. И для чего существует регистр VICSWPriorityMask, на который в мануале нет внятного объяснения?

И что за регистр, находящийся по адресу 0xFFFFF028 ? В мануале его нет, но на моей картинке в первом посте он есть!

Ещё прикол в том, что иногда подобный баг возникал прямо при первой отладке. Возможно когда отладчик прерывал работающую прогу прямо из прерывания FreeRTOS - Timer0 и все прерывания блокировались. Мля.

Сообщение отредактировал GetSmart - Nov 12 2009, 12:04


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
KRS
сообщение Nov 12 2009, 12:38
Сообщение #6


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(GetSmart @ Nov 12 2009, 15:13) *
Всвязи с этим возник вопрос - как при рестарте проги (программно или по JTAG) правильно сбрасывать VIC ? Чтобы ещё и счётчик приоритетов обнулялся.

Хороший вопрос!!!
Вообще надо что бы отладчик делал ресет контроллеру, но я тоже заметил что не всегда происходит сброс всей переферии. Похоже делается ресет, а потом проц останавливаетя, но уже успевает выполнить часть программы.
Можно в начале задержку поставить.

Цитата(GetSmart @ Nov 12 2009, 15:13) *
И для чего существует регистр VICSWPriorityMask, на который в мануале нет внятного объяснения?

Вам нужен datasheet от ARM
ARM DDI 0273A
ARM PrimeCell ™ Vectored Interrupt Controller (PL192)
Technical Reference Manual
Go to the top of the page
 
+Quote Post
VslavX
сообщение Nov 12 2009, 13:40
Сообщение #7


embarrassed systems engineer
*****

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



Цитата(GetSmart @ Nov 12 2009, 14:13) *
Поставил в начале main() вот это
Код
        VICVectAddr = 0;
        VICVectAddr = 0;
        VICVectAddr = 0;
        VICVectAddr = 0;
        VICVectAddr = 0;
        VICVectAddr = 0;
        VICVectAddr = 0;

И всё заработало smile.gif

Посмотрел в свои исходники - у меня есть такая строчки
Код
for (i=0; i<16; i++) pVic->sVIC_VECTOR = 0;     // очищаем аппаратный стек вложений

Начал вспоминать и вспомнил - VIC в LPC поддерживает схему приоритетов прерываний - когда происходит прерывание, VIC запоминает в свое внутреннем аппаратном стеке текущий уровень приоритета и все прерывания с более низким приоритетом - блокируются, с более высоким - разрешаются и "нестяться". Вот этот внутренний стек и чистится многократной записью VIC_VECTOR. 16 - глубина стека, равная числу уровней приоритета.

Цитата(GetSmart @ Nov 12 2009, 14:13) *
Может кто-нибудь знает, как сбрасываются запросы от Embedded ICE, DbgCommRx и Embedded ICE, DbgCommTX или сиё тайна NXP?

Да нет, в LPC23 все стандартно, задокументировано в документации ARM на ядро ARM7TDMI.
Доступ к регистрам DCC, например, такой:
Код
#define hal_status_dcc()     __MRC(14, 0, 0, 0, 0)
#define hal_write_dcc(a)     __MCR(14, 0, a, 1, 0, 0)
#define hal_read_dcc()       __MRC(14, 0, 1, 0, 0)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Nov 17 2009, 12:59
Сообщение #8


.
******

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



Зачем создавать новую тему, если можно здесь продолжить. Тем более, что название темы аналогичное.

Столкнулся с непонятным мне поведением LPC2368. Прога (та же), работает под FreeRTOS. Используются вложенные FIQ, работающие в Undef режиме и вложенные IRQ, работающие тоже на Undef режиме. Всё прекрасно работает под осью и без неё. Далее, меняю режим работы вложенных FIQ на IRQ и под FreeRTOS падаю в Data Abort. То же самое запускаю без FreeRTOS (вместо треда пустой цикл, хотя прога на уровне прерываний проигрывает музыку) и всё прекрасно работает.

Обёртку вложенных прерываний FIQ выкладывал в соседней теме. здесь:
http://electronix.ru/forum/index.php?showt...st&p=678194
Там нужно только при загрузке режима в CPSR поменять режим с 0x9b на 0x92 (или 0xd2 - без разницы).

Под FreeRTOS падает в месте, помеченном стрелкой:
Код
    void vPreemptiveTick( void )
    {
        /* Save the context of the interrupted task. */
        portSAVE_CONTEXT();                        <<-------

        /* Increment the RTOS tick count, then look for the highest priority
        task that is ready to run. */
        vTaskIncrementTick();
        vTaskSwitchContext();

        /* Ready for the next interrupt. */
        T0IR = 2;
        VICVectAddr = portCLEAR_VIC_INTERRUPT;

        /* Restore the context of the new task. */
        portRESTORE_CONTEXT();
    }

Код
vPreemptiveTick

    portSAVE_CONTEXT();    
       E92D0001   stmfd sp!, {r0}
       E94D2000   stmfd sp, {sp}^
       E1110001   mov r0,r0             (менял на tst r1, r1 - не помогло)
       E24DD004   sub sp, sp, #0x00000004
       E8BD0001   ldmfd sp!, {r0}
       E9204000   stmdb r0!, {lr}        <<<----- Data Abort (R0 = 0x0006be80, CPSR = 0x0006be80)

Причём именно после "хаковой" инструкции stm xx, {xx}^. По логике, эта инструкция должна загрузить регистр SP треда сначала в стек, а потом он загружается в текущий R0, но там просто чудеса творятся. Вообще, этот обработчик прерывания переключения тредов от таймера (vPreemptiveTick) какое-то время нормально работает. В каких-то особых случаях в регистре R0 оказывается значение в районе внутреннего флэш, конкретно из моей проги. Прикол ещё в том, что в регистре SPSR (текущего режима IRQ) оказывается то же самое значение (чего не может быть в принципе, т.к. в SPSR задействованы только первые 8 бит и последние 4). Проверил, что указатели стеков всех режимов в норме. И в режиме System/User стек = 40003360, хотя в R0 загрузилось другое число. Проверял, точно выяснил, что управление залетает в vPreemptiveTick когда все мои вложенные прерывания уже закончились, то есть нет перекрёстных входов, собсно как и должно быть.

Если есть настоящие спецы, которым интересен этот баг - могу сильно кастрировать прогу и выложить для тестирования. Либо прошу подсказать советом как мне найти почему этот баг происходит. Только прошу не оффтопить.

---------------------
Уже когда написал пост понял!!!!!!
После команды stmfd sp, {sp}^ стоит NOP (mov r0, r0), который и затирает R0 чёрт знает каким значением, но видимо из PC.

Вообще-то изменив команду на TST R1,R1 это не помогло. Зато выяснил, что значение загруженное в R0 равняется текущему LR, то есть R0, LR и SPSR совпадают.

Сообщение отредактировал GetSmart - Nov 17 2009, 13:34


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 17 2009, 13:04
Сообщение #9


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

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



Цитата
Либо прошу подсказать советом как мне найти почему этот баг происходит.


Ставлю литру на Ваш выбор, что в процессе выполнения команды mov r0,r0 происходит прерывание. В результате стек запарывается (видимо, сохранением LR в стек), ибо тут кодописатели - сами себе злобные буратины, код совершенно не предназначен для работы со вложенными прерываниями. Надо делать так:
Код
   stmfd sp!, {r0}
   sub sp,sp,#4
   stmia sp,{sp}^
   mov r0, r0
   ldr r0, [sp], #4


Короче, баг не в ядре, а в голове у кого-то.


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


.
******

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



Цитата(Rst7 @ Nov 17 2009, 19:04) *
Короче, баг не в ядре, а в голове у кого-то.

Внатуре smile.gif
Эти кретины сохраняют регистр не в стеке, а в свободной его области. И я потом на ней работаю и ненароком затираю biggrin.gif

YES!!!!!! Теперь работает smile.gifsmile.gifsmile.gif

Rst7, респект и уважуха biggrin.gif

Кто сообщит автору FreeRTOS, что у него косяк? smile.gif

Сообщение отредактировал GetSmart - Nov 17 2009, 13:11


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 17 2009, 13:20
Сообщение #11


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

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



Цитата
Rst7, респект и уважуха


Да ладно. Я вот настоящий баг знаю. Правда, в ядрах 926EJ-S, которые в чипсетах мобильников от Siemens (Infineon) и SE (там не знаю кто). Там MOV PC,Rx не меняет режим ядра ARM->Thumb, хотя по даташиту - должен.


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


.
******

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



Вот исправленный макрос
CODE
#define portSAVE_CONTEXT() \
{ \
extern volatile void * volatile pxCurrentTCB; \
extern volatile unsigned portLONG ulCriticalNesting; \
\
/* Push R0 as we are going to use the register. */ \
asm volatile ( \
"STMDB SP!, {R0} \n\t" \
\
/* Set R0 to point to the task stack pointer. */ \
"SUB SP,SP,#4 \n\t" \
"STMIA SP,{SP}^ \n\t" \
"NOP \n\t" \
"LDMIA SP!,{R0} \n\t" \
\
/* Push the return address onto the stack. */ \
"STMDB R0!, {LR} \n\t" \
\
/* Now we have saved LR we can use it instead of R0. */ \
"MOV LR, R0 \n\t" \
\
/* Pop R0 so we can save it onto the system mode stack. */ \
"LDMIA SP!, {R0} \n\t" \
\
/* Push all the system mode registers onto the task stack. */ \
"STMDB LR,{R0-LR}^ \n\t" \
"NOP \n\t" \
"SUB LR, LR, #60 \n\t" \
\
/* Push the SPSR onto the task stack. */ \
"MRS R0, SPSR \n\t" \
"STMDB LR!, {R0} \n\t" \
\
"LDR R0, =ulCriticalNesting \n\t" \
"LDR R0, [R0] \n\t" \
"STMDB LR!, {R0} \n\t" \
\
/* Store the new top of stack for the task. */ \
"LDR R0, =pxCurrentTCB \n\t" \
"LDR R0, [R0] \n\t" \
"STR LR, [R0] \n\t" \
); \
( void ) ulCriticalNesting; \
( void ) pxCurrentTCB; \
}
#endif


smile.gifsmile.gifsmile.gif

Теперь и на Supervisor-е работает вложенный FIQ! А раньше так же "падал" как и на IRQ.

Сообщение отредактировал GetSmart - Nov 17 2009, 13:42


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 17 2009, 13:51
Сообщение #13


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

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



Цитата
Теперь и на Supervisor-е работает вложенный FIQ! А раньше так же "падал" как и на IRQ.


Вот поэтому я резко отрицательно отношусь к чужому коду, ибо времени на вычитывание надо затратить часто больше, чем на собственную имплементацию. Особенно, если необходимо сделать какой-то нестандарт, ну вот типа как у Вас. Да и повторное использование своего тоже требует осторожности, по крайней мере обязательна вычитка узких мест.

PS Если охота пофлудить, можем развить тему унылогуаности всех методов, крутящихся возле идеи time-to-market, как то - повторное использование кода (да здравствуют апноты, либы производителей и исходники, скачанные где-то в интернете), ООП (как метод затруднения поиска потенциально бажных мест в коде wink.gif ), и т.д.


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


.
******

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



Цитата(Rst7 @ Nov 17 2009, 19:51) *
PS Если охота пофлудить, можем развить тему унылогуаности всех методов, крутящихся возле идеи time-to-market, как то - повторное использование кода (да здравствуют апноты, либы производителей и исходники, скачанные где-то в интернете), ООП (как метод затруднения поиска потенциально бажных мест в коде wink.gif ), и т.д.

Мне было бы интересно узнать что-то новое.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 17 2009, 14:17
Сообщение #15


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

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



Цитата
Мне было бы интересно узнать что-то новое.


Тактичное приглашение к флуду? wink.gif Завтра, я щас убегаю из-за компа, а с мобильника - нет того размаха smile.gif


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

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

 


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


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