TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: cucu en 05 de Mayo de 2009, 06:35:28
-
hola, tengo un gran problema que está relacionado con la definición de variables y su posición en memoria.
Mi programa funciona mejor o peor (pero nunca como yo quiero) según ponga determinadas variables como globales o locales, y según las sitúe en memoria restringida o no.
Vale, lo de la memoria restringida tiene sentido... esa variable no "la pisa" ninguna otra. Lo que no se es como definir una variable en una posición determinada de la memoria, se sitúan ahí y no se porque.
Pues quería preguntaros eso, como situar una variable en la posición de memoria que yo quiera (ya apaño el linker después para que se corresponda a memoria restringida) y porque mi funcionamiento cambia al poner una variable local (sólo la uso en el main) como global.
Muchas gracias. Saludos
-
¿Usas CCS?, si es así puedes hacerlo con
#LOCATE
Syntax:
#locate id=x
Elements:
id is a C variable,
x is a constant memory address
Purpose:
#LOCATE works like #BYTE however in addition it prevents C from using the area.
A special form of this directive may be used to locate all A functions local variables starting at a fixed location.
Use: #locate Auto = address
This directive will place the indirected C variable at the requested address.
Examples:
// This will locate the float variable at 50-53
// and C will not use this memory for other
// variables automatically located.
float x;
#locate x=0x50
-
Hola, gracias por responder tan rápido, no, utilizo C18.
Saludos
-
El mayor problema que yo veo al usar variables globales es que una variable así puede ser modificada al mismo tiempo por 2 o más subrutinas, afectando su valor esperado.
Ejemplo:
//Variable global
int32 conteo;
//Función principal
void main(void)
{
while(1)
{
delay_ms(1000);
++conteo;
}
}
//Función que se ejecuta al ocurrir una interrupción por timer 0
timer0()
{
if(conteo==0x10000000)
--conteo;
}
Lo que sucede es que cada 1s se incrementa el valor de la variable global conteo, la cual está armada con 4 bytes y hay que manipular uno por uno. ¿Pero qué pasa cuando llega la interrupción timer0 justamente cuando se está manipulando el valor de conteo? Supongamos que el pic apenas estaba manipulando el primer byte y llega la interrupción timer 0. El valor que va a comparar el if será un valor erróneo ya que no está completo, la variable todavía estaba a media modificación.
Si de casualidad coincide con 0x10000000, entonces se volverá a manipular el contenido de conteo erróneamente.
Al regresar de la interrupción, el pic seguirá manipulando el contenido de conteo... sin saber que ya fue manipulado por alguien más y por lo tanto afectará por 2da vez el valor real de la variable.
En conclusión, las variables globales no son peligrosas, pero hay que saber quién las manipulará y en qué momento. Hay que evitar colisiones. Lo mejor es siempre escribir variables locales. Si es necesario declararlas como globales, habrá que establecer algún mecanismo de protección de datos tales como semáforos o banderas que indiquen que la variable está siendo modificada por alguien más (ejemplo, el bit 7 UOWN que indica que el hardware usb de un pic está trabajando el contenido de un buffer).
-
Lo mejor es siempre escribir variables locales.
Creo que es la primera vez que lo hago, porque siempre estoy de acuerdo contigo, pero permíteme discrepar de ti, Migsantiago.
En procesos donde la velocidad es muy crítica, aquellos donde hay que arañar hasta el último ciclo de proceso, es mejor usar variables globales porque las locales y las pasadas como parámetro consumen ciclos al entrar y salir de las funciones donde son utilizadas.
-
Hola, algunos compilares usan como alternativa al locate el simbolo @ para definir una dirección absoluta, pero como no es estandar cada cual hace la que quiere. Otra manera seria definir un segmento nuevo en el archivo de configuración del linker y alocar esta variable en ese segmento.
Por lo demas segun mi punto de vista, deberias corregir tu programa porque no deberia funcionar dependiendo si una variable es local o global.
Saludos !
-
Respecto al uso de variables locales o globales, creo que depende mucho tambien de lo organizados que seamos para programar, por ejemplo para contadores de ciclos for, es mejor usar locales. Hubo por ahi algun hilo en el que se preguntaba porque una variable no se comportaba como debia y fue por el hecho de que se declaro como global y la usaba a diestra y sinisetra!!!!
-
Lo mejor es siempre escribir variables locales.
Creo que es la primera vez que lo hago, porque siempre estoy de acuerdo contigo, pero permíteme discrepar de ti, Migsantiago.
En procesos donde la velocidad es muy crítica, aquellos donde hay que arañar hasta el último ciclo de proceso, es mejor usar variables globales porque las locales y las pasadas como parámetro consumen ciclos al entrar y salir de las funciones donde son utilizadas.
Bueno, creo que me excedí al decir siempre :D Coincido contigo, hay veces en que conviene o no conviene usar variables locales.
Ah y no te preocupes si no estás de acuerdo conmigo. Sería un foro muy aburrido si a todo le dijéramos que sí. ;)
-
Hola, gracias a todos por las opiniones.
Estoy toquiteando un ejemplo de microchip, por eso me extraña tanto que poner la variable local o global me varíe tanto... porque entiendo que debería funcionar a la perfección, ¿no?
Por otro lado, lo de la localización en memoria, según lo hace el ejemplo este es como dice Richi de configurar el linker, pero no se como hace luego para alocar la variable en el segmento definido... he buscado por todas partes, pero nada, que no lo veo...
Gracias. Saludos