【ヒープメモリ管理クラス】
SDKにはマルチスレッド対応ではない関数がある。その全てをマルチスレッド対応とするには相当な労力が必要となるため、とりあえず、標準機能をラップしただけのマルチスレッド対応のメモリ管理クラスを作ってみた。
※重要:優先度の高いタスクは割り込み処理のようにふるまうため全てのマルチスレッド非対応関数の呼び出しは誤動作を引き起こす可能性があることに注意しよう。
このクラスのように割り込み禁止で保護するか、或いは、ミューテックス等で同時実行を回避すれば良い。マルチプロセッサの場合は割り込みを禁止しただけでは駄目でさらなる対策が必要となる。この意味が理解できない場合、このRTOSをお勧めすることはできない。
【ソース・コード】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
/* heap.h - Heap Memory Function Class Copyright (c) 2021 Sasapea's Lab. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __HEAP_H #define __HEAP_H #include <stdlib.h> #include <util/atomic.h> class Heap { public: static void *malloc(size_t size) { void *rv; ATOMIC_BLOCK(ATOMIC_RESTORESTATE) rv = malloc(size); return rv; } static void *calloc(size_t n, size_t size) { void *rv; ATOMIC_BLOCK(ATOMIC_RESTORESTATE) rv = calloc(n, size); return rv; } static void *realloc(void *ptr, size_t size) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) ptr = realloc(ptr, size); return ptr; } static void free(void *ptr) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) free(ptr); } }; #endif |
【実測値】
ATmega32u4/16MHzでの実測値。
1 2 3 4 5 6 |
setjmp+longjmpの処理時間 ... 10us ラウンドロビンによるタスク切り替え ... 16us セマフォ待ちからの起床時間 ... 20us ミューテックス待ちからの起床時間 ... 24us ピン変化待ちからの起床時間 ... 42us 休止可能な最小時間 ... 120us |
【総評】
AVR16MHzだとこんなもんかもしれないがはっきり言って思っていたよりも遅い。まだチューニングの余地はあるとは思うが頑張ってもせいぜい10%程度の改善しか見込めない気もする。それよりも実測値と同程度だろうと予想される割り込み禁止時間のほうが気になってしまう。
また、理想と言っても個人的な理想でしかなく全ての人にとっての理想などない。使う目的が異なれば重視するものも異なってくるからだ。だが、自分の理想に近づくよう改良できるのがオープンソースの最大の魅力。気に入らない部分があれば書き直せばいいだけだ。
今回のようにシンプルなRTOSであれば個人でも自作は十分可能である。まだ自作したことがない人は、ぜひ、挑戦してみて頂きたい。今回の投稿が皆様の参考にでもなれば幸いである。
【開発環境】
今回は、な~んと全てをarduino-IDEで開発してしまった。機能不足の点は否めないが慣れてしまえばシンプルで良い開発環境に思えてくるから不思議だ。(笑)
【基本的な使い方】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
#include "avros.h" void task1(void *arg) { arg = arg; while (1) { Timer::delay(1000); } } void task2(void *arg) { arg = arg; while (1) { Timer::delay(1000); } } void task3(void *arg) { arg = arg; while (1) { Timer::delay(1000); } } void setup() { Task::create(task1); Task::create(task2); Task::create(task3); Task::run(); } void loop() { Task::yield(); } |
【全ソースコードのダウンロード】
avros.zip
【関連する投稿】
理想のRTOSを自作する (1)
理想のRTOSを自作する (2)
理想のRTOSを自作する (3)
理想のRTOSを自作する (4)
理想のRTOSを自作する (5)
理想のRTOSを自作する (6)
理想のRTOSを自作する (7)
理想のRTOSを自作する (8)
理想のRTOSを自作する (9)
理想のRTOSを自作する (10)
理想のRTOSを自作する (11)