lunes, 18 de agosto de 2025

Nuevas recetas BitBake de Yocto

Estoy emocionado de anunciar un conjunto de nuevas recetas BitBake para Yocto que desarrollé, ya disponibles en GitHub. Estas recetas han sido diseñadas para facilitar la integración de funcionalidades clave en imágenes Yocto, especialmente orientadas a dispositivos como el Raspberry Pi. ¡Vamos a conocerlas!


1. wiringpi_yocto_recipe

Una receta para integrar la conocida biblioteca WiringPi, que permite el control eficiente de los pines GPIO de Raspberry Pi. Biblioteca popular escrita en C que accede directamente a registros de hardware, ofreciendo alta performance .

Aunque WiringPi habia sido deprecated previamente por su autor y otro maintainer, su compatibilidad con múltiples modelos de Pi, su desempeño superior y su uso extendido la hacen mas vailiosa que otras alternativas. Esta receta permite reconstruir su integración con Yocto fácilmente.

https://github.com/virtuosonic/wiringpi_yocto_recipe 


2. tzupdate-yocto-recipe

Una receta para integrar tzupdate, útil para configurar automáticamente la zona horaria a partir de geolocalización. Ideal para sistemas embebidos que arrancan en zonas horarias dinámicas o globales, asegurando que los relojes del sistema siempre estén sincronizados con la ubicación del dispositivo.

https://github.com/virtuosonic/tzupdate-yocto-recipe 


3. raspiserialnumber-yocto-recipe

Esta receta permite obtener el número de serie del Raspberry Pi directamente desde la imagen Yocto. Altamente útil para sistemas que requieren identificación única (como en IoT, despliegues masivos, sistemas de inventario), sin dependencias externas ni parches manuales.

https://github.com/virtuosonic/raspiserialnumber-yocto-recipe 


4. qtmainloopwdt_yocto_recipe

Una receta que combina Qt —popular framework para interfaces gráficas— con un watchdog (WDT) basado en main loop y QThread. Perfecta para aplicaciones que requieren interfaz gráfica y supervisión de salud del sistema. Ideal para proyectos donde la estabilidad y la interacción con el usuario son críticas.


¿Por qué son relevantes estas recetas?

  • Especialización fábrica-de-código embebido: Cubre desde manejo de hardware (WiringPi), ajustes del sistema (zona horaria), identificación de dispositivos (serial number), hasta monitoreo y UI (Qt + watchdog).

  • Facilitan el desarrollo Yocto: Integraciones listas para usar que ahorran tiempo frente a escribirse desde cero.

  • Flexibilidad en despliegue de Raspberry Pi: Aportan herramientas robustas para hacer imágenes Yocto más completas y adaptables.

  • Alineadas con prácticas Yocto: Cada recipe podría implementarse siguiendo las pautas de meta-layers, conf, machine, etc., destacadas en la documentación Yocto.


Conclusión

Estas recetas representan un aporte valioso para cualquier desarrollador embebido que trabaje con Yocto y Raspberry Pi. Desde controlar pines GPIO con WiringPi, hasta automatizar la zona horaria, obtener el serial del dispositivo, y combinar interfaces gráficas con watchdogs: cubren un espectro importante.

¿Necesitas consultoria referente a yocto? Contactame con el formulario de la derecha.

lunes, 14 de julio de 2025

MCP en C++: Implementaciones del Model Context Protocol en el Lenguaje de Alto Rendimiento

Model Context Protocol (MCP) se está convirtiendo rápidamente en una de las tecnologías más comentadas en el mundo del desarrollo de software moderno. Aunque C++ no es uno de los lenguajes oficialmente soportados por MCP, la comunidad ha comenzado a desarrollar sus propias implementaciones, ofreciendo opciones viables para quienes trabajan en entornos de alto rendimiento o sistemas embebidos.

¿Qué es MCP (Model Context Protocol)?

MCP, o Model Context Protocol, es un protocolo moderno para la interacción entre modelos y su contexto en tiempo real. Está diseñado para resolver problemas de sincronización, eficiencia y extensibilidad en arquitecturas distribuidas y orientadas a modelos, siendo especialmente útil en aplicaciones como gemelos digitales (digital twins), interfaces gráficas reactivas y sistemas de control.

Aunque MCP cuenta con soporte oficial en lenguajes como Python, JavaScript y Go, el soporte para C++ aún es experimental y no estandarizado.

