循环数据读取(如1Wire DS18B20温度),无需阻止主程序

时间:2016-11-17 19:14:09

标签: c linux multithreading raspberry-pi ipc

我正在尝试使用Raspberry Pi上的DS18B20传感器进行温度读数。我的问题是从这个传感器读取数据需要时间。它不多,或多或少1秒,但我不能允许我的主程序等到这个完成。我不需要'最近的价值'。这是温度,所以我会每分钟左右询问一下。但传感器可以每10秒进行一次测量,这将为我提供最近的足够价值。与此同时,我必须处理对应用程序提出的其他请求。所以我在考虑某种无限的测量循环。一般来说,它看起来像:

> start time measurement
> get DS18B20 value from 1 wire 
> parse output 
> stop measure time
> get the execution time, and put it in some global variable 
> sleep for UPDATE_EVERY_X - execution time

所以我想到了使用fork(),但这会在主进程退出时创建僵尸。主要应用是某种服务器,所以它在大多数时候都不会轻轻退出,所以我需要一些额外的保护,这应该不是Linux独有的方法。我正在努力将我的应用程序编写为便携式。

我的第二个想法是使用线程。发送一个线程来执行这个无限循环,并实现一些基本的生产者 - 消费者,使用互斥体等。该线程只会在完成所有操作时锁定输出温度,因此这将对阻塞时间产生显着影响。

第三种选择是使用异步IO。但这对我来说是一种神奇的知识。我之前没有使用它,但它出现在搜索结果中。

对于claryfication,这并不是严格意义上的1Wire DS18B20,而是关于当你需要每x秒执行一次任务并在进程之间共享信息时的主要方法,以及嵌入式定时器中断的类型。

最好的问候,voodoo16。

1 个答案:

答案 0 :(得分:0)

如果您想要最简单的选项,请记住“转换T”和“读取Scratchpad”命令是两个不同的步骤。您的程序可以读取温度,然后再返回值。没有必要拖延程序,除非您想要获得温度值转换完成的确切时刻。

mainLoop() {
    while(1) {
        // Do things
        int16_t rawTemperature = readScratchpad(myTemperatureSensor); // Get the last temperature reading
        if(!getTemperature(myTemperatureSensor)) { // Start the next conversion
            //Temperature conversion was not done, throw out value
            rawTemperature = INT16_MAX;
        }
        else {
            float temperature = ((float)rawTemperature / 4.0f);
            saveTemperature(temperature);
        }
        // Do other things while temperature conversion happens
    }
}

在这种情况下,getTemperature发出“Convert T”命令,并根据数据表返回0或1(如果先前的转换没有完成,则回复0,如果已经启动了新的转换,则回复1)。 p>