|
|
1 сар өмнө | |
|---|---|---|
| .vscode | 1 сар өмнө | |
| docs | 1 сар өмнө | |
| tinykernel | 1 сар өмнө | |
| .gitignore | 1 сар өмнө | |
| CMakeLists.txt | 1 сар өмнө | |
| LICENSE.md | 1 сар өмнө | |
| README.md | 1 сар өмнө | |
| main.cpp | 1 сар өмнө | |
| pico_sdk_import.cmake | 1 сар өмнө |
Raspberry Pi Pico 2 (RP2350 / ARM Cortex-M33) 向けの、シンプルで実用的なリアルタイム・プリエンプティブマルチタスクカーネルです。
State::Blocked) し、CPU を他のタスクに明け渡します。tk::create() を使ってタスクを登録します(最大 30 個のユーザータスクを登録可能)。
#include "tinykernel/kernel.hpp"
static void your_task(void *arg) {
for (;;) {
// なにか仕事をする
tk::sleep_ms(200); // スリープでCPUを譲渡
}
}
int main(void) {
stdio_init_all();
// your_task を登録(タスク関数ポインタ、引数、優先度)
tk::create(your_task, nullptr, tk::PRIO_NORMAL);
// スケジューラ起動(Core 1 も自動ブート、これ以降は戻らない)
tk::start();
for (;;) {}
}
メッセージを受け取る側は tk::Actor<MsgType, QueueSize> を継承します。
#include "tinykernel/actor.hpp"
// 1. Actor が受け取るメッセージの構造体を定義
struct YourActionMessage {
uint32_t msg;
char str[16];
};
// 2. メッセージを待ち受ける Actor を作成
class YourActor : public tk::Actor<YourActionMessage, 8> {
protected:
void on_start() override {
// タスク起動時に1回だけ呼ばれる(GPIOやデバイスの初期化など)
}
void on_message(const YourActionMessage& msg) override {
// メッセージを受信すると自動起床して実行される
// msg はキューに値コピーされているため安全
}
};
YourActor g_actor;
int main(void) {
stdio_init_all();
// タスクとして登録・起動
g_actor.start(tk::PRIO_NORMAL);
tk::start();
}
メッセージを送る側は tk::publish() を呼びます。
static void your_sender(void *arg) {
for (;;) {
YourActionMessage msg{1, "Hello!"};
// YourActionMessage を受け付けるすべての Actor に配信(1対多の同報可能)
tk::publish(msg);
tk::sleep_ms(1000);
} // msg のスコープが外れてスタックが消えても、受信側は壊れない!
}
int main(void) {
stdio_init_all();
g_actor.start(tk::PRIO_NORMAL);
tk::create(your_sender, nullptr, tk::PRIO_NORMAL);
tk::start();
}
Point: 送信側は Actor のインスタンスや名前を知る必要がありません。メッセージの型情報だけで
EventHubが適切な Actor へ直接届けてくれます。
sync.hpp)スレッド間の排他制御・同期プリミティブとして以下が用意されています。
#include "tinykernel/sync.hpp"
tk::Mutex g_mutex;
tk::BinarySemaphore g_sem(0, 1);
// RAII による安全なロック(std::lock_guard 互換)
void safe_function() {
tk::LockGuard<tk::Mutex> lock(g_mutex);
// クリティカルセクション...
} // スコープを抜けると自動アンロック
待機タスクの中で一番優先度(Priority)が高いタスクから順に起床します。
tk::PreemptGuard)I2C や SPI など、途中でタスク切り替えを起こしたくないペリフェラルトランザクションを行う場合、割り込み(時計やタイマー)を止めずに自コアのタスクスイッチだけを安全に一時抑止できます。
{
tk::PreemptGuard guard;
// 割り込み(SysTick やタイマー)は通常通り動き続け、他コアも影響を受けない。
// しかし、自コアのタスクスイッチだけは確実にブロックされる!
i2c_write_blocking(i2c0, addr, data, len, false);
} // スコープを抜けると自動でタスクスイッチが再開(保留中のPendSVが即発火)
独自の Pico プロジェクトの CMakeLists.txt で tinykernel ディレクトリを追加し、リンクするだけで即座に利用できます。
add_subdirectory(tinykernel)
target_link_libraries(your_project_name
pico_stdlib
tinykernel_lib
)