How to overcome read while write violation caused while erasing and programming the flash?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to overcome read while write violation caused while erasing and programming the flash?

978 Views
jananisubraveti
Contributor II

I am doing a bootloader project on KEA128RM and wrote a startup code in C that will run in prior to main. Next step is to erase a sector of flash and write into the flash. In doing so, I am unable to erase and write into it since reading a flash sector while erasing it or programming it is causing read while write violations. Here is my code and should I do relocation of vector table from flash to RAM inorder to overcome this violation?

/*
* startup.c
*
* Created on: 28.05.2018

*/

// very simple startup code with definition of handlers

// location of these variables is defined in linker script
#include "main.h"

extern unsigned __data_load;

extern unsigned _sdata;
extern unsigned _edata;

extern unsigned __START_BSS;
extern unsigned __END_BSS;

extern unsigned __init_array_start;
extern unsigned __init_array_end;

extern unsigned __fini_array_start;
extern unsigned __fini_array_end;

// main application
extern void __init_hardware(void);

void copy_data() {
unsigned *src = &__data_load;
unsigned *dst = &_sdata;
while (dst < &_edata) {
*dst++ = *src++;
}
}

void zero_bss() {
unsigned *dst = &__START_BSS;
while (dst < &__END_BSS) {
*dst++ = 0;
}
}


void call_init_array() {
unsigned *tbl = &__init_array_start;
while (tbl < &__init_array_end) {
((void (*)())*tbl++)();
}
}

void call_fini_array() {
unsigned *tbl = &__fini_array_start;
while (tbl < &__fini_array_end) {
((void (*)())*tbl++)();
}
}

// reset handler
void RESET_handler() {
copy_data();
zero_bss();
call_init_array();
// run application
__init_hardware();
// call destructors for static instances
call_fini_array();
// stop
while (1);
}

Here is my program to erase and write into flash in C

How can I overcome the problem of read while write violation?

/*
* eraseWrite.c
*
* Created on: 07.06.2018

*/

/**eraseWrite.c file **/
#include "eraseWrite.h"

void flashClkInit()
{
FTMRE_FCLKDIV = 0x00;
}

int eraseSector(int address) {
/* Wait until the command complete instruction is cleared and indicate that FCCOB registers are available i.e., CCIF (Command Complete Interrupt Flag) */

while(((FTMRE_FSTAT)&(1UL << 7))==0);

/*Clear any previous errors from the last operation i.e., clear ACCERR and FPVIOL bits in FSTAT register*/

//if(!((FTMRE_FSTAT)==0x80))
//{
FTMRE_FSTAT = 0x30;
//}

FTMRE_FPROT = FTMRE_FPROT & 0x64;

/*Write index to specify the command code to be loaded*/
FTMRE_FCCOBIX = 0x00;
/*Write command code for erasing a sector and memory address bits[23:16]*/
FTMRE_FCCOBHI = 0x0A;
/*Write memory address bits[23:16]*/
FTMRE_FCCOBLO = address>>16;

/*Write index to specify the lower byte memory address bits[15:0] to be loaded*/
FTMRE_FCCOBIX = 0x01;
/* Write the lower byte memory address bits[15:0]*/
FTMRE_FCCOBLO = address;
FTMRE_FCCOBHI = address >> 8;


/*Writing a 1 to the bit 7 of FSTAT register indicates that a flash command has completed*/

FTMRE_FSTAT = 0x80;

/*Wait for command completion*/

//while(((FTMRE_FSTAT)&(1UL << 7))==0x00);
while(!((FTMRE_FSTAT)&(1UL << 7)));
return 0;
}


int eraseVerifySector(int address) {
/* Wait until the command complete instruction is cleared and indicate that FCCOB registers are available i.e., CCIF (Command Complete Interrupt Flag) */

while(((FTMRE_FSTAT)&(1UL << 7))==0);

/*Write index to specify the command code to be loaded*/
FTMRE_FCCOBIX = 0x0;
/*Write command code for erasing a sector and memory address bits[23:16]*/
FTMRE_FCCOBHI = 0x03;
/*Write memory address bits[23:16]*/
FTMRE_FCCOBLO = address>>16;

/*Write index to specify the lower byte memory address bits[15:0] to be loaded*/
FTMRE_FCCOBIX = 0x01;
/* Write the lower byte memory address bits[15:0]*/
FTMRE_FCCOBLO = address;
FTMRE_FCCOBHI = address >> 8;

/*Writing a 1 to the bit 7 of FSTAT register indicates that a flash command has completed*/

FTMRE_FSTAT = 0x80;

/*Wait for command completion*/

//while(((FTMRE_FSTAT)&(1UL << 7))==0x00);
while(!((FTMRE_FSTAT)&(1UL << 7)));
return 0;
}

