【问题标题】:Cortex M3 - how to use semaphoresCortex M3 - 如何使用信号量
【发布时间】:2012-01-17 10:40:41
【问题描述】:

我有一个关于在 cortex m3 中使用信号量的问题。我找到了一个线程“ARM cortex: mutex using bit banding”ARM cortex: mutex using bit banding。 有一个简短的问题描述,最后一个答案对我的问题有好处 - 但我不确定如何在 c/c++ 中实现它。

“我从未在 ARM 上使用位带;我倾向于对所有此类操作使用加载独占/存储条件。使用循环加载独占旧值,计算新值,并使用条件存储将其写回。循环直到条件存储成功(如果不是第一次,它可能会第二次成功)。”

如果有人能发布一个简短的代码如何使用它,我将非常感激。

谢谢, 马丁

【问题讨论】:

    标签: c arm semaphore cortex-m3


    【解决方案1】:

    请注意,位带并非在所有实现中都可用(最值得注意的是,NXP 的 LPC1xxx 系列中缺少它)。

    有关使用 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;
      }
    };
    

    【讨论】:

    • 嗨,伊戈尔,感谢您的回复。我不太确定如何使用您的代码。我读到的关于信号量的所有内容都是有一个函数 semop() ,你可以做这样的事情: semop() - lock 。 . - 这是安全代码吗? (我对吗?) 。 semop() - 解锁 所以,现在我必须做这样的事情吗? a.take() 。 . - 我的安全代码在这里。 a.release() 谢谢,马丁
    • 代码不会因为你使用信号量而变得“安全”;如果需要,应该使用它们。通常,您使用它们来保护公共资源免受可能并发代码路径的同时访问。如果您没有某种 RTOS 或调度程序,则不太可能需要信号量。我建议您提出一个新问题并描述您要解决的实际问题,然后我们可以查看您是否需要信号量,如果需要,如何应用它们。
    • 嗨,Igor,感谢您的回答,很抱歉有一段时间没有回复...我使用的是 freeRTOS,看来我需要信号量。在快速检查了信号量后,我明白了我的问题——当然我之前的问题并不聪明:) 无论如何,谢谢你的帮助。
    • FreeRTOS 有 its own 同步对象,所以我建议使用它们。如果您认为我的回答对您有帮助,您应该接受它——如果他们看到您接受答案,就会有更多人愿意回答您的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-01
    • 2021-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多