
マルチタスクで行こう!
例によってマルチタスク化。例によってノンプリエンプティブ。
〇ドキュメントの在処
ネットを検索しても見つからないなぁ、、、と思っていたら、東大元暮らしでした!
ついついネット上に有ると思い込んでしまいますね。
▼FJUL-U16-100-INST-02.pdf
アーキテクチャの解説とアセンブラ命令コードの解説
▼FJXTCCU8_UM-08.pdf
コンパイラ・ユーザーズマニュアル
▼FJXTCCU8_PG-03.pdf
コンパイラ・プログラミングガイド
▼FJXTCCU8_LR-03.pdf
コンパイラ・ランゲージリファレンス
〇CPUについてまとめると
▼16bit RISCマイコン、記述が見つからなかったけれどハーバードアーキテクチャかもしれない。
一応1命令1クロック。
▼3段パイプライン。パイプラインストールを頻発しなければ結構速いかもしれない。
▼メモリ空間に関してsmallモデルとLargeモデルが有るが、今回はsmallモデルを対象としている。
ROM 64kbyte、RAM 6kbyte
〇ディスパッチャーを作る
どうでもイイことを勘違いして一日悩んだが、smallモデルであればわりと簡単だと思う。
/****************************************************************************/ /* dispatcher */ /****************************************************************************/ void sta_ctx( void *exe ) /*exe=ER0*/ { __asm( "L ER2,[ER0]\n" ); /**/ __asm( "MOV SP,ER2\n" ); /**/ __asm( "POP QR8\n" ); /*R8-R15 8bytes*/ __asm( "POP XR4\n" ); /*R4-R7 4bytes*/ __asm( "POP LR\n" ); /*link register 2bytes*/ } void swi_ctx( void *pre, void *post ) /*pre=ER0,post=ER2*/ { __asm( "PUSH LR\n" ); /*link register*/ __asm( "PUSH XR4\n" ); /*R4-R7*/ __asm( "PUSH QR8\n" ); /*R8-R15*/ __asm( "MOV ER4,SP\n" ); /**/ __asm( "ST ER4,[ER0]\n" ); /**/ __asm( "L ER0,[ER2]\n" ); /**/ __asm( "MOV SP,ER0\n" ); /**/ __asm( "POP QR8\n" ); /*R8-R15*/ __asm( "POP XR4\n" ); /*R4-R7*/ __asm( "POP LR\n" ); /*link register*/ }
〇サンプルプログラム

黄色タスクが250ms周期、青タスクが500ms周期、赤タスクが1000ms周期でLEDを点滅させているだけのプログラム
#include "multiTaskDemo_ide.h" // Additional Header #include <mul_tsk.h> #include "delivertive.h" #define BLUE_LED 26 #define RED_LED 20 #define YELLO_LED 25 void led_yello( void ); void led_blue( void ); void led_red( void ); char tsk1_stk[ 256 ]; char tsk2_stk[ 256 ]; char tsk3_stk[ 256 ]; void tsk_ini( void ) { reg_tsk( ID_led_yello,led_yello, tsk1_stk, sizeof(tsk1_stk), (VP_INT)0,(VP_INT)0,(VP_INT)0,(VP_INT)0 ); reg_tsk( ID_led_blue, led_blue, tsk2_stk, sizeof(tsk2_stk), (VP_INT)0,(VP_INT)0,(VP_INT)0,(VP_INT)0 ); reg_tsk( ID_led_red, led_red, tsk3_stk, sizeof(tsk3_stk), (VP_INT)0,(VP_INT)0,(VP_INT)0,(VP_INT)0 ); sta_tsk( ID_led_yello ); sta_tsk( ID_led_blue ); sta_tsk( ID_led_red ); } void setup(void) { Serial.begin( 115022UL ); tsk_ini(); //タスクの初期化 sta_rdq( ID_led_yello ); /*ラウンドロビン開始*/ } // Arduino loop sequence void loop(void) { } void led_yello( void ) { pinMode( YELLO_LED, OUTPUT ); digitalWrite( YELLO_LED, LOW ); while( 1 ) { digitalWrite( YELLO_LED, HIGH ); dly_tsk( 125UL ); digitalWrite( YELLO_LED, LOW ); dly_tsk( 125UL ); Serial.print( "task1 time=" ); Serial.print_long( millis(), DEC ); Serial.println( "ms" ); } } void led_blue( void ) { pinMode( BLUE_LED, OUTPUT ); digitalWrite( BLUE_LED, LOW ); while( 1 ) { digitalWrite( BLUE_LED, HIGH ); dly_tsk( 250UL ); digitalWrite( BLUE_LED, LOW ); dly_tsk( 250UL ); Serial.print( "task2 time=" ); Serial.print_long( millis(), DEC ); Serial.println( "ms" ); } } void led_red( void ) { pinMode( RED_LED, OUTPUT ); digitalWrite( RED_LED, LOW ); while( 1 ) { digitalWrite( RED_LED, HIGH ); dly_tsk( 500UL ); digitalWrite( RED_LED, LOW ); dly_tsk( 500UL ); Serial.print( "task3 time=" ); Serial.print_long( millis(), DEC ); Serial.println( "ms" ); } }
※IDEにプロジェクトの設定ファイルってのがあるんだけれど、ここに書きこんだからと言ってコンパイルオプションに展開されるわけではなく、悲しかった。
※ライブラリのデバックをしたくてSerial.printって書いても、「何それ?美味しいの?」ってコンパイラに言われて、悲しかった。