Compartir a través de


Sugerencias de diseño de aplicaciones básicas de alto nivel

Para construir una aplicación principal de alto nivel (HL) sobre cimientos sólidos, debe usar prácticas recomendadas fundamentales. Los siguientes son los más relevantes:

Las aplicaciones principales de alto nivel (HL) se ejecutan en contenedor en el sistema operativo Azure Sphere. Durante las revisiones de código y diseño de las soluciones de los clientes, hemos encontrado varios problemas típicos con las aplicaciones de HL-core. En este tema se describen sugerencias para mejoras de diseño para solucionar estos problemas.

Aspectos básicos generales

Para construir una aplicación de HL-core sobre cimientos sólidos, debe utilizar prácticas recomendadas fundamentales. Los siguientes son los más relevantes:

  • Inicialización y terminación: Asegúrese siempre de manejar la señal SIGTERM del SO Azure Sphere, e inicializar y destruir correctamente todos los controladores (como los de periféricos) al salir, ya sea por error o bloqueo. Para obtener más detalles, consulta Inicialización y terminación y la documentación de GNU sobre señales de terminación.
  • Usa siempre códigos de salida: Asegurarse de que la aplicación HL-core siempre proporciona un código de retorno significativo al salir o bloquearse (por ejemplo, usando el controlador SIGTERM) es esencial para diagnosticar correctamente el comportamiento del dispositivo, especialmente a partir de la telemetría de volcado de memoria del dispositivo. Para obtener más información, consulte Códigos de salida y Recopilar e interpretar datos de error.
  • Asegúrese de que los casos de errores siempre dan como resultado una salida o bloqueo de la aplicación en lugar de un estado de interbloqueo: Elaborar la lógica de recuperación de errores puede ser contraproducente, ya que puede introducir errores o comportamientos que provocan un interbloqueo o un estado difícil de diagnosticar. Una aplicación azure sphere bien diseñada siempre debe preferir el bloqueo o la salida (con un código de salida distinto de cero) a una situación potencial de interbloqueo, ya que esto da como resultado ambos:
    • Telemetría de errores, habilitando diagnósticos para este problema
    • Posibilidad de recuperación inmediata a un estado de trabajo, ya que el SO Azure Sphere reiniciará la aplicación
  • Control de errores y registro: El registro y el control de errores precisos son el núcleo del desarrollo de aplicaciones de calidad. Las implementaciones de funcionalidad rápida pueden permanecer enterradas en capas de código, luego construidas a medida que la aplicación se desarrolla a gran escala. Para obtener más información sobre los procedimientos recomendados, vea Control de errores y registro.
  • Use un temporizador del sistema como perro vigilante: Uno de los procedimientos recomendados más cruciales es implementar un callback de "temporizador de vigilancia" (al igual que los de hardware disponibles en los MCU de metal desnudo) que realiza un seguimiento de los estados de aplicación críticos, detectando interbloqueos y actuando en consecuencia (por ejemplo, salir y enviar telemetría). Para obtener más información, consulte Utilizar un temporizador del sistema como perro vigilante.
  • Nunca implemente aplicaciones de producción que se hayan creado dirigidas a un conjunto de herramientas de versión beta: No se recomienda usar conjuntos de herramientas de versión beta porque no se puede garantizar que el subconjunto beta no cambie en las versiones posteriores del sistema operativo. Los conjuntos de herramientas beta se publican únicamente para probar nuevas características antes de la versión oficial del SDK.

Control de la simultaneidad

  • Use EventLoop siempre que sea posible: Los subprocesos y los objetos de sincronización (es decir, silenciadores, semáforos, etc.) se usan para realizar tareas casi simultáneas, pero dentro de los sistemas incrustados son costosos en términos de uso de recursos del sistema. Por lo tanto, para mejorar el rendimiento, considere la posibilidad de usar epolls en lugar de subprocesos, para aquellas tareas que no son estrictamente críticas en el tiempo y no son sensibles al bloqueo mutuo. Vea Applibs eventloop.h para obtener información sobre cómo supervisar y distribuir eventos con EventLoop, incluidas las muestras relacionadas.
  • Busque la eficiencia en las tareas simultáneas: Es importante asegurarse de que el bloqueo de las operaciones y los tiempos de espera se mantienen al mínimo dentro de los callbacks epoll, de lo contrario, todas las demás devolución de llamada epoll se verán afectadas.
  • Cuándo usar subprocesos (pthread): Para escenarios específicos, como cuando bloquear llamadas son inevitables, el uso de subprocesos puede ser beneficioso, aunque normalmente estos escenarios tendrían una duración limitada y deberían definirse como tareas específicas. Por ejemplo, dado que el sistema operativo Azure Sphere (que ejecuta Linux) no expone LOS COEFICIENTER a aplicaciones de HL-core (esto solo está disponible para las aplicaciones RT-core), el uso de una combinación de tareas epoll y pthread podría ser óptimo para tratar, por ejemplo, una comunicación serial aguas abajo al descargar datos de Internet.

Importante

Azure Sphere OS puede interrumpir las operaciones oportunas, especialmente cuando está realizando atestación del dispositivo, buscando actualizaciones o cargando telemetría. Para las tareas de control de tiempo crítico, considere moverlas a los núcleos M4 y coordinarlas con un protocolo adecuado a través del buzón entre núcleos. Para obtener más información, consulte el ejemplo de comunicación entre núcleos.

Además de estas sugerencias, revise la documentación de Azure Sphere sobre eventos asincrónicos y simultaneidad.

Supervisión de conectividad

Una aplicación principal de alto nivel (HL) bien diseñada debe implementar una tarea adecuada de comprobación del estado de la conectividad, que debe basarse en una máquina de estado robusta que comprueba periódicamente el estado de la conexión a Internet (por ejemplo, mediante un temporizador epol ) aprovechando la API de Networking_IsNetworkingReady . En algunos casos puede usar la función Networking_GetInterfaceConnectionStatus, ya que proporciona un estado más detallado del estado de conectividad relacionado con una interfaz de red específica que la aplicación hl-core puede utilizar para abordar mejor su estado, aunque esto tiene un coste ya que no se recomienda llamarla con más frecuencia que cada 90 segundos.

La devolución de llamada de la máquina de estado suele tener los siguientes atributos:

  • Ejecute lo más rápido posible.
  • Su intervalo de sondeo debe diseñarse cuidadosamente, en función del escenario de la aplicación específica y de los requisitos generales de la solución (como tiempo constante, retraso incremental, etc.).
  • Una vez que se detecta una desconexión, puede ser útil llamar a Networking_GetInterfaceConnectionStatus una vez para registrar el estado específico de la interfaz de red, que se puede utilizar para diagnosticar el problema y notificar al usuario a través de una interfaz de usuario (como LED, pantalla, terminal). Puede encontrar una muestra de este enfoque en el código principal de la muestra DHCP de Azure Sphere.
  • Activar un mecanismo (por ejemplo, a través de una variable global) que detiene todas las demás tareas de la aplicación de HL-core que realizan (o están vinculadas) comunicaciones de red para optimizar el consumo de recursos hasta que se restablezca una conexión.
  • cURL ha actualizado recientemente el comportamiento de devolución de llamada y las mejores prácticas. Aunque Azure Sphere ha tomado medidas para garantizar que las versiones anteriores del comportamiento cURL sigan funcionando según lo esperado, se recomienda seguir las instrucciones más recientes de seguridad y confiabilidad al usar curl_multi, ya que el uso de devolución de llamadas recursivas puede provocar bloqueos inesperados, interrupciones de conectividad y posibles vulnerabilidades de seguridad. Si un TimerCallback se inicia con un tiempo de espera de 0 ms, tráelo como un tiempo de espera de 1ms para evitar devolución de llamadas recurrentes. Asegúrese también de llamar explícitamente a curl_multi_socket_action al menos una vez después de las llamadas a curl_multi_add_handle.

Además de las sugerencias anteriores, debe tener en cuenta los siguientes escenarios para la administración de energía:

  • Apaga el chip Azure Sphere después de enviar datos. Para obtener más información, consulta Administrar el estado de apagado para dispositivos Azure Sphere.
  • Dado que varios problemas pueden resultar de tiempos de espera de retroceso exponenciales largos, es fundamental realizar un seguimiento del tiempo de actividad total y establecer un temporizador de apagado en un límite razonable para no agotar la batería en condiciones en las que la conectividad ya no es posible debido a interrupciones externas u otros factores fuera del control de la aplicación.
  • Para controlar la supervisión de la conectividad durante interrupciones, el transceptor Wi-Fi puede apagarse deshabilitando la wlan0 interfaz de red (consulte Networking_SetInterfaceState y esperando hasta la siguiente comprobación de conectividad de nuevo, ahorrando aproximadamente 100 mW.

Administración y uso de memoria

En plataformas restringidas en memoria, las aplicaciones que realizan asignaciones de memoria frecuentes y desasignaciones podrían provocar que la administración de memoria del sistema operativo tenga problemas con la eficiencia, lo que podría provocar una fragmentación excesiva y la memoria agotada. Específicamente en el Azure Sphere MT3620, esto puede provocar condiciones de memoria insuficiente que podrían desencadenar el inicio del killer OOM del grupo C DEL Azure Sphere.

Es comprensible que las aplicaciones se desarrollan a menudo empezando desde una prueba de concepto inicial, que se vuelve más completa con las características necesarias para las versiones progresivas, descuidando finalmente las características menores que se incluyeron inicialmente. Las siguientes son sugerencias y optimizaciones que han demostrado ser eficaces para muchos escenarios analizados en el campo:

  • Especialmente en aplicaciones de HL-core que realizan un uso intensivo de la memoria, es esencial realizar un seguimiento del uso de memoria de la aplicación a través de azure Sphere API, que se describe en Determinar el uso de LA RAM de la aplicación en tiempo de ejecución. Normalmente esto se implementa en un perrito de vigilancia epoll-timer y la aplicación reacciona en consecuencia al uso inesperado de la memoria con el fin de reiniciar de una manera razonable; por ejemplo, salir con el código de salida adecuado.

    Varios clientes y socios han encontrado útil usar la utilidad de seguimiento de memoria Heap Tracker , que se publica en la Galería de esferas de Azure. Esta biblioteca se vincula de forma transparente a una aplicación de HL-core existente y realiza un seguimiento de las asignaciones de memoria y sus punteros relacionados, lo que permite una detección simplificada de la mayoría de los casos de fugas de memoria y usos incorrectos del puntero.

Importante

Esta práctica puede reducir la falta de respuesta o errores aparentemente inexploros del dispositivo que se notifican a menudo desde el campo. Tales fallas son causadas generalmente por fugas de memoria o sobrecargas que no son manejadas correctamente por la aplicación de HL-core y llevan al asesino de OOM a apagar el proceso de la aplicación. Esto, junto con una conectividad deficiente que impide que Azure Sphere OS envíe telemetría, puede dar lugar a posibles incidentes de campo, ya que el diagnóstico solo se puede detectar tirando de los registros de diagnóstico del SO Azure Sphere.

  • En plataformas con restricciones de memoria, generalmente es preferible evitar la asignación dinámica de memoria siempre que sea posible, especialmente en funciones llamadas frecuentemente. Esto reducirá enormemente la fragmentación de la memoria del montón y la probabilidad de errores posteriores de asignación del montón. Considere también un cambio de paradigma de asignación repetitiva de búferes de trabajo temporales a acceso directo a la pila (para variables de tamaños razonables) o búferes asignados globalmente, que aumentan en tamaño (a través realloc) al desbordamiento (vea Contenedores dinámicos y búferes). Si hay un requisito para descargar memoria, considere la posibilidad de aprovechar la memoria sin usar en los núcleos M4 (consulte Memoria disponible en Azure Sphere), que tiene 256KiB cada uno, con una aplicación rt-core ligera para el almacenamiento en caché de datos. Con el tiempo, podrías usar tarjetas SD externas o flash. Las muestras pueden encontrarse en los siguientes repositorios:

Seguir las sugerencias anteriores también puede ayudar a estimar y reservar la memoria necesaria para que la aplicación de HL-core funcione a toda su capacidad a lo largo de su ciclo de vida, al tiempo que le permite estimar mejor la superficie de memoria general de la aplicación para optimizaciones de diseño posteriores. Para obtener más información sobre la optimización del uso de memoria en aplicaciones de HL-core, incluidas las características de Azure Sphere OS y Visual Studio, consulte los siguientes artículos: