Discussion Forum

8031 POST (power on self test)

Next Thread | Thread List | Previous Thread Start a Thread | Settings

DetailsMessage
Read-Only
Author
Robert Berkey
Posted
11-Feb-2002 19:17 GMT
Toolset
C51
New! 8031 POST (power on self test)
I'm not having much success in finding an 8031 POST (power on self test) online. I'd be especially interested in tests from a microprocessor manufacturer.

For example, are there published tests to verify that the 128 bytes of indirect memory are reliable? Are there simple tests for the SFRs?

Thanks for your comments.

Robert Berkey
Read-Only
Author
Graham Cole
Posted
12-Feb-2002 10:01 GMT
Toolset
C51
New! RE: 8031 POST (power on self test)
You may find the following test useful. However, it is not in Keil assembler and will need some adapting.

The destructive RAM test tests all 256 bytes of the internal RAM - using only registers to control the loops and save the results. Note that the Stack Pointer is used to address memory - this is the only way to avoid using R0/R1.

The test is based on an artical for which I cannot now find the reference. The test makes a through check of individual memory cells, detects all but the most exotic addressing faults and will detect most instances where the state of a bit is affected by the state of nearby bits.

Note that this routine necessarily trashes the stack. The software invoking the destructive RAM test has to jump to this routine and provide a label to jump back to. The invoking software must then set up the stack etc.

The watchdog refered to in this routine is bespoke hardware.
;
;	Destructive Ram Test
;
;	NB. Number of bytes of memory to be tested must be 2^n.
;
							;
sub_cycles		REG	RCAP2L			;
sub_cycle_counter	REG	RCAP2H			;
test_pattern		REG	B			;
pass			REG	F0			;
test_failed		REG	F1			;
							;
destructive_ram_test:					;BEGIN
							;
		CLR	test_failed			;    test_failed := false.
							;
		MOV	DPTR,#drt_pattern_table		;
1$:							;    FOR table_pointer := 0 TO 23 D0
		SETB	pass				;
2$:							;        FOR pass := write TO read DO
							;
		CLR	A				;
		MOVC	A,@A+DPTR			;
		MOV	test_pattern,A			;            Read test_pattern.
		MOV	A,#01				;
		MOVC	A,@A+DPTR			;
		MOV	sub_cycles,A			;            Read sub_cycles.
							;
		MOV	SP,#00H				;            Zero the memory pointer.
							;
3$:							;            FOR memory_pointer := 0 TO 255 DO
							;
		MOV	sub_cycle_counter,sub_cycles	;
4$:							;                FOR sub_cycle_counter := sub_cycles TO 1 DO
		JNB	pass,5$				;                    IF pass = write THEN
							;
		DEC	SP				;
		PUSH	test_pattern			;                        Write test_pattern to memory.
		SJMP	8$				;
5$:							;                    ELSE
		POP	Acc				;                        Read memory.
		INC	SP				;
		CJNE	A,test_pattern,6$		;                        IF test_pattern = @memory_pointer THEN
		SJMP	7$				;                            OK
6$:							;                        ELSE
		SETB	test_failed			;                            Test failed.
7$:							;                        ENDIF
8$:							;                    ENDIF
		INC	SP				;                    Increment memory_pointer.
							;
		MOV	A,SP				;
		ANL	A,#00011111B			;
		JNZ	9$				;                    IF memory_pointer MOD 32 = 0 THEN
							;
		CPL	reset_watchdog 			;                        Toggle the watchdog with period of about 1 ms.
							;
9$:							;                    ENDIF
							;
		DJNZ	sub_cycle_counter,4$		;                ENDFOR
		XRL	test_pattern,#11111111B		;                Invert the test pattern.
		MOV	A,SP				;
		CJNE	A,#00,3$			;            ENDFOR
		JBC	pass,2$				;        ENDFOR
		INC	DPTR				;
		INC	DPTR				;        Increment the table pointer.
		MOV	A,DPL				;
		CJNE	A,#LOW( drt_pattern_table_end ),1$
		MOV	A,DPH				;
		CJNE	A,#HIGH( drt_pattern_table_end ),1$
							;    ENDFOR
		MOV	C,test_failed			;
		MOV	self_test_alarm,C		;    self_test_alarm := result of test.
							;
		LJMP	drt_return			;END
							;
drt_pattern_table:					;
			DB	10101010B,1		;00
			DB	01010101B,1		;01
			DB	11001100B,1		;02
			DB	00110011B,1		;03
			DB	11110000B,1		;04
			DB	00001111B,1		;05
			DB	11111111B,1		;06
			DB	00000000B,1		;07
			DB	11111111B,2		;08
			DB	00000000B,2		;09
			DB	11111111B,4		;10
			DB	00000000B,4		;11
			DB	11111111B,8		;12
			DB	00000000B,8		;13
			DB	11111111B,16		;14
			DB	00000000B,16		;15
			DB	11111111B,32		;16
			DB	00000000B,32		;17
			DB	11111111B,64		;18
			DB	00000000B,64		;19
			DB	11111111B,128		;20
			DB	00000000B,128		;21
			DB	11111111B,.LOW.(256)	;22
			DB	00000000B,.LOW.(256)	;23
