Tests Azure Sphere + LoRa Click

Dans mon précédent article, je vous parlais de mon test de passerelle LoRa opérée par Azure IoT Hub, j’avais démontré l’utilisation de LoRaWAN avec un appareil concocté par mes soins sans vous en apporter plus de détails.

Azure Sphere MT3620 Kit

Il est temps maintenant d’expliquer comment j’ai réalisé cette démonstration.

Azure Sphere

D’abord un petit tour d’horizon de Azure Sphere. Il s’agit d’une plateforme applicative sécurisée pour des appareils IoT. Il est composé d’un MCU connecté et sécurisé, d’un système d’exploitation sécurisé et d’un service cloud permettant de garantir la sécurité de l’appareil au travers de fonctionnalités comme le monitoring de sécurité, de la mise à jours de l’OS (FOTA), …

Le MCU Azure Sphere est donc un micro-contrôleur sécurisé et certifié par Microsoft. Il a été désigné spécialement pour réaliser des solutions d’IoT Sécurisés. Il est constitué de 4 cœurs physiques aux responsabilités séparées :

  • Cœur Pluton : chargé de toutes les fonctions de sécurité (cryptographie, démarrage sécurisé, …),
  • Processeur ARM Cortex-A : capable d’exécuter des applications générales et l’OS Linux embarqué. 2 environnements d’exécution y sont présents, le « Normal World » où s’exécute le système d’exploitation, les services standards, vos applications générales et le « Secured World » où est exécuté le moniteur de sécurité de Microsoft.
  • Processeur ARM Cortex-M : capable d’exécuter des applications « Temps Réel » ou des systèmes d’exploitations Temps Réel (RTOS). Les applications RT peuvent communiquer avec les entrées/sorties et avec des applications générales.
  • Cœur de connectivité : fournit les briques de communication Wifi accessibles par le noyaux linux et les applications générales.

Autour de tout cela, s’exécute un Firewall (pas au sens réseaux) qui permet de contrôler les accès aux entrées/sorties aux périphériques, imposer un cloisonnement entre les applications générales et ainsi protéger également le cœur d’exécution temps réel.

Enfin, Azure Sphere est connecté à des services de sécurité Azure Sphere permettant de réaliser notamment le monitoring de sécurité de vos appareils, la mise à jour en continue de l’OS le démarrage sécurisé de votre appareil (permettant de contrôler l’attestation de l’OS et vérifie qu’il démarre avec le bon logiciel, mais également avec la bonne version). Pour permettre cela, Azure Sphere s’authentifie auprès de ce service par Certificats SSL auprès des services Azure et/ou du cloud privé).

Plus d’infos sur :

Avnet MT3620 Kit

Dans mon cas, je me suis procuré un Starter Kit de chez Avnet (partenaire Microsoft), basé sur une puce MT3620, possédant également quelques sensors, LED et connecteurs (GROVE et Click) me permettant de démarrer rapidement des prototypes. Elle coûte 67,50 € Avnet : AES-MS-MT3620-SK-G by Avnet Engineering Services Evaluation & Development Kits | Avnet Europe.

Afficher l’image source

MIKROE LoRa Click

Comme nous l’avons vu, le kit MT3620 que j’ai possède deux interfaces Click permettant d’étendre les fonctionnalités de la carte avec d’autres modules. Pour la connectivité LoRa il existe par exemple le click LoRa fournit par MIKROE : LoRa Click | Mikroe que l’on peut avoir pour moins de $50.00 USD.

Comme nous pouvons le constater, le LoRa Click est en fait simplement une puce RN2483 bien connue et qui peut aussi facilement s’utiliser sur un Arduino. Cette puce communique au travers du protocole UART également disponible dans le SDK de base de Azure Sphere.

Mes anciens étudiants de l’UCA se rappellerons certainement en lisant cet article de la communication avec un Modem au travers de commandes AT (Hayes) que nous avions mis en œuvre avec des Arduino et des Modem xBee durant nos TPs…

Démarrage Azure Sphere

Démarrer avec le SDK de Azure Sphere est assez simple et plutôt bien documenté sur le site de Microsoft : Documentation Azure Sphere | Microsoft Docs

Pour démarrer, voici les pré-requis :

  • PC avec Windows 10 à jours ou Linux Ubuntu 18.04 LTS ou 20.04 LTS,
  • Visual Studio (ou Code),
  • Le SDK Azure Sphere (dont la CLI Azure Sphere).

Une fois tout préparé, nous sommes guidés vers l’enrollement de l’appareil Azure Sphere sur les services. Hé oui, comme nous l’avons vu, notre appareil sera connecté aux services Azure afin qu’il puisse bénéficier de toutes les fonctionnalités de sécurité qui sont apportés (dont la mise à jour OTA). Il nous faudra alors nous enregistrer chez Azure Sphere, créer ou rejoindre un Tenant Azure Sphere et revendiquer votre appareil.

Une fois ces premières étapes réalisées, vous pourrez alors connecter votre appareil à votre réseau Wifi, permettant ainsi à votre appareil de se connecter sur les services Azure Sphere et de télécharger ses mises à jour.

Toutes ces opérations se font via la CLI AzSphere que vous aurez installé avec le SDK.

Création de l’application LoRa

Maintenant que notre appareil est prêt à être utilisé. Nous allons pouvoir démarrer une nouvelle application générale Azure Sphere pour créer notre application LoRa.

Une fois notre squelette d’application démarrée, vous pourrez, comme moi, commencer par vous amuser avec le sample « Blink », à l’étendre avec la capture de quelques données de sensors. Puis à un moment, vous vous direz (comme moi), qu’il est temps de tester ce fameux Click LoRa et vous aurez certainement une déception. A mon grand étonnement également, je n’ai pas trouvé de SDK disponible sur Azure Sphere me permettant de communiquer avec le Click LoRa MIKROE (même chez eux). Et comme me l’a dit un sage : c’est une excellente nouvelle, au moins tu n’as pas de contraintes …. (je la ressortirais celle-là!)

HAL et Driver LoRa Click

Alors, c’est parti ! J’ai gratté dans les repositories publiques de MikroE et je suis tombé sur le driver et les samples du LoRa Click : MikroElektronika/LoRa_click: Library for RN2483 / RN2903. (github.com), excellente nouvelle puisque nous avons ici le header C pour réaliser l’implémentation Hardware et du driver :

Library SDK for LoRa MIKROE Click

Vous y retrouverez également les samples d’implémentation pour Arduino par exemple…

Alors ce driver est une excellente base pour mon implémentation, puisqu’elle prend en charge toutes les spécificités de la communication UART avec la puce RN2483 (seconde boucle de retours, etc…). Ceci-dit, il a fallut que je les customise pour tenir compte de certaines contraintes C de notre Azure Sphere. Fort heureusement, la communication UART, n’est vraiment pas compliquée (y compris avec Azure Sphere), la documentation Azure à ce sujet est d’ailleurs disponible : Use UARTs in high-level applications – Azure Sphere | Microsoft Docs.

Voici l’implémentation HAL que j’en ai tiré :

#include <errno.h>
#include <stdio.h> 
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>

#include <applibs/log.h>
#include <applibs/uart.h>
#include <applibs/gpio.h>

#include "peripheral_utilities.h"
#include "LoRa_ChipConfig.h"

static int UART_FD;
static int RST_FD;
static int CS_FD;

/** @defgroup LORA_HAL_UART HAL UART Interface */             /** @{ */

/**
 * @brief Map UART Function Pointers
 */
bool LoRa_hal_uartMap(void) {
  // Create a UART_Config object, open the UART and set up UART event handler
  UART_Config uartConfig;
  UART_InitConfig(&uartConfig);
    
  uartConfig.baudRate = 57600;
  uartConfig.dataBits = UART_DataBits_Eight;
  uartConfig.parity = UART_Parity_None;
  uartConfig.stopBits = UART_StopBits_One;
  uartConfig.flowControl = UART_FlowControl_None;

  UART_FD = UART_Open(LORA_UART_RXTX, &uartConfig);

  if (UART_FD == -1) {
    Log_Debug("ERROR: Could not open UART: %s (%d).\n", strerror(errno), errno);
    return false;
  }

  return true;
}

/**
 * @brief Map UART GPIO Pointers (CS, RST Pin)
 */
bool LoRa_hal_gpio_gpioMap(void){ 
  RST_FD = GPIO_OpenAsOutput(LORA_UART_RST, GPIO_OutputMode_PushPull, GPIO_Value_High);

  if (RST_FD == -1) {
    Log_Debug("ERROR: Could not open rst GPIO: %s (%d).\n", strerror(errno), errno);
    return false;
  }

  CS_FD = GPIO_OpenAsOutput(LORA_UART_CS, GPIO_OutputMode_PushPull, GPIO_Value_Low);

  if (CS_FD == -1) {
      Log_Debug("ERROR: Could not open cst GPIO: %s (%d).\n", strerror(errno), errno);
      return false;
  }

  return true;
}

/**
 * @brief Closes the LoRa UAR and GPIO Pointers
 */
void LoRa_hal_close(void)
{
  CloseFdAndPrintError(UART_FD, "LORA_UART_RXTX");
  CloseFdAndPrintError(CS_FD, "LORA_UART_CS");
  CloseFdAndPrintError(RST_FD, "LORA_UART_RST");
}

/**
 * @brief Sets the CS Pin at the input level
 */
void LoRa_hal_gpio_csSet(uint8_t input){ 
  GPIO_SetValue(CS_FD, input);
}

/**
 * @brief Sets the RST Pin at the input level
 */
void LoRa_hal_gpio_rstSet(uint8_t input){ 
  GPIO_SetValue(RST_FD, input);
}

/**
 * @brief hal_uartWrite
 *
 * @param[in] input tx data byte
 *
 * Function writes one byte on UART.
 */
void LoRa_hal_uartWrite(uint8_t input) {
  write(UART_FD, &input, 1);
}

/**
 * @brief hal_uartRead
 *
 * @return rx data byte
 *
 * Function reads one byte.
 */
ssize_t LoRa_hal_uartRead(uint8_t *ret)
{
  return read(UART_FD, ret, 1);
}

Vous avez la HAL, parfait, l’implémentation du driver est quasi identique à celle présente dans le repository de Mikro Elektronika. Quelques adaptations pour utiliser la librairie standard « strings.h » pour strcmp…. vous retrouverez mon implémentation sur mon repository Github pour plus de détails : kbeaugrand/Sphere-LoRa-Sample (github.com).

Et voilà, nous avons créé notre SDK LoRa pour Azure Sphere.

Connexion au réseau LoRa

Allez, c’est parti pour nous connecter à notre réseau LoRa depuis le code de notre application générale Azure Sphere. Pour ce faire, maintenant, nous allons utiliser le SDK que nous avons adapté pour notre hardware pour communiquer directement avec la puce RN2483.

Vous trouverez les références des commandes du module LoRa ici : RN2483 LoRa Technology Module Command Reference User Guide.

Voici par exemple les étapes pour configurer le module avant de s’y connecter :

char tmp_txt[ 50 ];

lora_init();
lora_process();

// start
lora_cmd( "mac reset 868", &tmp_txt[0]);
lora_cmd( "mac set deveui 9ABB196487A3E9D3", &tmp_txt[0]);
lora_cmd( "mac set appeui F33F1B9432896391", &tmp_txt[0]);
lora_cmd( "mac set appkey ****************************", &tmp_txt[0]);
lora_cmd( "mac set adr off", &tmp_txt[0]);
lora_cmd( "mac set ar off", &tmp_txt[0]);
lora_cmd( "mac save", &tmp_txt[0]);

Et enfin, voici pour rejoindre le réseau LoRa :

static bool connected = false;

static void TryConnectToLoRaNetwork(void)
{
    if (connected)
    {
        return;
    }

    lora_join( "otaa", &tmp_txt[0]);

    if ( strcmp(trim(tmp_txt), "accepted") == 0 ){
        Log_Debug("Device successfully connected.\n");
        connected = true;
    }
    else {
        Log_Debug("Device is not connected: %s\n", tmp_txt);
    }
}

Et finalement la méthode pour envoyer un message LoRa :

static void TrySendMessage(void)
{
    if (!connected)
    {
        Log_Debug("Cannot send a message since the device is offline.");
        return;
    }

    uint8_t resp = lora_mac_tx("cnf", "1", "48656C6C6F", &tmp_txt[0]);

    if ( resp != 0) {
        Log_Debug("Packet was not transmit: %d", resp);
    }
}

Conclusion

C’est parti pour le démarrage de l’application. Dans mon cas avec VSCode (et ce sera pareil avec Visual Studio), il suffit de faire un F5, l’application sera alors déployée sur votre carte et vous serez attaché au debugger vous permettant ainsi de mettre vos points d’arrêt et d’inspecter les variables de votre application.

Nous pourrons vérifier la connexion de l’appareil au réseau LoRa dans la console de sortie de l’application :

Starting debugger....
Process /mnt/apps/9df6877b-82a4-44c4-9f72-586c3288b9ee/bin/app created; pid = 40
Listening on port 2345
Remote debugging from host 192.168.35.1, port 1082
Opening SAMPLE_BUTTON_1 as input.
LoRa/UART Driver Initialized...
[DEBUG] UART > mac reset 868
[DEBUG] UART < ok
[DEBUG] UART > mac set deveui 9ABB196487A3E9D3
[DEBUG] UART < ok
[DEBUG] UART > mac set appeui F33F1B9432896391
[DEBUG] UART < ok
[DEBUG] UART > mac set appkey D6FE7596B8974EBF09314AC0C17AB307
[DEBUG] UART < ok
[DEBUG] UART > mac set adr off
[DEBUG] UART < ok
[DEBUG] UART > mac set ar off
[DEBUG] UART < ok
[DEBUG] UART > mac save
[DEBUG] UART < ok
[DEBUG] UART > mac join otaa
[DEBUG] _lora_par : ok
[DEBUG] _lora_repar : accepted
Device successfully connected.
[DEBUG] UART > mac tx cnf 1 48656C6C6F
[DEBUG] _lora_par : ok
[DEBUG] _lora_repar : mac_tx_ok
[DEBUG] UART > mac tx cnf 1 48656C6C6F

Notre application est désormais connectée à notre réseau LoRa WAN, il est alors possible d’envoyer nos messages « Hello » sur le réseau et le tour est joué.

Nous avons donc assez facilement réussi à créer notre prototype Azure Sphere connecté en LoRa et si vous avez vu mon précédent article, mon appareil est connecté à un réseau LoRa dont les devices sont authentifiés au travers de Azure IoT Hub …

2 commentaires sur “Tests Azure Sphere + LoRa Click

Votre commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l’aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l’aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s