C++ y MCP: Libertad y Rendimiento

El ecosistema de C++ es famoso por su flexibilidad y alto rendimiento, pero también por la falta de estandarización cuando se trata de nuevas tecnologías como MCP. Al no haber una implementación oficial, los desarrolladores deben elegir entre varias bibliotecas comunitarias que ofrecen distintos enfoques para integrar MCP en sus aplicaciones C++.

Implementaciones MCP en C++

A continuación, una lista de las implementaciones MCP en C++ que hemos encontrado hasta ahora:

  1. 🔗 Qihoo360/TinyMCP
    Una implementación ligera del protocolo MCP, diseñada para casos de uso mínimos o embedded. Destaca por su simplicidad y bajo consumo de recursos.

  2. 🔗 peppemas/mcp_server
    Servidor MCP escrito en C++, con enfoque en interoperabilidad y facilidad de integración en aplicaciones C++ modernas.

  3. 🔗 hkr04/cpp-mcp
    Una implementación de MCP centrada en estructuras de datos robustas y arquitectura modular. Ideal para quienes buscan una base sólida para proyectos de mayor escala.

Conclusión

Aunque C++ no tiene una implementación oficial de Model Context Protocol, ya existen varias alternativas funcionales. Esto representa una gran oportunidad para los desarrolladores que buscan combinar la potencia de C++ con la flexibilidad del protocolo MCP.

¿Usas C++ y estás considerando MCP en tu stack tecnológico? Explora estas bibliotecas, evalúa cuál se adapta mejor a tus necesidades y únete a la conversación en GitHub y otras comunidades técnicas.

miércoles, 4 de junio de 2025

Nueva forma de hacer un segmentation fault

        El segmentation fault,  segmentation violation, segfault, SIGSEGV o violación de acceso es la pesadilla de muchos, casi siempre causada por presencia de "undefined behaviour" (UB), lo primero que viene a la mente es punteros y memoria no asignada por ejemplo:

std::vector<int> *v;
v->push_back(5);

        Pero hoy les traigo una nueva forma de ocasionar un SIGSEGV sin usar punteros, memoria dinámica o malas practicas, con un objeto stack llamando a cualquier metodo va a generar un heap-buffer-overflow. Para esto vamos a crear una app con qml y C++ en Qt Creator. Después de tener el proyecto listo vamos a agregar una clase para el backend de nuestra app, esta solo tiene una función miembro que lo que hace es escribir a stderr, tiene un parámetro de tipo QVariantMap porque cuando pasas un objeto de javascript a C++ el runtime de qml lo convierte.

        En la función main vamos a crear una instancia de esa clase y hacerla accesible desde qml

        Como detonador vamos a crear una ventana con un botón, al hacer click se invoca la función con un objeto y es to inicia la reacción en cadena

        Ok, hasta aquí todo parece normal, todo es muy simple y no hay forma de que falle ¿Entonces donde esta el truco? ¡En las instrucciones de compilación! Este error lo encontre usando GCC (MinGW en windows), la biblioteca estandar incluida con GCC (libstdc++) tiene un modo debug, para activarlo hay que pasar un define al compilador: _GLIBCXX_DEBUG. Al activarlo g++ utiliza versiones debug de contenedores estandar que realizan mas verificaciones que lo normal, en la linea 7 se ve como se activa. 

        Tarde mucho en aislar el error porque tenia otros bugs y ya reparados parecia muy extraño ver un segfault en un objecto stack allocated, pero logre detectar lo que pasaba gracias al backtrace, pude ver que se estaba usando std::__debug::map en vez del regular, esto estaba causando un problema de incompatibilidad de ABI porque Qt6 esta compilado sin el modo debug y el memory layout es diferente y al querer accesar a los datos estos no estan el la misma direccion

        Para concluir surge esta pregunta: ¿Esto es UB? Se siguen todas las buenas practicas de C++ moderno en el proyecto y el código en si no tiene bugs, pero técnicamente si tiene UB porque al hacer el include el código de la biblioteca pasar a ser parte del programa, los contenedores de la biblioteca abstraen el manejo de memoria y aquí al acceder a una función a traves de una API no compatible se mostró el problema

El proyecto completo esta en mi github no olviden ponerle estrella

jueves, 29 de mayo de 2025

