Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Перезапуск?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Paramon
Проблема такова:
Требуется перезапускать устройство с сохранением одного параметра (слова) в каком нибудь регистре при возникновении Undef,DAbt,PAbt.
Имеется ввиду переходить в начало кода, /производить перенастройку всего железа/
Уменьшать сохренённое в регистре задание и продолжать работу.
В основе ADuC7024. Вроде всё работает, но иногда зависает и не перезапускается по непонятным причинам.

вот код:
Код
void    DAbt_Handler(void)    __arm
    {
        FIQEN = 0;
      //  IRQEN = 0;
        GP4CLR = _Set_DC_DC_Off;
        Service_Cicle = 0;
        while(Service_Cicle<TCK_MAX)
            {
                pw[Service_Cicle] = 0;
                Service_Cicle++;
            };
        GP2SET = _mod_on;
        //
        if(flag2 & _F_Work_On)
            {
                flag_abort = work_abort | DAbt_abort | Set_Prc;
            }
        else
            {
                flag_abort = no_work_abort | DAbt_abort | Set_Prc;
            };
        REMAP = 0;
        __asm{
                ldr        r8,=flag_abort
                ldr        r7,[r8]
                ldr     pc,0
            }
    }


Другие модули идентичны.

Устройсво работает в зоне больших эл.м помех. Кроме того возможны аппаратные казусы. А рядом никого нет, чтобы перезапустить и установить уменьшеное задание задание.

То что по DAbt оно отрабатывает - проверено. Но Undef и PAbt не зафиксировано.
(Устройство при таком перезапуске инкрементирует во FLASH - е кол-во тех или иных ситуаций по сохранённым в R7 данным)

Будьте добры укажите где копать. (Кроме железа - это мне известно)
Заранее благодарен!
WhiteWolf
1. Проверьте размеры стеков
2. Вы его перезапускаете в режиме Data abort, а не supervisor - это нормально?
3. Может попробовать LDR PC, 0x80000
3. Попробуйте перезапуск через RSTSTA - специально для этого предназначенный регистр. Сам так сделал, но у меня почему-то похоже после этого обнуляется структура в памяти, куда я сохраняю адрес проблемной инструкции, сейчас пытаюсь с этим разобраться.
Paramon
Цитата(WhiteWolf @ Oct 5 2007, 16:23) *
1. Проверьте размеры стеков
2. Вы его перезапускаете в режиме Data abort, а не supervisor - это нормально?
3. Может попробовать LDR PC, 0x80000
3. Попробуйте перезапуск через RSTSTA - специально для этого предназначенный регистр. Сам так сделал, но у меня почему-то похоже после этого обнуляется структура в памяти, куда я сохраняю адрес проблемной инструкции, сейчас пытаюсь с этим разобраться.


Понял свою ошибку. Спасибо!
Действительно не LDR PC,0 а LDR PC,0x800000.
Через RSTSTA уже пробовол, но при этом терял данные в регистре R7.
Данные, в каком регистре хранить знячения при перезапуске определил из анализа startup.s
Ещё проще в отладке заполнить чем - нибудь регистры, дойти до main и посмотреть какой регистр не изменился. У меня не менялись R7 и R8. И ещё какие - то. Уже не помню.
В самом начале main делал анализ и восстановление.
Вот код восстановления
Код
    __asm{
            ldr    r1,=flag_abort
            str    r7,[r1]
            ldr r7,=0
        }

а вот в моём случае восстановление задания и фиксация ошибок
Код
        if(flag_abort & work_abort)
            {
                //фиксация ошибок
                if(flag_abort & pow_abort)
                    {
                        if(_F_Ram_pow_err < 0xFFFF) _F_Ram_pow_err++;
                    }
                else if(flag_abort & Undef_abort)
                    {
                        if(_F_Ram_Undef_err < 0xFFFF) _F_Ram_Undef_err++;
                    }
                else if(flag_abort & DAbt_abort)
                    {
                        if(_F_Ram_DAbt_err < 0xFFFF) _F_Ram_DAbt_err++;
                    }
                else
                    {
                        if(_F_Ram_PAbt_err < 0xFFFF) _F_Ram_PAbt_err++;
                    };
                FEE_Save_page(_FEE_Start);
                //
                Set_Prc = flag_abort & 0x000000FF; //маска для задания
                if(Set_Prc > 5) Set_Prc -= 5;       //уменьшение задания на 5%
                drink_regulator();
                flag2 |= _F_Work_On;    //
                TCK_L = 0;
                LCD_On();
                LCD_Cur(STR1);
                LCD_Print_rus(" Восстановлен после");
                LCD_Cur(STR2);
                LCD_Print_rus("  Серьёзной ошибки");
                while(TCK_L < TCK_L_MAX)
                    {

                    }
                LCD_Cls();
            }
        else if(flag_abort & no_work_abort)
            {
                //
                if(flag_abort & pow_abort)
                    {
                        if(_F_Ram_pow_err < 0xFFFF) _F_Ram_pow_err++;
                    }
                else if(flag_abort & Undef_abort)
                    {
                        if(_F_Ram_Undef_err < 0xFFFF) _F_Ram_Undef_err++;
                    }
                else if(flag_abort & DAbt_abort)
                    {
                        if(_F_Ram_DAbt_err < 0xFFFF) _F_Ram_DAbt_err++;
                    }
                else
                    {
                        if(_F_Ram_PAbt_err < 0xFFFF) _F_Ram_PAbt_err++;
                    };
                FEE_Save_page(_FEE_Start);
                //
                TCK_L = 0;
                LCD_Cur(STR1);
                LCD_Print_rus(" Восстановлен после");
                LCD_Cur(STR2);
                LCD_Print_rus("  Серьёзной ошибки");
                while(TCK_L <TCK_L_MAX)
                    {

                    };
                LCD_Cls();
                LCD_Off();
            }
        else
            {
                G_Draw();
                LCD_Cls();
                LCD_Off();
            };
        flag_abort = 0;

Сейчас вроде всё нормально.
Dron_Gus
А как Вы симулируете исключительные ситуации?
aaarrr
Цитата(Dron_Gus @ Oct 8 2007, 21:51) *
А как Вы симулируете исключительные ситуации?

Проще всего проверить в реальном устройстве - например, запись по невыровненному адресу вызовет DAbort в контроллерах Atmel и NXP. В симуляторе можно прогнать Undef, все остальные исключения отличаются лишь способами получения адреса ошибки и выхода, который зачастую бывает не нужен.
Paramon
Цитата(Dron_Gus @ Oct 8 2007, 21:51) *
А как Вы симулируете исключительные ситуации?


Использую готовое устройство. Но отладку производил на симуляторе KEILа.
В готовом устр-ве ещё установил счётчики событи при анализе в момент перезапуска.

Забыл сказать по поводу стека. Там похоже всё нормально, т.к. при малом задании устройство работает вообще без сбоев.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.