IAP code for Freescale platforms
Dependents: 18_PT1000 RDA5807M-FM-Radio flashaccess TF_conops_BAEFLAGIMAN ... more
K22F
Due to the default clock setup of the K22F, flash write access is there disabled. In the future I might add a workaround, but for now see: https://developer.mbed.org/questions/52738/Error-with-FreescaleIAP-code-with-K22F/
Be careful with which flash you are erasing/overwriting!
Example code:
#include "mbed.h" #include "FreescaleIAP.h" int main() { int address = flash_size() - SECTOR_SIZE; //Write in last sector int *data = (int*)address; printf("Starting\r\n"); erase_sector(address); int numbers[10] = {0, 1, 10, 100, 1000, 10000, 1000000, 10000000, 100000000, 1000000000}; program_flash(address, (char*)&numbers, 40); //10 integers of 4 bytes each: 40 bytes length printf("Resulting flash: \r\n"); for (int i = 0; i<10; i++) printf("%d\r\n", data[i]); printf("Done\r\n\n"); while (true) { } }
For an example on using this for a bootloader, check out: http://developer.mbed.org/users/Sissors/code/Bootloader_K64F/
If you want to permanently store a variable between resets, you can run into the problem of how to define the value the first time. Since the mbed drag-and-drop loader seems to issue a full-chip erase, you cannot first upload a program to set the initial value, and then switch to the regular program: The full-chip erase will also erase your initial value. One option is to use the same statements as used in the bootloader example to force it to program initial values for your variables on your memory address. This should work fine, however it is target dependent where you want to program it (generally your last sector), so it makes for a less nice example program. You can also try to detect if it is the initial run by looking at the state of the flash, by default this is all '1's. The following example does this:
#include "mbed.h" #include "FreescaleIAP.h" int main() { int address = flash_size() - SECTOR_SIZE; //Write in last sector int *data = (int*)address; //By default flash is initialized at 0xFF, this is signed -1, so now we know //the program runs for the first time. You of course need to make sure your program //never writes -1 to this variable if you use this method //Alternatively you could also do the same, but with a seperate "initial run" variable added, //so your other variables can take any value if (data[0] == -1) { printf("Initial run\r\n"); printf("Writing 42 and 42\r\n"); erase_sector(address); int newvalues[2] = {42, 42}; program_flash(address,(char*) newvalues, 8); //Two integers of 4 bytes = 8 bytes while(1); } printf("Current = %d and %d, new is %d and %d\r\n", data[0], data[1], data[0]+1, data[1]-1); int newvalues[2] = {data[0]+1, data[1]-1}; erase_sector(address); program_flash(address, (char*) newvalues, 8); while(1); }
FreescaleIAP.h@6:186db0d96fcf, 2014-09-30 (annotated)
- Committer:
- nyatla
- Date:
- Tue Sep 30 14:00:43 2014 +0000
- Revision:
- 6:186db0d96fcf
- Parent:
- 5:a5cfedcf55d6
- Child:
- 7:474d231b2f35
Modification of FRDM-K64F ; add ProgramPhrase FCMD;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Sissors | 0:8eef5a3e83ca | 1 | #ifndef FREESCALEIAP_H |
Sissors | 0:8eef5a3e83ca | 2 | #define FREESCALEIAP_H |
Sissors | 0:8eef5a3e83ca | 3 | |
Sissors | 0:8eef5a3e83ca | 4 | #include "mbed.h" |
Sissors | 0:8eef5a3e83ca | 5 | |
Sissors | 5:a5cfedcf55d6 | 6 | #if defined(TARGET_KLXX) |
Sissors | 2:70ade1638644 | 7 | #define SECTOR_SIZE 1024 |
Sissors | 5:a5cfedcf55d6 | 8 | #elif defined(TARGET_K20D5M) | (TARGET_K22F) |
Sissors | 2:70ade1638644 | 9 | #define SECTOR_SIZE 2048 |
Sissors | 5:a5cfedcf55d6 | 10 | #elif defined(TARGET_K64F) |
Sissors | 2:70ade1638644 | 11 | #define SECTOR_SIZE 4096 |
Sissors | 2:70ade1638644 | 12 | #else |
Sissors | 5:a5cfedcf55d6 | 13 | #warning FreescaleIAP unknown target, using default 1024B |
Sissors | 2:70ade1638644 | 14 | #define SECTOR_SIZE 1024 |
Sissors | 2:70ade1638644 | 15 | #endif |
Sissors | 0:8eef5a3e83ca | 16 | |
Sissors | 0:8eef5a3e83ca | 17 | enum IAPCode { |
Sissors | 0:8eef5a3e83ca | 18 | BoundaryError = -99, //Commands may not span several sectors |
Sissors | 0:8eef5a3e83ca | 19 | AlignError, //Data must be aligned on longword (two LSBs zero) |
Sissors | 0:8eef5a3e83ca | 20 | ProtectionError, //Flash sector is protected |
Sissors | 0:8eef5a3e83ca | 21 | AccessError, //Something went wrong |
Sissors | 0:8eef5a3e83ca | 22 | CollisionError, //During writing something tried to flash which was written to |
Sissors | 0:8eef5a3e83ca | 23 | LengthError, //The length must be multiples of 4 |
Sissors | 1:702fd2d53c17 | 24 | RuntimeError, |
Sissors | 1:702fd2d53c17 | 25 | EraseError, //The flash was not erased before writing to it |
Sissors | 0:8eef5a3e83ca | 26 | Success = 0 |
Sissors | 0:8eef5a3e83ca | 27 | }; |
Sissors | 0:8eef5a3e83ca | 28 | |
Sissors | 2:70ade1638644 | 29 | /** Erase a flash sector |
Sissors | 2:70ade1638644 | 30 | * |
Sissors | 2:70ade1638644 | 31 | * The size erased depends on the used device |
Sissors | 2:70ade1638644 | 32 | * |
Sissors | 2:70ade1638644 | 33 | * @param address address in the sector which needs to be erased |
Sissors | 2:70ade1638644 | 34 | * @param return Success if no errors were encountered, otherwise one of the error states |
Sissors | 2:70ade1638644 | 35 | */ |
Sissors | 0:8eef5a3e83ca | 36 | IAPCode erase_sector(int address); |
Sissors | 2:70ade1638644 | 37 | |
Sissors | 2:70ade1638644 | 38 | /** Program flash |
Sissors | 2:70ade1638644 | 39 | * |
Sissors | 2:70ade1638644 | 40 | * Before programming the used area needs to be erased. The erase state is checked |
Sissors | 2:70ade1638644 | 41 | * before programming, and will return an error if not erased. |
Sissors | 2:70ade1638644 | 42 | * |
Sissors | 2:70ade1638644 | 43 | * @param address starting address where the data needs to be programmed (must be longword alligned: two LSBs must be zero) |
Sissors | 2:70ade1638644 | 44 | * @param data pointer to array with the data to program |
nyatla | 6:186db0d96fcf | 45 | * @param length number of bytes to program (must be a multiple of 4. must be a multiple of 8 when K64F) |
Sissors | 2:70ade1638644 | 46 | * @param return Success if no errors were encountered, otherwise one of the error states |
Sissors | 2:70ade1638644 | 47 | */ |
Sissors | 1:702fd2d53c17 | 48 | IAPCode program_flash(int address, char *data, unsigned int length); |
Sissors | 0:8eef5a3e83ca | 49 | |
Sissors | 2:70ade1638644 | 50 | /** |
Sissors | 2:70ade1638644 | 51 | * Returns size of flash memory |
Sissors | 2:70ade1638644 | 52 | * |
Sissors | 2:70ade1638644 | 53 | * This is the first address which is not flash |
Sissors | 2:70ade1638644 | 54 | * |
Sissors | 2:70ade1638644 | 55 | * @param return length of flash memory in bytes |
Sissors | 2:70ade1638644 | 56 | */ |
Sissors | 2:70ade1638644 | 57 | uint32_t flash_size(void); |
Sissors | 2:70ade1638644 | 58 | |
Sissors | 0:8eef5a3e83ca | 59 | #endif |