Accessing the FLASH causing BUS fault ??

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

Accessing the FLASH causing BUS fault ??

Jump to solution
6,662 Views
kinetis_user
Contributor II

Hello friends,

 

I am using CW 10.1 and Kinetis MK10N512VMD100.

Processor is running at 40MHz and flash is running at 20MHz.

I have written a simple program that will erase and program the flash.

After programming the flash once it has been erased I have reviewed the memory of the programmed flash space using the memory browser and it does contain the written information.

 

I have declared in the .lfc file not to include the area of the flash that I am rewriting, so

the linker will not put information there. I have verified in the project map file that indeed the sections

I am erasing are free from data.

 

However when trying to access the flash memory to verify its content I have an unhandled interrupt from time to time on specific flash address After checking what might trigger the unhandled interrupt

I was able to narrow the source to one of the following (Interrupt sources 5, 3)

PRECISERR: Precise data bus error

BFARVALID: BusFault

UNDEFINSTR: Undefined instruction UsageFault

 

I have tried changing clock rates, to see if this has any affect without success

Am I doing something wrong? Is there a silicon problem with clocking the flash?

See the attached sample program

 

 

 

// Not all the program is listed , only the flash erase section and the relevant include files

#include "PE_Types.h"
#include "PE_Error.h"
#include "PE_Const.h"
#include "IO_Map.h"
#include "FTFL_PDD.h"


#define FTFL_CMD_WRITE_LONG_WORD 0x06
#define FTFL_CMD_ERASE_FLASH_SECTOR 0x09
#define FTFL_CMD_PROGRAM_SECTION 0x0B
#define SECTOR_SIZE 2048 // 0x800

uint32_t gBadWords;
uint32_t gTest;
int8_t  FLASH_Erase(uint32_t StartAddress, uint32_t NoSectors)
{
// Start Address must be on a Sector boundaries
  uint32_t CurrentSectorStartAddress;
  uint32_t EndAddress,AddressData;
 
  // Clocking the FTFL module
 SIM_SCGC6 |= 1;                      

  
   while (!(FTFL_FSTAT_REG(FTFL_BASE_PTR) & FTFL_FSTAT_CCIF_MASK)); // Should never happen
  // Clear all error registers - Write 1 will clear them  
   FTFL_FSTAT_REG(FTFL_BASE_PTR) = (FTFL_FSTAT_FPVIOL_MASK | FTFL_FSTAT_ACCERR_MASK | FTFL_FSTAT_RDCOLERR_MASK);
    
   CurrentSectorStartAddress=StartAddress;
   EndAddress=StartAddress+NoSectors*SECTOR_SIZE;
  
   while (NoSectors)
   {
    while (!(FTFL_FSTAT_REG(FTFL_BASE_PTR) & FTFL_FSTAT_CCIF_MASK)); // Wait for previous erase sequence to end
    if (FTFL_FSTAT_REG(FTFL_BASE_PTR)  
     & (FTFL_FSTAT_RDCOLERR_MASK | FTFL_FSTAT_ACCERR_MASK | FTFL_FSTAT_FPVIOL_MASK | FTFL_FSTAT_MGSTAT0_MASK )
    ) return(1); // Error during last cycle
    // See section 28.4.10
       FTFL_PDD_SetFCCOBCommand(FTFL_BASE_PTR,FTFL_CMD_ERASE_FLASH_SECTOR); // Write Erase Command to FCCOB0 , Can be taken out of the while loop
       FTFL_PDD_SetFCCOBAddress(FTFL_BASE_PTR,CurrentSectorStartAddress); // Write FCCOB1,FCCOB2,FCC0B3 with the address
       FTFL_PDD_LaunchCommand(FTFL_BASE_PTR); // Just write '1' to CCIF , However this also clears the errors (which we dont' have)

       NoSectors--;
    CurrentSectorStartAddress+=SECTOR_SIZE;
       
   } // loop around number of sectors to erase
// Check that indeed all is erased
// The next few lines causes bus fault interrupt
// Using the memroy browser once can see that the memory is erased
 
 CurrentSectorStartAddress = StartAddress;
 gBadWords=0;
 while (CurrentSectorStartAddress<EndAddress)
 {
  AddressData = *(uint32_t *)CurrentSectorStartAddress;
  if (AddressData != 0xFFFFFFFFUL)
   gBadWords++;
  
  CurrentSectorStartAddress+=4;
 }
  
   // Un clocking the FTFL module
    SIM_SCGC6 &= (uint32_t) 0xFFFFFFFE;                  
  
  
   return(0);  
} // End of FLASH1_Erase 

