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

 
 
 
Reply to this topicStart new topic
> Программный рестарт MSP430F5438A, не работает, зараза. А на F2618 "прокатывало"
k155la3
сообщение Dec 29 2016, 07:45
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 434
Регистрация: 8-03-09
Из: Днепропетровск
Пользователь №: 45 848



Как правильно сделать программный рестарт в MSP430F5438A ?
(IAR, MODEL == LARGE)

То, что работало на F2618, не прокатывает:
Код
void SystemReStart()
{
        __disable_interrupt();
    asm ("push &0xfffe");
    asm ("ret");        
};

Код этой функции размещен в "за-64К" области.

Насколько удается посмотреть на отладчике, после этой процедуры идет влет в пустую область памяти 0xFF.

Изменил на asm для 20-битного адреса (pushx.a, reta) - "рояль не заиграл".

Ресет успешно выполняется способами
- старта WDT
- "подсовывания" перехода на команду, находящуюся не в программной памяти а в области адресов регистров (fetch)

(?) что может быть не так с "прямым" вызовом push+ret ?

Go to the top of the page
 
+Quote Post
controller_m30
сообщение Dec 29 2016, 22:52
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 254
Регистрация: 24-02-09
Пользователь №: 45 309



Сам пока не пробовал делать программный reset, но вот что нашел. Сброс контроллера можно вызвать:
1. Сброс PUC происходит при записи в FCTL1 (Flash Memory Controller) пароля, отличного от 0xa5.
2. Тоже при неправильном пароле для WDTCTL, отличном от 0х5а.
3. Тоже самое для регистра PMMCTL0 (отличие пароля от 0ха5).
4. Ещё в регистре PMMCTL0 есть биты PMMSWPOR и PMMSWBOR, которые программно (если правильно понял) вызывают Reset типа POR и BOR соотв.
5. При выборке команды из адресного пространства ввода/вывода.

А чего оно не выбирает адрес сброса...
Можно после команды asm ("push &0xfffe") посмотреть отладчиком, что на вершине стека оказалось.
Или, чтоб не искать ту вершину стека, следующей-же командой снять данные с вершины в какой-нить регистр (напр. asm ("pop r4")), и посмотреть, что оказалось в регистре (PC ведь тоже регистр - R0, так что разница только в номере).

Ещё варианты без обращения в стек:
Код
mov &0xfffe,r14
mov r14,PC
;--------------
или так
mov #0xfffe,r14
mov @r14,PC
;-------------
или совсем напрямую
mov &0xfffe,PC


Сообщение отредактировал controller_m30 - Dec 29 2016, 22:52
Go to the top of the page
 
+Quote Post
amiller
сообщение Dec 30 2016, 04:06
Сообщение #3


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

Группа: Участник
Сообщений: 117
Регистрация: 20-02-14
Из: Томск
Пользователь №: 80 612



Мне кажется поиск уникальных особенностей процессора для того, чтобы вызвать фатальное исключение - тупиковый путь.
Да и зачем? Программный reset весьма редкая и не требующая скорости операция.
Это не то место, которое нужно оптимизировать.
Чем Вам не нравится сброс через таймер-сторож? Этот способ уж точно работает на всех архитектурах.
Даже там, где нет встроенного WDT, всё равно ведь придётся ставить внешний WDT, без него никак.
Я лично просто запрещаю сброс WDT и жду reset.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Dec 30 2016, 10:36
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 434
Регистрация: 8-03-09
Из: Днепропетровск
Пользователь №: 45 848



Цитата(controller_m30 @ Dec 30 2016, 01:52) *
... Сброс контроллера можно вызвать:
1. Сброс PUC происходит при записи в FCTL1 (Flash Memory Controller) пароля, отличного от 0xa5.
2. Тоже при неправильном пароле для WDTCTL, отличном от 0х5а.
3. Тоже самое для регистра PMMCTL0 (отличие пароля от 0ха5).
4. Ещё в регистре PMMCTL0 есть биты PMMSWPOR и PMMSWBOR, которые программно (если правильно понял) вызывают Reset типа POR и BOR соотв.
5. При выборке команды из адресного пространства ввода/вывода.
. . . .


По Вашей номерации на F5438A у меня отрабатывает (2) и (5).
Я остановился на (5). Выглядит ОНО так (из техасских примеров)
Код
  ((void (*)())0x350)();

Для решения задачи, думаю, следует использовать WDT в штатном режиме (2)
но вариант с (5) более "компактен".

Предложенные Вами варианты "отлова" проверю. Спасибо за инф.
По ушлости характера я не могу остваить это "простотак" sm.gif


Цитата(amiller @ Dec 30 2016, 07:06) *
(1) Мне кажется поиск уникальных особенностей процессора для того, чтобы вызвать фатальное исключение - тупиковый путь.

(2) Да и зачем? Программный reset весьма редкая и не требующая скорости операция.

(3) Чем Вам не нравится сброс через таймер-сторож? Этот способ уж точно работает на всех архитектурах.
. . . .


(1) да вроде исключение/ресет по выборке команды "неоттуда" это далеко не уникальная особенность.
Почему бы ей не воспользоваться ?

