Включение аппаратного контроля в msm800 - PullRequest
1 голос
/ 06 октября 2009

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

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

Вот что написано в документации к устройству:

Функция: WATCHDOG

Номер: EBh

Описание:

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

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

AH: 78 ч. Функция DLAG Int15

AL: EBh Запрос функции

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

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

BL: строб FFh

01h-FFh Включить Watchdog / retrigger

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

Выходное значение: AL 01h сторожевой таймер истекло время ожидания

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

#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;
}

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

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

Ответы [ 5 ]

1 голос
/ 06 октября 2009

Если вы используете 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 голосов
/ 23 июля 2012

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

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

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

Также:

Существует несколько примеров программирования: CD-ROM продукта или область загрузки клиента: \ tools \ SM855 \ int15dl \…

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

0 голосов
/ 23 июля 2012

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

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

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

MICRO_PORT = 0xFF;
someval = MICRO_PORT;
0 голосов
/ 06 ноября 2009

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

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

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

0 голосов
/ 08 октября 2009

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

...