【问题标题】:STM32 - Read I/O from multiple TasksSTM32 - 从多个任务中读取 I/O
【发布时间】:2023-04-09 03:30:02
【问题描述】:

我在基于 STM32F4 的开发板中使用 FreeRTOS,并且阅读了有关使用队列和信号量的任务之间的通信,易于理解和应用。

但在文档中,我没有找到任何关于是否可以安全地从不同任务调用相同方法的信息,例如:

void DefaultTask(void const * argument)
{
    uint8_t pin = 10;
    uint16_t analog = ADC_GetAnalog(pin);
    uint32_t encoder =  Encoder_GetCount(1);
}

void SecondTask(void const * argument)
{
    uint8_t pin = 14;
    uint16_t analog = ADC_GetAnalog(pin);
    uint32_t encoder =  Encoder_GetCount(2);
}

ADC_GetAnalog:

uint16_t ADC_GetAnalog(uint8_t PinNumber)
{
    if((PinNumber >=1)&&(PinNumber<=18))
    {
        return ADC_Pin[PinNumber].AnalogValue;
    }
    else
        return 0;
}

我的系统中还有多个编码器(增加/减少 htim# 的属性 CNT 的中断),并在与 ADC 相同的行中调用 read 方法,也来自不同的任务:

uint32_t Encoder_GetCount(uint8_t encoder_num)
{
    volatile __IO uint32_t count = 0;
    switch(encoder_num)
    {
    case 1:
        count =  htim1.Instance->CNT;
        break;
    case 2:
        count =  htim3.Instance->CNT;
        break;
    case 3:
        count =  htim5.Instance->CNT;
        break;
    default:
        break;
    }

    return (uint32_t)count;
}

今天我使用这种方式,但想知道它是否是最好(更安全)的方式!!

【问题讨论】:

  • 可重入或线程安全的概念是您可以阅读的主题,因为您本质上是在询问函数是否可重入。

标签: c stm32 freertos


【解决方案1】:

从您提供的内容来看,您可以同时调用的函数似乎只是读取内容,而不是写入内容。所以你很高兴。就算你写东西,如果是局部变量也没问题(每个任务都有自己的副本)

当您编写全局变量或将内容写入某些外围设备(例如,串行闪存芯片,您不希望 2 个任务同时使用它)时,您需要注意同步问题。处理它的一种方法是简单地使用信号量/互斥体,或者最好(如果可能)只有一个任务可以访问此外围设备,干净的设计是可维护系统的关键。

【讨论】:

    【解决方案2】:

    这取决于函数的作用。

    您的函数不会更改任何全局变量,因此从不同任务调用它们应该是安全的。

    例如,如果您有写入全局变量的函数,例如。缓冲区,第二次调用将覆盖第一次调用所做的更改。如果缓冲区用于发送数据,则两个任务都可以(取决于时间)发送相同的字节。

    【讨论】:

    • 太棒了!我只读取那些共享方法中的变量,我确实有其他方法可以写入它,但在这种情况下我使用了信号量。