简体   繁体   English

等待信号时避免忙等待

[英]Avoid Busy waiting when waiting for a signal

I am trying a write a code which can be easily ported to any MCU.我正在尝试编写一个可以轻松移植到任何 MCU 的代码。 This MCU will act as a host and communicate with another audio codec chip.该 MCU 将充当主机并与另一个音频编解码器芯片通信。 When communicating with the chip, host MCU will write a request to chip and will wait for an interrupt line to go high and then read the response from the chip.与芯片通信时,主机MCU会向芯片写入请求,并等待中断线使go为高电平,然后读取芯片的响应。

Currently, I am using a Raspberry Pi as a host and hence I can poll the sysfs entries of the interrupt line.目前,我使用 Raspberry Pi 作为主机,因此我可以poll中断线的sysfs条目。 How can I achieve this in a primitive system which may not have a poll method.如何在可能没有poll方法的原始系统中实现这一点。 I am thinking I can update a global variable in the interrupt ISR and check this global variable repeatedly.我在想我可以在中断 ISR 中更新一个全局变量并反复检查这个全局变量。 And herein lies the problem that I want to avoid.这就是我想要避免的问题。 Main program loop itself may be getting called from one of the Timer interrupt handlers and busy waiting may not be a good option.主程序循环本身可能会从 Timer 中断处理程序之一调用,而忙等待可能不是一个好的选择。

Any ideas?有任何想法吗?

One size fits all fits no-one well.一种尺寸适合所有人,没有人适合。 Especially with mcus where space is limited and making a generic one size fits all library.特别是在空间有限的 mcus 中,使通用的一种尺寸适合所有库。 So proceed with care.所以请谨慎行事。

Each mcu is different, how they handle the movement of data varies, some have buffers, some have dma, etc. One would expect an interrupt is possible within the design, but not what everyone wants to do.每个 mcu 都不同,它们处理数据移动的方式各不相同,有些有缓冲区,有些有 dma 等。人们会期望在设计中可能会出现中断,但并不是每个人都想做。

You have left a significant amount of system information out, it sounds like this is an external codec chip but what does "response" mean.您留下了大量的系统信息,听起来这是一个外部编解码器芯片,但“响应”是什么意思。 Most MCUs can handle a gpio input rising edge or level causing an interrupt, but you have not described the interface to the codec chip, if it is a common interface like i2c or spi, what kind of data you are moving and as a result how each mcu handles that, which is of course brand and family specific and difficult at best to make a generic (not bloated) library.大多数 MCU 可以处理导致中断的 gpio 输入上升沿或电平,但您没有描述编解码器芯片的接口,如果它是 i2c 或 spi 之类的通用接口,您正在移动什么样的数据以及结果如何每个单片机都处理这个问题,这当然是品牌和系列特定的,充其量很难制作一个通用(而不是臃肿)的库。

The library if any needs to instead focus on call back and processing functions, in no way should the library care about the interrupt nor movement of data, the user supplies that, the library instead focuses on the data.如果有库需要专注于回调和处理功能,库绝不应该关心数据的中断或移动,用户提供它,库反而专注于数据。 Worst case the library has function calls it makes that the user fills in to implement things, send command, send data, receive data, wait for event, etc.最坏的情况库有 function 调用它使用户填写实现事物,发送命令,发送数据,接收数据,等待事件等。

if this is i2c then sure you can do the bit bang library as well and have a generic-ish list of drive high, drive low, float input, read input, delay half cycle, etc, wait for event, and then you implement the rest.如果这是 i2c,那么确保您也可以使用 bit bang 库,并拥有一个通用的驱动高、驱动低、浮点输入、读取输入、延迟半周期等列表,等待事件,然后实现rest。 (Well you could bit-bang spi as well and be independent of the mcu type). (好吧,您也可以使用 bit-bang spi 并且独立于 mcu 类型)。

Usually, microcontrollers have a variety of low-power "sleep modes".通常,微控制器有多种低功耗“睡眠模式”。 Each sleep mode has a different combination of things that are still running and a different combination of things that can wake up the microcontroller.每种睡眠模式都有不同的仍在运行的事物组合以及可以唤醒微控制器的不同事物组合。 For example, in one mode you may be able to leave the SPI peripheral transmitting data, and wake up with an interrupt, so you can give it some data to transmit and then enter sleep mode until it finishes.例如,在一种模式下,您可以让 SPI 外围设备传输数据,并通过中断唤醒,因此您可以给它一些数据以进行传输,然后进入睡眠模式,直到它完成。 A different mode may shut down all peripherals except for the GPIO pins.不同的模式可能会关闭除 GPIO 引脚之外的所有外设。 A different mode might shut down everything and only let the microcontroller be woken up with the reset pin.不同的模式可能会关闭一切,只让微控制器被复位引脚唤醒。

Since your code is designed to be ported to any microcontroller, you can't assume which sleep modes are available.由于您的代码旨在移植到任何微控制器,因此您不能假设哪些睡眠模式可用。 But you can write a busy-wait loop with optional sleeping, something like this:但是您可以编写一个带有可选睡眠的忙等待循环,如下所示:

setUpInterrupt();
while(!interruptHappened) {
    enterAppropriateSleepModeIfAvailable(); // the person who ports the code implements this
}

If the microcontroller doesn't have an appropriate sleep mode, the porter will make it so enterAppropriateSleepModeIfAvailable doesn't do anything, and this will be a busy-wait.如果微控制器没有适当的睡眠模式,搬运工将使其进入适当睡眠模式如果enterAppropriateSleepModeIfAvailable不做任何事情,这将是一个忙等待。 Otherwise, it will wait for the interrupt to happen.否则,它将等待中断发生。

Make sure that the microcontroller still wakes up - and doesn't get stuck in sleep mode - if the interrupt happens after while(!interruptHappened) but before enterAppropriateSleepModeIfAvailable() .如果中断发生在while(!interruptHappened)之后但enterAppropriateSleepModeIfAvailable()之前,请确保微控制器仍然唤醒 - 并且不会陷入睡眠模式。

You can try semaphores, mutex, locks, monitors.你可以尝试信号量、互斥体、锁、监视器。 Lock, mutex, semaphore... what's the difference? 锁、互斥、信号量……有什么区别? this will tell you the basic differences between them.这将告诉您它们之间的基本区别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM