Fscking Pointers.

Mar 26, 2025 Last reply: 1 year ago 7 Replies

It seems C has caught the disease of 'we will modify your code according to what WE think it means'..



..my pointers to 254 byte structures are going haywire when I add 256 bytes to them...I have to add one instead... ..add that to the fact that to write to flash RAM you need to specify the *offset* from flash RAM base, but to read it you need to use the actual hardware address...



sigh.



What is the generic type for a simple pointer to presumably bytes, in ARM C? Or should I resign myself to doing everything in 256byte chunks? the structure to be read and written from Flash is exactly that big for obvious hardware reasons...


Somebody didn’t read the C language spec properly ...

if C knows the thing being pointed to is a 254 byte struct, then adding

256 to it will move it by 65024 bytes surely?

adding 1, will move it by 254 bytes.

are you casting pointers?

traditionally char*

Pointers in C are incremented by the size of whatever they point to.

Yes, I've found it very frustrating in the past, too.

If you want to increment by one byte, you are clearly wanting to point to something within the struct, so, point at the struct member rather than the overall struct; and make sure that the member is amenable to being addressed byte by byte. If necessary, create a union with a byte array.

David

When you point to an object of type X, incrementing that pointer is in increments of the in-memory size of X, plus rounding. ie you might have a

254 byte structure but your compiler may decide to lay those out at it's convenience. It could be that it pads the size to 256 bytes to avoid unaligned accesses which your architecture may not support. To avoid that, declare the struct as packed (which is a compiler specific directive), which would save memory but could force it to break operations into aligned accesses (eg an unaligned 32 bit load might turn into two aligned loads plus some AND/OR/shift logic)

I suspect the flash is mapped as readable at some base address, but to write you need to issue a write command. ie to read you can just do:

int data = *(FLASH_READ_BASE + flash_offset);

but writing might be something like:

*(FLASH_WRITE_ADDR) = flash_offset; *(FLASH_WRITE_DATA) = 0x12345678; *(FLASH_WRITE_GO) = true;

Slightly less traditionally (C99 and later): #include <stdint.h>

and then you have the type uint8_t* as a pointer to unsigned 8 bit ints, and int8_t* pointing to signed 8 bit ints.

I don't know the flash type or block size (this is a Pico?) but if you write chunks you're likely to cause fewer erase cycles than writing random bytes here and there. It's going to cause less wear to round to 256 then have things unaligned and span block boundaries.

Theo

It was an attempt to unify address arithmetic, involving both arrays and pointers, under a common paradigm. I am surprised that people still continue to be surprised by it. Wasn’t it covered in whatever introduction to C the kids are reading these days?

“It’s not a bug, it’s a feature!”

Getting more and more like Pascal.

Sigh. I will have to rethink, cast everything to one standard and stick to that, I think

It would be quicker in assembler...

Essentially yes. There are no functions to read flash, but to write and to erase are discrete functions taking offset, not absolute addresses

Thanks for that. I think for readability that is preferable to char * as there is a hint of 'this is a string' about that.

uint8_t* means 'a pointer that increments by one for each byte'

You CAN only write chunks of 256 bytes and erasure is a whole 4k block.

Thanks for that. Having slept on it I think that I will go for 'the closest to assembler' and use uint8_t * except where accessing the structure contents. Then I can explicitly cast it to a structure pointer.

I had forgotten about packing arrays too. Pico is a 32 bit chip. No idea how wide its data bus is - ah that's 32 bits as well.

So I guess byte accesses are 32 bit access with the answer shifted right ...

Rethink needed there as well

Thanks for all the hints

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required