2012-02-10 20 views
18

En el pasado, he trabajado mucho con AVR de 8 bits y MSP430 donde la RAM y el flash se almacenaban en el chip directamente. Cuando compila y descarga su programa, de alguna manera "simplemente funciona" y no necesita preocuparse acerca de dónde y cómo se almacenan realmente las variables.Cómo utilizar la memoria externa en un microcontrolador

Ahora estoy comenzando un proyecto en el que me gustaría poder agregar algo de memoria externa a un microcontrolador (un TI Stellaris LM3S9D92 si eso importa) pero no estoy del todo seguro de cómo se usa el código. la RAM externa. Puedo ver cómo se configura el bus externo más o menos como cualquier otro periférico, pero lo que me confunde es cómo el procesador realiza un seguimiento de cuándo hablar con la memoria externa y cuándo hablar con la interna.

Por lo que puedo decir, la RAM externa se asigna al mismo espacio de direcciones que la SRAM interna (la interna se inicia en 0x20000000 y la externa se inicia en 0x60000000). ¿Eso significa que si escribía algo como esto:

int* x= 0x20000000; 
int* y= 0x60000000; 

¿Sería x e y apuntaría a los primeros 4 bytes (suponiendo 32 bits enteros) de memoria RAM interna y externa, respectivamente? Si es así, ¿y si he hecho algo como esto:

int x[999999999999]; //some super big array that uses all the internal ram 
int y[999999999999]; //this would have to be in external ram or it wouldn't fit 

Imagino que me había necesidad de decir algo acerca de los límites de que cada tipo de memoria es o tengo todo mal y el hardware lo descubre por sí mismo? ¿Los scripts del enlazador lidian con esto? Sé que tienen algo que ver con el mapeo de la memoria, pero no sé exactamente qué hacer. Después de leer acerca de cómo configurar un compilador cruzado ARM me da la sensación de que algo como winavr (avr-gcc) estaba haciendo muchas cosas como esta detrás de escena para no tener que lidiar con eso.

Perdón por dar vueltas un poco, pero realmente agradecería que alguien pudiera decirme si estoy en el camino correcto con estas cosas.

actualización

Para cualquier futuros lectores que encontré esto después de unas horas de googlear http://www.bravegnu.org/gnu-eprog/index.html. Combinado con las respuestas aquí me ayudó mucho.

+0

Es posible que desee preguntar en http://electronics.stackexchange.com/. También es posible que desee consultar la [hoja de datos de Stellaris] (http://www.ti.com/lit/ds/spms257a/spms257a.pdf). –

Respuesta

11

En general, así es exactamente como funciona. Debe configurar correctamente el hardware y/o el hardware puede tener cosas codificadas en direcciones fijas.

Puede hacer la misma pregunta, ¿cómo sabe el hardware que cuando escribo un byte en la dirección 0x21000010 (lo inventé) que ese es el registro de espera de transmisión uart y que escribir significa que quiero enviar un byte ¿fuera el uart? La respuesta porque está codificada en la lógica de esa manera. O la lógica podría tener un desplazamiento, el uart podría poder moverlo podría estar en algún otro contenido del registro de control más 0x10. cambie ese registro de control (que a su vez tiene alguna dirección codificada) de 0x21000000, a 0x90000000 y luego escriba a 0x90000010 y otro byte sale de la uart.

tendría que mirar a esa parte en particular, pero si es compatible con la memoria externa, a continuación, en la teoría de que es todo lo que tiene que hacer saber cuáles son las direcciones en el espacio procesadores de direcciones se asignan a la memoria externa y lee y escribe causará accesos de memoria externa.

Las computadoras basadas en Intel, PC, tienden a gustarle a un gran espacio de direcciones, use el comando lspci en su caja Linux (si tiene una) u otro comando si tiene Windows o Mac, y encontrará que su video a la tarjeta se le ha dado un pedazo de espacio de direcciones.Si atraviesa la protección de la CPU/sistema operativo y debe escribir a una dirección en ese espacio, saldrá directamente del procesador a través de los controladores pcie y dentro de la tarjeta de video, ya sea causando estragos o simplemente cambiando el color de una pixel Ya ha tratado esto con su avr y msp430s. Algunas direcciones en el espacio de direcciones son flash, y algunas son ram, hay algo de lógica fuera del núcleo de la CPU que mira el bus de direcciones de núcleos de la CPU y toma decisiones sobre dónde enviar ese acceso. Hasta el momento en que el banco flash y el banco ram y la lógica están contenidos dentro de los límites del chip, esto no es mucho más allá de que la lógica responda a una dirección, y de ahí se crea un ciclo de memoria externo, cuando es hecho o el resultado vuelve en una lectura que completa el ciclo de la memoria interna y usted pasa a la siguiente.

¿Tiene sentido o lo estoy empeorando?

+0

Eso tiene perfecto sentido para mí, una cosa que todavía no entiendo: ¿tendría que asignar manualmente variables en el ram externo/interno en C? No esperaría que la pila sea lo suficientemente inteligente como para saltar el límite interno/externo, pero ¿qué ocurre si declaro una tonelada de variables globales? ¿Hay alguna manera de decir algo como "poner esta variable en el ariete interno si cabe, de lo contrario, hacerlo vivir en el ariete externo"? – nightrain

+0

ese tipo de preguntas no son específicas de la memoria externa, tienes que administrar tu memoria sin importar en qué plataforma estés. Es probable que necesites tomar el control del enlazador para colocar lo que quieras colocar en esa memoria. corriendo en un sistema embebido tienes que administrar tu pila y montón si usas uno para asegurar que ninguno choca con algo. toneladas de globales es una forma segura de hacerlo, pero no necesariamente eficiente con la memoria. –

+1

para herramientas gnu/gcc hay un script enlazador, ya sea que lo haya escrito o esté enterrado en el compilador en alguna parte y se elija un script basado quizás en el procesador o tipo de sistema que elija. puedes anular eso y usar el tuyo propio. Los scripts del enlazador gnu/gcc son configurables y potentes hasta un punto que puede ser doloroso de crear y usar, puede ajustar a mano la ubicación de cada archivo, tal vez incluso hasta funciones o variables. Normalmente quiere que su pila esté en la memoria más rápida. –

0

Puede usar el registro de palabras reservadas para sugerir al compilador que ponga esa variable en una ubicación de la memoria interna: register int iInside; Tenga cuidado; el compilador sabe cuántos bytes de almacenamiento de registros están disponibles, y cuando todo el espacio disponible se va, no tendrá importancia.

Utilice las variables de registro solo para elementos que se van a utilizar muy, muy frecuentemente, como los contadores.

+0

'RAM interna' no significa registros de CPU. También OP quiere hacer lo más opuesto: usar memoria externa (un chip separado del μC) –

Cuestiones relacionadas