Compresion de videos

 Scripts con los argumentos para comprimir videos con ffmpeg



Aqui la version con compresion h265 que crea archivos mas perqueños pero tal vez sea menos compatible


jueves, 15 de mayo de 2025

Qt Creator se congela (Not responding) depurando un Segfault

 He estado desarrollando un app en windows usando Qt Creator, esta app usa ListView para mostrar datos y al hacer un cambio en el código introduje un bug de SEGFAULT a causa de usar un QList<QObjectDerived*> como modelo en vez de usar un QAbstractListModel debidamente creado para el propósito, pero lo que me pareció muy curioso(molesto) es que al después de ver el crash y volver a correr el programa con el debugger activo Qt Creator se congelaba. 

Parece ser un bug en la integración de Visual Studio, porque al usar GCC con GDB el funcionamiento es normal, el programa se detiene en el crash y se puede leer el Call Stack.

Mientras con el depurador de Microsoft solo aparece un dialogo con el texto:

Exception Triggered The inferior stopped because it triggered an exception.

 


Si alguien sabe otra solución por favor comentenla

martes, 8 de abril de 2025

Iconos gratis

 Aquí dejo una colección de links a sitios de iconos gratis

Imágenes de stock

Parece que todas las imágenes ya las puede generar la IA, pero seamos honestos: la mayoría de sus intentos de foto-realismo se ven horribles.  Aquí dejo una pequeña colección de links a imágenes de stock

martes, 1 de abril de 2025

no matching function for call to connect

Conectar un signal a un slot en Qt es tan simple como

connect(source,  &Source::Mysignal, destination, &Destination::slot);

Pero hoy recibi este error: No matching function for call to ‘MyClass::connect(QBluetoothDeviceDiscoveryAgent*&, , MyClass*, void (MyClass::*)(QBluetoothDeviceDiscoveryAgent::Error))’ 

En este caso el error es porque QBluetoothDeviceDiscoveryAgent tiene 2 miembros con el nombre "error", 

  • void QBluetoothDeviceDiscoveryAgent::error(QBluetoothDeviceDiscoveryAgent::Error error);
  • Error QBluetoothDeviceDiscoveryAgent::error() const;
Para desambiguar la llamada hay que usar un cast especificando la firma de tipado de la función

undefined reference to vtable for MyClass

 Normalmente cuando el compilador reporta el error "undefined reference to vtable for MyClass" es porque

  • Una funcion miembro sobrecargada no se marco como "virtual"
  • La funcion miembro sobrecargada no esta definida( no se ha implementado el cuerpo de la funcion)
Pero hoy encontre un caso diferente, mientras creaba una clase derivada de QObject para un servicio que usa QtBluetooth, ambos casos estaban cubiertos. El problema resulto ser que no estaba activo el MOC (Meta Object Compiler).
Para Arreglarlo solo hay que activarlo con una variable en el archivo 
CMakelists.txt



Debe ir antes del comando "add_executable"

martes, 18 de febrero de 2025

Error 15 (Lookup error.) en libmosquittopp

        He estado programando un app para monitorear una flotilla usando MQTT. Todo iba muy bien estaba programando en ubuntu 24 LTS y Qt Creator, pero a la hora de querer probarla en windows no se conectaba al broker, esto era muy raro ya que en Linux estaba funcionando perfectamente.

        Depurando encontre que mosqpp::mosquittopp::connect_async estaba retornando 15, un "Lookup error", en vez de cero que seria lo optimo, estuve googleando y no encontraba ningun caso igual, probe montones de cosas, como por ejemplo:

  • Compilar diferente version de mosquitto
  • Usar la distribucion binaria
  • Conectar a otros brokers
  • Usar la ip publica del broker directamente
  • Cambiar el DNS de windows
  • Cambiar la configuracion de red de Windows
        Despues empece a leer el codigo fuente de mosquitto y vi que el codigo de error MOSQ_ERR_EAI (15) era retornado mucho despues de fallar una llamada a getaddrinfo() entonces decidi poner una llamada a  getaddrinfo() para saber de que se trataba. 
        La invocacion de la funcion fallo pero dio un mensaje de error interesante: "Either the application has not called WSAStartup, or WSAStartup failed."
        Ya con esa informacion sospeche de la solucion correcta: algo no estaba inicializado y asi era hacia falta llamar mosqpp::lib_init(), asi que agregue al inicio del programa:

