2010-05-18 14 views
5

Biorąc pod uwagę, że na ARM Cortex M3, mogę:ARM Cortex: mutex używając nieco banding

  • atomowo czytać pojedynczy bit
  • atomowo ustawić pojedynczy bit
  • niepodzielnie usuwać pojedynczy bit

Jak mogę połączyć te dla mutex stylu zestawu operacji:

try lock 
take lock 
release lock 

Wygląda na to, że try_lock lub take_lock wymagałoby dwóch operacji, które nie byłyby atomowe.

Czy potrzebuję większej kontroli, aby to osiągnąć? Wyłączenie globalnych przerwań byłoby to możliwe, ale wydaje się, że powinno być bardziej chirurgiczne podejście.

Odpowiedz

4

Twoja rwl_TryLock() niekoniecznie zwraca błąd, jeśli blokada jest już wstrzymana, gdy jest wywoływana (Twój kompilator powinien dawać przynajmniej ostrzeżenie o kodzie ścieżka, która nie ma wartości zwracanej). Spróbuj wykonać następujące czynności:.

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; 
} 

Należy zauważyć, że powyższe nie będzie pracować dla rekurencyjnie twierdząc taką samą blokadę (czyli jeśli zadanie określone przez who == 1 ma już blokady i próbuje zastrzeżenia go ponownie, powyższy kod nie będzie działa poprawnie), ale tak samo było z twoim oryginałem.

Ponadto, przerwań można wyłączyć/włączyć na Cortex M3 dość szybko (jest to prosta aktualizacja do rejestru NVIC). Czy jesteś pewien, że twój system nie może żyć z dodatkowymi kilkoma cyklami opóźnienia przerwania, aby kod służący do obsługi struktur danych blokad był prosty (co zwykle oznacza łatwiejsze wykonanie poprawnej)?

1

Niektóre Informacje po poszukiwaniach.

" ARM Cortex-M3 bit-banding mikrokontrolera rdzeń ARM oferuje jeszcze inny sposób na wdrożenie semaforów Napisz dostęp do zmiennych w regionie alias nieco pasma powoduje atomowej dostęp do odczytu-modyfikacji-zapisu do lokalizacji w pamięci w regionie bitmapowym na poziomie magistrali systemowej W jaki sposób przekształca się to w semafory? Zmienna w regionie bit-band mogłaby służyć jako kontener dla semaforów.Każdy klient "posiada" bitów w tym kontenerze, gdy klient potrzebuje odebrać semafor, ustawia swój własny bit, pisząc 1 do odpowiedniej lokalizacji w aliasie pasma bitów, a następnie odczyta kontener (region pasma bitowego) i d sprawdź, czy nie ustawiono innych bitów, co oznacza, że ​​klient odniósł się do semafora. W przypadku ustawiania innych bitów klient musiałby ponownie wyczyścić własny bit i ponowić próbę (być może po odczekaniu). " (source)

Oto mój ropy (niesprawdzone) Interpretacja:

/* 
* 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. Ustawić/jasne nieco używając nieco banding (atomowych)

Jednak to robi nie działa !!!

+0

Jeśli dwie rzeczy próbują uzyskać dostęp do blokady, wydaje się, jakby oba dostępy mógł zgłosić awarię . Lepszym rozwiązaniem byłoby użycie spinloopa ldrex/strex. Jak już powiedziano, do jakiego stopnia dostępy bit-band gwarantują atomowość w obecności takich rzeczy jak DMA i takie? Jeśli zapis DMA i zapis bitmapowy występują mniej więcej jednocześnie, czy zapis DMA gwarantuje, że nie zachodzi pomiędzy aspektami "odczytu" i "zapisu" zapisu bitmapowego? – supercat

0

Nigdy nie używałem bit-bandingu na ARM; moja skłonność będzie polegała na używaniu trybu load-exclusive/store-conditional dla wszystkich takich operacji. Użyj pętli do wczytania starej wartości, oblicz nową wartość i użyj zapisu warunkowego, aby ją zapisać.Pętla do momentu, w którym magazyn warunkowy zakończy się sukcesem (co prawdopodobnie nastąpi za drugim razem, jeśli nie nastąpi pierwszy).

2

Taśma nie pasuje do tej sytuacji. To po prostu naprawdę fajny sposób ustawiania bitów w plikach rejestru urządzeń i pamięci. Użyj instrukcji Load Exclusive i Store Exclusive, aby zaimplementować semafor/mutex. Oto przykładowy dokument, który można wykorzystać, który implementuje semafor za pomocą tych instrukcji i szczegółowo opisuje, jak to działa.

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

Mając na uwadze powyższe, można zmniejszyć zużycie pamięci swojego muteksy za pomocą bitowego pasy ...