2009-10-06 1 views
1

Мне нужно включить аппаратное сторожевое устройство встроенного компьютера msm800.Включение аппаратного сторожевого таймера в msm800

К сожалению, я почти ничего не знаю об использовании языков ассемблера.

Это то, что документация для устройства говорит:

Функция: WATCHDOG

Номер: EBh

Описание:

Включает стробы и отключает Watchdog. После включения питания сторожевой таймер всегда отключен. После того, как сторожевого была включена, пользовательское приложение должен выполнить строб, по крайней мере каждый 800ms, в противном случае сторожевой выполняет аппаратный сброс

Входные значения:

AH: 78h функция DLAG INT15

AL: EBh запрос Функция

BL: 00h Отключить

BL: 01h Включить

BL: FFh Строб

01h-FFh Enable Watchdog/Retrigger

BH: 00h = BL -> число сек./01h = BL -> количество мин.

значение Выход: AL таймер 01ч Watchdog тайм-аут произошел

И это то, что я придумал:

#include <stdio.h> 

int main() { 

    asm(
     "movb  $0x78,  %ah\n\t" 
     "movb  $0xEB,  %al\n\t" 
     "movb  $0x01,  %bl\n\t" 
     "movb  $0x00,  %bh\n\t" 
     "int  $0x80" 
    ); 

    return 0; 
} 

Это неправильно, хотя - бег результатов в сбоем сегментации, у меня есть правильные значения в регистрах, но не знают, как реально запустить эту функцию.

Любая помощь?

+0

Я никогда не работал с msm800 (я даже не знал, что он существует) , но можете ли вы написать команды asm в строке? В системах, которые я использовал asm, мне пришлось писать его напрямую, а не в строке. – nuriaion

+0

Я тоже никогда не видел инструкции, написанные таким образом. – blak3r

ответ

1

Если вы используете gcc, вам нужно указать, какие регистры сбиты.

asm(
    "movb   $0x78,   %ah\n\t" 
    "movb   $0xEB,   %al\n\t" 
    "movb   $0x01,   %bl\n\t" 
    "movb   $0x00,   %bh\n\t" 
    "int   $0x80" 
    : 
    : 
    : "ax", "bx", //... and what else may be clobbered by the int $80 
); 
+0

Невозможно скомпилировать его таким образом, что делает «:» делать в gcc asm? – zbigh

+0

Он отделяет список, если выходные, входные и сбитые регистры. Если вы не используете GCC, точка, вероятно, спорный, потому что ваш компилятор будет очень вероятно, сохранить все регистры каждый раз, когда вы используете «ассемблер». – hirschhornsalz

0

Обычно ваш поставщик компилятора предоставляет способ настройки периферийных устройств CPU в коде C. Я бы попытался найти ваше руководство для «WDT» или «Watchdog» и посмотреть, не предоставляет ли он некоторые удобные методы.

0

Проблема, с которой вы сталкиваетесь, может быть связана с переключением контекста. Вы передаете управление через команду прерывания, что означает, что часть переключения контекста должна обрабатываться вашим кодом. Короче говоря, вам нужно написать процедуру обслуживания прерываний и вызвать ее из вашей основной функции.

Процедура должна сохранять состояние процессора до того, как он фактически прервет процессор.Это делается потому, что обработка прерываний может изменять содержимое регистров.

При выходе программа должна восстановить состояние процессора. Процедура обслуживания прерываний не будет принимать никаких аргументов и не будет возвращать какое-либо значение.

0

Вот код, у меня есть для установки конкретного адреса или регистрации в C (работает только с GCC):

#define MICRO_PORT (*(vuint8 *)(0x40100000)) 

Это определяет 8-битный порт или регистрации по адресу 0x40100000, можно прочитать/записать в виде любой другой переменной:

MICRO_PORT = 0xFF; 
someval = MICRO_PORT; 
0

Я нашел это в документации:

функция сторожевого интегрирована в функции INT15

Так что вам кажется, что вы должны называть int 0x15, а не 0x80. 0x80 - это системный вызов Linux.

также:

Есть некоторые примеры программирования доступны: Продукт CD-Rom или клиент область загрузки: \ Tools \ SM855 \ int15dl \ ...

Вы смотрели на этих примерах?