mosqpp::lib_init();
atexit([](){mosqpp::lib_cleanup();});

miércoles, 28 de febrero de 2024

Wifi en poky

        El layer estándar para Rasperry pi "meta-raspberrypi" incluye WiFi en la imagen core-image-base, pero no se inicia automáticamente en la configuración predeterminada. Aquí te cuento como iniciarlo:

  1. Inicia el servicio de red con el comando service network start
  2. Edita el archivo /etc/wpa_supplicant.conf para que incluya tu país de WiFi, nombre de red y contraseña de red
  3. Activa la interfaz de WiFi ejecutando `ifup wlan0`
        Con eso ya debería estar disponible la red, pero encaso de que wpa_supplicant no se active correctamente estos comandos pueden funcionar
  1. `wpa_supplicant -iwlan0 -c /etc/wpa_supplicant.conf`
  2. `wpa_cli -iwlan0 reconfigure`
Aqui te dejo un ejemplo del archivo /etc/wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
update_config=1
country=US

network={
        ssid="Internet"
        psk="contraseñasecreta"
}

miércoles, 14 de febrero de 2024

Mensaje de error al abrir Qt Creator

        Desde hace un tiempo cada vez que abria Qt Creator en Windows aparecia un MessageBox con el titulo "gdb.exe - System Error" y el siguiente mensaje:

The code execution cannot proceed because libpython3.9.dll was not found. Reinstalling the program may fix this problem.


        Probe unas cuantas cosas, primero lo que solicito el mensaje, desinstalar Qt por completo y reinstalar. esto no hizo ningún cambio al problema. Después el sospechoso obvio era python, probe instalar python 3.9 y nada. Desinstalé el python que ya tenia, que creo era la version 3.11, también desinstalé todas las versiones y nada. Llegue a pensar que era algo relacionado a Windows 11, ya que tengo otra maquina con Windows 10 sin este problema. Me rendí por el momento y lo deje así, ya que Qt Creator era funcional, solo era la molestia.

        Después de unos meses ignorando el mensaje, se me ocurrió si había alguna instalación conflictiva de gdb, para encontrar cual es el programa que se ejecuta en linux al invocar un comando se usa el comando which, pero Windows no cuenta con el, en cambio la alternativa que esta disponible en versiones recientes es el comando where, simplemente escribí "where gdb.exe"  dentro de windows terminal y me dio el resultado:

C:\Program Files\Inkscape\bin\gdb.exe

        Por alguna razon que desconozco inkscape incluye a gdb, así que lo borre para ver si solucionaba el problema, esta vez dejo de aparecer el mensaje, inkscape también sigue funcional, tal vez lo necesite para una funcionalidad que yo no uso.

lunes, 4 de diciembre de 2023

What are some of the worst things about C/C++?



Top 5 things I don’t like from C++

#5. std::queue
This container doesn’t have an iterator, you can access the underlying container (usually std::list or std::deque) but that doesn’t feel right.

#4. std::array
This container is useful, but it has one flaw, the size is chosen at compile time. A non resizable container that could specify size at runtime is missing.

#3. enum class
The currently recommended way to uses enums is enum class. But I'm not gonna doit, declaring them that way removes the basic operators that usually can be used with enumerator, you could use static_cast on each access to the variable, but it would look horrible. The idiomatic way would be to override operator<< for your enum class, but if you have several enum class it becomes against the DRY principle. You could say: "only create one enum class with all your values", that would be against the purpose of the enum class, avoiding asigning a non valid or duplicate value.

#2. std::map::operator[]
When using that operator passing a Key that doesn’t exists, it will create the Key

#1. std::string
This class is missing (or added really late) several functions that are available in alternatives like wxString or QString, this functions include startsWith, contains, tokenizing, converting from float with specific locale

#BONUSTRACK. The C language
Sooner or later you will need some advanced feature like databases, compression or network and the option to use a mature library written in C will be one of the best options. The bad side being that you will be mixing C++ and C idioms, it wont be pretty. Then there is the option to use a wrapper, but those get deprecated sometimes without reason.

P.D. I really like this language this are the few thing I don’t really like.

miércoles, 5 de abril de 2023

lunes, 10 de octubre de 2022

