如何在嵌入式C和Atmega 16中使用互斥体? [英] How to use mutex in embedded C and Atmega 16?

查看:236
本文介绍了如何在嵌入式C和Atmega 16中使用互斥体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个Atmega微控制器的C代码,我想在其中使用Mutex。
要包括哪些库?以及如何实现代码?



我想让这个Mutex阻止在一个函数中更改一个变量的定时器中断

解决方案

互斥体在正常的中断处理程序和主程序之间不是正确的。一个线程主要的问题是中断处理程序不能被挂起,后来继续获取互斥体。



延迟中断处理程序是不同的,为此,如果操作系统提供相应的功能(但仍然不常见)。互斥是多线程操作系统的一部分,因此不会作为孤立的库。如果您使用操作系统,您应该在其文档中找到有关如何使用它们的信息。



如注释所述,在修改变量时禁用该中断是一种替代方法。因为没有什么是免费的(除了FOSS,当然;-),这会增加锁定部分持续时间的中断延迟。



您可以替代使用C11的原子操作标准,但不确定它们是否可用于此平台(它们是可选的)。关于中断控制:如果你有一个中断处理程序,你必须已经启用了中断,所以应该是这样的:@Clifford已经显示了一个替代方案,如果这些不可用。



直接如何禁用。然而,更好的方法是使用启用/禁用全局中断信号的CPU指令(可能类似于dint / eint - 只是查看参考手册)。大多数工具链为内置或头文件中的C(++)提供内在函数,无需汇编程序。



无中断锁定的解决方案是使用帮助器标志:

  volatile uint8_t modified; // global like ticks 

ticksInterrupt(){
modified = 1;
//更新ticks
}

uint32_t getTicks(){
uint32_t result;
do {
modified = 0;
result = ticks;
} while(modified);
返回结果;
}

与8位CPU的32位比较相比,这个速度更快,可能更少在RAM中的附加标志字节的成本以及在int处理程序中的额外写入修改(IIRC,这是AVR上的一条指令)。



这种方法假定非嵌套中断(这是AVR和其他8- / 16位器件的标准配置,但不是强制性的),但是您需要知道这一点。)


I am writting a C code for Atmega Microcontroller and I want to use Mutex in it. What library to include? and how to implement the code?

I want this Mutex to prevent a Timer interrupt from changing a variable during a function.

解决方案

A mutex is not the right thing to use between a regular interrupt handler and the main program, resp. a thread. Main problem is that the interrupt handler cannot be suspended and later continued once it gets the mutex.

A deferred interrupt handler is different and for this it may work if the OS provides the corresponding features (but it is still uncommon). A a mutex is part of a multi-threading operating system and therefore does not come as isolated library. If you use an OS, you should find information how/when/were to use them in its documentation.

As stated in a comment, disable that interrupt while modifying the variable is one alternative. As nothing is for free (except FOSS, of course;-), this increases interrupt latency by the duration of the locked portion.

You might alternaitvely use atomic operations from C11 standard, but not sure if they are available for this platform (they are optional). @Clifford has shown an alternative if these are not available.

Regarding interrupt control: If you have an interrupt handler, you already must have enabled the interrupt, so it should be straight-forward how to disable it. However, a better way would be to use the CPU instructions which enable/disable the global interupt signal (might be something like dint/eint - just look into the reference manual). Most toolchains provide intrinsic functions for C(++) either built-in or in a header file, eliminating the need for assembler.

A solution without interrupt locking would be to use a helper flag:

volatile uint8_t modified;  // global like ticks

ticksInterrupt() {
    modified = 1;
    // update ticks
}

uint32_t getTicks() {
    uint32_t result;
    do {
        modified = 0;
        result = ticks;
    } while ( modified ) ;
    return result;
}

This is faster and likely less code than a 32bit compare on 8bit CPUs at the cost of an additional flag-byte in RAM and the additional write to modified in the int-handler (IIRC, this is a single instruction on AVR).

This approach assumes non-nested interrupts (which is standard on AVR and other 8-/16-bitters, but not mandatory - you need to know this anyway, however).

这篇关于如何在嵌入式C和Atmega 16中使用互斥体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