Estoy escribiendo código para una puerta de enlace de comunicación en serie usando MSP430F2619 con Code Composer Studio 6.1.
La puerta de enlace tiene dos modos de funcionamiento diferentes:
Maestro este es el modo predeterminado. Sondeará los datos como bus maestro en un bus RS485 y luego los enviará a otra placa con un protocolo diferente.
Esclavo en el que responde a una aplicación de PC en puerto Serial.
El programa estará en modo maestro o esclavo ya que el mismo bus RS-485 se comparte entre la aplicación de PC y otras placas esclavas.
En lugar de usar 2 búferes de memoria diferentes para cada modo, estoy tratando de averiguar si ambos búferes pueden usar la misma memoria física.
Intenté buscar en la función de superposición de memoria de Code Composer Studio sin éxito.
Esencialmente, tengo esto:
char Slaverxbuffer[2048]; char Masterrxbuffer[2048];Quiero que estos dos búferes compartan la misma memoria para usar 2 KB de memoria en lugar de 4 KB.
Así que necesito una forma para que Slaverxbuffer y Masterrxbuffer usen la misma área de memoria, algo como:
char Sharedbuffer[2048];¿Podría tener un solo búfer y compartirlo entre los dos modos de operación? Esa sería probablemente la solución más simple.
De lo contrario, en C y C++, puede lograr esto haciendo que los dos búferes sean campos en un tipo de unión . Cada uno de los miembros de la unión tiene la misma dirección base en la memoria y el tamaño total de la unión es el tamaño del miembro más grande.
El código sería algo como esto:
union OverlaidBuffer { char Slaverxbuffer[2048]; char Masterrxbuffer[2048]; }; union OverLaidBuffer overlay; /* Code to use the slave buffer */ for(unsigned int index = 0; index < 2048; ++index) { overlay.Slaverxbuffer[index] = some_slave_value(); } /* Code to use the master buffer */ for(unsigned int index = 0; index < 2048; ++index) { overlay.Masterrxbuffer[index] = some_master_value(); }Tenga en cuenta que si usa una unión, siempre debe leer del miembro al que escribió más recientemente. Escribir a un miembro y luego leer de otro es un comportamiento indefinido y es probable que resulte en un código con errores. Por ejemplo, el código:
overlay.Slaverxbuffer[i] = 1; overlay.Masterrxbuffer[i] = 2; x = overlay.Slaverxbuffer[i]; bien puede establecer x en 1 ya que ese es "obviamente" el último valor almacenado en overlay.Slaverxbuffer[i] , aunque esa dirección de memoria ahora contiene el valor 2.
Otra forma de lograr esto es usar directivas de compilador y enlazador para colocar los dos búferes en ubicaciones específicas de la memoria. La mayoría de las cadenas de herramientas incrustadas le permitirán hacer esto a través de una directiva #pragma en el código fuente. El formato exacto de la directiva dependerá de la cadena de herramientas particular; un par de ejemplos están abajo.
TI Code Composer Studio (referencia MSP430 Optimización de la Guía del usuario del compilador C/C++ )
#pragma DATA_SECTION(Slaverxbuffer, "some_section") char Slaverxbuffer[2048];IAR Embedded Workbench (referencia a la Guía de desarrollo de IAR C/C++ )
#pragma section = "some_section" char Slaverxbuffer[2048];Luego, en el archivo del enlazador, agregue directivas para colocar el símbolo en una ubicación específica:
TI Code Composer Studio (referencia MSP430 Guía del usuario de herramientas de lenguaje ensamblador )
SECTIONS { .some_section : load = 0x12345678 }IAR Embedded Workbench (referencia a la Guía de desarrollo de IAR C/C++ )
place at address mem:0x12345678 { readwrite section some_section };Si, como dice, no quiere una unión, ¿podría tener un solo búfer y una variable separada para registrar en qué modo se encuentra?
char rxBuffer[2048]; bool rxMode; // false = master, true = slaveDe esta manera, puede tener el búfer en una ubicación de memoria fija (definida por el enlazador) y vincular al búfer