deviceready has not fired after 5 seconds.

        Un mensaje muy molesto y no muy informativo que obtenemos al desarrollar con Apache Cordova es el siguiente:
"deviceready has not fired after 5 seconds."
        Esto puede ser por que no esta actualizado Cordova. Lo mejor es quitar el platform android y volverlo a agregar 

Compilación cruzada para Raspberry Pi3 B+

https://mechatronicsblog.com/cross-compile-and-deploy-qt-5-12-for-raspberry-pi/

    Probe este tutorial, está muy bien escrito y parece que se ha revisado con la retroalimentación de los comentarios, pero tuve algunas complicaciones mientras intenté generar binarios para la Raspberry pi 3 B+

    Mi primer intento fue usando Ubuntu 20 contenido en WSL2 dentro de Windows 11. Pero tuve muchos error por variables globales no definidas y archivos de cabecera ausentes.
   En otro intento use Ubuntu 20 dentro de virtual box un problema fue que las últimas versiones de Qt no son compatibles con el compilador de este tutorial y las versiones que son usadas ya fueron movidas a el directorio de archive. https://download.qt.io/archive/qt/5.12/
    Finalmente cuando logré compilar Qt y una aplicación demo, intenté compilar uno de mis programas, pero mi programa utiliza clases que son experimentales en gcc 6.3 y el compilador del tutorial es 4.8, no pudiendo terminar de compilar por la ausencia de esas clases.

sábado, 12 de febrero de 2022

Inhabilitada - Moto G8 Power

     Esta es más una bitácora que un tutorial. Hoy el móvil de mi esposa tenía problemas conectándose al wifi, el celular es un Moto G8 Power, el modem es un Arris TG2482 de Izzi. En el estado de la wlan en android mostraba "Inhabilitada", también cuando lograba conectarse, se desconectaba después de unos minutos y solo aparecía una de las dos ESSID, la de 5GHz no era visible.  Extrañamente mi Redmi 9 funcionaba normalmente y también un Xbox one.
    Todo parecía ser un defecto en el teléfono hasta que la laptop, una HP, también presento el problema y no se listaba la wlan.
    La solución fue desconectar la corriente del módem y volverlo a conectar para reiniciarlo.

jueves, 22 de octubre de 2020

undefined reference to dladdr

        Acabo de empezar a probar la librería loguru, que esta probando ser muy util para hacer logging en C++, para compilarla simplemente agregue los dos archivos de código a mi proyecto, pero durante el enlazado tuve un error similar a:

undefined reference to dladdr

        Esta es una dependencia que no menciona la documentación, para corregirlo solo hay que para la opción -ldl al compilador o en la ventana de ajuste de enlazado del IDE agregar dl a las librerías.

jueves, 17 de septiembre de 2020

Teclado virtual para flutter

        Flutter permite crear interfaces de usuario muy bellas, algo muy deseable para implementar la interfaz de un sistema embebido usando una raspberry pi y una pantalla táctil.

        Pero un inconveniente seria que el sistema operativo raspbian no tiene un teclado on-screen que aparece automáticamente al enfocar un campo de texto como en Android y iOS y se oculte cuando ya terminamos de escribir.

        En los siguientes enlaces se describen un paquete para flutter que permite implementar esa funcionalidad.


https://pub.dev/packages/virtual_keyboard

https://pub.dev/packages/keyboard_actions

jueves, 25 de junio de 2020

MCP3002 con wiringPi

    La librería wiringPi tiene funciones para leer voltajes usando un ADC mcp3002, para esto basta hacer una llamada a la función mcp3002Setup al inicio del programa y llamar analogRead para obtener las lecturas de los sensores conectados al mcp3002.
    Pero en la ultima versión publicada antes de ser declarado obsoleto (2.50), se le agrego un error al código que ejecuta corrimiento hacia la izquierda 8 bits, siendo que anteriormente recorría 7 bits que era lo correcto.
    Este error ocasiona lecturas erróneas, por ejemplo usando un potenciometro entre el mínimo y la mitad varia entre 3 y ~890 al pasa la mitad parece que regresa a 0 y vuelve a subir.
    Ya publique la corrección en github y envié un pull request a el github de wiringPi, aquí comparto el enlace.
https://github.com/WiringPi/WiringPi/pull/78

    La otra alternativa es crear una función equivalente para no tener que re-compilar wiringPi, por ejemplo: