简体   繁体   English

FreeRTOS锁定和任务

[英]FreeRTOS locks and tasks

When should I use locks using freertos on something like cortex-m3? 什么时候我应该在像cortex-m3这样的东西上使用freertos? It seems to be clear using multicore systems but what about single core? 使用多核系统似乎很清楚,但单核心呢?

For example I have two tasks. 例如,我有两个任务。 In first I increment variable named counter . 首先我增加名为counter变量。 Second task saves current value of that variable when some event occurs. 当某些事件发生时,第二个任务保存该变量的当前值。 Should I use locks here? 我应该在这里使用锁吗? May first task corrupt value which second task is saving? 可能先破坏第二个任务正在保存的值吗?

Yes, you should use locks to protect access to the shared resource. 是的,您应该使用锁来保护对共享资源的访问。

You can't be sure that the sequence generated by the compiler to read the shared variable is atomic, so it might be unsafe. 您无法确定编译器生成的读取共享变量的序列是否为原子序列,因此可能不安全。

If you want to be a bit more hard-core, possibly gaining performance, you can use various ways to actually ensure that the variable can be accessed atomically. 如果你想要更加强硬,可能获得性能,你可以使用各种方法来确保变量可以原子方式访问。 See comment. 见评论。

You need use locks to synchronize concurrent access to shared objects, the easiest scenario would be like: 您需要使用锁来同步对共享对象的并发访问,最简单的方案是:

lock_t l; // defines a lock of your system

// thread 1:
lock(l);
counter += 1;
unlock(l);


// thread 2:
lock(l);
do_something(counter);
unlock(l);

In your specific example where there is one reader and one writer (so not in the "general" case, and definitely not in the case where there are multiple writers) then I would suggest a lock is not need if the variable being written/read is the natural word size of the architecture, and is needed if the variable is not the natural word size of the architecture. 在您的具体示例中,有一个读取器和一个写入器(所以不是在“一般”情况下,绝对不是在有多个写入器的情况下),那么我建议如果写入/读取变量则不需要锁定是体系结构的自然字大小,如果变量不是体系结构的自然字大小,则需要它。

In your case the word size is 32-bits, so if the variable is a uint32_t then it will be updated atomically, and one writer and multiple readers is safe. 在你的情况下,字大小是32位,所以如果变量是uint32_t,那么它将以原子方式更新,并且一个编写器和多个读取器是安全的。 If on the other hand the variable were a uint64_t then it will be updated (written to) in two separate accesses, and you must ensure the reader does not access the variable in between the two updates as to do so would be to read a corrupted (half updated) value. 另一方面,如果变量是uint64_t,那么它将在两次单独的访问中更新(写入),并且您必须确保读者不会访问两次更新之间的变量,因为这样做会读取损坏的(一半更新)价值。

In FreeRTOS a simple way of doing this would be to use a basic critical section thus: 在FreeRTOS中,一个简单的方法就是使用一个基本的临界区:

taskENTER_CRITICAL();
My64BitVariable++;
taskEXIT_CRITICAL();

The best method though depends on the frequency of the event. 最好的方法取决于事件的频率。 If the event is "not too fast", then why not send the value from one task to another using a queue , in which case FreeRTOS takes care of all the concurrency issues for you. 如果事件“不太快”,那么为什么不使用队列将值从一个任务发送到另一个任务,在这种情况下,FreeRTOS会为您处理所有并发问题。 Better (faster and less RAM) still, depending on what the receiving task is doing, have the writing task send the value to the receiving task directly using a direct to task notification . 更好(更快和更少RAM)仍取决于接收任务正在做什么,让写任务直接使用直接任务通知将值发送到接收任务。

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

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