This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

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

Parents
  • 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.
    

Reply
  • 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.
    

Children
No data