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

 
 
 
Reply to this topicStart new topic
> Перезапуск?, "Перезапуск"(в кавычках)
Paramon
сообщение Oct 4 2007, 12:22
Сообщение #1


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

Группа: Участник
Сообщений: 128
Регистрация: 5-10-06
Пользователь №: 20 997



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

Будьте добры укажите где копать. (Кроме железа - это мне известно)
Заранее благодарен!
Go to the top of the page
 
+Quote Post
WhiteWolf
сообщение Oct 5 2007, 12:23
Сообщение #2





Группа: Новичок
Сообщений: 10
Регистрация: 22-05-07
Пользователь №: 27 874



1. Проверьте размеры стеков
2. Вы его перезапускаете в режиме Data abort, а не supervisor - это нормально?
3. Может попробовать LDR PC, 0x80000
3. Попробуйте перезапуск через RSTSTA - специально для этого предназначенный регистр. Сам так сделал, но у меня почему-то похоже после этого обнуляется структура в памяти, куда я сохраняю адрес проблемной инструкции, сейчас пытаюсь с этим разобраться.
Go to the top of the page
 
+Quote Post
Paramon
сообщение Oct 8 2007, 03:47
Сообщение #3


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

Группа: Участник
Сообщений: 128
Регистрация: 5-10-06
Пользователь №: 20 997



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

Сейчас вроде всё нормально.
Go to the top of the page
 
+Quote Post
Dron_Gus
сообщение Oct 8 2007, 17:51
Сообщение #4


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

Группа: Свой
Сообщений: 1 202
Регистрация: 9-01-05
Из: Санкт-Петербург
Пользователь №: 1 861



А как Вы симулируете исключительные ситуации?


--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Oct 8 2007, 19:08
Сообщение #5


Гуру
******

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



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

Проще всего проверить в реальном устройстве - например, запись по невыровненному адресу вызовет DAbort в контроллерах Atmel и NXP. В симуляторе можно прогнать Undef, все остальные исключения отличаются лишь способами получения адреса ошибки и выхода, который зачастую бывает не нужен.
Go to the top of the page
 
+Quote Post
Paramon
сообщение Oct 9 2007, 03:31
Сообщение #6


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

Группа: Участник
Сообщений: 128
Регистрация: 5-10-06
Пользователь №: 20 997



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


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

Забыл сказать по поводу стека. Там похоже всё нормально, т.к. при малом задании устройство работает вообще без сбоев.

Сообщение отредактировал Paramon - Oct 9 2007, 03:34
Go to the top of the page
 
+Quote Post

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

 


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


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