0 Kudos
Reply
1 Solution
4,040 Views
kinetis_user
Contributor II

Thank you !!!!!

Sorry for my late response , I was out of the office for the last two weeks and now that I'm back I saw these posts.

Indeed we had the same problem.

Disabling the cache solved my problem as well.

However I think that Freescalse has a cache issue with the Kinetis.

In both cases , my case and comsosysarch case , we were writing to one bank of the memory while the code was running from a different bank of the flash memory. I think that there is an error in freescale's cache algorithm and by chance the last XX bits in the second bank that I was writing to , were the same for the code that was running from the other flash bank and that caused the problem. (My problem was that I got a hard fault of invalid opcode)

 

When I tried to access theses FMC registers from the debugger I was unable to do so (I am able to access other registers in the FMC and FTFL modules and other modules as well)

After accessing these registers I got the error message from the debugger : An internal error occurred during: "Update Details Pane Sections". For input string: "1x"

Strange...

 

Anyway thank you so much for the answer. Now I can keep on working :smileyhappy:


 

View solution in original post

0 Kudos
Reply
10 Replies
4,040 Views
comsosysarch
Contributor III

I just posted an eerily similar problem.

 

I wonder if you are having the same thing but different.

 

In mine the program, long after flash write, goes in and out of an ISR during reading of the flash contents and vectors to never-never land at the address corrresponding to my flash data value (not flash address... the data value stored in the flash).

 

It is possible yours could be doing the same, but your data value where it vectors could be legal just have a mis-aligned or missing instruction? So you get a bus fault and illegal instruction error instead of a memory instruction access violation like me.

 

Write a handler for the bus fault interrupt (enable it). In the handler put an endless while loop. Set a breakpoint (or if you are IAR which it sounds like you can just tell the debugger to break on a bus fault exception - same result).

 

When the error occurs examine the stack pointer and count up to find the program counter value at the time of the exception. See what code you have running there.

 

I'm a noob on ARM and K60... so I probably can not help much, but I can share what I did to isolate my own still-unresolved problem a little bit.

 

0 Kudos
Reply
4,040 Views
Dekiru
Contributor IV

You should try to disable cache to see if it helps or not:

 

FMC_PFB0CR &= 0xFFFFFFE0;

FMC_PFB1CR &= 0xFFFFFFE0;

 

Regards

0 Kudos
Reply
4,040 Views
comsosysarch
Contributor III

That certainly made my problem go away, and that you very much for that... but I'd sure like to know why! (in part because I would like to avoid just dumping flash caching for my whole appplication so I would like to be more "surgical" in disabling what and when)

Is there some issue with flash caching of mixed data and instruction accesses and interrupt handling?

 

0 Kudos
Reply
4,040 Views
Dekiru
Contributor IV

The reason of this fault might be:

 

If you update flash then execute code from that updated locations without a proper cache invalidation, accessing the area gives old values that is not meaningful then hardware fault happens.

 

You should check if the cache is invalidated correctly after flash writing (CINV_WAY of FMC_PFBxCR)

0 Kudos
Reply
4,041 Views
kinetis_user
Contributor II

Thank you !!!!!

Sorry for my late response , I was out of the office for the last two weeks and now that I'm back I saw these posts.

Indeed we had the same problem.

Disabling the cache solved my problem as well.

However I think that Freescalse has a cache issue with the Kinetis.

In both cases , my case and comsosysarch case , we were writing to one bank of the memory while the code was running from a different bank of the flash memory. I think that there is an error in freescale's cache algorithm and by chance the last XX bits in the second bank that I was writing to , were the same for the code that was running from the other flash bank and that caused the problem. (My problem was that I got a hard fault of invalid opcode)

 

When I tried to access theses FMC registers from the debugger I was unable to do so (I am able to access other registers in the FMC and FTFL modules and other modules as well)

After accessing these registers I got the error message from the debugger : An internal error occurred during: "Update Details Pane Sections". For input string: "1x"

Strange...

 

Anyway thank you so much for the answer. Now I can keep on working :smileyhappy:


 

0 Kudos
Reply
4,040 Views
kinetis_user
Contributor II

And here is the official answer from Freescale.

Downloaded the errata for the K10 chip and found the following (probably the same issue with the K60)

Too bad that non of their engineers were able to point me to that issue.

e2644: FMC: Speculation logic is not supported on program flash only or program

flash only with swap feature devices.

Errata type: Errata

Mask Set Errata for Mask 0M33Z, Rev. 13 JUL 2011

Freescale Semiconductor, Inc. 5

Description: Due to a logic error, speculation logic is not supported on program flash only or program flash

only with swap feature devices. Out of reset the FMC_PFB0CR and FMC_PFB1CR registers

which control the speculation mechanism are configured for full speculation functionality for

both flash banks. Devices with FlexMemory are not affected.

Workaround: Disable the use of speculation for program flash only and program flash only with swap feature

devices by programming FMC_PFB0CR[2:1] and FMC_PFB1CR[2:1] bits to 2'h0.

 

e2647: FMC: Cache aliasing is not supported on 512 KB and 384 KB program flash

only devices.

Errata type: Errata

Description: Due to logic error, cache aliasing is not supported on 512 KB and 384 KB program flash only

devices. Out of reset the FMC_PFB0CR and FMC_PFB1CR registers which control the cache

aliasing mechanism are configured for full cache/page buffer for both flash banks. Devices with

FlexMemory or 128 KB, 192 KB and 256 KB program flash only are not affected.

Workaround: Disable the use of the cache for 512 KB and 384 KB program flash only devices by

programming FMC_PFB0CR[4:3] and [0] and FMC_PFB1C[4:3] and [0] bits all to 1'b0.

0 Kudos
Reply
4,040 Views
alexx_88
Contributor III

Have the same issue both on K22 and K24.

0 Kudos
Reply
4,040 Views
egoodii
Senior Contributor III

Not sure why you dredged-up this 6-year-old thread, but if you have the SAME issue then the fix is THE SAME.

Otherwise, if your problem is caused by doing any flash-write OTHER than 'full phrase, exactly one programming access', then I suggest you look for any of the many threads regarding 'overprogramming' of flash.

0 Kudos
Reply
4,040 Views
alipoth
Contributor III

I can reproduce the bug on K70 maskset 3N96B despite the errata not mentioning it. The workaround is to disable caching (either in LMEM or FMC).

0 Kudos
Reply
4,040 Views
comsosysarch
Contributor III

Actually paring it down to just the following worked for me so far too...

 

// disable flash cachingFMC_PFB0CR &= ~FMC_PFB0CR_B0SEBE_MASK;//FMC_PFB0CR &= ~FMC_PFB0CR_B0IPE_MASK;FMC_PFB0CR &= ~FMC_PFB0CR_B0DPE_MASK;//FMC_PFB0CR &= ~FMC_PFB0CR_B0ICE_MASK;FMC_PFB0CR &= ~FMC_PFB0CR_B0DCE_MASK;//FMC_PFB1CR &= ~FMC_PFB1CR_B1SEBE_MASK;//FMC_PFB1CR &= ~FMC_PFB1CR_B1IPE_MASK;//FMC_PFB1CR &= ~FMC_PFB1CR_B1DPE_MASK;//FMC_PFB1CR &= ~FMC_PFB1CR_B1ICE_MASK;//FMC_PFB1CR &= ~FMC_PFB1CR_B1DCE_MASK;

 

I am running from flash in bank 0 (lower) and using non-volatile data tables from bank 1 (upper).

I tried just disabling bank 1 instructions and bank 1 instruction prefetch (which should both never happen since I made the linker never put code there) and that did not make my error go away by itself, even when I added to disable the bank 1 single entry buffer as well.

Then I tried just disabling bank 0 data and data prefetch (there should be some of course but not nearly the impact of disabling code cache). This appeared to work for a minute or so (my error otherwise happens almost right away) but eventually gave me a fault (sometimes a usage fault instead of a memory fault - but I expect probably the same root issue). So I also disabled the single entry buffer on bank 0 and this has run for > 15 minutes with no faults.

 

0 Kudos
Reply