Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are different pointers and void pointers being used by these functions?

I have an ATMega328 and I'm using the <avr/eeprom.h> functions to use the inbuilt EEPROM.

I can use the EEPROM correctly but I don't understand the function arguments I pass to the EEPROM functions.

For example, to write different types of data I can use

void eeprom_update_byte (uint8_t *addr, uint8_t value);
void eeprom_update_word (uint16_t *addr, uint16_t value);
void eeprom_update_dword (uint32_t *addr, uint32_t value);
void eeprom_update_float (float *addr, float value);
  • But why does the pointer type for the address (the addr parameter) change depending on the function used? If addr just points to a valid EEPROM address why is the type different in each function?

  • Also, the use of the void * in the EEPROM function below is confusing me. I understand that a void * can point to any address, so I'm assuming the function simply writes byte by byte the data in src but I'm unsure if this is correct?

void eeprom_update_block (const void *src, void *dst, size_t n);

like image 490
CS Student Avatar asked Nov 23 '25 16:11

CS Student


2 Answers

The first four functions listed define the type of object being written. So internally the function might look like this:

void eeprom_update_float (float *addr, float value)
{
    *addr = value;
}

This offers type safety benefits (e.g. cannot write a float into a uint16_t) by ensuring that the destination pointer is the same as the source variable.

The final version void eeprom_update_block() simply writes an arbitrary block of memory to a given address. It probably uses something like memcpy underneath:

void eeprom_update_block (const void *src, void *dst, size_t n)
{
    memcpy(dst, src, n);
}

This version of the function doesn't have any type safety advantages, but can be used to write non-trivial data into memory. For example, a struct can be written like this:

eeprom_update_block(&myStruct, dst, sizeof(myStruct));
like image 134
Karl Nicoll Avatar answered Nov 26 '25 05:11

Karl Nicoll


There is no technical reason behind taking type-specific pointers in the first four APIs. These functions could be redefined with void* without the need to recompile code relying on them:

void eeprom_update_byte (void *addr, uint8_t value);
void eeprom_update_word (void *addr, uint16_t value);
void eeprom_update_dword (void *addr, uint32_t value);
void eeprom_update_float (void *addr, float value);

There is no special alignment requirements in EEPROM, so my guess is that Atmel team used type-specific pointers for aesthetic reasons.

Also, the use of the void* in the EEPROM function below is confusing me.

eeprom_update_block is an untyped version of type specific eeprom_update_XXX functions. Note that since the second parameter is void*, a third parameter specifying block size is now required, while eeprom_update_XXX functions imply the size from the type of their argument.

like image 26
Sergey Kalinichenko Avatar answered Nov 26 '25 06:11

Sergey Kalinichenko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!