Secuencia de Arranque e Inicialización¶
Esta página describe el flujo completo de arranque del sistema LAMULA DRx, desde que se aplica energía a la placa ZedBoard hasta que las tareas de FreeRTOS entran en su bucle de ejecución permanente.
Secuencia General de Arranque¶
El proceso de arranque combina la etapa bare-metal gestionada por la First Stage Boot Loader (FSBL) de Xilinx con el arranque síncrono del firmware sobre FreeRTOS.
sequenceDiagram
autonumber
participant HW as Hardware / Zynq BootROM
participant FSBL as FSBL (OCM / Standalone)
participant PL as Lógica Programable (FPGA)
participant C as main() / main_thread (FreeRTOS)
participant HW_DRV as Drivers HW (Timing / Stimulus / Ray)
participant SCHED as Scheduler FreeRTOS / Tareas
HW->>FSBL: Carga FSBL desde OCM
FSBL->>FSBL: Inicializa relojes PS (PLL), MIO y DDR3 (ps7_init)
FSBL->>PL: Programa Bitstream (system.bit) vía PCAP
FSBL->>C: Carga y salta a drx_app.elf en DDR3
C->>C: main() crea main_thrd y llama a vTaskStartScheduler()
C->>HW_DRV: DrxTiming_Start() (Configura motor PRF y valida D-09)
C->>HW_DRV: DrxStimulus_Init() (Ventana AXI-Lite BRAM v11 + SelfTest)
C->>HW_DRV: DrxRay_Init() (Crea anillo BD DMA S2MM + hilos)
C->>HW_DRV: DrxControlBoot_SelfTest() & DrxAfcApp_Init()
C->>SCHED: DrxStatusTask_Create() (Arranca tarea de estado/BITE)
C->>SCHED: lwip_init() -> Crea NW_THRD (red Ethernet 1GbE)
C->>SCHED: DrxTransportTask_Create() & vTaskDelete(NULL)
Detalle Paso a Paso de main_thread¶
La función main_thread() (fw/src/app/main.c) ejecuta la secuencia de inicialización del sistema en un orden estrictamente controlado:
1. Inicialización del Motor de Timing (DrxTiming_Start())¶
- Ruta:
fw/src/app/drx_timing_cfg.c. - Por qué ocurre primero: En reset, todos los registros de timing valen
0. La lógica D-09 rechaza unpulse_widthde 0 y marcaTIMING_STATUS = 0x6. Si la tarea de monitoreo de estado arrancara antes, imprimiría falsos positivos de error por UART. - Acciones:
- Inhabilita el secuenciador (
DrxReg_TimingDisable()). - Escribe los parámetros de PRF, ancho de pulso, retardos y cantidad de celdas (bins).
- Relee los registros por AXI-Lite (
DrxReg_VerifyTimingConfig()) para descartar fallos en el bus AXI. - Limpia los bits sticky de reset en
TIMING_STATUS. - Habilita el secuenciador (
DrxReg_TimingEnable()) y confirma queTRIG_COUNTincrementa.
2. Inicialización de la Ventana de Estímulo (DrxStimulus_Init())¶
- Ruta:
fw/src/app/drx_stimulus.c. - Acciones: Verifica que la versión del mapa de registros sea 11. Habilita el flag
vector_loadenCTRL, carga por AXI-Lite el vector de tono nominal en la BRAM devector_source, fija la longitud a 4000 muestras y ejecuta autopruebas de saturación.
3. Inicialización del Anillo DMA y Sumidero de Rayos (DrxRay_Init())¶
- Ruta:
fw/src/app/drx_ray.c. - Acciones:
- Inicializa el controlador AXI DMA (
XAxiDma_CfgInitialize). - Asigna e invalida la caché para los
DRX_RAY_BUFFERS(16 buffers circulares en DDR3). - Crea el anillo de descriptores Scatter-Gather (
XAxiDma_BdRingCreate). - Instala el manejador de interrupción
ray_isren el GIC (IRQ ID 61). - Crea la tarea de recepción
drx_ray(DrxRayTask_Create()) y encola los buffers iniciales.
4. Autoprueba del Plano de Control y AFC¶
- Ruta:
fw/src/app/drx_control_boot.cyfw/src/app/drx_afc_app.c. - Acciones: Ejercita el reconocedor de tramas del contrato DRx↔DSP con tramas sintéticas antes de abrir cualquier socket de red, verificando que una actualización de AFC cambia la palabra
NCO_PINCcorrectamente.
5. Arranque de la Tarea de Estado (DrxStatusTask_Create())¶
- Ruta:
fw/src/app/drx_status_task.c. - Acciones: Inicia la tarea
drx_statuspara realizar el sondeo periódico (cada 1000 ms) de los registros de error sticky (W1C).
6. Inicialización de Red lwIP y Transporte TCP¶
- Acciones:
- Invocación de
lwip_init(). - Creación de la tarea de red
NW_THRD(network_thread). - Adición del adaptador EMAC (
xemac_add) con dirección IP estática192.168.1.10. - Creación de la tarea
DrxTransportTaskque abre el socket servidor TCP en el puerto 5000 (DRX_DSP_TCP_PORT). - Eliminación de la tarea
main_thrdmediantevTaskDelete(NULL).
Admoniciones sobre Trampas Comunes de Arranque¶
Trampa 1: Intentar comunicar con la PL antes de verificar VERSION
Llamar a funciones del driver AXI-Lite sin verificar previamente DrxReg_Version() puede causar comportamientos impredecibles si el bitstream cargado en la PL no coincide con el mapa de registros que compiló el firmware.
Trampa 2: Carga de descriptores DMA y coherencia de caché
El controlador AXI DMA escribe los rayos directamente en la memoria RAM DDR3 sin pasar por la L1/L2 cache del procesador Cortex-A9. Antes de entregar un buffer al DMA en submit_buffer(), es obligatorio invalidar el rango de direcciones con Xil_DCacheInvalidateRange(); de lo contrario, un write-back posterior del procesador sobreescribirá los datos del rayo recién llegado.