【问题标题】:Multiple threads calling the same function with a peripheral routine多个线程使用外围例程调用相同的函数
【发布时间】:2014-03-07 11:19:53
【问题描述】:

我有 2 个线程 Thread1 和 Thread2。而且我确实有一个外设读取或写入的功能。说一个 SPI 读或写函数。在某些情况下,两个线程都使用 SPI 函数。由于线程本质上是并发的,因此两个线程是否有可能同时尝试访问该函数。那就是想要将 0x10 0x25 写入 SPI 的 Thread1。而 Thread2 想要写入 0x20 0x56。如果不使用任何同步机制,是否有可能将错误的序列写入 SPI 缓冲区?

【问题讨论】:

  • 是的,这种可能性是存在的。你最好在这里使用互斥锁!
  • 即,函数开始时的互斥​​锁和函数仪式结束时的解锁?
  • 没错。在 SPI_Read 例程开始时调用 Mutex-Get,在 SPI_Read 例程结束时调用 Mutex-Put。另外,将此 Mutex 初始化为继承优先级,以允许它使用优先级反转解决 3 线程死锁。
  • 不是错字。假设您有 3 个线程,优先级为 High、Med 和 Low。现在,假设低优先级线程执行 SPI 读取请求,从而获取 SPI 互斥锁。然后,Med-priority 线程唤醒(无论出于何种原因),并立即切换到操作(因为它的优先级高于当前执行线程的优先级)。最后,高优先级线程唤醒执行 SPI 读取请求。由于低优先级线程已经获取了 SPI 互斥锁,因此高优先级线程被阻塞。
  • 所以本质上,Med-priority 线程比 High-priority 线程“首选”。请注意,SPI 仅由低优先级线程和高优先级线程使用。 Med-priority线程与它无关。互斥锁可以使用优先级反转来解决这个死锁。

标签: c multithreading synchronization embedded-linux spi


【解决方案1】:

将您的 SPI 视为共享资源(关键部分),它必须是互斥的。

以下是在 SPI 访问操作期间防止上下文切换的一般方案:

static pthread_mutex_t _mutex;

void SPI_init()
{
    ...
    pthread_mutex_init(&_mutex);
    ...
}

void SPI_read(...)
{
    pthread_mutex_lock(&_mutex);
    ...
    pthread_mutex_unlock(&_mutex);
}


void SPI_write(...)
{
    pthread_mutex_lock(&_mutex);
    ...
    pthread_mutex_unlock(&_mutex);
}

【讨论】:

  • 还有一件事@barack。您刚刚在较早的评论中提到“将此互斥体初始化为继承优先级”。这里有照顾吗
  • @SilentCat:不,不是。以上只是一个总体方案。您需要查看 Linux API 并找到互斥初始化的确切细节。
【解决方案2】:

可以按任何顺序安排线程。所以,是的,您可以向外围寄存器写入错误的序列。

因此,为了避免这种情况,请使用同步原语!

请参阅此关于如何使用互斥锁的基本教程:http://www.thegeekstuff.com/2012/05/c-mutex-examples/

【讨论】:

  • @brockenfoot 你能建议一种方法来避免这种情况吗?
  • 检查我发布的链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
  • 1970-01-01
  • 2014-12-22
  • 2023-04-03
相关资源
最近更新 更多