Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
La mise à jour du microprogramme du composant (CFU) est un protocole et un processus permettant d’envoyer de nouvelles images de microprogramme à installer sur l’appareil cible.
Remarque
CFU est disponible dans Windows 10, version 2004 (Mise à jour de mai 2020 de Windows 10) et versions ultérieures.
Les soumissions de CFU au microprogramme résident consistent en des paires de fichiers : un fichier constitue la partie offre, l'autre, la partie contenu. Chaque soumission CFU (chaque offre et chaque paire de contenu) doit être créée hors ligne avant que la soumission soit envoyée au microprogramme qui implémente le processus CFU.
Dans l’exemple de code source du Firmware dans le référentiel CFU sur GitHub, le code commun indépendant de l’implémentation générale pour le CFU est contenu dans ComponentFwUpdate.c. Tous les autres fichiers sont des fichiers d’assistance qui peuvent être mis à jour ou modifiés pour l’implémentation unique du développeur.
Contenu
- L’offre et les parties de contenu
L’offre et les parties de contenu
L’offre et le contenu constituent une paire de fichiers dans le schéma CFU.
La partie offre est simplement un fichier long de 16 octets qui correspond à la structure FWUPDATE_OFFER_COMMAND décrite ci-dessous.
La partie de contenu, le microprogramme réel à mettre à jour est au format dicté par le développeur de l’utilisateur final. L’exemple de code CFU fourni utilise des fichiers SREC pour le contenu du microprogramme.
L’offre est une séquence de 16 octets. Cette structure d’offre est placée dans le fichier d’offre. Il s’agit essentiellement de données binaires, et non de texte, car l’offre contient des champs de bits de signification spécifique.
L’offre représentée dans le fichier est mappée à cette structure C :
typedef struct
{
struct
{
UINT8 segmentNumber;
UINT8 reserved0 : 6;
UINT8 forceImmediateReset : 1;
UINT8 forceIgnoreVersion : 1;
UINT8 componentId;
UINT8 token;
} componentInfo;
UINT32 version;
UINT32 hwVariantMask;
struct
{
UINT8 protocolRevision : 4;
UINT8 bank : 2;
UINT8 reserved0 : 2;
UINT8 milestone : 3;
UINT8 reserved1 : 5;
UINT16 productId;
} productInfo;
} FWUPDATE_OFFER_COMMAND;
De l’adresse basse à l’adresse élevée, le premier octet de l’offre est un numéro de segment.
<------- 4 bytes -----------> <-- 8 bytes --> <-------- 4 bytes --------->
+================================-=============================================+
| 15:0 7:3 2:0 7:6 5:4 3:0 31:0 31:0 7:0 7:0 7:7 6:6 5:0 7:0 |
| PI | R1 | MS | R0 | BK | PR | VM | VN | TK | CI | FV | FR | R0 | SN |
+================================-=============================================+
De l’adresse haute à l’adresse basse :
Byte(s) Value
---------------------------------------------------------
15:14 | (PI) Product ID is 2 bytes
13 | (R1) Reserved1 5-bit register
| (MS) Milestone 3-bit register
12 | (R2) Reserved2 2-bit register
| (BK) Bank 2-bit register
| (PR) Protocol Revision 2-bit register
11:8 | (VM) Hardware Variant Mask 32-bit register
7:4 | (VN) Version 32-bit register
3 | (TK) Token 8-bit register
2 | (CI) Component ID 8-bit register
1 | (FV) Force Ignore Version 1-bit register
| (FR) Force Immediate Reset 1-bit register
| (R0) Reserved0 6-bit register
0 | (SN) Segment Number 8-bit register
---------------------------------------------------------
Détails de l’enregistrement de l’offre
ID de produit. Une valeur d’ID de produit unique pour cette image CFU peut être appliquée à ce champ.
UINT16 productID;
Jalon du microprogramme que représente le contenu de l’offre. Les jalons peuvent être différentes versions de la build HW, par exemple, la build EV1, la build EV2, et ainsi de suite. La définition de jalon et l’affectation de valeur sont laissées au développeur.
UINT8 milestone : 3;
Si le microprogramme est destiné à une banque spécifique , le champ 2 bits prend en charge quatre banques. L’utilisation d’un registre bancaire est incluse dans le format de l’offre, car il existe des instances où les appareils cibles utilisent des régions de microprogramme banque.
Si c'était le cas et que l'offre était destinée à mettre à jour une banque en utilisation, le firmware qui implémente le CFU sur la cible pourrait rejeter l'offre. Sinon, le microprogramme sur la cible implémentant le CFU peut prendre d'autres mesures si nécessaire.
Si le banquage d’images de microprogrammes n’est pas dans la conception du microprogramme de l’utilisateur final, il est raisonnable d’ignorer ce champ (défini sur des valeurs pratiques, mais la valeur dans le champ de banquage est facultative et dépend de la façon dont le microprogramme cible implémente le CFU).
UINT8 bank : 2;
La version du protocole CFU utilisée est en 4 bits.
UINT8 protocolRevision : 4;
Masque de bits correspondant à tout le matériel unique sur lequel cette image de microprogramme peut fonctionner. Par exemple, l'offre peut signifier qu'elle peut s'exécuter sur la version X du matériel, mais pas sur la version Y du matériel. La définition de bits et l’affectation de valeur sont laissées au développeur.
UINT32 hwVariantMask;
Version du microprogramme proposée.
UINT32 version;
Jeton d’octet permettant d’identifier le logiciel spécifique à l’utilisateur qui effectue l’offre. Cela est destiné à différencier les pilotes et les outils qui peuvent tous les deux essayer de mettre à jour le même microprogramme en cours d’exécution. Par exemple, un pilote de mise à jour CFU peut être affecté à un jeton 0xA et un outil de mise à jour de développement peut être affecté 0xB. À présent, le microprogramme en cours d’exécution peut choisir d’accepter ou d’ignorer les commandes en fonction du processus qui tente de le mettre à jour.
UINT8 token;
Composant de l’appareil pour appliquer la mise à jour du microprogramme.
UINT8 componentId;
proposer des indicateurs d'interprétation : si nous voulons que le micrologiciel in situ ignore l’incompatibilité de version (plus ancienne sur une version plus récente), réglez le bit pour forcer l'ignoration de la version.
UINT8 forceIgnoreVersion: 1;
La réinitialisation immédiate est forcée par un bit. Si ce bit est déclaré, le logiciel hôte s’attend à ce que le microprogramme in situ entraîne la réinitialisation de l’appareil. Les actions de la réinitialisation sont spécifiques à la plateforme. Le microprogramme de l’appareil peut choisir de prendre des mesures qui échangent les blocs mémoire pour faire du microprogramme fraîchement mis à jour le microprogramme actif in situ. Ou pas. Cela dépend de l'implémentation du firmware. L'attente est généralement que si une réinitialisation immédiate est forcée, l'appareil effectuera les actions nécessaires pour que le microprogramme mette à jour la nouvelle banque et devienne le microprogramme actif en cours d'exécution sur l'appareil cible.
UINT8 forceImmediateReset : 1;
Si la partie contenu de l'ensemble offre-contenu implique plusieurs éléments de contenu.
UINT8 segmentNumber;
Offres de traitement technique
L’API ProcessCFWUOffer accepte deux arguments :
void ProcessCFWUOffer(FWUPDATE_OFFER_COMMAND* pCommand,
FWUPDATE_OFFER_RESPONSE* pResponse)
Dans ce cas d’usage, supposons que le logiciel utilisateur envoie des octets de données au microprogramme en cours d’exécution, puis que le premier message est le message de l’offre.
Le message d’offre est un message de 16 octets décrit ci-dessus (la structure FWUPDATE_OFFER_COMMAND).
Ces données du message d'offre sont utilisées par le microprogramme en cours d'exécution pour le traitement de l'offre.
Pendant la disposition de l’offre, le firmware en cours d’exécution informe l’expéditeur en remplissant les champs de la structure FWUPDATE_OFFER_RESPONSE.
Interprétation de l’offre
Le microprogramme en cours d’exécution doit suivre son état dans le processus CFU. Il peut être prêt/en attente pour accepter une offre, au milieu d’une transaction CFU ou en attendant de changer les banques entre le microprogramme actif et inactif.
Si le firmware en cours d'exécution se trouve au milieu d'une transaction CFU, n'acceptez pas, ne traitez pas cette offre et informez l'hôte en conséquence.
if (s_currentOffer.updateInProgress)
{
memset(pResponse, 0, sizeof (FWUPDATE_OFFER_RESPONSE));
pResponse->status = FIRMWARE_UPDATE_OFFER_BUSY;
pResponse->rejectReasonCode = FIRMWARE_UPDATE_OFFER_BUSY;
pResponse->token = token;
return;
}
Le champ ID de composant de l’offre peut être utilisé pour signaler au microprogramme en cours d’exécution qu’une action spéciale est demandée à partir du microprogramme en cours d’exécution. Dans l’exemple de code CFU, une commande d’offre spéciale est utilisée par l’hôte pour récupérer l’état du moteur CFU , si le logiciel en cours d’exécution est capable et prêt à accepter les offres CFU.
else if (componentId == CFU_SPECIAL_OFFER_CMD)
{
FWUPDATE_SPECIAL_OFFER_COMMAND* pSpecialCommand =
(FWUPDATE_SPECIAL_OFFER_COMMAND*)pCommand;
if (pSpecialCommand->componentInfo.commandCode == CFU_SPECIAL_OFFER_GET_STATUS)
{
memset(pResponse, 0, sizeof (FWUPDATE_OFFER_RESPONSE));
pResponse->status = FIRMWARE_UPDATE_OFFER_COMMAND_READY;
pResponse->token = token;
return;
}
}
Enfin, une vérification est effectuée pour savoir s'il existe un échange bancaire en attente. Le "bank swap" désigne le firmware qui conserve l'information sur le fait qu'il soit encore en train de passer de l'application active en cours d'exécution à la nouvelle image téléchargée.
Comment et où le basculement bancaire est effectué est une tâche spécifique d’implémentation pour le microprogramme incorporé. Le protocole et le processus CFU permettent d’échanger des informations entre l’application utilisateur distante qui effectue l’FU et le microprogramme in situ en cours d’exécution.
else if (s_bankSwapPending)
{
memset(pResponse, 0, sizeof (FWUPDATE_OFFER_RESPONSE));
pResponse->status = FIRMWARE_UPDATE_OFFER_REJECT;
pResponse->rejectReasonCode = FIRMWARE_UPDATE_OFFER_SWAP_PENDING;
pResponse->token = token;
return;
}
Enfin, si l’état du microprogramme en cours d’exécution n’est pas occupé, et que le componentId n’est pas une commande spéciale et qu’il n’y a pas d’échange bancaire en attente . ENSUITE, nous pouvons traiter cette offre.
Le traitement d’une offre implique, mais n’est pas limité à, les quatre étapes décrites ci-dessous :
Étape 1 - Vérifier la banque
Vérifiez la banque de l'application en cours à la banque de l'offre. Sont-ils identiques ou différents ?
Si c'est identique, rejetez l’offre (nous ne voulons pas remplacer l’image en cours/active).
Sinon, continuez.
Étape 2 - Vérifier hwVariantMask
Le microprogramme en cours d’exécution vérifie l’offre hwVariantMask sur le HW sur lequel il s’exécute. Cela permet au microprogramme incorporé de rejeter une offre si l’offre n’est pas valide pour la cible. (par exemple, si le microprogramme en cours d’exécution se trouve sur une ancienne build HW et que le nouveau microprogramme proposé est destiné à une build HW plus récente, alors le microprogramme en cours d’exécution doit rejeter cette offre)
Si elle n’est pas valide, rejetez l’offre.
Sinon, continuez.
Étape 3 - Vérifier la version du microprogramme
Vérifiez si la version du contenu du microprogramme proposé a une version antérieure ou ultérieure au microprogramme de l’application actuelle.
Il revient à l'implémentation des utilisateurs de décider comment vérifier quel firmware est supérieur à un autre et s'il convient d'autoriser l'utilisation du champ « forceIgnoreVersion » dans l'offre. Le développement classique de firmware permet au champ « forceIgnoreVersion » d'être utilisé pendant le développement du produit et dans les versions de débogage du firmware, mais interdit (ne permettant pas la mise à jour d'un firmware plus ancien par-dessus un firmware plus récent) dans le firmware de production/mise en production.
Si cette vérification a échoué, rejetez l’offre.
Sinon, continuez.
Étape 4 : Accepter l’offre
L’offre est bonne. Acceptez l’offre avec une réponse adaptée à la façon dont les messages et l’état sont retournés par le microprogramme à l’application utilisateur distante. La soi-disant « réponse » est des données (une structure de données packée, comme indiqué dans les fichiers d’en-tête de démonstration) et ces données sont écrites dans l’application utilisateur par les moyens appropriés pour l’appareil.
Traiter le contenu
Le traitement du contenu est généralement un processus multistep. Les différentes étapes font référence à la capacité du microprogramme à accepter l’image du microprogramme en parties, également appelée « blocs » de données. Il n’est pas toujours possible d’envoyer l’image entière à la fois au microprogramme incorporé. Il est donc réaliste d’attendre l’implémentation du protocole CFU et le processus d’acceptation du contenu en petits morceaux.
Cette discussion part de l’hypothèse qu'il existe lors de la description du processus du contenu de la CFU.
La machine à états du traitement du contenu comporte trois états.
État du traitement du premier bloc.
État du traitement du dernier bloc.
État du traitement d’un bloc entre le premier et le dernier.
Structure de la commande de contenu
Comme l’offre, le contenu a une structure avec des champs utilisés par les algorithmes CFU dans la démonstration.
typedef struct
{
UINT8 flags;
UINT8 length;
UINT16 sequenceNumber;
UINT32 address;
UINT8 pData[MAX_UINT8];
} FWUPDATE_CONTENT_COMMAND;
La structure de la commande de contenu est plus simple que la structure de l’offre. Le contenu est défini comme une séquence d’octets à écrire en mémoire. Le préambule du contenu est les champs de cette structure :
UINT8 flagsIndique si le contenu « bloc » est le premier, le dernier ou l’autre.UINT8 lengthMarque la longueur dupDatachamp. Dans le code de démonstration de CFU, la limite de la taille dupDataest de 255 octets. D’autres implémentations peuvent varier la taille maximale du « bloc ».UINT16 sequenceNumberIndique le compteur d’indice du bloc qui est soumis en tant que contenu.UINT32 addressDécalage d’adresse du bloc. Dans la démonstration du CFU de cette version, l’implémentation a des informations prédéfinies sur l’adresse physique de chaque zone d'application. Par exemple, une implémentation de microprogramme à double banque peut avoir App1 commencer à l’adresse0x9000et App2 commencer à l’adresse0xA0000. Ainsi, selon la façon dont l'image du firmware a été préparée (S-Records), l'adresse dans le SREC peut être l'adresse physique ou un décalage. Dans tous les cas, il doit y avoir une compréhension partagée entre la préparation du contenu et les routines spécifiques de l’implémentation du traitement du contenu du CFU pour déterminer la véritable adresse physique où le bloc doit être écrit en mémoire. Il est laissé au développeur du microprogramme d’adopter les meilleures pratiques et de vérifier les plages d’adresses valides pour chaque blog de contenu. Par exemple, le code CFU illustre une vérification effectuée si App1 (destiné à0x9000) a, par exemple, des adresses qui se chevauchent avec App2, etc.UINT8 pData[MAX_UINT8]- Il s’agit des octets bruts du bloc d’image du microprogramme. On veille soigneusement à ce que l’application utilisateur place uniquementlengthoctets dans le flux d’octets complet du bloc de contenu.
Aucun champ de bits n'est utilisé dans la structure de contenu, conformément à la démonstration CFU du code fourni.
Premier bloc
Le premier bloc démarre le téléchargement du contenu du microprogramme. Le microprogramme en cours d’exécution tente d’écrire le bloc en mémoire non volatile. Bien sûr, le contenu « bloc » contient des informations sur l’emplacement où le bloc doit être écrit, la quantité de données à écrire et d’autres champs.
Chaque appareil cible componentID est différent et il existe plusieurs méthodes pour conserver les données en mémoire. Par exemple, un componentId peut nécessiter l’écriture dans un flash interne, un autre componentId peut écrire dans un flash SPI externe ou un autre peut utiliser le protocole I2C d’un autre IC pour mettre à jour son image. La démonstration incluse dans ce document met en évidence l’utilisation d’une fonction appelée ICompFwUpdateBspWrite que chaque microprogramme unique doit implémenter avec connaissance des fonctions d’E/S de mémoire non volatile sous-jacentes de la cible pour laquelle elle a été conçue.
Tout autre bloc sauf premier ou dernier
Le processus d’acceptation de nouveaux blocs se poursuit lorsque l’application utilisateur remet un autre bloc, à nouveau avec des métadonnées dans le message pour l’adresse de l’endroit où le bloc doit être écrit, le nombre d’octets contenus et d’autres champs.
Le microprogramme in situ traiterait cela comme un scénario de premier bloc.
Toutefois, il convient de noter qu'à tout moment où le système ne parvient pas à capturer et à conserver le bloc en mémoire, c'est au microprogramme in situ de répondre avec un code d'échec.
Dernier bloc
Le dernier bloc présente un défi uniquement si le microprogramme in situ doit effectuer des tâches pour valider l’image qui vient d’être écrite dans la mémoire.
Tout d’abord, le dernier bloc est écrit en mémoire.
Ensuite, au minimum, une vérification CRC doit être effectuée entre les données déjà écrites en mémoire (du premier au dernier bloc) par rapport au champ CRC du dernier bloc. Il revient à chaque microprogramme d'implémentation de savoir comment obtenir le CRC de l’image téléchargée.
N’oubliez pas que l’exécution de la vérification CRC prend du temps. Contrairement au flux normal de l’exécution du CFU pour la soumission d'offres et de blocs. La dernière soumission de bloc, si elle inclut un contrôle CRC, aura un certain délai car la vérification du CRC examine potentiellement une grande région de mémoire. Selon l’appareil cible et d’autres facteurs, cela peut ne pas être un problème.
Important
La vérification CRC de l’image entrante est facultative et peut être commentée. Toutefois, les meilleures pratiques doivent être mises en place pour adopter au moins cette vérification. Il est fortement recommandé qu’à ce stade du processus de l’FUC, d’autres actions soient prises pour garantir l’intégrité de l’image téléchargée. Certaines de ces actions peuvent inclure la vérification d’une partie « signée » de l’image et/ou de vérifier les chaînes de certificats d’approbation ou d’autres approches recommandées pour garantir une image de microprogramme sécurisée. Ceux-ci sont laissés au développeur du microprogramme.
Nettoyer après le dernier bloc
Maintenant que le dernier bloc est écrit et que la vérification CRC est terminée, le microprogramme peut répondre à un échec si une partie de la validation a échoué.
Dans le cas contraire, l’attente est que le processus CFU dans le microprogramme réponde avec un état de succès.
Réinitialisation forcée cochée
L’indicateur de réinitialisation forcé dans l’offre est utilisé pour déterminer si l’unité MCU de la cible doit subir une réinitialisation (réinitialisation définie par l’utilisateur).
En règle générale, lorsqu’une réinitialisation est forcée, l’intention est de réinitialiser le MCU pour que la banque d'applications bascule. La mise à jour des variables persistantes pour indiquer quelle image du microprogramme doit être démarrée lors de la réinitialisation est laissée au développeur du microprogramme.