Secuencia de arranque, timers, work queues y FIFOs
Comenzar arrow_downwardZephyr inicializa el sistema en fases bien definidas antes de llamar a main().
Cada fase tiene un nivel de prioridad. Los drivers y subsistemas se registran con macros SYS_INIT() indicando en qué fase deben inicializarse.
Entender la diferencia es fundamental para escribir código correcto.
lightbulb Código de aplicación normal se ejecuta en contexto de thread.
Referencia rápida de qué APIs se pueden usar en cada contexto.
| Aspecto |
account_tree
Thread Context
|
bolt
ISR Context
|
|---|---|---|
| k_sleep() | Permitido | Prohibido |
| k_sem_take() con timeout | Permitido | Prohibido |
| k_sem_give() | Permitido | Permitido |
| k_mutex_lock() | Permitido | Prohibido |
| k_work_submit() | Permitido | Permitido |
k_work_submit() para diferir trabajo pesado a contexto de thread.
Un thread transita entre diferentes estados durante su ejecución.
k_sleep() pasa a Unready, k_yield() pasa a Ready, timeout completado despierta al thread.
¿Cómo decide Zephyr qué thread ejecutar a continuación?
lightbulb Menor número = Mayor prioridad
Al cambiar de thread, el scheduler guarda y restaura el estado completo:
k_yield() - cede voluntariamente
k_sleep() - espera tiempo
Ejecutar código periódicamente o tras un retardo.
Los kernel timers ejecutan un callback cuando expiran. El callback se ejecuta en contexto de ISR (System Timer interrupt).
K_TIMER_DEFINE()
k_timer_start()
k_timer_stop()
period = K_NO_WAIT
period > 0
Diferir trabajo de ISR a contexto de thread.
Los work queues permiten encolar trabajo que se ejecutara en un thread dedicado, no en ISR.
k_work_submit()
k_work_queue_init()
A diferencia de message queues, los FIFOs manejan datos de tamaño variable.
Los FIFOs almacenan punteros a datos alojados en el heap. Requieren que el primer miembro de la estructura sea void *fifo_reserved.
k_malloc()/k_free() para gestionar la memoria.
k_free(), la memoria se pierde para siempre.
¿Cuándo usar cada mecanismo de Zephyr?
| Primitiva | Características | Uso típico |
|---|---|---|
| Thread preemptible | Stack propio, puede ser interrumpido | Código de aplicación general |
| Thread cooperativo | No interrumpido por scheduler | Secciones críticas, drivers |
| System workqueue | Stack compartido, prioridad -1 | Diferir trabajo de ISR |
| User workqueue | Stack privado, más determinista | Tareas ligeras de aplicación |
| Kernel timer | Callback en ISR | Tareas periódicas cortas |
| FIFO | Datos de tamaño variable, usa heap | Comunicación con memoria dinámica |
Los tres pilares para trabajar con Zephyr avanzado.
Callback de timer y handlers de interrupcion. No bloquear.
Work handlers y código normal. Todas las APIs disponibles.
Siempre liberar memoria. Configurar CONFIG_HEAP_MEM_POOL_SIZE.
"Usa work queues para mover trabajo pesado fuera de ISR a contexto de thread."
Regla de oro: ISRs cortas, trabajo largo en threads o work queues.
Herramientas y técnicas para depurar aplicaciones Zephyr.