1

I need to enable the hardware watchdog of an msm800 embedded computer.

Unfortunately I hardly know anything about using assembly languages.

This is what the documentation for the device says:

Function: WATCHDOG

Number: EBh

Description:

Enables strobes and disables the Watchdog. After power-up, the Watchdog is always disabled. Once the Watchdog has been enabled, the user application must perform a strobe at least every 800ms, otherwise the watchdog performs a hardware reset

Input values:

AH: 78h DLAG Int15 function

AL: EBh Function request

BL: 00h Disable

BL: 01h Enable

BL: FFh Strobe

01h-FFh Enable Watchdog / retrigger

BH: 00h = BL -> number of sec. / 01h = BL -> number of min.

Output value: AL 01h Watchdog timer time-out occurred

And this is what i came up with:

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

It's wrong though - running results in segmentation fault, I have the right values in registers, but don't know how to actually run the function.

Any help?

starblue
  • 55,348
  • 14
  • 97
  • 151
zbigh
  • 457
  • 2
  • 9
  • 16
  • I never worked with a msm800 (i didn't even know that it exists) but are you shure that you need to write the asm commands in a string? On the systems i used asm i had to write it directly and not in a string. – nuriaion Oct 06 '09 at 06:48
  • I too have never seen asm instructions written like this either. – blak3r Oct 08 '09 at 07:13

5 Answers5

1

If you are using gcc, you need to tell it which registers are clobbered.

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
);
Gunther Piez
  • 29,760
  • 6
  • 71
  • 103
  • Can't compile it this way, what does ":" do in gcc asm? – zbigh Oct 06 '09 at 10:43
  • It separates a list if output, input and clobbered registers. If you are not using gcc, the point is probably moot, because your compiler will very likely save all registers everytime you use "asm". – Gunther Piez Oct 07 '09 at 11:48
0

Here's the code I have for setting a specific address or register in C (works with GCC):

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

This defines an 8-bit port or register at address 0x40100000, can be read/written as any other variable:

MICRO_PORT = 0xFF;
someval = MICRO_PORT;
John U
  • 2,886
  • 3
  • 27
  • 39
0

I found this in the docs:

The watchdog feature is integrated in the INT15 function

So it seems you should call int 0x15, not 0x80. 0x80 is a Linux syscall.

Also:

There are some programming examples available: Product CD-Rom or customer download area: \tools\SM855\int15dl\…

Have you looked at those examples?

Igor Skochinsky
  • 24,629
  • 2
  • 72
  • 109
0

Usually your compiler vendor will provide a way of setting CPU peripherals in C code. I'd try searching your manual for "WDT" or "Watchdog" and see if it provides some convenience methods.

blak3r
  • 16,066
  • 16
  • 78
  • 98
0

The problem you are facing might be related to context switching. You transfer the control to via an interrupt instruction, which means the context switching part needs to be handled by your code. In short, you have to write a interrupt service routine and call it from your main function.

The routine should save the state of the processor before it actually interrupts the processor. This is done because the interrupt-processing might modify contents of registers.

On exit the routine should restore the state of the processor. The interrupt service routine will not take any argument and will not return any value.