(2) тут я с Вами категорически не согласен. Как минимум 3 вызова.
- мне через внешний терминал (USART) надо (ну так получилось) рестатануть прибор.
- после перепрошивки FW требуется рестарт
- в процессе работы прибора софт начинает понимать, что "все пропало" и единственный шанс на нормализацию работы - рестарт.
(каким образом это будет сделано - не принципиально)

(3) WDT полностью устраивает.

ps - вот разбор причин рестарта для F5438A (может кому потребуется)
Код
int main(void)
{
   WDTCTL = WDTPW | WDTHOLD;

   switch ( __even_in_range( SYSRSTIV, SYSRSTIV_PMMKEY ) )
   {
       case SYSRSTIV_NONE:     ResetSign = 0x00;   break; // No Interrupt pending
       case SYSRSTIV_BOR:      ResetSign = 0x01;   break; // BOR
       case SYSRSTIV_RSTNMI:   ResetSign = 0x02;   break; // RST/NMI
       case SYSRSTIV_DOBOR:    ResetSign = 0x03;   break; // Do BOR
       case SYSRSTIV_LPM5WU:   ResetSign = 0x04;   break; // Port LPM5 Wake Up
       case SYSRSTIV_SECYV:    ResetSign = 0x05;   break; // Security violation
       case SYSRSTIV_SVSL:     ResetSign = 0x06;   break; // SVSL
       case SYSRSTIV_SVSH:     ResetSign = 0x07;   break; // SVSH
       case SYSRSTIV_SVML_OVP: ResetSign = 0x08;   break; // SVML_OVP
       case SYSRSTIV_SVMH_OVP: ResetSign = 0x09;   break; // SVMH_OVP
       case SYSRSTIV_DOPOR:    ResetSign = 0x0A;   break; // Do POR
       case SYSRSTIV_WDTTO:    ResetSign = 0x0B;   break; // WDT Time out
       case SYSRSTIV_WDTKEY:   ResetSign = 0x0C;   break; // WDTKEY violation
       case SYSRSTIV_KEYV:     ResetSign = 0x0D;   break; // Flash Key violation
       case SYSRSTIV_PLLUL:    ResetSign = 0x0E;   break; // PLL unlock
       case SYSRSTIV_PERF:     ResetSign = 0x0F;   break; // peripheral/config area fetch
       case SYSRSTIV_PMMKEY:   ResetSign = 0x10;   break; // PMMKEY violation = (0x0020u) = SYSRSTIV_PSSKEY
       default:                ResetSign = 0xFF;   break;
   }


Сообщение отредактировал k155la3 - Dec 30 2016, 10:38
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Dec 30 2016, 10:52
Сообщение #5


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 566
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



jmp reset не катит?


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
k155la3
сообщение Dec 30 2016, 12:14
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 434
Регистрация: 8-03-09
Из: Днепропетровск
Пользователь №: 45 848



Цитата(MrYuran @ Dec 30 2016, 13:52) *
jmp reset не катит?


Шас проверил еще раз (только на отладчике)

(controller_m30)
Код
или совсем напрямую
mov &0xfffe,PC

а тк код сишный
Код
   __no_operation();            << BP
   asm("mov &0xfffe,PC");

Прошагал отладчиком по asm - все ресетится.
Проверю еще на Release.

Go to the top of the page
 
+Quote Post
k155la3
сообщение Dec 30 2016, 13:29
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 434
Регистрация: 8-03-09
Из: Днепропетровск
Пользователь №: 45 848



Цитата(k155la3 @ Dec 30 2016, 15:14) *
Шас проверил еще раз (только на отладчике)

(controller_m30)
Код
или совсем напрямую
mov &0xfffe,PC

а тк код сишный
Код
   __no_operation();            << BP
   asm("mov &0xfffe,PC");

Прошагал отладчиком по asm - все ресетится.
Проверю еще на Release.


======

Исследования показали, что переход по ресету проходит (на адрес, куда указывает ресетный вектор)
и далее в начало main().

По непонятной для меня причине при таком "ресете" происходит зацикл в ф-ии инициализации UCS (тактовой системы).
При ресете через WDT, fetch или аппаратном - этот блок не циклит.

Код
  . . . .
      do
    {
              UCSCTL7 &= ~( XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);    // Clear XT2,XT1,DCO fault flags
              __no_operation();
              SFRIFG1 &= ~OFIFG;                      // Clear fault flags
        } while ( SFRIFG1 & OFIFG );                  // Test oscillator fault flag
  . . . .

(функция XT2 выводов отключена, генератор XT2 не исползуется и физически кварца нет)
Упорно устанавливается (при программном ресете по JMP) флаг XT2OFFG в UCSCTL7 и соотв-но общий флаг (SFRIFG1 & OFIFG).

Делаю для себя вывод, что для такого "рестарта" требуется начальная подготовка процессора, чтобы все прошло корректно.
(установка UCS и возможно, PMM в определенное состояние)

Итак. Ресетится проще всего:
(1) - через WDT
(2) - через peripheral/config area fetch
Шас использую (2), потом переделаю на (1)
(сугобо IMHO)


Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 29th March 2017 - 22:52
Рейтинг@Mail.ru


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