2012-01-17 4 views
3

У меня вопрос об использовании семафоров в коре m3. Я нашел нить «ARM cortex: mutex с использованием бит-диапазона» ARM cortex: mutex using bit banding. Существует краткое описание проблемы, и последний ответ будет полезен для моей проблемы, но я не уверен, как это реализовать в c/C++.Cortex M3 - как использовать семафоры

«Я никогда не использовал бит-банданг на ARM, вместо этого вместо этого было бы использовать load-exclusive/store-conditional для всех таких операций. Используйте цикл для загрузки-исключая старое значение, вычислите новый значение и использовать условное хранилище для его записи. Петля до тех пор, пока не будет выполнено условное хранилище (что, вероятно, будет во второй раз, если оно не будет первым).

Я был бы очень признателен, если кто-то может опубликовать короткий код, как его использовать.

Спасибо, Martin

ответ

2

Пожалуйста, обратите внимание, что бита полосатость не доступна на все реализации (в первую очередь, это отсутствующие в серии LPC1xxx компании NXP).

Для официального способа реализации семафора с использованием LDREX/STREX см. ARM Synchronization Primitives Development Article. Он использует сборку ARM.

Ниже приведен простой класс, в котором используются встроенные функции компилятора (непроверенные!). Название, вероятно, является неправильным, поскольку оно действительно работает как мьютекс. Также отсутствуют инструкции DMB, которые могут потребоваться.

class Semaphore 
{ 
    enum { SemFree, SemTaken }; 
    // semaphore value 
    int s; 

public: 
    // constructor 
    Semaphore(): s(SemFree) {}; 

    // try to take the semaphore and return success 
    // by default block until succeeded 
    bool take(bool block = true) 
    { 
    int oldval; 
#if defined(TARGET_LPC1768) // on Cortex-M3 we can use ldrex/strex 
    do { 
     // read the semaphore value 
     oldval = __ldrex(&s); 
     // loop again if it is locked and we are blocking 
     // or setting it with strex failed 
    } 
    while ((block && oldval == SemTaken) || __strex(SemTaken, &s) != 0); 
    if (!block) __clrex(); // clear exclusive lock set by ldrex 
#else // on arm7 there's only swp 
    do { 
     // swp sets the pointed data to the given value and returns the previous one 
     oldval = __swp(SemTaken, &s); 
     // if blocking, loop until the previous value becomes 0 
     // which would mean we have successfully taken the lock 
    } 
    while (block && oldval == SemTaken); 
#endif 
    return oldval == SemFree; 
    } 

    // release the semaphore 
    void release() 
    { 
    s = SemFree; 
    } 
}; 
+0

Привет, Игорь, спасибо за ваш ответ. Я не уверен, как использовать код. Все, что я прочитал о семафорах, было то, что была функция semop(), и вы могли бы сделать что-то вроде этого: semop() - lock . . - это безопасный код? (я прав?) . semop() - unlock Итак, теперь мне нужно сделать что-то вроде этого? a.take() . . - мой защищенный код здесь . a.release() Thanks, Martin –

+0

Код не становится «безопасным» только потому, что вы используете семафоры; они должны использоваться, если в этом есть необходимость. Обычно вы используете их для защиты общего ресурса от одновременного доступа с помощью возможных параллельных путей кода. Если у вас нет какой-либо RTOS или планировщика, маловероятно, что вам нужны семафоры. Я предлагаю вам задать новый вопрос и описать проблему _actual_, которую вы пытаетесь решить, тогда мы увидим, нужны ли вам семафоры, и если да, то как их применять. –

+0

Привет, Игорь, спасибо за ваш ответ и жаль, что я не ответил на какое-то время ... Я использую freeRTOS, и мне кажется, что мне нужны семафоры. После быстрой проверки семафоров я понял свою проблему - и, конечно, мой предыдущий вопрос не был умным :) Во всяком случае, спасибо за вашу помощь. –