drt_pattern_table_end	EQU	$			;
							;
;
Read-Only
Author
Robert Berkey
Posted
13-Feb-2002 18:09 GMT
Toolset
C51
New! RE: 8031 POST (power on self test)
To: Graham Cole

I converted your code to 8031 and Keil. The 8031 only has 128 bytes of
indirect RAM and lacks some of the registers used in your processor. I also
had to substitute for the local labels. I do wish that Keil would add local
labels to their assembler.

The Keil simulator indicates that this test runs in 80 milliseconds and uses
123 bytes of code space. Our watchdog waits 1.5 seconds before it gets
alarmed, so I've removed that feature.

;
;     Destructive 8031 Indirect-RAM Test
;        Public Domain 2002
;
;       Tests 080H bytes Using Borer Test
;
sub_cycles              EQU     TH0     ; reuse timer 0 register
sub_cycle_counter       EQU     TL0     ; reuse timer 0 register
test_pattern            EQU     B       ; register
pass                    EQU     F0      ; bit, set=read clear=write
test_failed             EQU     PSW.1   ; bit
        BSEG
SELF_TEST_ALARM:        DBIT    1
        CSEG
                                        ;
DESTRUCTIVE_IDATA_TEST:
;       CLR     TR0                     ; assumes timer 0 is stopped
                                        ;BEGIN
        CLR     test_failed             ;  test_failed := false.
                                        ;
        MOV     DPTR,#dit_pattern_table ;
_1:                                     ;  FOR table_pointer := 0 TO 10 D0
        SETB    pass                    ;
_2:                                     ;    FOR pass := write TO read DO
                                        ;
        CLR     A                       ;
        MOVC    A,@A+DPTR               ;
        MOV     test_pattern,A          ;      Read test_pattern.
        MOV     A,#01                   ;
        MOVC    A,@A+DPTR               ;
        MOV     sub_cycles,A            ;      Read sub_cycles.
                                        ;
        MOV     SP,#00H                 ;      Zero the memory pointer.
                                        ;
_3:                                     ;      FOR memory_pointer := 0 TO 07FH DO
                                        ;
        MOV     sub_cycle_counter,sub_cycles
_4:                                     ;        FOR sub_cycle_counter := sub_cycles TO 1 DO
        JNB     pass,_5                 ;          IF pass = write THEN
                                        ;
        DEC     SP                      ;
        PUSH    test_pattern            ;            Write test_pattern to memory.
        SJMP    _8                      ;
_5:                                     ;          ELSE
        POP     Acc                     ;            Read memory.
        INC     SP                      ;
        CJNE    A,test_pattern,_6       ;            IF test_pattern = @memory_pointer THEN
        SJMP    _7                      ;                            OK
_6:                                     ;            ELSE
        SETB    test_failed             ;                            Test failed.
_7:                                     ;            ENDIF
_8:                                     ;          ENDIF
        INC     SP                      ;          Increment memory_pointer.
                                        ;
        DJNZ    sub_cycle_counter,_4    ;        ENDFOR
        XRL     test_pattern,#11111111B ;        Invert the test pattern.
        MOV     A,SP                    ;
        CJNE    A,#080H,_3              ;      ENDFOR
        JBC     pass,_2                 ;    ENDFOR
        INC     DPTR                    ;
        INC     DPTR                    ;    Increment the table pointer.
        MOV     A,DPL                   ;
        CJNE    A,#LOW( dit_pattern_table_end ),_1
        MOV     A,DPH                   ;
        CJNE    A,#HIGH( dit_pattern_table_end ),_1
                                        ;  ENDFOR
        MOV     C,test_failed           ;
        MOV     self_test_alarm,C       ;  self_test_alarm := result of test.
                                        ;
DIT_RETURN:
        LJMP    RESTORE_IDATA           ;END
RESTORE_IDATA:
        JMP     $                       ;

dit_pattern_table:                      ;
        DB      10101010B,1             ;00
        DB      01010101B,1             ;00
        DB      11001100B,1             ;01
        DB      00110011B,1             ;01
        DB      11110000B,1             ;02
        DB      00001111B,1             ;02
        DB      11111111B,1             ;03
        DB      00000000B,1             ;03
        DB      11111111B,2             ;04
        DB      00000000B,2             ;04
        DB      11111111B,4             ;05
        DB      00000000B,4             ;05
        DB      11111111B,8             ;06
        DB      00000000B,8             ;06
        DB      11111111B,16            ;07
        DB      00000000B,16            ;07
        DB      11111111B,32            ;08
        DB      00000000B,32            ;08
        DB      11111111B,64            ;09
        DB      00000000B,64            ;09
        DB      11111111B,128           ;10
        DB      00000000B,128           ;10
