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

 
 
> STM32F1xx и Fault, Не получается отловить из какого места
XGoblinX
сообщение Aug 29 2011, 11:23
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 43
Регистрация: 13-12-10
Пользователь №: 61 586



Всем здравствуйте!

Есть программка на иаре. Загружаю под SWD в STM32F103.
int main( void )
{
memset(0x20000000, 0, 0xffffff);
}

Во время выполнения естественно падаю в 0xC.
Но после этого я не могу посмотреть откуда именно (с какой инструкции) он туда свалился.
Хочу для себя понять на будущее, как ловить такие вещи.
Спасибо заранее.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
brag
сообщение Jun 14 2012, 11:46
Сообщение #2


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

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Цитата
Ребята стал попадать в обработчик хард-фолта с таким вот состоянием.

В LR у Вас явно не то, что должно быть, обработчик видимо у Вас кривой.

Адрес возврата и другую информацию отлавливаю так. верный вариант по задумке разработчика armv7m
Код
eHardFault
    mov r0,#0
    mov r1,lr
    mov r2,sp; always MSP in exception handler
    mrs r3,PSP
    bl printfault
    b .

void printfault(U32 flt,U32 lr,U32 *msp,U32 *psp){
    U32 retaddr;

    // analyze EXC_RETURN
    if((lr&0x0F)==1||(lr&0x0F)==9){
        retaddr=msp[6];
    }else if((lr&0x0F)==0x0D){
        retaddr=psp[6];
    }else ra=0xFFFFFFFF;

   // print
    switch(flt){
    case ...:
              }
}

В месте с адресом возврата нужно печатать CFSR, BFAR и HFSR.

Что касается отлова места, от куда растут ноги... Во первых надо внимательно прочитать описание на вышеприведенные регистры CFSR, BFAR, HFSR - информации про fault там не мало.
Обычно, если занесло не туда(на пример при переполнении буффера в стеке), то исключениия могут быть следующие
1. UsageFault - попали на существующую память, но дело дошло до некорректной инструкции.
2. BusFault - попали на недоступную для выполнения кода память
В обеих случаях адрес возврата может быть не тот,что нам интересно. Для начала нужно это проверить, посмотрев в дизассемблер вашего реального КОДА - если там этого адреса нету - значит он не тот. В таком случаи дальше уже стандартного метода нету.
Если баг вылазит сразу, то и поймать место легко - стевим бряк на выходы с функций и смотрим куда попадает.
Если не очень сразу - в дебаггерах есть трассировка вызовов и переходов. Натрейсить многомегабайтный лог и потом искать в обратном порядке последнюю запланированную инструкцию(так, которая есть в вашем КОДЕ).

Если баг вылазит очень редко (на пример, раз в неделю) и весь код вы уже перечесали на предмет переполнений и indirect-вызовов - тут надо хорошенько напрячь мозги и прокурить документацию.

У меня была ситуация с PendSV, SVC обработчиками.
Код
ePendSV
; push LR(EXC_RETURN),R11-R4 to PSP, save PSP
    mrs r0,PSP
    stmdb r0!,{r4-r11,lr}
    
    ...save context....
              ... get new context....
    
; restore LR(EXC_RETURN),R11-R4 from new PSP, set new PSP, return
    ldmia r0!,{r4-r11,lr}
    msr PSP,r0
    bx lr

void eSVCall(void){
    U32 a0,a1,a2,a3,svc,*psp;
    
    psp=(U32*)__get_PSP();
    a0=psp[0];a1=psp[1];a2=psp[2];a3=psp[3]; // get arguments from user stack
    svc=psp[4]; // get service call ID from user stack
    
              a=service(svc,a0,a1,a2,a3);
    
    psp[0]=a0; // save return value (r0) to user stack
}


используем это дело так:
Код
         mov r0,...; arg1
         mov r1,...; arg2
         mov r12,#1; SVC ID
         svc 0
