7 votos

Método o función para determinar si el puntero es la dirección en flash o memoria RAM?

Estoy trabajando con un ARM Cortex M4 microcontrolador que tiene un DMA, periférico o controlador de DMA. Uno de los requisitos de la DMA es que no puede tener acceso a los punteros a direcciones que existen en flash, pero sólo los punteros a direcciones que están en la memoria RAM. Hay una manera para determinar si una determinada puntero que señala a flash o memoria RAM?

Si no, yo creo que es necesario inicializar realmente un buffer en RAM, a continuación, strcpy, o algo parecido a la transferencia de lo que es en flash en la memoria RAM para el DMA puede leer. ¿Alguien sabe de una mejor manera de hacer esto para no perder el tiempo de la CPU si no hay manera de saber si el puntero apunta a flash o memoria RAM?

Este es un Atmel SAM4S.

5voto

Dan Auclair Puntos 3063

Principal problema con la comprobación de si un puntero está en el rango específico es, lamentablemente, la C de la norma en sí misma. Aritmética de punteros tiene definido un comportamiento sólo si se realiza en los punteros del mismo tipo dentro del rango de memoria de un mismo objeto (es decir, dentro de la misma asignado rango de matriz). Un los operadores de comparación se definen como las operaciones aritméticas, esta restricción no se aplica a ellos también. Una solución para este problema sería la fundición de la punteros a la uintptr_t tipo definido en stdint.h, que es de tipo entero garantizado para mantener un valor de puntero. Y, a continuación, realizar sus comparaciones.

Ahora a la parte de la obtención del derecho de los límites. Normalmente, un C proyecto podría contener algún tipo de linker script de la definición de regiones de memoria de la arquitectura específica. Comúnmente se incluyen líneas similares a las siguientes:

MEMORY
{
    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x40000
    SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x8000
}

luego, en la misma secuencia de comandos las siguientes definiciones se pueden añadir:

  _flash_start = ORIGIN(FLASH);
  _flash_end = ORIGIN(FLASH) + LENGTH(FLASH);

Y, a continuación, en el código de C estos símbolos se puede acceder mediante:

extern int _flash_start ;  
extern int _flash_end;

Y, a continuación, una parte difícil: La dirección de la _flash_start corresponderá a la flash a partir de la dirección, y la dirección de la _flash_end corresponderá a la flash de la dirección final. I. e. el &_flash_start y &_flash_end están dando el rango deseado.

5voto

okysabeni Puntos 244

Si el MCU sigue el ARM Cortex convenciones, usted puede mirar en el nibble superior de la dirección en cuestión:

int
inflash_p(void *addr)
{
    uintptr_t addr_int = addr;
    unsigned int addrtype = addr_int >> 28;

    // 0 = flash, 1,2 = ram, 4 = periph, e = system
    return (addrtype == 0);
}

5voto

GetFree Puntos 495

Conoce el mapa de memoria de tu microcontrolador, así que usted puede simplemente prueba el puntero contra el inicio y el final direcciones de la memoria RAM. En la mayoría de los casos su linkerscript proporcionará a estas direcciones, por lo que no es necesario escribirlas en sí mismo (los detalles se depende de yourlinkerscript). Tenga en cuenta que wehen utilizar el linkerscript, los valores no se conoce en tiempo de compilación, por lo que el compilador no puede optimizar comparisions contra el saber de los punteros.

2voto

Al pacino Puntos 415

Usted puede convertir el puntero a un entero, entonces comparar su valor con el flash de espacio de direcciones como se define en el MCU del mapa de memoria. Por ejemplo, si el flash la memoria está en direcciones 0x10000000 - 0x1001ffff, se podría hacer:

void DMA_Function(uint8_t *ptr)
{
    uint32_t ptrAddress = (uint32_t)ptr;

    if (ptrAddress >= 0x10000000 && ptrAddress < 0x10020000)
        //The address is in flash
    else
        //The address is not in flash

    ...
}

Por supuesto, en el código real es mejor usar constantes en lugar de direcciones codificadas de forma rígida -- FLASH_START_ADDR y FLASH_END_ADDR, por ejemplo. Si quieres ser extra-flexible puede definir enlazador de variables para el flash de direcciones, lo que mantiene las direcciones de su código fuente completo.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X