Función para determinar el tamaño de los datos [cerrado]

0

Estoy usando el emulador eeprom, que escribe una página de flash de 60 bytes a la vez. Los datos que se escribirán en esa página se almacenan primero en un búfer de 60 bytes (matriz de 60 elementos) en la memoria RAM y luego se transfieren a flash de una vez. Ahora quiero hacer mi propia función por encima de esa biblioteca que tomará la dirección y los datos y los almacenará en el búfer de la página en consecuencia. Es decir, si los datos tienen una longitud de 16 bits, deben almacenarse en dos ubicaciones consecutivas en la matriz de almacenamiento de la página. Si tienen una longitud de 8 bits, deben almacenarse en una única ubicación indicada por dirección. Mi consulta es cómo mi función puede determinar el tamaño de los datos que quiero almacenar, solo a partir de la variable de datos

    
pregunta Sajid

3 respuestas

4

Esto no es realmente una pregunta de sistemas integrados o electrónicos.

Si usas C ++, puedes hacer múltiples funciones de escritura bajo un nombre, gracias a la sobrecarga:

#include <inttypes.h>

void store_data(void *addr, uint8_t data);
void store_data(void *addr, uint16_t data);
void store_data(void *addr, uint32_t data);
void store_data(void *addr, uint64_t data);

Cada sobrecarga sabe qué tan grandes son los datos del tipo de su argumento.

En C, podría tener una macro:

void store_data_sz(void *addr, size_t size, void *pdata);

/* data argument of macro must be an lvalue */
#define store_data(addr, data) store_data_sz(addr, sizeof (data), &(data))

También hay algo que decir para tener funciones separadas para tamaños comunes y luego una general para longitud variable:

void store_8(void *addr, int data);
void store_16(void *addr, int data);
void store_32(void *addr, unsigned long data);
void store_buf(void *addr, void *buf, size_t size);

Podemos tener una interfaz macro para esto, otra vez. Aquí tenemos algunas dependencias del sistema, como la suposición de que si algo es del tamaño 1, es una unidad de 8 bits, y así sucesivamente:

#define store_data(addr, data) do {                 \
  switch (sizeof(data)) {                           \
  case 1: store_8(addr, data); break;               \
  case 2: store_16(addr, data); break;              \
  case 4: store_32(addr, data); break;              \
  case 8: store_64(addr, data); break;              \
  default: store_buf(addr, &(data), sizeof (data)); \
  }                                                 \
} while (0)

Dado que sizeof(data) es una expresión constante (la excepción a esto son las matrices de longitud variable C99), sabemos en el momento de la compilación que solo uno de los casos de conmutación es alcanzable; Cualquier compilador decente tirará los casos imposibles. Verifique el código compilado y desmóntelo para estar seguro.

    
respondido por el Kaz
3

No puede. Un puntero a 8 bits de datos es exactamente lo mismo que un puntero a 16 bits de datos. Deberá proporcionar un parámetro adicional que indique a la función el tamaño de los datos o dos funciones diferentes, una para 8 bits y otra para 16 bits.

    
respondido por el Majenko
0

No creo que haya una forma de hacerlo directamente, pero si necesita ese tipo de funcionalidad, podría escribir su función para tomar un parámetro adicional que especifica el tamaño de los datos y luego envolverlo en una macro incluye un sizeof ().

Algo como esto:

    int my_func (void *data, int size)    {
   // do stuff with *data and use value in size
    }

#define mc_func(thing)    my_func(&thing, sizeof(thing))

Entonces si haces algo como:

mc_func(my_16bit_variable);

terminarás llamando a tu función my_func con la dirección de my_16bit_variable en *data y 2 en size .

    
respondido por el brhans

Lea otras preguntas en las etiquetas