; now r0 has return value

При вызове обработчика инструкцией svc регистры сохранятся в стек, обработчиком перезапишется в стеке значение регистра(ов), при выходе из исключения регистры восстановятся со стека с уже перезаписанными значениями.

Вроде все гуд, НО!
Прочитав фразу "Because SVCall and PendSV have the same execution priority they cannot preempt each other" из refмануала на armv7m так и сделал - назначил обеим обработчикам одинаковый приоритет и был уверен, что все сделал правильно. Хотя в моем случаи это было неверно.

Дело в том, что в armv7m есть такая вероятность, что PendSV и SVCall одновременно могут висеть в ожидании, а если они имеют одинаковый приоритет, то порядок их выполнения неопределен, тк там есть механизмы Late arrival preemption, Tail-chaining и конвеер. Подробно можно почитать в ARM DDI0403D

Теперь, если исключение PendSV наступит в момент, когда иснтрукция svc уже в конвеере, но пока само исключение SVCall еще не сгенерировано, мы попадаем в обработчик PendSV, которий в итоге перезапишет значение PSP и выйдет. Далее по tail-chain выполнится уже SVCall, который будет уже обращатся к чужому стеку... Баг вылазит довольно редко, с интервалом от нескольких часов, до недели а то и больше. И вылазит он не в виде fault-a, а в виде вызова исключения(зачастую успешным) с неправильными аргументами или значением возврата.программа вроде работает, но не так, как надо. я очень долго не мог этот баг выудить... Недели копания в дебагере, чтения документации, анализа кода... И все практически напрасно. Помогло только чтение документации + симуляция поведения проца в голове..
Зато решение оказалось просто смешное - поднять приоритет SVCall sm.gif Это даст гарантию, что SVCall всегда будет выполнено до PendSV. и глюка уже не будет.

Заставить PendSV и SVCall одновременно висеть в Pending state легко: Запускаем таймер, частоту задть по максимуму, чтобы вероятность поднять. в таймере делаем PENDSVSET. Теперь если прерывание таймера вытеснит SVCall до старта самого обработчика SVCall(тоесть SVCall все еще в pending-state), выполнится обработчик таймера, установит PendSV тоже в pending-state. Все, при выходе с обработчика таймера при равном приоритете PendSV и SVCall может выполнится любая из них,порядок неопределен.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- XGoblinX   STM32F1xx и Fault   Aug 29 2011, 11:23
- - SII   А где пытаетесь смотреть? Адрес возврата (из котор...   Aug 29 2011, 11:33
|- - XGoblinX   Цитата(SII @ Aug 29 2011, 11:33) А где пы...   Aug 29 2011, 11:38
- - KnightIgor   Цитата(XGoblinX @ Aug 29 2011, 13:23) Все...   Aug 29 2011, 11:49
|- - XGoblinX   Цитата(KnightIgor @ Aug 29 2011, 11:49) А...   Aug 29 2011, 12:17
- - SII   Почитайте внимательно описание архитектуры на пред...   Aug 29 2011, 13:05
- - Aleksandr Baranov   Если я правильно понял вопрос, есть известный спос...   Aug 29 2011, 18:20
|- - XGoblinX   Цитата(Aleksandr Baranov @ Aug 29 2011, 18...   Aug 30 2011, 05:03
|- - demiurg_spb   Ребята, стал попадать в обработчик хард-фолта с та...   Jun 14 2012, 10:02
- - andrewlekar   По идее да. Смотрите в map файле, что за функция н...   Jun 14 2012, 11:13
|- - demiurg_spb   Огромное спасибо за столь исчерпывающие рекомендац...   Jun 14 2012, 12:04
- - brag   У Вас по ходу LR выводился из стека, а я думал то ...   Jun 14 2012, 12:10
- - demiurg_spb   Спасибо! Отличная мысль!   Jun 14 2012, 17:17


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

 


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


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