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)?
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