Hector Martin wrote: > I'm writing an 18F2520 bootloader. I need suggestions as to going about > patching the reset vector. The patching code is PC-side, so a somewhat > complex algorithm (by PIC standards) is OK. I also have a small feature > to patch the interrupt vector in a similar way to allow for remote-reset > (using only the UART) to reprogram without hitting the reset button, so > I'll need to do the same with the interrupt vector (this is an optional > setting). The bootloader sits at the end of Flash memory, and I have a > 64 byte block available for duplicating the original vectors and other > information (I need one byte of this block, at least, for settings). What I do looks like this (inside the PIC, nothing PC-side): - The bootloader owns the first 8 bytes (everything between the reset vector and the first interrupt vector). The rest of the bootloader sits at the top of memory. - When receiving a hex file, the bootloader stores addresses 0 to 7 of the application code into an area that it controls, ie. not into their original locations. - The bootloader doesn't use interrupts, so it doesn't have to do anything special with them; the original application code gets written to anything between address 8 and the start address of the bootloader area. The bootloader also doesn't do anything while the application is running; it's only active at boot. - Because it owns the reset vector, the bootloader gets control at reset. If nothing to do, or at the end of a programming run, it passes control to the area with the first 8 application bytes, which usually contains a jump to the start of the application code. If it doesn't (which in my case is very rare, because so far I've always had an interrupt), there's a "goto 8" at the end of these 8 bytes that does that. > No matter what I try, there will always be a way of generating an > incompatible reset vector, but I want something that works well with > most compilers and isn't overly complex to implement The one thing that wouldn't work with my scheme is if there is a jump to one of the first 8 bytes in the application (except 0). But I think this is quite rare. > What are the typical reset and interrupt vectors produced by C18? Does it > always use a goto (easy) or branch (not so easy), does it try to squeeze > code into the vectors (very annoying), does it just clobber the > interrupt vector when no interrupts are in use (bad for the extra > feature)? What about other compilers? Hi-Tech puts some basic context saving code at the interrupt vectors, followed by a goto. If no interrupt functions are defined, it doesn't generate any interrupt vector code. The goto that is at the reset vector is preceded by a nop in some cases (seems to be required by some erratas). > For reference, the interrupt hijack function works like this: if the user > code doesn't use the UART, it can request the bootloader leave > interrupts enabled and hijack the low vector, and leave the UART > enabled. The vector in the bootloader code checks for RCIF and receives > a character. If the character looks like a bootloader init sequence, it > resets the PIC. Otherwise, it restores registers and jumps back to the > user vector (it uses a couple hacks to avoid the usage of any RAM at > all). This looks like it might complicate things. Do you really have to redirect the interrupts? Isn't it enough to check at boot? Anyway, if you need to do this, maybe something similar as what I'm doing with the reset vector works for you. Just extend it to cover the interrupt vectors. Gerhard -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist