This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Can't read from flash beyond 0x10000

I have a large array of uint16_t data to use as a lookup table, which is defined in flash. It's 4002 bytes in size, and I can set where in flash it is saved. I'm accessing it both as value = array[index]; and as pointer_to_array += index; value = *pointer_to_array; both with the same result.

The result is that if any element of the array is beyond 0x10000, reading it back results in 0xFFFF. Looking at it in 'Memory' in keil, it has the correct value; it's only when reading from it in code that it fails.

What could be causing this?

It can't be the keil code size limit, as that's 32k and the code size is just over 16k.

I've tried looking at the Memory Protection Unit, but as far as I can tell, readback protection applies to the whole of a flash region, not individual blocks. Could write/erase protection be affecting this somehow?

Can individual blocks of flash be powered on and off individually? So far I've only found this with RAM, but given 0x10000 is on the boundary of a flash block it seems plausible.

Or could something be preventing reading from higher than 16 bit flash addresses somehow?

Any help appreciated!

Parents Reply Children
  • I don't think it can be that. I don't end up in the hard fault handler, I just get a value of 0xFFFF.

    I've currently got the array starting at 0xF400, so that the last ~kB is past 0x10000. I can read back the correct values for the first 3 kB, but as soon as I try to read from 0x10000 I get 0xFFFF. Up to that point I'm reading uint16_ts, so presumably I am doing non-word-aligned reads perfectly fine (which in itself might be worrying).

    I did try making everything uint32_t, but the only difference was I read back 0xFFFFFFFF.

    Is there some reason non-aligned reads are allowed below 0x10000 but not above?

  • Since you're not accessing addresses by de-referencing the pointer to the address, I would assume that the compiler does some magic :-)

    1. Could you try accessing the data by de-referencing a pointer to that specific address? uint32_t test = *(uint32_t *) 0x10000; Does it give you the correct value?

    2. Could you attach a simplified version of the project so I can have a look?

Related