We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi, I wanto to have the posibility to update the firmware in my AT89C51ED2. For that, I've done two codes, the BASIC CODE (from 0x0000 to 0x3FFF) and the EXTENDET CODE (from 0x4000 to 0xFFFF). When I want to do a firmawe update I erase only the blocks from 0x4000 to 0xFFFF, so I've always a BASIC CODE to minimal operation.
There are many difference between these codes, but one of them is how to manage the interrups. Both have the same hardware interrupt vectors but not the same interrupt routine.
For example, the BASIC CODE has in the UART interrupt this code:
void uart_interrupt(void) interrupt 4 { if(kernel_new_prog_enable == 1) { // Jump new interrupt int_uart_interrupt(); return; } if(RI == 1) { RI = 0; uart_data = SBUF; // Implementation of modbus RTU // Initiate with basetime t0_init(0xFF-((UART_TXRX_RATE*2)>>8), 0xFF-(UART_TXRX_RATE*2)); // Accepts what is comming uart_buffer[uart_index] = uart_data; uart_index++; P0_0 = ~ P0_0; } else { TI = 0; if(uart_index < uart_frame) { SBUF = uart_buffer[uart_index]; uart_index++; } else { uart_index = 0; } } } void int_uart_interrupt(void) { return; }
and the EXTENDET CODE has this interrupt function:
void uart_interrupt(void) interrupt 4 { if(RI == 1) { RI = 0; uart_data = SBUF; // Implementation of modbus RTU // Initiate with basetime t0_init(0xFF-((UART_TXRX_RATE*2)>>8), 0xFF-(UART_TXRX_RATE*2)); // Accepts what is comming uart_buffer[uart_index] = uart_data; uart_index++; P0_0 = ~ P0_0; } else { TI = 0; if(uart_index < uart_frame) { SBUF = uart_buffer[uart_index]; uart_index++; } else { uart_index = 0; } } }
Both funciton are the same, the only difference is at the beginning, the condition statement witch ask if the EXTENDET CODE exists. Offcourse if the EXTENDET CODE exists, the compiler makes a LCALL to the position of the function
int_uart_interrupt
. I've forced that this function code shoud be stored at the address 0x4023, and I've shifted the interrupt vector address in the EXTENDET CODE to 0x4000, so the UART interrupt is stored now in 0x4023. In the address 0x4023 is a LJMP to where the EXTENDET CODE UART interrupt function is. At the moment this is working well, but is there a simple way to do that? Hope you understand my English and my code, and also my explanation. Thanks. Regards, Piero Codas
Thanks a lot Thomas, finaly I've done this:
void uart_interruptEXT(void) { ((void (code *) (void)) 0x4023) (); } void uart_interruptBASE(void) { if(RI == 1) { RI = 0; uart_data = SBUF; // Implementation of modbus RTU // Initiate with basetime t0_init(0xFF-((UART_TXRX_RATE*2)>>8), 0xFF-(UART_TXRX_RATE*2)); // Accepts what is comming uart_buffer[uart_index] = uart_data; uart_index++; P0_0 = ~ P0_0; } else { TI = 0; if(uart_index < uart_frame) { SBUF = uart_buffer[uart_index]; uart_index++; } else { uart_index = 0; } } } void uart_interrupt(void) interrupt 4 { if(kernel_new_prog_enable == 1) { // Jump EXT interrupt uart_interruptEXT(); } else { // Jump BASE interrupt uart_interruptBASE(); } }
The EXT CODE starts at 0x4000 and the interrupt vector is shifted to 0x4000, so the USRT interrupt will be at 0x4023.
This is more clean and anyone can read this and minimal modification in the proyect properties has to be added (EXT CODE).
I'm insisting in that because I'm working with a team, and I'm not the only one witch is programming code.
Thanks again.
Regards,
Piero
the interrupt vector is shifted sure, you can do that; HOWEVER, I would recommend agaist it. Doing this, you get in the situation of "this will make the chip unusable (require REAL programming) if the power fails when executing the vector relocation.
For the above reason This stubborn old geezer refuse to accept ANY 'update code' where the change between run and update require more than ONE assembler instruction.
Erik
Erik, I'm not sure about wath you're saying.
There is a question before making the LJMP to the EXT vector address. This question determines if there exists the EXT CODE, else the LJMP instruction is not made.
Am I understanding wrong?
this will make the chip unusable (require REAL programming) if the power fails when executing the vector relocation
Just for aclaration, when the firmware update command is received by the secondary station, the first thing it does is a software reset. In the next startup, the EXT CODE is deshabilited, so only the BASE CODE can do the complete firmware update (erase blocks and save flash).
If a power fail occurs during a firmware update the EXT CODE is never habilited until a success firmware update is done.