Hi Team,
There's an issue from the customer need your help:
My program is divided into two parts, one is the bootloader, which is allocated in sector A, and the other is the APP part, which is allocated in sector H. My problem is that when I jump into the APP from the bootloader after erasing the APP, the code executed at this time should be 0xff, which should trigger an interrupt of an illegal instruction, but this interrupt function is also allocated in the erased sector. Area, I want to know how the program will be executed at this time, whether it will fall into an infinite loop or continue to execute this illegal instruction. And during this process, I discovered that the xa12 (gpio84) pin actually outputs a low-level signal. This pin is clearly used to indicate whether to jump into sci_boot. It is an input pin. My entire program does not involve this. The pin performs configuration and other operations, and there is no external signal to drive it. How does it become an output and output a low level?
my subsequent investigation found that this problem occurred when the power failed when I was halfway through upgrading the APP, and it only occurred when the power supply slowly dropped. Later, I initially located the runtime's boot28.asm and executed the 25th line of the attached code. When gpio84 outputs a low level, because I can't understand assembly, I still don't understand how it operates the gpio port. I see this This piece of code should be a code to initialize variables. I guess it is because the initialization table is damaged and it writes random data to the GPIO register. But even if he writes 0 to the GPIO register, doesn’t the register still have mode and direction settings? No Is there still register write protection? How did it finally become a low level output?
****************************************************************************
* PROCESS CINIT INITIALIZATION TABLE. TABLE IS IN PROGRAM MEMORY IN THE *
* FOLLOWING FORMAT: *
* *
* .word <length of init data in words> *
* .word or .long <address of variable to initialize> *
* .word <init data> *
* .word ... *
* *
* If the variable's address is greater than 65535 (located in 'far' *
* memory), then the address field of the cinit record will be 32-bits *
* instead of the default 16-bits. The length value is negated to tag *
* cinit records for those variables located in far memory. *
* *
* The init table is terminated with a zero length *
* *
****************************************************************************
MOVL XAR7,#cinit ; point XAR7 at start of table
CLRC TC ; reset TC bit used as far flag
B START, UNC ; jump to start processing
LOOP:
MOVB AH,#0 ; zero out upper addr bits
PREAD AL,*XAR7 ; load address of variable to be inited
ADDB XAR7,#1 ; point to initialization data
B GET_DATA,NTC ; get data if variable is not far
CLRC TC ; reset TC bit used as far flag
PREAD AH,*XAR7 ; otherwise, get hi bits of 22-bit addr
ADDB XAR7,#1
GET_DATA:
MOVL XAR6,ACC ; address
RPT AR1 ; repeat length + 1 times
|| PREAD *XAR6++,*XAR7 ; copy data from table to memory
MOVL ACC,XAR7 ; using ACC as temp, point XAR7 to
ADD ACC,AR1 ; next cinit record since PREAD
ADDB ACC,#1 ; doesn't change value of XAR7.
MOVL XAR7,ACC
START:
PREAD AL,*XAR7 ; load length
B GET_ADDR,GEQ ; a length < 0 denotes far data
NEG AL ; negate value to get real length
SETC TC ; flag that the address field is 32-bits
GET_ADDR:
MOVZ AR1,AL ; copy length value to loop register
ADDB XAR7,#1 ; point to address field
BANZ LOOP,AR1-- ; if (length-- != 0) continue
Best Regards,
Ben