|
Как это делается средствами Си или IAR C |
|
|
|
Dec 21 2006, 05:49
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
Цитата(SasaVitebsk @ Dec 21 2006, 07:24)  При программировании однокристалок иногда приходится обрабатывать глобальные ошибки. Или, к примеру, реагировать на существенное изменение конфигурации.
В этом случае самый простой а чаще и найболее надёжный способ, - это рестарт программы. Во всяком случае я пользовался таким способом под ASM и, несмотря на "некрасивость", не хочу обходится без этого и на СИ.
На Си я делаю это так: asm("jmp 0"); // Начать сначала
У меня это единственный оператор ASM на всё прогу. Может существует специальный вызов для IAR, что-то вроде __restart(); ?
И ещё один вопрос. Компилятор вопреки моему мнению скомпилировал его не в jmp. Это зачем? В бутлоадере исплользовал такое объявление функции: Код void (*start_application)( void ) = 0x0000; //pointer to application //at flash start Далее, в произвольном месте программы, мы можем ее вызвать и соответственно перейти по адресу 0. З.Ы. Работает. Использую компилятор GCC.
--------------------
Выбор.
|
|
|
|
|
Dec 21 2006, 08:11
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(SasaVitebsk @ Dec 21 2006, 05:24)  При программировании однокристалок иногда приходится обрабатывать глобальные ошибки. Или, к примеру, реагировать на существенное изменение конфигурации.
В этом случае самый простой а чаще и найболее надёжный способ, - это рестарт программы. Во всяком случае я пользовался таким способом под ASM и, несмотря на "некрасивость", не хочу обходится без этого и на СИ.
На Си я делаю это так: asm("jmp 0"); // Начать сначала
У меня это единственный оператор ASM на всё прогу. Может существует специальный вызов для IAR, что-то вроде __restart(); ?
И ещё один вопрос. Компилятор вопреки моему мнению скомпилировал его не в jmp. Это зачем? Переносимого в рамках языка способа нет. Все очень зависит от целевого проца и кросс-компилятора. В некоторых процах есть специальные команды для глобального сброса. Сброс, также, может поддерживаться компилятором путем различного рода расширений языка. В конце концов, сбросы тоже разные бывают - "холодные", "теплые". Для "холодного" можно просто завести внешнюю ногу Reset на один из пинов МК и принудильно самого себя сбрасывать. "Теплый" сброс может быть огранизован по-разному, начиная от явного прописывания адреса перехода на вектор сброса и заканчивая сбросом средствами процессора - сторожевым таймером или специальными командами или установкой (сбросом) специальных битов в регистрах спец. функций.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Dec 22 2006, 05:19
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
Цитата(zltigo @ Dec 21 2006, 15:45)  Цитата(haker_fox @ Dec 21 2006, 04:49)  В бутлоадере исплользовал такое объявление функции: void (*start_application)( void ) = 0x0000; //pointer to application Далее, в произвольном месте программы, мы можем ее вызвать и соответственно перейти по адресу 0.
RAM зачем расходовать попусту? Сразу и пишите. (void (*)(void))(0x0000)(); Спасибо! Я не задумывался об этом. Теперь буду знать. А компилятор не оптимизирует, приведенное мной выражение?
--------------------
Выбор.
|
|
|
|
|
Dec 22 2006, 13:08
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(jorikdima @ Dec 22 2006, 11:20)  ну в данном то случае и goto() подойдет, верно? ????? О чем это ????? Не понимаю совсем. #define goto( addr ) ((void (*)(void))(addr))() Или о чем?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 22 2006, 17:37
|
Местный
  
Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219

|
Цитата(zltigo @ Dec 22 2006, 16:17)  Цитата(jorikdima @ Dec 22 2006, 14:30)  от если метку моставить туда куда идти надо (на main() например), то можно просто goto Label;
Ну-ну область видимости меток ограничена  , по понятным причинам, и за пределы функции уж точно не выпрыгните. Можно использовать функции setjmp() и longjmp().
|
|
|
|
|
Dec 22 2006, 23:01
|
Местный
  
Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219

|
Цитата(zltigo @ Dec 22 2006, 18:41)  Цитата(_Bill @ Dec 22 2006, 16:37)  Можно использовать функции setjmp() и longjmp().
Для описанного случая нельзя  setjmp() текущий pc и стек сохраняет а не устанавливает какой хочется. Я имел в виду переход между функцииями. setjmp() запоминает стек и PC точки перехода в буфере, переход в эту точку происходит путем вызова функции longjmp().
Сообщение отредактировал _Bill - Dec 22 2006, 23:02
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|