Cortex M3 - 如何使用信号量

发布于 2024-12-27 13:26:01 字数 392 浏览 3 评论 0原文

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

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

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

谢谢, 马丁

I have a question about using semaphores in cortex m3. I've found a thread "ARM cortex: mutex using bit banding" ARM cortex: mutex using bit banding .
There is a short description of the problem, and the last answer would be good for my problem - but I am not sure how can I implement it in c/c++.

"I've never used bit-banding on the ARM; my inclination instead would be to use load-exclusive/store-conditional for all such operations. Use a loop to load-exclusive the old value, compute the new value, and use a conditional store to write it back. Loop until the conditional store succeeds (which it probably will the second time, if it doesn't the first)."

I would be very grateful if someone could post a short code how to use it.

Thanks,
Martin

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

海之角 2025-01-03 13:26:01

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

有关使用 LDREX/STREX 实现信号量的官方方法,请参阅 ARM 同步原语开发文章。它使用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;
  }
};

Please note that bit-banding is not available on all implementations (most notably, it's missing in NXP's LPC1xxx series).

For an official way of implementing semaphore using LDREX/STREX, see ARM Synchronization Primitives Development Article. It uses ARM assembly.

Below is a simple class I made that uses compiler intrinsics (untested!). The name is probably a misnomer since it actually works like a mutex. It's also missing DMB instructions which might be necessary.

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;
  }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文