2010-05-18 16 views
5

Étant donné que, sur le processeur ARM Cortex M3, je peux:ARM Cortex: mutex à l'aide de bandes de bits

  • lire atomiquement un seul bit
  • mis atomiquement un seul bit
  • un seul bit atomiquement clair

Comment puis-je combiner ces derniers pour un ensemble de style mutex des opérations:

try lock 
take lock 
release lock 

Il semble que try_lock ou take_lock aurait besoin de deux opérations qui ne seraient pas atomique.

Ai-je besoin de plus de contrôle pour y parvenir? Désactiver les interruptions globales le ferait mais il semble qu'il devrait y avoir une approche plus chirurgicale.

Répondre

4

Votre rwl_TryLock() ne retourne pas nécessairement un échec si le verrou est déjà maintenu quand il est appelé (votre compilateur devrait donner au moins un avertissement sur un code chemin qui n'a pas de valeur de retour). Essayez ce qui suit:.

int rwl_TryLock(volatile uint32_t *lock, int who){ 

    Var_SetBit_BB((uint32_t)lock, who); 
    if(*lock == (1<<who)){ // check that we have exclusive access 
     // got the lock! 
     return 1; 
    } 

    // do not have the lock 
    Var_ResetBit_BB((uint32_t)lock, who); // clear the lock flag 
    return 0; 
} 

Notez que ce qui précède ne fonctionnera pas pour réclamer récursive le même verrou (par exemple, si la tâche spécifiée par who == 1 a déjà le verrou et tente de le réclamer à nouveau, le code ci-dessus ne sera pas travailler correctement), mais c'était aussi vrai pour votre original.

En outre, les interruptions peuvent être désactivées/activées sur le Cortex M3 assez rapidement (il est simple mise à jour un registre NVIC). Etes-vous sûr que votre système ne peut pas vivre avec quelques cycles supplémentaires de latence d'interruption pour garder le code de manipulation des structures de données de verrouillage simple (ce qui signifie généralement plus facile à corriger)?

1

Certains pour plus d'informations après quelques recherches.

" ARM Cortex-M3-bandes bits noyau de microcontrôleur ARM offre une autre façon de mettre en œuvre sémaphores l'accès en écriture aux variables dans la région d'alias-bande bits provoque une atomique un accès en lecture-modification-écriture à un emplacement de mémoire dans la région de la bande de bits au niveau du bus système. Comment cela se traduit dans sémaphores? une variable dans la région de la bande de bits pourrait servir de conteneur pour sémaphores. Chaque client « possède » un peu dans ce conteneur. Chaque fois qu'un client a besoin de réclamer le sémaphores, il définit son propre bit en écrivant un 1 à l'emplacement correspondant dans la région d'alias-bande bits. il serait alors lire le conteneur (région de la bande de bits) un d Vérifiez qu'aucun autre bit n'est défini, ce qui signifie que le client a réussi à revendiquer le sémaphore. Dans le cas où d'autres bits sont définis, le client devrait à nouveau effacer son propre bit, et réessayer (peut-être après avoir attendu). " (source)

Voici mon brut (non testé) Interprétation:

/* 
* Frees a lock. 
* 
* @note lock must point to a fully aligned 32 bit integer. 
* (atomically set to 0) 
* 
* @returns 1 if successfull 
*/ 
int rwl_FreeLock(volatile uint32_t *lock){ 
    *lock = 0; 
    return 1; // always successful 
} 

/* 
* Attempts to acquire a lock 
* @param who is the client taking the lock 
* @lock pointer to the mutex (uint32_t value in memory) 
* @note lock must point to a fully aligned 32 bit integer. 
* (atomically set to 1 only if set to 0) 
*/ 
int rwl_TryLock(volatile uint32_t *lock, int who){ 
    // initial check of lock 
    if(*lock == 0){ 
     Var_SetBit_BB((uint32_t)lock, who); 
     if(*lock == (1<<who)){ // check that we still have exclusive access 
      // got the lock! 
      return 1; 
     } else { 
        // do not have the lock 
      Var_ResetBit_BB((uint32_t)lock, who); // clear the lock flag 
      return 0; 
     } 
    } 
} 

Var_Set_BB/Var_Reset_BB:. Activer/désactiver l'un peu à l'aide de bandes de bits (atomique)

Cependant, il ne

+0

Si deux choses tentent d'accéder à la serrure, il semblerait que les deux accès peuvent signaler l'échec . Une meilleure approche serait d'utiliser un spinloop ldrex/strex. Cela étant dit, dans quelle mesure les accès bande-bande sont-ils garantis atomiques en présence de choses comme DMA et autres? Si une écriture DMA et une écriture en bande binaire se produisent à peu près simultanément, l'écriture DMA est-elle assurée de ne pas se produire entre les aspects «lire» et «écrire» de l'écriture en bande binaire? – supercat

0

Je ne l'ai jamais utilisé de baguage peu sur le bras; mon inclination serait plutôt d'utiliser load-exclusive/store-conditionnel pour toutes ces opérations. Utilisez une boucle pour charger - exclure l'ancienne valeur, calculer la nouvelle valeur et utiliser un magasin conditionnel pour l'écrire.Boucle jusqu'à ce que le magasin conditionnel réussisse (ce qui sera probablement la deuxième fois, si ce n'est pas le premier).

2

La bande de bits ne fonctionnera pas dans cette situation. C'est juste une manière vraiment soignée de placer des morceaux dans les dossiers de registre de dispositif et votre mémoire. Utilisez les instructions Load Exclusive et Store Exclusive pour implémenter votre sémaphore/mutex. Voici un exemple de document que vous pouvez utiliser pour implémenter un sémaphore en utilisant ces instructions et il explique comment cela fonctionne.

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439b/CHDDIGAC.html

Cela étant dit, vous pouvez réduire l'empreinte mémoire de vos mutex en utilisant des bandes de bits ...