;       DB      11111111B,LOW(256)      ;11   for newer processors with 256
;                                               bytes of indirect ram
;       DB      00000000B,LOW(256)      ;11
dit_pattern_table_end   EQU     $       ;
                                        ;
END

The destructive RAM test tests all 128 bytes of the internal RAM - using only
registers to control the loops and save the results.  Note that the Stack
Pointer is used to address memory - this is the only way to avoid using
R0/R1.

The test makes a through check of individual memory cells, detects all but
the most exotic addressing faults and will detect most instances where the
state of a bit is affected by the state of nearby bits.

Note that this routine necessarily trashes the stack.  The software invoking
the destructive RAM test has to jump to this routine and provide a label to
jump back to.  The invoking software must then set up the stack etc.

Reference:

Borer, A.J.: Total Memory Test, Microprocessors and Microsystems, May 1980.

Also of interest is:

McEliece, R.J.: The Reliability of Computer Memories, Scientific American,
January 1985.
Read-Only
Author
Robert Berkey
Posted
13-Feb-2002 18:13 GMT
Toolset
C51
New! RE: 8031 POST (power on self test)
I like the idea of being very thorough with this testing.

I suppose that for the SFR's, I could go through each of them and wiggle
each bit.

I wonder why such routines aren't published, though. It seems like every
microprocessor would need one. I remember that when the IBM PC was first introduced, I felt that the addition of a POST in their BIOS was an advance in microcomputer technology.

That leads to the question, "has your test ever reported a bad processor?"
Read-Only
Author
tom mazowiesky
Posted
13-Feb-2002 19:38 GMT
Toolset
C51
New! RE: 8031 POST (power on self test)
Back in the late 70's and early 80's it was a requirement for any kind of Military hardware that used micro's to perform a complete self test, not just of the RAM and EPROM but of the processor as well. Chip vendors supplied the micro test as part of a requested doc package for military users. The Intel 8080 version performed a test on all machine codes - if it passed you exited only one way, otherwise you wound up in various end points.

I think as time went on, chip processes became so much better that this kind of test fell by the wayside ( I don't know if this is still a requirement by the military). For the 8051 and its variants it might not be worth it except for cases where life and limb is at stake (medical equipment and the like). There have been some concerns expressed about the latest technology parts, because the material thickness and volume are so small that stray alpha particles are becoming dangerous again.

You might want to visit http://www.embedded.com for a recent article on this subject.

Read-Only
Author
Graham Cole
Posted
14-Feb-2002 13:26 GMT
Toolset
C51
New! RE: 8031 POST (power on self test)
The destructive RAM test has discovered problems. 80C52 software that includes the Borer RAM test and a number of other self-test features has been incorporated into some 200,000 production units.

The production contractors are not too analytical about why a unit fails, so I don't have exact figues, but it is clear that processor failures are rare. Probably between one in 1,000 and and one in 10,000.

The self-test features generally ensure that units with faulty processors do not leave the factory. Only one service return indicating a failure to pass the destructive RAM test has ever been brought to my attention.

The software includes other self-test features inlcuding testing SFRs on the lines that you suggest. I am not aware of this test ever detecting a fault. However, I think it is still worth doing as the effects of such faults may be very subtle.

Although faults have been rare, it is important the remember that components are changing all the time. Your software may be put into processors made by different companies at different factories and even into processors that have a completely different construction. As fabrication techniques change, failure rates could change suddenly without warning.

I feel that all embeded systems should include a power-on RAM and ROM test as a minimum and that a watchdog of some sort is a very good idea.

Depending on the application, you might also consider a continuous ROM test and a non-destructive RAM test.
Read-Only
Author
Graham Cole
Posted
12-Feb-2002 11:16 GMT
Toolset
C51
New! RE: 8031 POST (power on self test)
I found that reference:

Borer, A.J.: Total Memory Test, Microprocessors and Microsystems, May 1980.

Also of interest is:

McEliece, R.J.: The Reliability of Computer Memories, Scientific American, January 1985.

I have written an explanation of how the Borer test works. If you post your e-mail address, I will send you a copy.
Read-Only
Author
Robert Berkey
Posted
14-Feb-2002 20:16 GMT
Toolset
C51
New! RE: 8031 POST (power on self test)
>If you post your e-mail address, I will send you a copy.

Thanks, my email address is:

Berkey01
<at-sign>
myrealbox
<period>
com

I hope that's not confusing, but I don't want automated email sniffers seeing it.
Read-Only
Author
Jon Ward
Posted
12-Feb-2002 19:21 GMT
Toolset
C51
New! RE: 8031 POST (power on self test)
You may want to check the following knowledgebase article:

http://www.keil.com/support/docs/2156.htm

It should provide a few hints for how to get started.

Jon
Read-Only
Author
erik malund
Posted
13-Feb-2002 21:16 GMT
Toolset
C51
New! RE: 8031 POST (power on self test)
But note that Jack talks about multi GHz chips at submicron size, fortunately we are not there yet with the '51s

Erik

Next Thread | Thread List | Previous Thread Start a Thread | Settings