rappels de Interrupt-Related
En option, le pilote d’un contrôleur d’E/S à usage général (GPIO) peut prendre en charge les interruptions GPIO. Pour prendre en charge les interruptions GPIO, un pilote de contrôleur GPIO implémente un ensemble de fonctions de rappel pour gérer ces interruptions. Le pilote inclut des pointeurs vers ces fonctions de rappel dans le paquet d’inscription que le pilote fournit lorsqu’il s’inscrit lui-même en tant que client de l’extension d’infrastructure GPIO (GpioClx). Pour plus d’informations sur ce paquet d’inscription, consultez GPIO_CLIENT_REGISTRATION_PACKET.
En règle générale, un contrôleur GPIO qui est une partie intégrée d’une puce Système sur puce (SoC) a des registres matériels mappés en mémoire qui sont directement accessibles par le processeur dans la puce SoC. Toutefois, un périphérique contrôleur GPIO distinct peut être connecté en externe à la puce SoC via un bus série, comme illustré dans le diagramme suivant.
Dans ce diagramme, le contrôleur GPIO externe est connecté à un bus I²C. Ce bus est contrôlé par un contrôleur de bus I²C qui fait partie intégrante de la puce SoC. La ligne de demande d’interruption du contrôleur GPIO externe est connectée à une broche sur le contrôleur GPIO intégré. La DDI GpioClx peut prendre en charge le contrôleur GPIO intégré et le contrôleur GPIO externe dans cet exemple.
Si un périphérique de contrôleur GPIO est mappé en mémoire, le pilote du contrôleur GPIO peut accéder directement aux registres matériels du contrôleur sur DIRQL. Toutefois, si le contrôleur GPIO est connecté en série, le pilote du contrôleur GPIO peut accéder aux registres matériels uniquement à l’adresse IRQL = PASSIVE_LEVEL, comme indiqué dans LES ISR passifs.
Le pilote d’un contrôleur GPIO qui a des registres matériels mappés en mémoire doit définir le bit de l’indicateur MemoryMappedController dans les informations de périphérique fournies par le pilote à GpioClx. Sinon, GpioClx suppose que les registres matériels ne sont pas mappés en mémoire et que le pilote peut accéder à ces registres uniquement à l’adresse IRQL = PASSIVE_LEVEL. Pour plus d’informations sur ce bit d’indicateur, consultez CONTROLLER_ATTRIBUTE_FLAGS.
GpioClx implémente une routine de service d’interruption (ISR) pour traiter les demandes d’interruption à partir du contrôleur GPIO. Cet ISR appelle les fonctions de rappel suivantes liées aux interruptions :
CLIENT_ClearActiveInterruptsCLIENT_MaskInterruptsCLIENT_QueryActiveInterruptsCLIENT_QueryEnabledInterruptsCLIENT_UnmaskInterrupt Ces fonctions sont appelées au niveau de DIRQL ou PASSIVE_LEVEL, selon que l’ISR dans GpioClx s’exécute sur DIRQL ou PASSIVE_LEVEL. L’ISR appelle ces fonctions au niveau de DIRQL si MemoryMappedController = 1, et à PASSIVE_LEVEL si MemoryMappedController = 0. Dans les deux cas, l’ISR sérialise automatiquement ses rappels afin qu’un appel à l’une de ces fonctions ne se produise pas au milieu d’un appel à une autre de ces fonctions.
L’extension d’infrastructure GPIO appelle les fonctions de rappel suivantes liées aux interruptions uniquement à PASSIVE_LEVEL, que l’indicateur MemoryMappedController soit défini ou non :
CLIENT_DisableInterruptCLIENT_EnableInterrupt Si l’indicateur MemoryMappedController n’est pas défini, toutes les fonctions de rappel liées aux interruptions sont appelées à PASSIVE_LEVEL. GpioClx sérialise automatiquement les appels à ces fonctions afin qu’aucun appel à l’une de ces fonctions ne se produise au milieu d’un appel à une autre de ces fonctions.
Toutefois, si l’indicateur MemoryMappedController est défini, les fonctions CLIENT_EnableInterrupt et CLIENT_DisableInterrupt doivent synchroniser explicitement leurs opérations d’activation et de désactivation d’interruption sur l’ISR GpioClx, qui appelle les quatre autres fonctions de rappel liées aux interruptions au niveau de DIRQL.
En règle générale, les autres fonctions de rappel CLIENT_Xxx (dont les noms ne contiennent pas « Interruption ») n’effectuent pas de traitement lié aux interruptions et, par conséquent, n’ont pas besoin de se synchroniser avec gpioClx ISR. Toutefois, si l’une de ces fonctions est appelée à PASSIVE_LEVEL et contient du code qui accède aux paramètres d’interruption accessibles par les fonctions liées aux interruptions au niveau de DIRQL, ce code doit être synchronisé avec l’ISR.
Pour prendre en charge la synchronisation des interruptions, GpioClx implémente un ensemble de verrous d’interruption. Une fonction de rappel qui s’exécute à PASSIVE_LEVEL peut appeler la méthode GPIO_CLX_AcquireInterruptLock pour acquérir un verrou d’interruption et appeler la méthode GPIO_CLX_ReleaseInterruptLock pour libérer le verrou. Lorsque la fonction détient le verrou d’interruption, l’ISR GpioClx ne peut pas s’exécuter, et cet ISR ne peut pas appeler une fonction de rappel liée aux interruptions. Pour permettre aux interruptions GPIO d’être gérées en temps opportun, le pilote ne doit pas maintenir le verrou d’interruption plus longtemps que nécessaire.
Pour plus d’informations, consultez Synchronisation d’interruption pour les pilotes de contrôleur GPIO.