Skip to content

Instantly share code, notes, and snippets.

@Len42
Last active May 25, 2022 19:36
Show Gist options
  • Save Len42/cca2361048a0134763d625e9065d429d to your computer and use it in GitHub Desktop.
Save Len42/cca2361048a0134763d625e9065d429d to your computer and use it in GitHub Desktop.
CritSec - Critical section helper class for Raspberry Pi Pico SDK (RP2040)
// CritSec - Critical section helper class for Raspberry Pi Pico SDK
// by Len Popp
//
// Usage
//
// #include "CritSec.h"
//
// {
// CritSec<AnyType>::init();
// /* ... */
// {
// CritSec<AnyType> cs;
// /* ... critical section code ... */
// }
// }
//
// Notes
//
// To protect a block of code with a critical_section_t, declare a CritSec
// object at the start of the scope block. The CritSec will block in its
// constructor until the critical_section_t is available and it will release
// the critical_section_t in its destructor at the end of the block.
//
// All CritSec objects declared with the same template type, e.g. CritSec<AnyType>,
// will share a single critical_section_t object. CritSec objects declared with
// a different type, e.g. CritSec<SomeOtherType>, will use a different
// critical_section_t object.
//
// When compiling for the Raspberry Pi Pico, the C++ Standard Library does not have
// support for thread concurrency (std::mutex etc.). Therefore the Pi Pico SDK has
// its own concurrency support (spin_lock_t, critical_section_t, etc.).
// This helper class simplifies the use of critical sections and reduces errors by
// not requiring matching enter & exit calls. It generates efficient inlined code
// which is identical to using critical_section_t explicitly (tested with gcc 11.2).
#pragma once
#include "pico/sync.h"
template<typename T>
class CritSec
{
public:
CritSec() { critical_section_enter_blocking(&cs); }
~CritSec() { critical_section_exit(&cs); }
static void init() { critical_section_init(&cs); }
static void deinit() { critical_section_deinit(&cs); }
private:
static critical_section_t cs;
};
template<typename T> critical_section_t CritSec<T>::cs;
#include "pico/stdlib.h"
#include "CritSec.h"
struct Data
{
int a = 1;
};
static Data data;
int main()
{
CritSec<Data>::init();
{
CritSec<Data> cs;
data.a = 17;
}
CritSec<Data>::deinit();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment