• Fscking Pointers.

    From The Natural Philosopher@21:1/5 to All on Wed Mar 26 19:11:24 2025
    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...



    --
    It is the folly of too many to mistake the echo of a London coffee-house
    for the voice of the kingdom.

    Jonathan Swift

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Higton@21:1/5 to The Natural Philosopher on Wed Mar 26 20:14:18 2025
    In message <vs1jgs$2co6s$3@dont-email.me>
    The Natural Philosopher <tnp@invalid.invalid> wrote:

    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...

    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andy Burns@21:1/5 to The Natural Philosopher on Wed Mar 26 20:08:42 2025
    The Natural Philosopher wrote:

    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...

    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.


    ..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...

    are you casting pointers?

    sigh.

    What is the generic type for a simple pointer to presumably bytes, in
    ARM C?

    traditionally char*

    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...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to The Natural Philosopher on Wed Mar 26 19:51:44 2025
    On Wed, 26 Mar 2025 19:11:24 +0000, The Natural Philosopher wrote:

    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...

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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Theo@21:1/5 to Andy Burns on Wed Mar 26 23:07:16 2025
    Andy Burns <usenet@andyburns.uk> wrote:
    The Natural Philosopher wrote:

    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...

    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.

    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)

    ..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...

    are you casting pointers?

    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;

    What is the generic type for a simple pointer to presumably bytes, in
    ARM C?

    traditionally char*

    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.

    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...

    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to David Higton on Wed Mar 26 23:57:47 2025
    On Wed, 26 Mar 2025 20:14:18 GMT, David Higton wrote:

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

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

    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!”

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From The Natural Philosopher@21:1/5 to Theo on Thu Mar 27 06:47:23 2025
    On 26/03/2025 23:07, Theo wrote:
    Andy Burns <usenet@andyburns.uk> wrote:
    The Natural Philosopher wrote:

    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...

    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.

    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)

    ..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...

    are you casting pointers?

    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;

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

    What is the generic type for a simple pointer to presumably bytes, in
    ARM C?

    traditionally char*

    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.

    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'


    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...

    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.

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


    Theo

    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



    --
    “The ultimate result of shielding men from the effects of folly is to
    fill the world with fools.”

    Herbert Spencer

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From The Natural Philosopher@21:1/5 to David Higton on Thu Mar 27 06:29:53 2025
    On 26/03/2025 20:14, David Higton wrote:
    If necessary, create a union with a byte
    array.

    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...
    --
    You can get much farther with a kind word and a gun than you can with a
    kind word alone.

    Al Capone

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)