Autor Tema: Problema con variables globales tipo union.  (Leído 2093 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Salty

  • PIC10
  • *
  • Mensajes: 15
Problema con variables globales tipo union.
« en: 24 de Noviembre de 2014, 05:09:43 »
Buenos dias.

Soy nueva en pic, estoy utilizando un PIC18F46K22 para realizar un proyecto en MPLABX con el compilador XC8 (v1.33).

Necesito ayuda con unas variables (en un programa en c) a las que tengo que acceder al byte entero que ocupan unas veces (ESTADO = 0x00) y otras veces tengo que acceder solamente a alguno de sus bits.

Para poder hacer las dos cosas he visto que hay que hacer algo como esto:

typedef union
{
    unsigned char byte;
    struct{
        unsigned b0:0, b1:0, b2:0, b3:0, b4:0, b5:0, b6:0, b7:0;
    };
} t_byte;

t_byte    ESTADO;



De esta manera puedo acceder al byte así:
ESTADO.byte = 0x00;
y luego acceder a un bit así:
ESTADO.b7 = 1;

Con esto me compila perfectamente (en el .c). El caso es que necesito utilizar esa variable en unas bibliotecas creadas tambien por mi, y ahí las declaro como:

extern t_byte ESTADO;

Y no compila.

El error exacto que me da es este:

CALC_ERROR1.h:70: error: (1098) conflicting declarations for variable "SEG_BANDA" (CALC_ERROR1.h:69)

CALC_ERROR.h es la biblioteca en la que lo uso y SEG_BANDA no es una variable, es una función dentro de esa biblioteca.

Ese es el único error que me da pero estoy bastante segura que es por lo de las compartir las variables t_byte porque antes de eso compilaba sin problemas.

Si comento la función SEG_BANDA entera y vuelvo a compilar el error me da en la siguiente función.

Espero haberme explicado bien y no haberos aturullado mucho jaja. Si alguien tiene alguna idea agradezco todo tipo de ayuda :D.

Gracias por adelantado.

Desconectado Salty

  • PIC10
  • *
  • Mensajes: 15
Re: Problema con variables globales tipo union.
« Respuesta #1 en: 24 de Noviembre de 2014, 08:50:51 »
Hola de nuevo.

He juntado todo el codigo en el .c y compila perfectamente, de modo que debo estar haciendo algo mal al declarar las variables como extern en los .h.

¿Alguien me pude dar un ejemplo de como hacerlo? ¿O se os ocurre otra manera de acceder a las variables como byte y a un bit concreto en el mismo programa sin tener que definir un tipo union? Por si lo que ocurre es que no se puede compartir ese tipo de variable.

Desconectado Tisco

  • PIC16
  • ***
  • Mensajes: 108
Re: Problema con variables globales tipo union.
« Respuesta #2 en: 24 de Noviembre de 2014, 09:54:31 »
Normalmente lo se hace es poner el tipo del dato en la cabecera, y la implemetación en el fichero de código.

En tu caso:

Fichero .c:

Código: C
  1. t_byte    ESTADO;

Fichero .h:

Código: C
  1. #ifndef THISHEADER_H
  2. #define THISHEADER_H
  3.  
  4. typedef union
  5. {
  6.     unsigned char byte;
  7.     struct{
  8.         unsigned b0:0, b1:0, b2:0, b3:0, b4:0, b5:0, b6:0, b7:0;
  9.     };
  10. } t_byte;
  11.  
  12. extern t_byte ESTADO;
  13.  
  14. #endif /* THISHEADER_H */

De esta forma, con hacer un #include de la cabecera ya tendrías acceso a la variable.

De todas formas, por seguridad (y aunque en C no es muy cómodo), se suele encapsular la variable en el .c de manera que para acceder a ella se tenga que hacer a través de funciones. Este método es el que normalmente tendrás que emplear si te piden un código robusto.

Un saludo.

Desconectado Salty

  • PIC10
  • *
  • Mensajes: 15
Re: Problema con variables globales tipo union.
« Respuesta #3 en: 24 de Noviembre de 2014, 12:33:18 »
Problema solucionado!! Muchas gracias :D  ((:-)) Pero ahora me has picado la curiosidad jaja ¿como se encapsula la variable para hacer mas robusto el programa? No entiendo bien a que te refieres y seria muy interesante para el proyecto. Gracias otra vez :D

Desconectado Tisco

  • PIC16
  • ***
  • Mensajes: 108
Re: Problema con variables globales tipo union.
« Respuesta #4 en: 24 de Noviembre de 2014, 16:28:06 »
Pues con encapsular variables me refiero a que no se pueda acceder a dicha variable desde fuera del fichero de código (.c en tu caso).

Con esto te evitas que otros módulos puedan tocar esa variable.

La forma fácil de hacerlo en C, si sólo tienes una variable que quieres proteger, es crear una función que, por ejemplo, almacene el valor que quieras y otra que te devuelva el valor almacenado. Sería algo como:

Fichero.c
Código: C
  1. #include "header.h"
  2.  
  3. static uint32_t var = 0u;
  4.  
  5. void storeValue(uint32_t value) {
  6.         var = value;
  7. }
  8.  
  9. uint32_t readValue() {
  10.         return (var);
  11. }

Fichero.h
Código: C
  1. #ifndef HEADER_H
  2. #define HEADER_H
  3.  
  4. #include <stdint.h>
  5.  
  6. void storeValue(uint32_t value);
  7. uint32_t readValue(void);
  8.  
  9. #endif  // HEADER_H

Si ya tienes más de una variable que quieras proteger, en C se hace bastante lioso de implementar para no repetir código; normalmente se emplean estructuras con punteros a funciones.

En C++ (o la mayoría de lenguajes OO) la encapsulación se lleva bastante más ya que es muy simple de implementar una clase con su miembro a proteger y sus métodos de acceso.

De todas formas, esto de la protección de datos es algo más relativo a lo que te pidan en el proyecto: normas a pasar, estilo de programación, rendimiento del sistema... Incluso, a lo mejor, puede que no sea necesario proteger partes del código si tienes una buena batería de tests que permite confiar en la robustez del mismo.

Saludos!

Desconectado Salty

  • PIC10
  • *
  • Mensajes: 15
Re: Problema con variables globales tipo union.
« Respuesta #5 en: 26 de Noviembre de 2014, 08:34:49 »
Entendido :D muchas gracias de nuevo, de momento dejare el programa como está ya que no ha dado problemas y de hacerlo lo haría con bastantes variables