I am attempting to write a flash loader that will boot from either the factory image or the first upgrade, depending on the value in the first word of flash.
I am using an explorerKit and 14.3.3 of xTIMEcomposer.
I have written two applications. Both factory.xe and blue.xe reads the contents of the first word, increments it and writes it back.
factory.xe writes lowest three bits to the coloured LEDs. That the coloured LEDs change on each boot confirms it is working.
blue.xe turns on the single green LED.
loader.xc should read this same value and run factory.xe if even, blue.xe if odd. i.e. it should toggle between the two on each boot. Code for this is below.
It is booting the factory image every time.
The documentation says I should use readFlashDataPage(0). Various forum posts say that this is wrong and I should used readFlashDataPage(BOOT_PARTITON_SIZE). I have tried both, with no success.
There are also posts that say readFlashDataPage() does not work in init(). I have tried it in checkCandidateImageVersion(). No success.
So...
1) What is the definitive answer to what should be passed to readFlashDataPage?
2) Does it work in init()?
3) Is there something else I am doing wrong?
4) How do I debug the flash loader? Is it possible to catch a printf from it? Some other way of debugging?
Code: Select all
#include <platform.h>
#include <xs1.h>
#include <stdio.h>
extern void * unsafe readFlashDataPage(unsigned int address);
enum interest {NOT_INTERESTED, INTERESTED};
static unsigned int selectedAddress;
static int bootCount;
#define BOOT_PARTITON_SIZE (102400)
// Call first by loader
void init()
{
printf("LOADER: Init\n");
selectedAddress = 0;
unsafe
{
bootCount = *(int *)readFlashDataPage(BOOT_PARTITON_SIZE);
}
}
// Called for each image with correct CRC for first 256 bytes
int checkCandidateImageVersion(int imageVersion)
{
return (imageVersion == (bootCount % 2)) ? INTERESTED : NOT_INTERESTED;
}
// Called for each image with overall correct CRC, for which INTERESTED was returned
void recordCandidateImage(int imageVersion, unsigned int imageAddress)
{
selectedAddress = imageAddress;
}
// Called to report which image to boot
unsigned int reportSelectedImage()
{
return selectedAddress;
}