PIC32MX hanging when jumping to code in program flash? - Page 1
Forum section: electronics / beginners

author: ethereal
author_rank: Contributor
timestamp: February 02, 2016, 10:47:33 pm
content: Hi everyone,I'm having a spot of trouble whilst writing a bootloader for a PIC32MX250F128B. (I decided to embark on this quest in order to familiarize myself with the PIC32MX architecture. Can't say it's been fun, but it certainly has been a learning experience...) I've successfully managed to get everything in my bootloader up and running, except for the functionality that lets me jump to the target code.I'll simplify the situation (it's a little bit more complicated than this, but I'm confident the rest isn't my problem right now): upon reciving a "boot" command over the UART line, I jump to the target program's entry point, currently hardcoded to the beginning of program flash (0xbd000000). This code will then set up its stack, initialize its global variables, and do all the usual program startup logic. In order to test my bootloader, though, I've stripped it down to the bare minimum: write a character out to the UART and then repeat.Here's my assembly helper function that jumps into the loaded code:Code:enter_target_code:li $t1, 0xbd000000j $t1Simple, right? Well, as soon as I try to use this, the PIC hangs. OK, maybe it's just the code I'm loading there, right? I tried the following code instead:Code:enter_target_code:la $t1, target_codej $t1target_code:addi $t0, $zero, 65li $t1, 0xbf806020sw $t0, 0($t1)la $t2, target_codej $t2This works as expected -- my terminal fills up with 'A's. I found the machine code for target_code, copied it into the flash, and then changed the jump target:Code:enter_target_code:li $t1, 0xbd000000j $t1target_code:addi $t0, $zero, 65li $t1, 0xbf806020sw $t0, 0($t1)la $t2, target_codej $t2Note that the copied code still has thelainstruction pointing towards the boot flash code, so it shouldn't stay there for more than one iteration. Still, it does nothing and hangs. I have interrupts disabled (the bootloader doesn't use any interrupt-driven code), and I have manually verified (with an external programmer) that my bootloader is doing what it claims to be doing (with respect to flash programming). I've read through the code several times to make sure nothing strange is going on, and I've been perusing the datasheets and manuals to try and figure out what's happening.Sadly, I haven't found anything yet. Does anyone have any insight to offer? Or requests for more information that might be of use?(Also, as an aside: I've been pointed towards the AN1388 bootloader from Microchip several times, and I've been looking through its source as well, but I'm unable to find anything related to this kind of problem.)Thanks!- ethereal

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: February 02, 2016, 11:11:41 pm
content: I've never found the need to resort to assembler with PIC32 bootloaders - you should be able to do it all with C, with appropriate linker file twiddling.The way mine tend to work is by the bootloader code looking at whether the reset was caused by the WDT - if so it jumps to the main app code (after checking for a valid checksum) , otherwise it enters the bootloader.Within the bootloader, the WDT is only reset if a valid command is received, so if not, it times out, causes a reset that then jumps to the main code. This ensures that the main code sees everything set up as at reset, without any changes the bootloader may have made to registers etc.The jump-to-app code is from the Microchip appnote :Code:void JumpToApp(void){void (*fptr)(void);fptr = (void (*)(void))USER_APP_RESET_ADDRESS;fptr();}

author: ethereal
author_rank: Contributor
timestamp: February 02, 2016, 11:25:12 pm
content: Quote from: mikeselectricstuff on February 02, 2016, 11:11:41 pmNow that is a clever idea. I might just steal that from you.I've changed the jump-to-loaded-code bit to use the same function pointer call as the AN1388 code, and it still produces the same result (hanging).- ethereal

author: amyk
author_rank: Super Contributor
timestamp: February 03, 2016, 03:52:15 am
content: PIC32MX is a MIPS; possibly something to do with thehttp://en.wikipedia.org/wiki/Branch_delay_slot, and whether or not the assembler is doing something sneaky with branch offsets etc.? Post the actual bytes that are written into the flash.

author: ethereal
author_rank: Contributor
timestamp: February 03, 2016, 07:00:50 am
content: Quote from: amyk on February 03, 2016, 03:52:15 amFound it. Apparently, one of the helper scripts I was using was being "helpful" and performing a transparent little/big-endian conversion behind the scenes. So when I used my external verifier to make sure the flash was programmed correctly . . . yeah. Thanks for the suggestion, this made me go through it manually. I'll keep that in mind for next time...Thanks for the help.- ethereal