Estoy trabajando en un proyecto integrado que involucra E/S en registros FPGA mapeados en memoria. Los punteros a estas regiones de memoria deben marcarse como volatile para que el compilador no "optimice" las lecturas y escrituras en el FPGA almacenando en caché los valores en los registros de la CPU.
En algunos casos, queremos copiar una serie de registros FPGA en un búfer para su uso posterior. Dado que los registros están asignados a direcciones contiguas, memcpy parece apropiado, pero pasar nuestro puntero volatile como argumento fuente da una advertencia sobre descartar el calificador volatile .
¿Es seguro (y sensato) descartar la volatile del puntero para suprimir esta advertencia? A menos que el compilador haga algo mágico, no puedo imaginar un escenario en el que llamar a memcpy no pueda realizar una copia real. La alternativa es simplemente usar un bucle for y copiar byte por byte, pero las implementaciones de memcpy pueden (y lo hacen) optimizar la copia en función del tamaño de la copia, la alineación, etc.
Como desarrollador de FPGA y software integrado, solo hay una respuesta clara: no use memcpy et al. para esto
Algunos motivos:
memcpy no garantiza eso. Sin embargo, puedes usar un bucle for simple y copiarte a ti mismo. Esto es seguro, si los registros son volatile ( ver más abajo ).
Dependiendo de su plataforma, la volatile por sí sola podría no ser suficiente. El área de memoria tampoco debe almacenarse en caché y estar estrictamente ordenada (y, posiblemente, no compartida). De lo contrario, los buses del sistema podrían (y lo harán en algunas plataformas) reordenar los accesos.
Además, es posible que necesite barreras/vallas para que su CPU no reordene los accesos. Lea atentamente las especificaciones de su hardware al respecto.
Si necesita transferir bloques más grandes con más frecuencia, piense en usar DMA. Si el FPGA usa PCI(e), podría usar busmaster DMA con dispersión/recopilación, por ejemplo (sin embargo, esto no se implementa fácilmente; lo hice yo mismo, pero podría valer la pena el esfuerzo).
El mejor (y más sensato) enfoque depende en realidad de múltiples factores, como la plataforma, la velocidad requerida, etc. De todos los enfoques posibles, consideraría que usar mempcy() es uno de los menos sensatos (1) en el mejor de los casos (1): no estoy seguro si esa es la gramática correcta, pero espero que haya entendido mi punto).
Absolutamente no es seguro. No hay garantía alguna en qué orden memcpy copiará los datos y cuántos bytes se copian a la vez.