int programFlash(int address, uint32_t word0, uint32_t word1) {
/*for (int i = 0; i < length; i+=4) {
progResult = programWord(address + i, data + i);
}*/

/*Wait until the command complete instruction is cleared and indicate that FCCOB registers are available i.e., CCIF (Command Complete Interrupt Flag)*/

while(((FTMRE_FSTAT)&(1UL << 7))==0);

/*Clear any previous errors from the last operation i.e., clear ACCERR and FPVIOL bits in FSTAT register*/

//if(!((FTMRE_FSTAT)==0x80))
//{
FTMRE_FSTAT = 0x30;
//}

// Write index to specify the command code to be loaded
FTMRE_FCCOBIX = 0x00;
// Write command code and memory address bits[23:16]
FTMRE_FCCOBHI = 0x06;// program FLASH command
FTMRE_FCCOBLO = address>>16;// memory address bits[23:16]
// Write index to specify the lower byte memory address bits[15:0] to be loaded
FTMRE_FCCOBIX = 0x01;
// Write the lower byte memory address bits[15:0]
FTMRE_FCCOBLO = address;
FTMRE_FCCOBHI = address>>8;
// Write index to specify the word0 (MSB word) to be programmed
FTMRE_FCCOBIX = 0x02;
// Write the word 0
//FTMRE_FCCOB = (word0) & 0xFFFF;
FTMRE_FCCOBHI = (word0) >>8;
FTMRE_FCCOBLO = (word0);
// Write index to specify the word1 (LSB word) to be programmed
FTMRE_FCCOBIX = 0x03;
// Write word 1
FTMRE_FCCOBHI = (word0>>16)>>8;
FTMRE_FCCOBLO = (word0>>16);

// Write index to specify the word0 (MSB word) to be programmed
FTMRE_FCCOBIX = 0x4;
// Write the word2
//FTMRE_FCCOB = (word1) & 0xFFFF;
FTMRE_FCCOBHI = (word1) >>8;
FTMRE_FCCOBLO = (word1);

// Write index to specify the word1 (LSB word) to be programmed
FTMRE_FCCOBIX = 0x5;
// Write word 3
//FTMRE_FCCOB = (word1>>16) & 0xFFFF;
FTMRE_FCCOBHI = (word1>>16)>>8;
FTMRE_FCCOBLO = (word1>>16);

/*Writing a 1 to the bit 7 of FSTAT register indicates that a flash command has completed*/

FTMRE_FSTAT = 0x80;

/*Wait for command completion*/

//while(((FTMRE_FSTAT)&(1UL << 7))==0x00);
while(!((FTMRE_FSTAT)&(1UL << 7)));

return 0;
}

/*
* eraseWrite.h
*
* Created on: 07.06.2018

*/

#ifndef SRC_ERASEWRITE_H_
#define SRC_ERASEWRITE_H_

#include "derivative.h" /* include peripheral declarations */
#include "std_types.h"

#define SECTOR_SIZE 512

extern long int flashLocat;

int progResult;

void flashClkInit();
int eraseSector(int address);
int eraseVerifySector(int address);
//int programFlash(int address, char *data, unsigned int length);
int programFlash(int address, uint32_t word0, uint32_t word1);
int programWord(int address, char *data);

#endif /* SRC_ERASEWRITE_H_ */

Labels (1)
Tags (1)
0 Kudos
1 Reply

743 Views
mjbcswitzerland
Specialist V

Hi

There are turn-key boot loaders for the KEA128 (Kboot, UART, SD card, Modbus, I2C) at the links below.
This also includes all the flash routines so no development effort is needed in case you require a professional quality (also free open source) solution.
If your interest is mainly educational you can use its code, which simulates the KEA128 and the flash operation in visual studio, as reference and copy over just the parts that you require to your own environment.

Regards

Mark

Kinetis: http://www.utasker.com/kinetis.html
Kinetis KEA128:
- http://www.utasker.com/kinetis/TRK-KEA128.html
- http://www.utasker.com/kinetis/FRDM-KEAZ128Q80.html
Serial Loader: http://www.utasker.com/docs/uTasker/uTaskerSerialLoader.pdf

Free Open Source solution: https://github.com/uTasker/uTasker-Kinetis
Working project in 15 minutes video: https://youtu.be/K8ScSgpgQ6M

For better, faster, cheaper product developments consider the uTasker developer's version, professional Kinetis support, one-on-one training and complete fast-track project solutions to set you apart from the herd : http://www.utasker.com/support.html

0 Kudos