Hi. I have problems with my MK22FX512VLH12. I save my data by powerfail on my internal flash and sometimes I can not save all my data. For example my flash have this entries: AA AA AA AA BB BB BB BB FF FF FF FF FF FF FF FF.
The first 8 bytes are ok but the last 8 bytes do not save on the flash. If I want to read the last 4 bytes (FF FF FF FF), I get an Bus Error. On the Comand window from uVision stands: Cannot access Memory (@ 0x10004210, Read, Acc Size: 4 Byte). I read the data with a normal pointer. Why I can not read this address?
If all data stored by powerfail I have no problems.
Hi Oliver,
After had a brief look through your code, I'd highly recommend you to use the C90TFS software driver, and you can find the some flash demos in the KSDK, please refer to them for details.
KSDK: Software Development Kit for Kinetis MCUs|NXP
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
In the original FlashProgram() function are a few lines between disableInterrupts() and enableInterrupts().
I am seeing that someone comment it out.
When I am writing to the D-Flash and an Interrupt occurs (ISR in P-Flash), can it corrupt my data in the D-Flash?
And when I am trying to read them, then i get a Bus Error?
Hi Ralf,
I was wondering if you can share the thorough steps of your implementation, then I can replicate the issue on my site and it can help me to figure out the root of cause.
Hope it helps.
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi. Here is my code.
uint32_t oftenWrittenDataInSectorOffset = 0x20;
uint32_t oftenWrittenDataSectorOffset = 0x1000;
uint32_t oftenWrittenDataFlashBaseAddress = 0x10000000;
uint32_t oftenWrittenDataCounter = 0;
uint32_t fewWrittenDataInSectorOffset = 0x40;
uint32_t fewWrittenDataSectorOffset = 0x1000;
uint32_t fewWrittenDataFlashBaseAddress = 0x10010000;
Whey I detect a power fail, I execute this function:
uint32_t writeDataOnFlash(uint32_t dest, uint32_t size){
int32_t checkSum = 0;
uint8_t oftenWrittenData[24] = {0};
uint64_t cast;
uint8_t *pData;
uint32_t ret;
if(size > 24){
//Size to large
return ERR_SIZE;
}
for(int i = size; i > 0; i--){
//read data and calculate checkSum
pData = (uint8_t *) ((dest-1) + i);
oftenWrittenData[i-1] = *pData;
checkSum += *pData;
}
pData = (uint8_t *) &cast;
for(int i = 0; i < 4; i++){
//counter write to cast variable
*pData = *(((unsigned char *)(&oftenWrittenDataCounter))+i);
checkSum += *pData;
pData++;
}
for(int i = 0; i < 4; i++){
//first value write to cast variable
*pData = *(((unsigned char *)(&oftenWrittenData))+i);
pData++;
}
//write counter and first value on flash memory
ret = FlashProgram(&ssdConfig, destOftenWrittenData, 8, (uint8_t*) &cast, pFlashCommandSequence);
if(ret != 0){
//error write on flash memory
return ERR_WRITE;
}
pData = (uint8_t *) &cast;
for(int i = 4; i < 12; i++){
//write 2. value and 3. value to cast variable
*pData = *(((unsigned char *)(&oftenWrittenData))+i);
pData++;
}
//write 2. value and 3. value on flash memory
ret = FlashProgram(&ssdConfig, destOftenWrittenData+8, 8, (uint8_t*) &cast, pFlashCommandSequence);
if(ret != 0){
//error write on flash memory
return ERR_WRITE;
}
pData = (uint8_t *) &cast;
for(int i = 12; i < 20; i++){
//write 4. value and 5. value to cast variable
*pData = *(((unsigned char *)(&oftenWrittenData))+i);
pData++;
}
//write 4. value and 5. value on flash memory
ret = FlashProgram(&ssdConfig, destOftenWrittenData+16, 8, (uint8_t*) &cast, pFlashCommandSequence);
if(ret != 0){
//error write on flash memory
return ERR_WRITE;
}
pData = (uint8_t *) &cast;
for(int i = 20; i < 24; i++){
//6. value write to cast variable
*pData = *(((unsigned char *)(&oftenWrittenData))+i);
pData++;
}
for(int i = 0; i < 4; i++){
//checkSum write to cast variable
*pData = *(((unsigned char *)(&checkSum))+i);
pData++;
}
//write 6. value and checkSum on flash memory
ret = FlashProgram(&ssdConfig, destOftenWrittenData+24, 8, (uint8_t*) &cast, pFlashCommandSequence);
if(ret != 0){
//error write on flash memory
return ERR_WRITE;
}
//get next free flash memory
getOftenWrittenDataFlashAddress();
return OK;
}
Sometimes I have no time to save the 6. value and the checkSum. My flash memory is in this case FF FF FF FF FF FF FF FF for the 6. value and the checksum.
When I make a reset, I execute this function:
When I try to read the checksum with a normal pointer I get an Bus Error. (readCheckSum = *pCounter;)
uint32_t readDataFromFlash(uint32_t dest, uint32_t size){
int32_t *pCounter;
uint8_t *pByteCounter;
int32_t lastEntry;
int32_t readCheckSum;
int32_t proveCheckSum = 0;
uint8_t *pDest = (uint8_t *) dest;
if(size > 24){
//try to read to much bytes from flash
return ERR_SIZE;
}
//last entry is next free flash address - offset of stored data
lastEntry = destOftenWrittenData - oftenWrittenDataInSectorOffset;
uint32_t nextValue = 0;
do{
//find right data
if(lastEntry == 0x0FFFFFE0){
//transition from first sector to last sector
lastEntry = 0x10000000;
pCounter = (int *) (lastEntry + (oftenWrittenDataInSectorOffset - 0x4));
readCheckSum = *pCounter;
if(readCheckSum == -1){
lastEntry = 0x1000FFE0;
}
}
//read checksum
pCounter = (int *) (lastEntry + (oftenWrittenDataInSectorOffset - 0x4));
readCheckSum = *pCounter; // Here I get the error!
if(readCheckSum == -1){
//data empty
proveCheckSum = 0;
lastEntry -= oftenWrittenDataInSectorOffset;
nextValue++;
continue;
}
//calculate checksum
for(int j = 0; j < 28; j++){
pByteCounter = (unsigned char *) (lastEntry + j);
proveCheckSum += *pByteCounter;
}
//found right data
if(readCheckSum == proveCheckSum){
//set next value to 128, so the do while reach the end
nextValue = 128;
}else{
proveCheckSum = 0;
}
lastEntry -= oftenWrittenDataInSectorOffset;
nextValue++;
}while(proveCheckSum != readCheckSum && nextValue < 128); //prove checksum; if all checksums (128) in sector wrong -> break
if(proveCheckSum == readCheckSum){
//checksum right -> read data
for(int i = 4; i < size+4; i++){
pByteCounter = (unsigned char *) ((lastEntry + oftenWrittenDataInSectorOffset)+i);
*(pDest + (i-4)) = *pByteCounter;
}
return OK;
}
return ERR_NO_VALID_DATA;
}
Thanks. I post the code on monday.