├── part_2 ├── sect_4 │ ├── include │ │ ├── trykernel.h │ │ ├── knldef.h │ │ ├── syslib.h │ │ └── typedef.h │ ├── application │ │ └── main.c │ ├── kernel │ │ └── syslib.c │ ├── linker │ │ └── pico_memmap.ld │ └── boot │ │ └── vector_tbl.c └── sect_3 │ ├── include │ ├── knldef.h │ ├── syslib.h │ └── typedef.h │ ├── application │ └── main.c │ ├── linker │ └── pico_memmap.ld │ └── boot │ ├── vector_tbl.c │ └── boot2.c ├── part_3 ├── sect_1 │ ├── include │ │ ├── trykernel.h │ │ ├── knldef.h │ │ ├── syslib.h │ │ └── typedef.h │ ├── kernel │ │ ├── syslib.c │ │ ├── context.c │ │ └── dispatch.S │ ├── linker │ │ └── pico_memmap.ld │ ├── application │ │ └── main.c │ └── boot │ │ └── vector_tbl.c ├── sect_2 │ ├── include │ │ ├── trykernel.h │ │ ├── config.h │ │ ├── apidef.h │ │ ├── error.h │ │ ├── syslib.h │ │ ├── typedef.h │ │ └── knldef.h │ ├── kernel │ │ ├── scheduler.c │ │ ├── syslib.c │ │ ├── context.c │ │ ├── inittsk.c │ │ ├── task_queue.c │ │ ├── dispatch.S │ │ └── task_mange.c │ ├── application │ │ └── usermain.c │ ├── linker │ │ └── pico_memmap.ld │ └── boot │ │ └── vector_tbl.c └── sect_3 │ ├── include │ ├── trykernel.h │ ├── config.h │ ├── apidef.h │ ├── error.h │ ├── syslib.h │ ├── typedef.h │ └── knldef.h │ ├── kernel │ ├── scheduler.c │ ├── syslib.c │ ├── context.c │ ├── task_sync.c │ ├── systimer.c │ ├── inittsk.c │ ├── task_queue.c │ ├── dispatch.S │ └── task_mange.c │ ├── linker │ └── pico_memmap.ld │ ├── application │ └── usermain.c │ └── boot │ └── vector_tbl.c ├── part_5 ├── include │ ├── trykernel.h │ ├── config.h │ ├── error.h │ ├── syslib.h │ ├── typedef.h │ └── apidef.h ├── device │ ├── adc │ │ ├── dev_adc.h │ │ ├── adc_sysdep.h │ │ └── adc_rp2040.c │ ├── i2c │ │ └── dev_i2c.h │ └── devmgr │ │ ├── device_tbl.c │ │ ├── device.h │ │ └── device.c ├── kernel │ ├── scheduler.c │ ├── syslib.c │ ├── context.c │ ├── inittsk.c │ ├── systimer.c │ ├── task_queue.c │ ├── dispatch.S │ ├── task_mange.c │ └── task_sync.c ├── application │ ├── app.h │ ├── usermain.c │ └── lsns.c ├── linker │ └── pico_memmap.ld └── boot │ ├── vector_tbl.c │ └── boot2.c ├── part_4 ├── sect_1 │ ├── include │ │ ├── trykernel.h │ │ ├── config.h │ │ ├── apidef.h │ │ ├── error.h │ │ ├── syslib.h │ │ ├── typedef.h │ │ ├── knldef copy.h │ │ └── knldef.h │ ├── kernel │ │ ├── scheduler.c │ │ ├── syslib.c │ │ ├── context.c │ │ ├── inittsk.c │ │ ├── systimer.c │ │ ├── task_queue.c │ │ ├── dispatch.S │ │ ├── task_mange.c │ │ └── task_sync.c │ ├── linker │ │ └── pico_memmap.ld │ ├── application │ │ └── usermain.c │ └── boot │ │ └── vector_tbl.c ├── sect_2 │ ├── include │ │ ├── trykernel.h │ │ ├── config.h │ │ ├── error.h │ │ ├── syslib.h │ │ ├── typedef.h │ │ ├── apidef.h │ │ └── knldef.h │ ├── kernel │ │ ├── scheduler.c │ │ ├── syslib.c │ │ ├── context.c │ │ ├── inittsk.c │ │ ├── systimer.c │ │ ├── task_queue.c │ │ ├── dispatch.S │ │ ├── task_mange.c │ │ └── task_sync.c │ ├── linker │ │ └── pico_memmap.ld │ └── boot │ │ └── vector_tbl.c └── sect_3 │ ├── include │ ├── trykernel.h │ ├── config.h │ ├── error.h │ ├── syslib.h │ ├── typedef.h │ └── apidef.h │ ├── kernel │ ├── scheduler.c │ ├── syslib.c │ ├── context.c │ ├── inittsk.c │ ├── systimer.c │ ├── task_queue.c │ ├── dispatch.S │ ├── task_mange.c │ └── task_sync.c │ ├── linker │ └── pico_memmap.ld │ └── boot │ └── vector_tbl.c ├── changelog.md ├── LICENSE └── ReadMe.md /part_2/sect_4/include/trykernel.h: -------------------------------------------------------------------------------- 1 | #include "typedef.h" 2 | #include "sysdef.h" 3 | #include "syslib.h" 4 | -------------------------------------------------------------------------------- /part_3/sect_1/include/trykernel.h: -------------------------------------------------------------------------------- 1 | #include "typedef.h" 2 | #include "sysdef.h" 3 | #include "syslib.h" 4 | #include "knldef.h" 5 | -------------------------------------------------------------------------------- /part_5/include/trykernel.h: -------------------------------------------------------------------------------- 1 | #include "typedef.h" 2 | #include "error.h" 3 | #include "config.h" 4 | #include "sysdef.h" 5 | #include "syslib.h" 6 | #include "apidef.h" 7 | -------------------------------------------------------------------------------- /part_3/sect_2/include/trykernel.h: -------------------------------------------------------------------------------- 1 | #include "typedef.h" 2 | #include "sysdef.h" 3 | #include "syslib.h" 4 | #include "config.h" 5 | #include "error.h" 6 | #include "knldef.h" 7 | #include "apidef.h" 8 | -------------------------------------------------------------------------------- /part_3/sect_3/include/trykernel.h: -------------------------------------------------------------------------------- 1 | #include "typedef.h" 2 | #include "sysdef.h" 3 | #include "syslib.h" 4 | #include "config.h" 5 | #include "error.h" 6 | #include "knldef.h" 7 | #include "apidef.h" 8 | -------------------------------------------------------------------------------- /part_4/sect_1/include/trykernel.h: -------------------------------------------------------------------------------- 1 | #include "typedef.h" 2 | #include "sysdef.h" 3 | #include "syslib.h" 4 | #include "config.h" 5 | #include "error.h" 6 | #include "knldef.h" 7 | #include "apidef.h" 8 | -------------------------------------------------------------------------------- /part_4/sect_2/include/trykernel.h: -------------------------------------------------------------------------------- 1 | #include "typedef.h" 2 | #include "sysdef.h" 3 | #include "syslib.h" 4 | #include "config.h" 5 | #include "error.h" 6 | #include "knldef.h" 7 | #include "apidef.h" 8 | -------------------------------------------------------------------------------- /part_4/sect_3/include/trykernel.h: -------------------------------------------------------------------------------- 1 | #include "typedef.h" 2 | #include "sysdef.h" 3 | #include "syslib.h" 4 | #include "config.h" 5 | #include "error.h" 6 | #include "knldef.h" 7 | #include "apidef.h" 8 | -------------------------------------------------------------------------------- /part_5/device/adc/dev_adc.h: -------------------------------------------------------------------------------- 1 | #ifndef DEV_ADC_H 2 | #define DEV_ADC_H 3 | 4 | extern ER dev_adc_open(UW unit, UINT option); 5 | extern ER dev_adc_read(UW unit, UW ch, UW *buf, SZ size, SZ *asize); 6 | 7 | #endif /* DEV_ADC_H */ -------------------------------------------------------------------------------- /part_3/sect_2/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | /* 4 | * Try Kernel 5 | * コンフィギュレーション定義 6 | */ 7 | 8 | #define CNF_MAX_TSKID 32 /* 最大タスク数 */ 9 | #define CNF_MAX_TSKPRI 16 /* 最大タスク優先度 */ 10 | 11 | #endif /* CONFIG_H */ -------------------------------------------------------------------------------- /part_3/sect_3/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | /* 4 | * Try Kernel 5 | * コンフィギュレーション定義 6 | */ 7 | 8 | #define CNF_MAX_TSKID 32 /* 最大タスク数 */ 9 | #define CNF_MAX_TSKPRI 16 /* 最大タスク優先度 */ 10 | 11 | #endif /* CONFIG_H */ -------------------------------------------------------------------------------- /part_4/sect_1/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | /* 4 | * Try Kernel 5 | * コンフィギュレーション定義 6 | */ 7 | 8 | #define CNF_MAX_TSKID 32 /* 最大タスク数 */ 9 | #define CNF_MAX_TSKPRI 16 /* 最大タスク優先度 */ 10 | 11 | #endif /* CONFIG_H */ -------------------------------------------------------------------------------- /part_5/device/i2c/dev_i2c.h: -------------------------------------------------------------------------------- 1 | #ifndef DEV_I2C_H 2 | #define DEV_I2C_H 3 | 4 | extern ER dev_i2c_open(UW unit, UINT omode); 5 | extern ER dev_i2c_read(UW unit, UW sadr, UB *buf, SZ size, SZ *asize); 6 | extern ER dev_i2c_write(UW unit, UW sadr, UB *buf, SZ size, SZ *asize); 7 | 8 | #endif /* DEV_I2C_H */ -------------------------------------------------------------------------------- /part_2/sect_3/include/knldef.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef KNLDEF_H 3 | #define KNLDEF_H 4 | /* 5 | *** Try Kernel 6 | * カーネル内部共通定義 7 | */ 8 | 9 | /* グローバル関数 */ 10 | extern void Reset_Handler(void); /* リセットハンドラ */ 11 | 12 | /* OSメイン関数 */ 13 | extern int main(void); 14 | 15 | #endif /* KNLDEF_H */ -------------------------------------------------------------------------------- /part_2/sect_4/include/knldef.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef KNLDEF_H 3 | #define KNLDEF_H 4 | /* 5 | *** Try Kernel 6 | * カーネル内部共通定義 7 | */ 8 | 9 | /* グローバル関数 */ 10 | extern void Reset_Handler(void); /* リセットハンドラ */ 11 | 12 | /* OSメイン関数 */ 13 | extern int main(void); 14 | 15 | #endif /* KNLDEF_H */ -------------------------------------------------------------------------------- /part_4/sect_2/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | /* 4 | * Try Kernel 5 | * コンフィギュレーション定義 6 | */ 7 | 8 | #define CNF_MAX_TSKID 32 /* 最大タスク数 */ 9 | #define CNF_MAX_TSKPRI 16 /* 最大タスク優先度 */ 10 | 11 | #define CNF_MAX_FLGID 8 /* 最大イベントフラグ数 */ 12 | 13 | #endif /* CONFIG_H */ -------------------------------------------------------------------------------- /part_5/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | /* 4 | * Try Kernel 5 | * コンフィギュレーション定義 6 | */ 7 | 8 | #define CNF_MAX_TSKID 32 /* 最大タスク数 */ 9 | #define CNF_MAX_TSKPRI 16 /* 最大タスク優先度 */ 10 | 11 | #define CNF_MAX_FLGID 8 /* 最大イベントフラグ数 */ 12 | #define CNF_MAX_SEMID 8 /* 最大セマフォ数 */ 13 | 14 | #endif /* CONFIG_H */ -------------------------------------------------------------------------------- /part_4/sect_3/include/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | /* 4 | * Try Kernel 5 | * コンフィギュレーション定義 6 | */ 7 | 8 | #define CNF_MAX_TSKID 32 /* 最大タスク数 */ 9 | #define CNF_MAX_TSKPRI 16 /* 最大タスク優先度 */ 10 | 11 | #define CNF_MAX_FLGID 8 /* 最大イベントフラグ数 */ 12 | #define CNF_MAX_SEMID 8 /* 最大セマフォ数 */ 13 | 14 | #endif /* CONFIG_H */ -------------------------------------------------------------------------------- /part_5/device/devmgr/device_tbl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "device.h" 3 | #include "..\i2c\dev_i2c.h" 4 | #include "..\adc\dev_adc.h" 5 | 6 | /* デバイス登録テーブル*/ 7 | T_DEV_DEF dev_tbl[DEV_NUM] = { 8 | {"iica", 0, 0, 0, dev_i2c_open, dev_i2c_read, dev_i2c_write}, // I2C0 9 | {"iicb", 1, 0, 0, dev_i2c_open, dev_i2c_read, dev_i2c_write}, // I2C1 10 | {"adca", 0, 0, 0, dev_adc_open, dev_adc_read, 0}, // ADC 11 | }; 12 | -------------------------------------------------------------------------------- /part_2/sect_3/application/main.c: -------------------------------------------------------------------------------- 1 | #include "typedef.h" 2 | #include "sysdef.h" 3 | #include "syslib.h" 4 | 5 | /* 時間待ち関数 */ 6 | static void delay_ms( UINT ms) 7 | { 8 | UINT cnt = ms/TIMER_PERIOD; 9 | 10 | while(cnt) { 11 | if((in_w(SYST_CSR) & SYST_CSR_COUNTFLAG)!=0) { /* TIMER_PERIOD経過するとフラグがセット */ 12 | cnt--; 13 | } 14 | } 15 | } 16 | 17 | int main(void) 18 | { 19 | while(1) { 20 | out_w(GPIO_OUT_XOR, (1<<25)); /* LEDの表示反転 */ 21 | delay_ms(500); /* 0.5秒待ち */ 22 | } 23 | return 0; 24 | } -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [0.0.5] 2024-01-08 4 | 5 | ### Fixed 6 | 7 | - システムタイマの処理にてタイムアウトが発生すると次のタイムイベントを確認せずに終了する(タイムイベントの実行に遅延が生じる可能性がある) 8 | 9 | ## [0.0.4] 2023-08-31 10 | 11 | ### Fixed 12 | 13 | - 待ち解除において対象待ちオブジェクトのチェック抜けの習性 14 | 15 | ## [0.0.3] 2023-08-16 16 | 17 | ### Fixed 18 | 19 | - 4章以降、タイムアウトエラーの修正(E_OKが返っていた) ※雑誌記事は間違い無し 20 | - 5章、アプリのLCD表示の誤字修正 21 | 22 | ## [0.0.2] 2023-07-20 23 | 24 | ### Fixed 25 | 26 | - レジスタのビットマスクの反転忘れ(初期値0なので直接の影響なし) 27 | - タスクのスタックをUBからUWに(最適化で4バイト境界から外れるのを防ぐため) 28 | 29 | ## [0.0.1] 2023-05-24 30 | 31 | ### Added 32 | 33 | - 初版 34 | -------------------------------------------------------------------------------- /part_2/sect_4/application/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* 時間待ち関数 */ 4 | static void delay_ms( UINT ms) 5 | { 6 | UINT cnt = ms/TIMER_PERIOD; 7 | 8 | while(cnt) { 9 | if((in_w(SYST_CSR) & SYST_CSR_COUNTFLAG)!=0) { /* TIMER_PERIOD経過するとフラグがセット */ 10 | cnt--; 11 | } 12 | } 13 | } 14 | 15 | int main(void) 16 | { 17 | tm_com_init(); /* デバッグ出力の初期化 */ 18 | 19 | tm_putstring("hello,world\n"); /* デバッグ出力 */ 20 | 21 | while(1) { 22 | out_w(GPIO_OUT_XOR, (1<<25)); /* LEDの表示反転 */ 23 | delay_ms(500); /* 0.5秒待ち */ 24 | } 25 | return 0; 26 | } -------------------------------------------------------------------------------- /part_5/device/devmgr/device.h: -------------------------------------------------------------------------------- 1 | #ifndef DEVICE_H 2 | #define DEVICE_H 3 | 4 | #include "typedef.h" 5 | #include "error.h" 6 | 7 | #define DEVNM_LEN 8 8 | typedef struct 9 | { 10 | UB devnm[DEVNM_LEN]; // デバイス名 11 | UINT unit; // ユニット番号 12 | UINT omode; // オープンモード 13 | UINT opncnt; // オープン数 14 | ER (*fn_opn)(); // オープン関数 15 | ER (*fn_srea)(); // リード関数 16 | ER (*fn_swri)(); // ライト関数 17 | } T_DEV_DEF; 18 | 19 | #define DEV_NUM 3 /* 登録デバイス数*/ 20 | extern T_DEV_DEF dev_tbl[]; /* デバイ登録で―ブル*/ 21 | 22 | #endif /* DEVICE_H */ 23 | -------------------------------------------------------------------------------- /part_3/sect_1/include/knldef.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef KNLDEF_H 3 | #define KNLDEF_H 4 | /* 5 | *** Try Kernel 6 | * カーネル内部共通定義 7 | */ 8 | 9 | /* グローバル関数 */ 10 | extern void Reset_Handler(void); // リセットハンドラ 11 | extern void dispatch_entry(void); // ディスパッチャ 12 | 13 | /* ディスパッチャの呼出し */ 14 | #define SCB_ICSR 0xE000ED04 // 割込み制御ステートレジスタのアドレス 15 | #define ICSR_PENDSVSET (1<<28) // PendSV set-pending ビット 16 | static inline void dispatch( void ) 17 | { 18 | out_w(SCB_ICSR, ICSR_PENDSVSET); // PendSV例外を発生 19 | } 20 | 21 | extern void scheduler(void); // スケジューラ 22 | 23 | extern void *make_context( UW *sp, UINT ssize, void (*fp)()); // タスクコンテキストの作成 24 | 25 | /* OSメイン関数 */ 26 | extern int main(void); 27 | 28 | #endif /* KNLDEF_H */ -------------------------------------------------------------------------------- /part_3/sect_2/include/apidef.h: -------------------------------------------------------------------------------- 1 | #ifndef APIDEF_H 2 | #define APIDEF_H 3 | /* 4 | *** Try Kernel 5 | * API定義 6 | */ 7 | 8 | /*タスク生成情報 */ 9 | typedef struct { 10 | ATR tskatr; // タスク属性 11 | FP task; // タスク起動アドレス 12 | PRI itskpri; // タスク優先度 13 | SZ stksz; // スタックサイズ 14 | void *bufptr; // スタックのバッファポインタ 15 | } T_CTSK; 16 | 17 | /* タスク属性 */ 18 | #define TA_HLNG 0x0000001 19 | #define TA_USERBUF 0x0000020 20 | #define TA_RNG0 0x0000000 21 | #define TA_RNG1 0x0000100 22 | #define TA_RNG2 0x0000200 23 | #define TA_RNG3 0x0000300 24 | 25 | /* タスク管理API */ 26 | ID tk_cre_tsk( const T_CTSK *pk_ctsk ); 27 | ER tk_sta_tsk( ID tskid, INT stacd ); 28 | void tk_ext_tsk( void ); 29 | 30 | #endif /* APIDEF_H */ -------------------------------------------------------------------------------- /part_5/kernel/scheduler.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * スケジューラ 4 | */ 5 | #include 6 | #include 7 | 8 | TCB *ready_queue[CNF_MAX_TSKPRI]; // タスクのレディキュー 9 | TCB *cur_task; // 実行中のタスク 10 | TCB *sche_task; // 次に実行するタスク 11 | 12 | UW disp_running; // ディスパッチャ実行中 13 | 14 | /* タスクのスケジューリング */ 15 | void scheduler(void) 16 | { 17 | INT i; 18 | 19 | for(i = 0; i < CNF_MAX_TSKPRI; i++) { 20 | if( ready_queue[i] != NULL) break; 21 | } 22 | 23 | if(i < CNF_MAX_TSKPRI) { 24 | sche_task = ready_queue[i]; 25 | } else { 26 | sche_task = NULL; // 実行できるタスクは無い 27 | } 28 | if(sche_task != cur_task && !disp_running) { 29 | dispatch(); // ディスパッチャを実行 30 | } 31 | } -------------------------------------------------------------------------------- /part_3/sect_2/kernel/scheduler.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * スケジューラ 4 | */ 5 | #include 6 | #include 7 | 8 | TCB *ready_queue[CNF_MAX_TSKPRI]; // タスクのレディキュー 9 | TCB *cur_task; // 実行中のタスク 10 | TCB *sche_task; // 次に実行するタスク 11 | 12 | UW disp_running; // ディスパッチャ実行中 13 | 14 | /* タスクのスケジューリング */ 15 | void scheduler(void) 16 | { 17 | INT i; 18 | 19 | for(i = 0; i < CNF_MAX_TSKPRI; i++) { 20 | if( ready_queue[i] != NULL) break; 21 | } 22 | 23 | if(i < CNF_MAX_TSKPRI) { 24 | sche_task = ready_queue[i]; 25 | } else { 26 | sche_task = NULL; // 実行できるタスクは無い 27 | } 28 | if(sche_task != cur_task && !disp_running) { 29 | dispatch(); // ディスパッチャを実行 30 | } 31 | } -------------------------------------------------------------------------------- /part_3/sect_3/kernel/scheduler.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * スケジューラ 4 | */ 5 | #include 6 | #include 7 | 8 | TCB *ready_queue[CNF_MAX_TSKPRI]; // タスクのレディキュー 9 | TCB *cur_task; // 実行中のタスク 10 | TCB *sche_task; // 次に実行するタスク 11 | 12 | UW disp_running; // ディスパッチャ実行中 13 | 14 | /* タスクのスケジューリング */ 15 | void scheduler(void) 16 | { 17 | INT i; 18 | 19 | for(i = 0; i < CNF_MAX_TSKPRI; i++) { 20 | if( ready_queue[i] != NULL) break; 21 | } 22 | 23 | if(i < CNF_MAX_TSKPRI) { 24 | sche_task = ready_queue[i]; 25 | } else { 26 | sche_task = NULL; // 実行できるタスクは無い 27 | } 28 | if(sche_task != cur_task && !disp_running) { 29 | dispatch(); // ディスパッチャを実行 30 | } 31 | } -------------------------------------------------------------------------------- /part_4/sect_1/kernel/scheduler.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * スケジューラ 4 | */ 5 | #include 6 | #include 7 | 8 | TCB *ready_queue[CNF_MAX_TSKPRI]; // タスクのレディキュー 9 | TCB *cur_task; // 実行中のタスク 10 | TCB *sche_task; // 次に実行するタスク 11 | 12 | UW disp_running; // ディスパッチャ実行中 13 | 14 | /* タスクのスケジューリング */ 15 | void scheduler(void) 16 | { 17 | INT i; 18 | 19 | for(i = 0; i < CNF_MAX_TSKPRI; i++) { 20 | if( ready_queue[i] != NULL) break; 21 | } 22 | 23 | if(i < CNF_MAX_TSKPRI) { 24 | sche_task = ready_queue[i]; 25 | } else { 26 | sche_task = NULL; // 実行できるタスクは無い 27 | } 28 | if(sche_task != cur_task && !disp_running) { 29 | dispatch(); // ディスパッチャを実行 30 | } 31 | } -------------------------------------------------------------------------------- /part_4/sect_2/kernel/scheduler.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * スケジューラ 4 | */ 5 | #include 6 | #include 7 | 8 | TCB *ready_queue[CNF_MAX_TSKPRI]; // タスクのレディキュー 9 | TCB *cur_task; // 実行中のタスク 10 | TCB *sche_task; // 次に実行するタスク 11 | 12 | UW disp_running; // ディスパッチャ実行中 13 | 14 | /* タスクのスケジューリング */ 15 | void scheduler(void) 16 | { 17 | INT i; 18 | 19 | for(i = 0; i < CNF_MAX_TSKPRI; i++) { 20 | if( ready_queue[i] != NULL) break; 21 | } 22 | 23 | if(i < CNF_MAX_TSKPRI) { 24 | sche_task = ready_queue[i]; 25 | } else { 26 | sche_task = NULL; // 実行できるタスクは無い 27 | } 28 | if(sche_task != cur_task && !disp_running) { 29 | dispatch(); // ディスパッチャを実行 30 | } 31 | } -------------------------------------------------------------------------------- /part_4/sect_3/kernel/scheduler.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * スケジューラ 4 | */ 5 | #include 6 | #include 7 | 8 | TCB *ready_queue[CNF_MAX_TSKPRI]; // タスクのレディキュー 9 | TCB *cur_task; // 実行中のタスク 10 | TCB *sche_task; // 次に実行するタスク 11 | 12 | UW disp_running; // ディスパッチャ実行中 13 | 14 | /* タスクのスケジューリング */ 15 | void scheduler(void) 16 | { 17 | INT i; 18 | 19 | for(i = 0; i < CNF_MAX_TSKPRI; i++) { 20 | if( ready_queue[i] != NULL) break; 21 | } 22 | 23 | if(i < CNF_MAX_TSKPRI) { 24 | sche_task = ready_queue[i]; 25 | } else { 26 | sche_task = NULL; // 実行できるタスクは無い 27 | } 28 | if(sche_task != cur_task && !disp_running) { 29 | dispatch(); // ディスパッチャを実行 30 | } 31 | } -------------------------------------------------------------------------------- /part_5/kernel/syslib.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * システムライブラリ 4 | */ 5 | #include 6 | #include 7 | 8 | /* UART0の初期化 */ 9 | void tm_com_init(void) 10 | { 11 | out_w(UART0_BASE+UARTx_IBRD, 67); /* ボーレート設定 */ 12 | out_w(UART0_BASE+UARTx_FBRD, 52); 13 | out_w(UART0_BASE+UARTx_LCR_H, 0x70); /* データ形式設定 */ 14 | out_w(UART0_BASE+UARTx_CR, UART_CR_RXE|UART_CR_TXE|UART_CR_EN); /* 通信イネーブル */ 15 | } 16 | 17 | 18 | /* デバッグ用UART出力 */ 19 | UINT tm_putstring(char* str) 20 | { 21 | UINT cnt = 0; 22 | 23 | while(*str) { 24 | while((in_w(UART0_BASE+UARTx_FR) & UART_FR_TXFF)!= 0); /* 送信FIFOの空き待ち */ 25 | out_w(UART0_BASE+UARTx_DR, *str++); /* データ送信 */ 26 | cnt++; 27 | } 28 | return cnt; 29 | } 30 | -------------------------------------------------------------------------------- /part_2/sect_4/kernel/syslib.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * システムライブラリ 4 | */ 5 | #include 6 | #include 7 | 8 | /* UART0の初期化 */ 9 | void tm_com_init(void) 10 | { 11 | out_w(UART0_BASE+UARTx_IBRD, 67); /* ボーレート設定 */ 12 | out_w(UART0_BASE+UARTx_FBRD, 52); 13 | out_w(UART0_BASE+UARTx_LCR_H, 0x70); /* データ形式設定 */ 14 | out_w(UART0_BASE+UARTx_CR, UART_CR_RXE|UART_CR_TXE|UART_CR_EN); /* 通信イネーブル */ 15 | } 16 | 17 | 18 | /* デバッグ用UART出力 */ 19 | UINT tm_putstring(char* str) 20 | { 21 | UINT cnt = 0; 22 | 23 | while(*str) { 24 | while((in_w(UART0_BASE+UARTx_FR) & UART_FR_TXFF)!= 0); /* 送信FIFOの空き待ち */ 25 | out_w(UART0_BASE+UARTx_DR, *str++); /* データ送信 */ 26 | cnt++; 27 | } 28 | return cnt; 29 | } 30 | -------------------------------------------------------------------------------- /part_3/sect_1/kernel/syslib.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * システムライブラリ 4 | */ 5 | #include 6 | #include 7 | 8 | /* UART0の初期化 */ 9 | void tm_com_init(void) 10 | { 11 | out_w(UART0_BASE+UARTx_IBRD, 67); /* ボーレート設定 */ 12 | out_w(UART0_BASE+UARTx_FBRD, 52); 13 | out_w(UART0_BASE+UARTx_LCR_H, 0x70); /* データ形式設定 */ 14 | out_w(UART0_BASE+UARTx_CR, UART_CR_RXE|UART_CR_TXE|UART_CR_EN); /* 通信イネーブル */ 15 | } 16 | 17 | 18 | /* デバッグ用UART出力 */ 19 | UINT tm_putstring(char* str) 20 | { 21 | UINT cnt = 0; 22 | 23 | while(*str) { 24 | while((in_w(UART0_BASE+UARTx_FR) & UART_FR_TXFF)!= 0); /* 送信FIFOの空き待ち */ 25 | out_w(UART0_BASE+UARTx_DR, *str++); /* データ送信 */ 26 | cnt++; 27 | } 28 | return cnt; 29 | } 30 | -------------------------------------------------------------------------------- /part_3/sect_2/kernel/syslib.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * システムライブラリ 4 | */ 5 | #include 6 | #include 7 | 8 | /* UART0の初期化 */ 9 | void tm_com_init(void) 10 | { 11 | out_w(UART0_BASE+UARTx_IBRD, 67); /* ボーレート設定 */ 12 | out_w(UART0_BASE+UARTx_FBRD, 52); 13 | out_w(UART0_BASE+UARTx_LCR_H, 0x70); /* データ形式設定 */ 14 | out_w(UART0_BASE+UARTx_CR, UART_CR_RXE|UART_CR_TXE|UART_CR_EN); /* 通信イネーブル */ 15 | } 16 | 17 | 18 | /* デバッグ用UART出力 */ 19 | UINT tm_putstring(char* str) 20 | { 21 | UINT cnt = 0; 22 | 23 | while(*str) { 24 | while((in_w(UART0_BASE+UARTx_FR) & UART_FR_TXFF)!= 0); /* 送信FIFOの空き待ち */ 25 | out_w(UART0_BASE+UARTx_DR, *str++); /* データ送信 */ 26 | cnt++; 27 | } 28 | return cnt; 29 | } 30 | -------------------------------------------------------------------------------- /part_3/sect_3/kernel/syslib.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * システムライブラリ 4 | */ 5 | #include 6 | #include 7 | 8 | /* UART0の初期化 */ 9 | void tm_com_init(void) 10 | { 11 | out_w(UART0_BASE+UARTx_IBRD, 67); /* ボーレート設定 */ 12 | out_w(UART0_BASE+UARTx_FBRD, 52); 13 | out_w(UART0_BASE+UARTx_LCR_H, 0x70); /* データ形式設定 */ 14 | out_w(UART0_BASE+UARTx_CR, UART_CR_RXE|UART_CR_TXE|UART_CR_EN); /* 通信イネーブル */ 15 | } 16 | 17 | 18 | /* デバッグ用UART出力 */ 19 | UINT tm_putstring(char* str) 20 | { 21 | UINT cnt = 0; 22 | 23 | while(*str) { 24 | while((in_w(UART0_BASE+UARTx_FR) & UART_FR_TXFF)!= 0); /* 送信FIFOの空き待ち */ 25 | out_w(UART0_BASE+UARTx_DR, *str++); /* データ送信 */ 26 | cnt++; 27 | } 28 | return cnt; 29 | } 30 | -------------------------------------------------------------------------------- /part_4/sect_1/kernel/syslib.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * システムライブラリ 4 | */ 5 | #include 6 | #include 7 | 8 | /* UART0の初期化 */ 9 | void tm_com_init(void) 10 | { 11 | out_w(UART0_BASE+UARTx_IBRD, 67); /* ボーレート設定 */ 12 | out_w(UART0_BASE+UARTx_FBRD, 52); 13 | out_w(UART0_BASE+UARTx_LCR_H, 0x70); /* データ形式設定 */ 14 | out_w(UART0_BASE+UARTx_CR, UART_CR_RXE|UART_CR_TXE|UART_CR_EN); /* 通信イネーブル */ 15 | } 16 | 17 | 18 | /* デバッグ用UART出力 */ 19 | UINT tm_putstring(char* str) 20 | { 21 | UINT cnt = 0; 22 | 23 | while(*str) { 24 | while((in_w(UART0_BASE+UARTx_FR) & UART_FR_TXFF)!= 0); /* 送信FIFOの空き待ち */ 25 | out_w(UART0_BASE+UARTx_DR, *str++); /* データ送信 */ 26 | cnt++; 27 | } 28 | return cnt; 29 | } 30 | -------------------------------------------------------------------------------- /part_4/sect_2/kernel/syslib.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * システムライブラリ 4 | */ 5 | #include 6 | #include 7 | 8 | /* UART0の初期化 */ 9 | void tm_com_init(void) 10 | { 11 | out_w(UART0_BASE+UARTx_IBRD, 67); /* ボーレート設定 */ 12 | out_w(UART0_BASE+UARTx_FBRD, 52); 13 | out_w(UART0_BASE+UARTx_LCR_H, 0x70); /* データ形式設定 */ 14 | out_w(UART0_BASE+UARTx_CR, UART_CR_RXE|UART_CR_TXE|UART_CR_EN); /* 通信イネーブル */ 15 | } 16 | 17 | 18 | /* デバッグ用UART出力 */ 19 | UINT tm_putstring(char* str) 20 | { 21 | UINT cnt = 0; 22 | 23 | while(*str) { 24 | while((in_w(UART0_BASE+UARTx_FR) & UART_FR_TXFF)!= 0); /* 送信FIFOの空き待ち */ 25 | out_w(UART0_BASE+UARTx_DR, *str++); /* データ送信 */ 26 | cnt++; 27 | } 28 | return cnt; 29 | } 30 | -------------------------------------------------------------------------------- /part_4/sect_3/kernel/syslib.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * システムライブラリ 4 | */ 5 | #include 6 | #include 7 | 8 | /* UART0の初期化 */ 9 | void tm_com_init(void) 10 | { 11 | out_w(UART0_BASE+UARTx_IBRD, 67); /* ボーレート設定 */ 12 | out_w(UART0_BASE+UARTx_FBRD, 52); 13 | out_w(UART0_BASE+UARTx_LCR_H, 0x70); /* データ形式設定 */ 14 | out_w(UART0_BASE+UARTx_CR, UART_CR_RXE|UART_CR_TXE|UART_CR_EN); /* 通信イネーブル */ 15 | } 16 | 17 | 18 | /* デバッグ用UART出力 */ 19 | UINT tm_putstring(char* str) 20 | { 21 | UINT cnt = 0; 22 | 23 | while(*str) { 24 | while((in_w(UART0_BASE+UARTx_FR) & UART_FR_TXFF)!= 0); /* 送信FIFOの空き待ち */ 25 | out_w(UART0_BASE+UARTx_DR, *str++); /* データ送信 */ 26 | cnt++; 27 | } 28 | return cnt; 29 | } 30 | -------------------------------------------------------------------------------- /part_5/kernel/context.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * コンテキスト管理 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /* スタック上の実行コンテキスト情報 */ 12 | typedef struct { 13 | UW r_[8]; /* R4-R11 レジスタの値(例外処理により退避) */ 14 | UW r[4]; /* R0-R3 レジスタの値*/ 15 | UW ip; /* R12 レジスタの値*/ 16 | UW lr; /* lr レジスタの値 */ 17 | UW pc; /* pc レジスタの値 */ 18 | UW xpsr; /* xpsr レジスタの値 */ 19 | } StackFrame; 20 | 21 | /* 初期実行コンテキストの作成 */ 22 | void *make_context( UW *sp, UINT ssize, void (*fp)()) 23 | { 24 | StackFrame *sfp; 25 | 26 | /* スタック上の実行コンテクスト情報へのポインタをsfpに設定 */ 27 | sfp = (StackFrame*)((UW)sp + ssize); 28 | sfp--; 29 | 30 | /* 実行コンテキスト情報の初期化 */ 31 | sfp->xpsr = 0x01000000; 32 | sfp->pc = (UW)fp & ~0x00000001UL; 33 | 34 | return (void*)sfp; 35 | } 36 | -------------------------------------------------------------------------------- /part_3/sect_1/kernel/context.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * コンテキスト管理 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /* スタック上の実行コンテキスト情報 */ 12 | typedef struct { 13 | UW r_[8]; /* R4-R11 レジスタの値(例外処理により退避) */ 14 | UW r[4]; /* R0-R3 レジスタの値*/ 15 | UW ip; /* R12 レジスタの値*/ 16 | UW lr; /* lr レジスタの値 */ 17 | UW pc; /* pc レジスタの値 */ 18 | UW xpsr; /* xpsr レジスタの値 */ 19 | } StackFrame; 20 | 21 | /* 初期実行コンテキストの作成 */ 22 | void *make_context( UW *sp, UINT ssize, void (*fp)()) 23 | { 24 | StackFrame *sfp; 25 | 26 | /* スタック上の実行コンテクスト情報へのポインタをsfpに設定 */ 27 | sfp = (StackFrame*)((UW)sp + ssize); 28 | sfp--; 29 | 30 | /* 実行コンテキスト情報の初期化 */ 31 | sfp->xpsr = 0x01000000; 32 | sfp->pc = (UW)fp & ~0x00000001UL; 33 | 34 | return (void*)sfp; 35 | } 36 | -------------------------------------------------------------------------------- /part_3/sect_2/kernel/context.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * コンテキスト管理 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /* スタック上の実行コンテキスト情報 */ 12 | typedef struct { 13 | UW r_[8]; /* R4-R11 レジスタの値(例外処理により退避) */ 14 | UW r[4]; /* R0-R3 レジスタの値*/ 15 | UW ip; /* R12 レジスタの値*/ 16 | UW lr; /* lr レジスタの値 */ 17 | UW pc; /* pc レジスタの値 */ 18 | UW xpsr; /* xpsr レジスタの値 */ 19 | } StackFrame; 20 | 21 | /* 初期実行コンテキストの作成 */ 22 | void *make_context( UW *sp, UINT ssize, void (*fp)()) 23 | { 24 | StackFrame *sfp; 25 | 26 | /* スタック上の実行コンテクスト情報へのポインタをsfpに設定 */ 27 | sfp = (StackFrame*)((UW)sp + ssize); 28 | sfp--; 29 | 30 | /* 実行コンテキスト情報の初期化 */ 31 | sfp->xpsr = 0x01000000; 32 | sfp->pc = (UW)fp & ~0x00000001UL; 33 | 34 | return (void*)sfp; 35 | } 36 | -------------------------------------------------------------------------------- /part_3/sect_3/kernel/context.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * コンテキスト管理 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /* スタック上の実行コンテキスト情報 */ 12 | typedef struct { 13 | UW r_[8]; /* R4-R11 レジスタの値(例外処理により退避) */ 14 | UW r[4]; /* R0-R3 レジスタの値*/ 15 | UW ip; /* R12 レジスタの値*/ 16 | UW lr; /* lr レジスタの値 */ 17 | UW pc; /* pc レジスタの値 */ 18 | UW xpsr; /* xpsr レジスタの値 */ 19 | } StackFrame; 20 | 21 | /* 初期実行コンテキストの作成 */ 22 | void *make_context( UW *sp, UINT ssize, void (*fp)()) 23 | { 24 | StackFrame *sfp; 25 | 26 | /* スタック上の実行コンテクスト情報へのポインタをsfpに設定 */ 27 | sfp = (StackFrame*)((UW)sp + ssize); 28 | sfp--; 29 | 30 | /* 実行コンテキスト情報の初期化 */ 31 | sfp->xpsr = 0x01000000; 32 | sfp->pc = (UW)fp & ~0x00000001UL; 33 | 34 | return (void*)sfp; 35 | } 36 | -------------------------------------------------------------------------------- /part_4/sect_1/kernel/context.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * コンテキスト管理 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /* スタック上の実行コンテキスト情報 */ 12 | typedef struct { 13 | UW r_[8]; /* R4-R11 レジスタの値(例外処理により退避) */ 14 | UW r[4]; /* R0-R3 レジスタの値*/ 15 | UW ip; /* R12 レジスタの値*/ 16 | UW lr; /* lr レジスタの値 */ 17 | UW pc; /* pc レジスタの値 */ 18 | UW xpsr; /* xpsr レジスタの値 */ 19 | } StackFrame; 20 | 21 | /* 初期実行コンテキストの作成 */ 22 | void *make_context( UW *sp, UINT ssize, void (*fp)()) 23 | { 24 | StackFrame *sfp; 25 | 26 | /* スタック上の実行コンテクスト情報へのポインタをsfpに設定 */ 27 | sfp = (StackFrame*)((UW)sp + ssize); 28 | sfp--; 29 | 30 | /* 実行コンテキスト情報の初期化 */ 31 | sfp->xpsr = 0x01000000; 32 | sfp->pc = (UW)fp & ~0x00000001UL; 33 | 34 | return (void*)sfp; 35 | } 36 | -------------------------------------------------------------------------------- /part_4/sect_2/kernel/context.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * コンテキスト管理 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /* スタック上の実行コンテキスト情報 */ 12 | typedef struct { 13 | UW r_[8]; /* R4-R11 レジスタの値(例外処理により退避) */ 14 | UW r[4]; /* R0-R3 レジスタの値*/ 15 | UW ip; /* R12 レジスタの値*/ 16 | UW lr; /* lr レジスタの値 */ 17 | UW pc; /* pc レジスタの値 */ 18 | UW xpsr; /* xpsr レジスタの値 */ 19 | } StackFrame; 20 | 21 | /* 初期実行コンテキストの作成 */ 22 | void *make_context( UW *sp, UINT ssize, void (*fp)()) 23 | { 24 | StackFrame *sfp; 25 | 26 | /* スタック上の実行コンテクスト情報へのポインタをsfpに設定 */ 27 | sfp = (StackFrame*)((UW)sp + ssize); 28 | sfp--; 29 | 30 | /* 実行コンテキスト情報の初期化 */ 31 | sfp->xpsr = 0x01000000; 32 | sfp->pc = (UW)fp & ~0x00000001UL; 33 | 34 | return (void*)sfp; 35 | } 36 | -------------------------------------------------------------------------------- /part_4/sect_3/kernel/context.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * コンテキスト管理 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /* スタック上の実行コンテキスト情報 */ 12 | typedef struct { 13 | UW r_[8]; /* R4-R11 レジスタの値(例外処理により退避) */ 14 | UW r[4]; /* R0-R3 レジスタの値*/ 15 | UW ip; /* R12 レジスタの値*/ 16 | UW lr; /* lr レジスタの値 */ 17 | UW pc; /* pc レジスタの値 */ 18 | UW xpsr; /* xpsr レジスタの値 */ 19 | } StackFrame; 20 | 21 | /* 初期実行コンテキストの作成 */ 22 | void *make_context( UW *sp, UINT ssize, void (*fp)()) 23 | { 24 | StackFrame *sfp; 25 | 26 | /* スタック上の実行コンテクスト情報へのポインタをsfpに設定 */ 27 | sfp = (StackFrame*)((UW)sp + ssize); 28 | sfp--; 29 | 30 | /* 実行コンテキスト情報の初期化 */ 31 | sfp->xpsr = 0x01000000; 32 | sfp->pc = (UW)fp & ~0x00000001UL; 33 | 34 | return (void*)sfp; 35 | } 36 | -------------------------------------------------------------------------------- /part_3/sect_3/kernel/task_sync.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスク付属同期機能 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | /* タスクの実行遅延 API */ 10 | ER tk_dly_tsk( RELTIM dlytim ) 11 | { 12 | UINT intsts; 13 | ER err = E_OK; 14 | 15 | DI(intsts); // 割込みの禁止 16 | if(dlytim > 0) { 17 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); // タスクをレディキューから外す 18 | 19 | /* TCBの各種情報を変更する */ 20 | cur_task->state = TS_WAIT; // タスクの状態を待ち状態に変更 21 | cur_task->waifct = TWFCT_DLY; // 待ち要因を設定 22 | cur_task->waitim = dlytim + TIMER_PERIOD; // 待ち時間を設定 23 | cur_task->waierr = &err; // 待ち解除時のエラーコード 24 | 25 | tqueue_add_entry(&wait_queue, cur_task); // タスクをウェイトキューに繋ぐ 26 | scheduler(); // スケジューラの実行 27 | } 28 | EI(intsts); // 割込みの許可 29 | return err; 30 | } -------------------------------------------------------------------------------- /part_3/sect_3/include/apidef.h: -------------------------------------------------------------------------------- 1 | #ifndef APIDEF_H 2 | #define APIDEF_H 3 | /* 4 | *** Try Kernel 5 | * API定義 6 | */ 7 | 8 | /* タイムアウト時間 */ 9 | #define TMO_POL (0) // タイムアウト時間 0 10 | #define TMO_FEVR (-1) // 無限待ち 11 | 12 | /*タスク生成情報 */ 13 | typedef struct { 14 | ATR tskatr; // タスク属性 15 | FP task; // タスク起動アドレス 16 | PRI itskpri; // タスク優先度 17 | SZ stksz; // スタックサイズ 18 | void *bufptr; // スタックのバッファポインタ 19 | } T_CTSK; 20 | 21 | /* タスク属性 */ 22 | #define TA_HLNG 0x0000001 23 | #define TA_USERBUF 0x0000020 24 | #define TA_RNG0 0x0000000 25 | #define TA_RNG1 0x0000100 26 | #define TA_RNG2 0x0000200 27 | #define TA_RNG3 0x0000300 28 | 29 | /* タスク管理API */ 30 | ID tk_cre_tsk( const T_CTSK *pk_ctsk ); 31 | ER tk_sta_tsk( ID tskid, INT stacd ); 32 | void tk_ext_tsk( void ); 33 | 34 | /* タスク付属同期API */ 35 | ER tk_dly_tsk( RELTIM dlytim ); 36 | 37 | #endif /* APIDEF_H */ -------------------------------------------------------------------------------- /part_3/sect_3/kernel/systimer.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * システムタイマ 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | TCB *wait_queue; /* 時間待ち状態のタスクの待ち行列(ウェイトキュー) */ 10 | 11 | /* システムタイマ割込みハンドラ */ 12 | void systimer_handler(void) 13 | { 14 | TCB *tcb, *next; 15 | 16 | for( tcb = wait_queue; tcb != NULL; tcb = next) { 17 | next = tcb->next; 18 | if(tcb->waitim == TMO_FEVR) { 19 | continue; 20 | } else if(tcb->waitim > TIMER_PERIOD) { 21 | tcb->waitim -= TIMER_PERIOD; // 待ち時間から経過時間を減じる。 22 | } else { // 待ち時間が経過したタスクを実行できる状態に戻す 23 | tqueue_remove_entry( &wait_queue, tcb); // タスクをウェイトキューから外す 24 | *tcb->waierr = E_OK; 25 | tcb->state = TS_READY; 26 | tcb->waifct = TWFCT_NON; 27 | tqueue_add_entry( &ready_queue[tcb->itskpri], tcb); // タスクをレディキューにつなぐ 28 | } 29 | } 30 | scheduler(); // スケジューラを実行する 31 | } -------------------------------------------------------------------------------- /part_5/application/app.h: -------------------------------------------------------------------------------- 1 | extern ID dd_i2c0, dd_i2c1; // I2Cデバイスディスクリプタ 2 | extern ID dd_adc; // A/DCデバイスディスクリプタ 3 | extern ID flgid_1; // イベントフラグID 4 | 5 | /* センサーデータ */ 6 | extern UW gsns_data; // ジェスチャセンサーのデータ 7 | extern UW lsns_data; // 光センサーのデータ 8 | 9 | /* イベントフラグのフラグ定義 */ 10 | #define FLG_GSNS (1<<0) // ジェスチャセンサーのデータ更新 11 | #define FLG_LSNS (1<<1) // 光センサーのデータ更新 12 | #define FLG_ALL (FLG_GSNS|FLG_LSNS) 13 | 14 | /* ジェスチャーセンサーのデータ定義*/ 15 | #define GSNS_RIGHT (1<<0) 16 | #define GSNS_LEFT (1<<1) 17 | #define GSNS_UP (1<<2) 18 | #define GSNS_DOWN (1<<3) 19 | #define GSNS_FORWARD (1<<4) 20 | #define GSNS_BACKWARD (1<<5) 21 | 22 | /* 光センサー 明暗の境界値 */ 23 | #define LSNS_THRESHOLD 1000 24 | 25 | /* ジェスチャーセンサー制御タスクIDおよび生成情報 */ 26 | extern ID tskid_gsns; 27 | extern T_CTSK ctsk_gsns; 28 | 29 | /* 光センサー制御タスクIDおよび生成情報 */ 30 | extern ID tskid_lsns; 31 | extern T_CTSK ctsk_lsns; 32 | 33 | /* LCD制御タスクIDおよび生成情報 */ 34 | extern ID tskid_lcd; 35 | extern T_CTSK ctsk_lcd; -------------------------------------------------------------------------------- /part_4/sect_1/include/apidef.h: -------------------------------------------------------------------------------- 1 | #ifndef APIDEF_H 2 | #define APIDEF_H 3 | /* 4 | *** Try Kernel 5 | * API定義 6 | */ 7 | 8 | /* タイムアウト時間 */ 9 | #define TMO_POL (0) // タイムアウト時間 0 10 | #define TMO_FEVR (-1) // 無限待ち 11 | 12 | /*タスク生成情報 */ 13 | typedef struct { 14 | ATR tskatr; // タスク属性 15 | FP task; // タスク起動アドレス 16 | PRI itskpri; // タスク優先度 17 | SZ stksz; // スタックサイズ 18 | void *bufptr; // スタックのバッファポインタ 19 | } T_CTSK; 20 | 21 | /* タスク属性 */ 22 | #define TA_HLNG 0x0000001 23 | #define TA_USERBUF 0x0000020 24 | #define TA_RNG0 0x0000000 25 | #define TA_RNG1 0x0000100 26 | #define TA_RNG2 0x0000200 27 | #define TA_RNG3 0x0000300 28 | 29 | /* タスク管理API */ 30 | ID tk_cre_tsk( const T_CTSK *pk_ctsk ); 31 | ER tk_sta_tsk( ID tskid, INT stacd ); 32 | void tk_ext_tsk( void ); 33 | 34 | /* タスク付属同期API */ 35 | ER tk_dly_tsk( RELTIM dlytim ); 36 | ER tk_slp_tsk( TMO tmout ); 37 | ER tk_wup_tsk( ID tskid ); 38 | 39 | #endif /* APIDEF_H */ -------------------------------------------------------------------------------- /part_5/include/error.h: -------------------------------------------------------------------------------- 1 | #ifndef ERROR_H 2 | #define ERROR_H 3 | /* 4 | * Try Kernel 5 | * エラーコード定義 6 | */ 7 | 8 | #define E_OK (0) // 正常終了 9 | 10 | #define E_SYS (-5) // システムエラー 11 | #define E_NOCOP (-6) // コプロセッサ使用不可 12 | #define E_NOSPT (-9) // 未サポート機能 13 | #define E_RSFN (-10) // 予約機能コード番号 14 | #define E_RSATR (-11) // 不正属性 15 | #define E_PAR (-17) // パラメータ不正 16 | #define E_ID (-18) // ID不正 17 | #define E_CTX (-25) // コンテキストエラー 18 | #define E_MACV (-26) // メモリアクセス違反 19 | #define E_OACV (-27) // オブジェクトアクセス違反 20 | #define E_ILUSE (-28) // システムコール不正 21 | #define E_NOMEM (-33) // メモリ不足 22 | #define E_LIMIT (-34) // 上限値エラー 23 | #define E_OBJ (-41) // オブジェクト状態エラー 24 | #define E_NOEXS (-42) // オブジェクト不正エラー 25 | #define E_QOVR (-43) // 上限エラー 26 | #define E_RLWAI (-49) // 待ち状態強制解除 27 | #define E_TMOUT (-50) // タイムアウトエラー 28 | #define E_DLT (-51) // 待ちオブジェクト削除 29 | #define E_DISWAI (-52) // 待ち禁止による待ち状態解除 30 | #define E_IO (-57) // I/Oエラー 31 | 32 | #endif // ERROR_H -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Yuichi Toyoyama 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /part_3/sect_2/include/error.h: -------------------------------------------------------------------------------- 1 | #ifndef ERROR_H 2 | #define ERROR_H 3 | /* 4 | * Try Kernel 5 | * エラーコード定義 6 | */ 7 | 8 | #define E_OK (0) // 正常終了 9 | 10 | #define E_SYS (-5) // システムエラー 11 | #define E_NOCOP (-6) // コプロセッサ使用不可 12 | #define E_NOSPT (-9) // 未サポート機能 13 | #define E_RSFN (-10) // 予約機能コード番号 14 | #define E_RSATR (-11) // 不正属性 15 | #define E_PAR (-17) // パラメータ不正 16 | #define E_ID (-18) // ID不正 17 | #define E_CTX (-25) // コンテキストエラー 18 | #define E_MACV (-26) // メモリアクセス違反 19 | #define E_OACV (-27) // オブジェクトアクセス違反 20 | #define E_ILUSE (-28) // システムコール不正 21 | #define E_NOMEM (-33) // メモリ不足 22 | #define E_LIMIT (-34) // 上限値エラー 23 | #define E_OBJ (-41) // オブジェクト状態エラー 24 | #define E_NOEXS (-42) // オブジェクト不正エラー 25 | #define E_QOVR (-43) // 上限エラー 26 | #define E_RLWAI (-49) // 待ち状態強制解除 27 | #define E_TMOUT (-50) // タイムアウトエラー 28 | #define E_DLT (-51) // 待ちオブジェクト削除 29 | #define E_DISWAI (-52) // 待ち禁止による待ち状態解除 30 | #define E_IO (-57) // I/Oエラー 31 | 32 | #endif // ERROR_H -------------------------------------------------------------------------------- /part_3/sect_3/include/error.h: -------------------------------------------------------------------------------- 1 | #ifndef ERROR_H 2 | #define ERROR_H 3 | /* 4 | * Try Kernel 5 | * エラーコード定義 6 | */ 7 | 8 | #define E_OK (0) // 正常終了 9 | 10 | #define E_SYS (-5) // システムエラー 11 | #define E_NOCOP (-6) // コプロセッサ使用不可 12 | #define E_NOSPT (-9) // 未サポート機能 13 | #define E_RSFN (-10) // 予約機能コード番号 14 | #define E_RSATR (-11) // 不正属性 15 | #define E_PAR (-17) // パラメータ不正 16 | #define E_ID (-18) // ID不正 17 | #define E_CTX (-25) // コンテキストエラー 18 | #define E_MACV (-26) // メモリアクセス違反 19 | #define E_OACV (-27) // オブジェクトアクセス違反 20 | #define E_ILUSE (-28) // システムコール不正 21 | #define E_NOMEM (-33) // メモリ不足 22 | #define E_LIMIT (-34) // 上限値エラー 23 | #define E_OBJ (-41) // オブジェクト状態エラー 24 | #define E_NOEXS (-42) // オブジェクト不正エラー 25 | #define E_QOVR (-43) // 上限エラー 26 | #define E_RLWAI (-49) // 待ち状態強制解除 27 | #define E_TMOUT (-50) // タイムアウトエラー 28 | #define E_DLT (-51) // 待ちオブジェクト削除 29 | #define E_DISWAI (-52) // 待ち禁止による待ち状態解除 30 | #define E_IO (-57) // I/Oエラー 31 | 32 | #endif // ERROR_H -------------------------------------------------------------------------------- /part_4/sect_1/include/error.h: -------------------------------------------------------------------------------- 1 | #ifndef ERROR_H 2 | #define ERROR_H 3 | /* 4 | * Try Kernel 5 | * エラーコード定義 6 | */ 7 | 8 | #define E_OK (0) // 正常終了 9 | 10 | #define E_SYS (-5) // システムエラー 11 | #define E_NOCOP (-6) // コプロセッサ使用不可 12 | #define E_NOSPT (-9) // 未サポート機能 13 | #define E_RSFN (-10) // 予約機能コード番号 14 | #define E_RSATR (-11) // 不正属性 15 | #define E_PAR (-17) // パラメータ不正 16 | #define E_ID (-18) // ID不正 17 | #define E_CTX (-25) // コンテキストエラー 18 | #define E_MACV (-26) // メモリアクセス違反 19 | #define E_OACV (-27) // オブジェクトアクセス違反 20 | #define E_ILUSE (-28) // システムコール不正 21 | #define E_NOMEM (-33) // メモリ不足 22 | #define E_LIMIT (-34) // 上限値エラー 23 | #define E_OBJ (-41) // オブジェクト状態エラー 24 | #define E_NOEXS (-42) // オブジェクト不正エラー 25 | #define E_QOVR (-43) // 上限エラー 26 | #define E_RLWAI (-49) // 待ち状態強制解除 27 | #define E_TMOUT (-50) // タイムアウトエラー 28 | #define E_DLT (-51) // 待ちオブジェクト削除 29 | #define E_DISWAI (-52) // 待ち禁止による待ち状態解除 30 | #define E_IO (-57) // I/Oエラー 31 | 32 | #endif // ERROR_H -------------------------------------------------------------------------------- /part_4/sect_2/include/error.h: -------------------------------------------------------------------------------- 1 | #ifndef ERROR_H 2 | #define ERROR_H 3 | /* 4 | * Try Kernel 5 | * エラーコード定義 6 | */ 7 | 8 | #define E_OK (0) // 正常終了 9 | 10 | #define E_SYS (-5) // システムエラー 11 | #define E_NOCOP (-6) // コプロセッサ使用不可 12 | #define E_NOSPT (-9) // 未サポート機能 13 | #define E_RSFN (-10) // 予約機能コード番号 14 | #define E_RSATR (-11) // 不正属性 15 | #define E_PAR (-17) // パラメータ不正 16 | #define E_ID (-18) // ID不正 17 | #define E_CTX (-25) // コンテキストエラー 18 | #define E_MACV (-26) // メモリアクセス違反 19 | #define E_OACV (-27) // オブジェクトアクセス違反 20 | #define E_ILUSE (-28) // システムコール不正 21 | #define E_NOMEM (-33) // メモリ不足 22 | #define E_LIMIT (-34) // 上限値エラー 23 | #define E_OBJ (-41) // オブジェクト状態エラー 24 | #define E_NOEXS (-42) // オブジェクト不正エラー 25 | #define E_QOVR (-43) // 上限エラー 26 | #define E_RLWAI (-49) // 待ち状態強制解除 27 | #define E_TMOUT (-50) // タイムアウトエラー 28 | #define E_DLT (-51) // 待ちオブジェクト削除 29 | #define E_DISWAI (-52) // 待ち禁止による待ち状態解除 30 | #define E_IO (-57) // I/Oエラー 31 | 32 | #endif // ERROR_H -------------------------------------------------------------------------------- /part_4/sect_3/include/error.h: -------------------------------------------------------------------------------- 1 | #ifndef ERROR_H 2 | #define ERROR_H 3 | /* 4 | * Try Kernel 5 | * エラーコード定義 6 | */ 7 | 8 | #define E_OK (0) // 正常終了 9 | 10 | #define E_SYS (-5) // システムエラー 11 | #define E_NOCOP (-6) // コプロセッサ使用不可 12 | #define E_NOSPT (-9) // 未サポート機能 13 | #define E_RSFN (-10) // 予約機能コード番号 14 | #define E_RSATR (-11) // 不正属性 15 | #define E_PAR (-17) // パラメータ不正 16 | #define E_ID (-18) // ID不正 17 | #define E_CTX (-25) // コンテキストエラー 18 | #define E_MACV (-26) // メモリアクセス違反 19 | #define E_OACV (-27) // オブジェクトアクセス違反 20 | #define E_ILUSE (-28) // システムコール不正 21 | #define E_NOMEM (-33) // メモリ不足 22 | #define E_LIMIT (-34) // 上限値エラー 23 | #define E_OBJ (-41) // オブジェクト状態エラー 24 | #define E_NOEXS (-42) // オブジェクト不正エラー 25 | #define E_QOVR (-43) // 上限エラー 26 | #define E_RLWAI (-49) // 待ち状態強制解除 27 | #define E_TMOUT (-50) // タイムアウトエラー 28 | #define E_DLT (-51) // 待ちオブジェクト削除 29 | #define E_DISWAI (-52) // 待ち禁止による待ち状態解除 30 | #define E_IO (-57) // I/Oエラー 31 | 32 | #endif // ERROR_H -------------------------------------------------------------------------------- /part_5/kernel/inittsk.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 初期タスク 4 | */ 5 | #include 6 | #include 7 | 8 | void initsk(INT stacd, void *exinf); // 初期タスクの実行プログラム 9 | UW tskstk_ini[256/sizeof(UW)]; // 初期タスクのスタック 10 | ID tskid_ini; // 初期タスクのID番号 11 | 12 | T_CTSK ctsk_ini = { 13 | .tskatr = TA_HLNG | TA_RNG0 | TA_USERBUF, // タスク属性 14 | .task = initsk, // タスクの実行関数 15 | .itskpri = 1, // タスク優先度 16 | .stksz = sizeof(tskstk_ini), // スタックサイズ 17 | .bufptr = tskstk_ini, // スタックへのポインタ 18 | }; 19 | 20 | void initsk(INT stacd, void *exinf) 21 | { 22 | tm_com_init(); // シリアル通信の初期化 23 | tm_putstring("Strat Try Kernel\n"); 24 | 25 | usermain(); 26 | tk_ext_tsk(); 27 | } 28 | 29 | int main(void) 30 | { 31 | tskid_ini = tk_cre_tsk(&ctsk_ini); // 初期タスク生成 32 | tk_sta_tsk(tskid_ini, 0); // 初期タスク実行 33 | 34 | while(1); // ここは実行されない 35 | } -------------------------------------------------------------------------------- /part_3/sect_2/kernel/inittsk.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 初期タスク 4 | */ 5 | #include 6 | #include 7 | 8 | void initsk(INT stacd, void *exinf); // 初期タスクの実行プログラム 9 | UW tskstk_ini[256/sizeof(UW)]; // 初期タスクのスタック 10 | ID tskid_ini; // 初期タスクのID番号 11 | 12 | T_CTSK ctsk_ini = { 13 | .tskatr = TA_HLNG | TA_RNG0 | TA_USERBUF, // タスク属性 14 | .task = initsk, // タスクの実行関数 15 | .itskpri = 1, // タスク優先度 16 | .stksz = sizeof(tskstk_ini), // スタックサイズ 17 | .bufptr = tskstk_ini, // スタックへのポインタ 18 | }; 19 | 20 | void initsk(INT stacd, void *exinf) 21 | { 22 | tm_com_init(); // シリアル通信の初期化 23 | tm_putstring("Strat Try Kernel\n"); 24 | 25 | usermain(); 26 | tk_ext_tsk(); 27 | } 28 | 29 | int main(void) 30 | { 31 | tskid_ini = tk_cre_tsk(&ctsk_ini); // 初期タスク生成 32 | tk_sta_tsk(tskid_ini, 0); // 初期タスク実行 33 | 34 | while(1); // ここは実行されない 35 | } -------------------------------------------------------------------------------- /part_3/sect_3/kernel/inittsk.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 初期タスク 4 | */ 5 | #include 6 | #include 7 | 8 | void initsk(INT stacd, void *exinf); // 初期タスクの実行プログラム 9 | UW tskstk_ini[256/sizeof(UW)]; // 初期タスクのスタック 10 | ID tskid_ini; // 初期タスクのID番号 11 | 12 | T_CTSK ctsk_ini = { 13 | .tskatr = TA_HLNG | TA_RNG0 | TA_USERBUF, // タスク属性 14 | .task = initsk, // タスクの実行関数 15 | .itskpri = 1, // タスク優先度 16 | .stksz = sizeof(tskstk_ini), // スタックサイズ 17 | .bufptr = tskstk_ini, // スタックへのポインタ 18 | }; 19 | 20 | void initsk(INT stacd, void *exinf) 21 | { 22 | tm_com_init(); // シリアル通信の初期化 23 | tm_putstring("Strat Try Kernel\n"); 24 | 25 | usermain(); 26 | tk_ext_tsk(); 27 | } 28 | 29 | int main(void) 30 | { 31 | tskid_ini = tk_cre_tsk(&ctsk_ini); // 初期タスク生成 32 | tk_sta_tsk(tskid_ini, 0); // 初期タスク実行 33 | 34 | while(1); // ここは実行されない 35 | } -------------------------------------------------------------------------------- /part_4/sect_1/kernel/inittsk.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 初期タスク 4 | */ 5 | #include 6 | #include 7 | 8 | void initsk(INT stacd, void *exinf); // 初期タスクの実行プログラム 9 | UW tskstk_ini[256/sizeof(UW)]; // 初期タスクのスタック 10 | ID tskid_ini; // 初期タスクのID番号 11 | 12 | T_CTSK ctsk_ini = { 13 | .tskatr = TA_HLNG | TA_RNG0 | TA_USERBUF, // タスク属性 14 | .task = initsk, // タスクの実行関数 15 | .itskpri = 1, // タスク優先度 16 | .stksz = sizeof(tskstk_ini), // スタックサイズ 17 | .bufptr = tskstk_ini, // スタックへのポインタ 18 | }; 19 | 20 | void initsk(INT stacd, void *exinf) 21 | { 22 | tm_com_init(); // シリアル通信の初期化 23 | tm_putstring("Strat Try Kernel\n"); 24 | 25 | usermain(); 26 | tk_ext_tsk(); 27 | } 28 | 29 | int main(void) 30 | { 31 | tskid_ini = tk_cre_tsk(&ctsk_ini); // 初期タスク生成 32 | tk_sta_tsk(tskid_ini, 0); // 初期タスク実行 33 | 34 | while(1); // ここは実行されない 35 | } -------------------------------------------------------------------------------- /part_4/sect_2/kernel/inittsk.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 初期タスク 4 | */ 5 | #include 6 | #include 7 | 8 | void initsk(INT stacd, void *exinf); // 初期タスクの実行プログラム 9 | UW tskstk_ini[256/sizeof(UW)]; // 初期タスクのスタック 10 | ID tskid_ini; // 初期タスクのID番号 11 | 12 | T_CTSK ctsk_ini = { 13 | .tskatr = TA_HLNG | TA_RNG0 | TA_USERBUF, // タスク属性 14 | .task = initsk, // タスクの実行関数 15 | .itskpri = 1, // タスク優先度 16 | .stksz = sizeof(tskstk_ini), // スタックサイズ 17 | .bufptr = tskstk_ini, // スタックへのポインタ 18 | }; 19 | 20 | void initsk(INT stacd, void *exinf) 21 | { 22 | tm_com_init(); // シリアル通信の初期化 23 | tm_putstring("Strat Try Kernel\n"); 24 | 25 | usermain(); 26 | tk_ext_tsk(); 27 | } 28 | 29 | int main(void) 30 | { 31 | tskid_ini = tk_cre_tsk(&ctsk_ini); // 初期タスク生成 32 | tk_sta_tsk(tskid_ini, 0); // 初期タスク実行 33 | 34 | while(1); // ここは実行されない 35 | } -------------------------------------------------------------------------------- /part_4/sect_3/kernel/inittsk.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 初期タスク 4 | */ 5 | #include 6 | #include 7 | 8 | void initsk(INT stacd, void *exinf); // 初期タスクの実行プログラム 9 | UW tskstk_ini[256/sizeof(UW)]; // 初期タスクのスタック 10 | ID tskid_ini; // 初期タスクのID番号 11 | 12 | T_CTSK ctsk_ini = { 13 | .tskatr = TA_HLNG | TA_RNG0 | TA_USERBUF, // タスク属性 14 | .task = initsk, // タスクの実行関数 15 | .itskpri = 1, // タスク優先度 16 | .stksz = sizeof(tskstk_ini), // スタックサイズ 17 | .bufptr = tskstk_ini, // スタックへのポインタ 18 | }; 19 | 20 | void initsk(INT stacd, void *exinf) 21 | { 22 | tm_com_init(); // シリアル通信の初期化 23 | tm_putstring("Strat Try Kernel\n"); 24 | 25 | usermain(); 26 | tk_ext_tsk(); 27 | } 28 | 29 | int main(void) 30 | { 31 | tskid_ini = tk_cre_tsk(&ctsk_ini); // 初期タスク生成 32 | tk_sta_tsk(tskid_ini, 0); // 初期タスク実行 33 | 34 | while(1); // ここは実行されない 35 | } -------------------------------------------------------------------------------- /part_5/kernel/systimer.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * システムタイマ 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | TCB *wait_queue; /* 時間待ち状態のタスクの待ち行列(ウェイトキュー) */ 10 | 11 | /* システムタイマ割込みハンドラ */ 12 | void systimer_handler(void) 13 | { 14 | TCB *tcb, *next; 15 | 16 | for( tcb = wait_queue; tcb != NULL; tcb = next) { 17 | next = tcb->next; 18 | if(tcb->waitim == TMO_FEVR) { 19 | continue; 20 | } else if(tcb->waitim > TIMER_PERIOD) { 21 | tcb->waitim -= TIMER_PERIOD; // 待ち時間から経過時間を減じる。 22 | } else { // 待ち時間が経過したタスクを実行できる状態に戻す 23 | tqueue_remove_entry( &wait_queue, tcb); // タスクをウェイトキューから外す 24 | 25 | if(tcb->waifct == TWFCT_DLY) { 26 | *tcb->waierr = E_OK; // tk_dly_tskからの復帰はエラー無し 27 | } else { 28 | *tcb->waierr = E_TMOUT; // タイムアウト・エラー 29 | } 30 | 31 | tcb->state = TS_READY; 32 | tcb->waifct = TWFCT_NON; 33 | tqueue_add_entry( &ready_queue[tcb->itskpri], tcb); // タスクをレディキューにつなぐ 34 | } 35 | } 36 | scheduler(); // スケジューラを実行する 37 | } -------------------------------------------------------------------------------- /part_4/sect_1/kernel/systimer.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * システムタイマ 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | TCB *wait_queue; /* 時間待ち状態のタスクの待ち行列(ウェイトキュー) */ 10 | 11 | /* システムタイマ割込みハンドラ */ 12 | void systimer_handler(void) 13 | { 14 | TCB *tcb, *next; 15 | 16 | for( tcb = wait_queue; tcb != NULL; tcb = next) { 17 | next = tcb->next; 18 | if(tcb->waitim == TMO_FEVR) { 19 | continue; 20 | } else if(tcb->waitim > TIMER_PERIOD) { 21 | tcb->waitim -= TIMER_PERIOD; // 待ち時間から経過時間を減じる。 22 | } else { // 待ち時間が経過したタスクを実行できる状態に戻す 23 | tqueue_remove_entry( &wait_queue, tcb); // タスクをウェイトキューから外す 24 | 25 | if(tcb->waifct == TWFCT_DLY) { 26 | *tcb->waierr = E_OK; // tk_dly_tskからの復帰はエラー無し 27 | } else { 28 | *tcb->waierr = E_TMOUT; // タイムアウト・エラー 29 | } 30 | 31 | tcb->state = TS_READY; 32 | tcb->waifct = TWFCT_NON; 33 | tqueue_add_entry( &ready_queue[tcb->itskpri], tcb); // タスクをレディキューにつなぐ 34 | } 35 | } 36 | scheduler(); // スケジューラを実行する 37 | } -------------------------------------------------------------------------------- /part_4/sect_2/kernel/systimer.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * システムタイマ 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | TCB *wait_queue; /* 時間待ち状態のタスクの待ち行列(ウェイトキュー) */ 10 | 11 | /* システムタイマ割込みハンドラ */ 12 | void systimer_handler(void) 13 | { 14 | TCB *tcb, *next; 15 | 16 | for( tcb = wait_queue; tcb != NULL; tcb = next) { 17 | next = tcb->next; 18 | if(tcb->waitim == TMO_FEVR) { 19 | continue; 20 | } else if(tcb->waitim > TIMER_PERIOD) { 21 | tcb->waitim -= TIMER_PERIOD; // 待ち時間から経過時間を減じる。 22 | } else { // 待ち時間が経過したタスクを実行できる状態に戻す 23 | tqueue_remove_entry( &wait_queue, tcb); // タスクをウェイトキューから外す 24 | 25 | if(tcb->waifct == TWFCT_DLY) { 26 | *tcb->waierr = E_OK; // tk_dly_tskからの復帰はエラー無し 27 | } else { 28 | *tcb->waierr = E_TMOUT; // タイムアウト・エラー 29 | } 30 | 31 | tcb->state = TS_READY; 32 | tcb->waifct = TWFCT_NON; 33 | tqueue_add_entry( &ready_queue[tcb->itskpri], tcb); // タスクをレディキューにつなぐ 34 | } 35 | } 36 | scheduler(); // スケジューラを実行する 37 | } -------------------------------------------------------------------------------- /part_4/sect_3/kernel/systimer.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * システムタイマ 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | TCB *wait_queue; /* 時間待ち状態のタスクの待ち行列(ウェイトキュー) */ 10 | 11 | /* システムタイマ割込みハンドラ */ 12 | void systimer_handler(void) 13 | { 14 | TCB *tcb, *next; 15 | 16 | for( tcb = wait_queue; tcb != NULL; tcb = next) { 17 | next = tcb->next; 18 | if(tcb->waitim == TMO_FEVR) { 19 | continue; 20 | } else if(tcb->waitim > TIMER_PERIOD) { 21 | tcb->waitim -= TIMER_PERIOD; // 待ち時間から経過時間を減じる。 22 | } else { // 待ち時間が経過したタスクを実行できる状態に戻す 23 | tqueue_remove_entry( &wait_queue, tcb); // タスクをウェイトキューから外す 24 | 25 | if(tcb->waifct == TWFCT_DLY) { 26 | *tcb->waierr = E_OK; // tk_dly_tskからの復帰はエラー無し 27 | } else { 28 | *tcb->waierr = E_TMOUT; // タイムアウト・エラー 29 | } 30 | 31 | tcb->state = TS_READY; 32 | tcb->waifct = TWFCT_NON; 33 | tqueue_add_entry( &ready_queue[tcb->itskpri], tcb); // タスクをレディキューにつなぐ 34 | } 35 | } 36 | scheduler(); // スケジューラを実行する 37 | } -------------------------------------------------------------------------------- /part_3/sect_1/kernel/dispatch.S: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 簡易ディスパッチャ 4 | */ 5 | .align 2 6 | .thumb_func 7 | .globl dispatch_entry 8 | 9 | dispatch_entry: 10 | /* ① 実行中のタスクの実行コンテキスト情報をスタックに退避 */ 11 | push {r4-r7} 12 | mov r0, r8 13 | mov r1, r9 14 | mov r2, r10 15 | mov r3, r11 16 | push {r0-r3} 17 | 18 | /* ② 現在実行中のタスクの確認 */ 19 | ldr r0, =cur_task 20 | ldr r1, [r0] 21 | cmp r1, #0 22 | beq disp_010 // cur_taskのID番号 = 0 ならば disp_010へ 23 | 24 | /* ③ SPレジスタの値をctx_tblに格納 */ 25 | ldr r0, =ctx_tbl 26 | sub r1, #1 27 | lsl r1, r1, #2 28 | mov r2, sp 29 | str r2, [r0, r1] 30 | 31 | disp_010: 32 | /* ④ 実行中のタスクの変更 */ 33 | ldr r0, =next_task 34 | ldr r1, [r0] 35 | ldr r0, =cur_task 36 | str r1, [r0] 37 | 38 | /* ⑤ スタックの切り替え */ 39 | ldr r0, =ctx_tbl 40 | sub r1, #1 41 | lsl r1, r1, #2 42 | ldr r2, [r0, r1] 43 | mov sp, r2 44 | 45 | /* ⑥ スタック上のコンテキス情報の復元 */ 46 | pop {r0-r3} 47 | mov r11, r3 48 | mov r10, r2 49 | mov r9, r1 50 | mov r8, r0 51 | pop {r4-r7} 52 | bx lr 53 | -------------------------------------------------------------------------------- /part_5/kernel/task_queue.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスクの待ち行列操作関数 4 | */ 5 | #include 6 | #include 7 | 8 | /* エントリ追加関数 */ 9 | void tqueue_add_entry(TCB **queue, TCB *tcb) 10 | { 11 | TCB *queue_end; 12 | 13 | if(*queue == NULL) { // キューは空なので先頭に追加 14 | *queue = tcb; 15 | tcb->pre = tcb; 16 | } else { // キューの終端に追加 17 | queue_end = (*queue)->pre; 18 | queue_end->next = tcb; 19 | tcb->pre = queue_end; 20 | (*queue)->pre = tcb; 21 | } 22 | tcb->next = NULL; 23 | } 24 | 25 | /* 先頭エントリ削除関数 */ 26 | void tqueue_remove_top(TCB **queue) 27 | { 28 | TCB *top; 29 | 30 | if(*queue == NULL) return; // キューは空 31 | 32 | top = *queue; 33 | *queue = top->next; 34 | if(*queue != NULL) { 35 | (*queue)->pre = top->pre; 36 | } 37 | } 38 | 39 | /* 指定エントリ削除関数 */ 40 | void tqueue_remove_entry(TCB **queue, TCB *tcb) 41 | { 42 | if(*queue == tcb) { // 指定したエントリはキューの先頭 43 | tqueue_remove_top(queue); 44 | } else { // キューの途中から指定エントリを削除 45 | (tcb->pre)->next = tcb->next; 46 | if(tcb->next != NULL) { 47 | (tcb->next)->pre = tcb->pre; 48 | } else { 49 | (*queue)->pre = tcb->pre; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /part_3/sect_2/kernel/task_queue.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスクの待ち行列操作関数 4 | */ 5 | #include 6 | #include 7 | 8 | /* エントリ追加関数 */ 9 | void tqueue_add_entry(TCB **queue, TCB *tcb) 10 | { 11 | TCB *queue_end; 12 | 13 | if(*queue == NULL) { // キューは空なので先頭に追加 14 | *queue = tcb; 15 | tcb->pre = tcb; 16 | } else { // キューの終端に追加 17 | queue_end = (*queue)->pre; 18 | queue_end->next = tcb; 19 | tcb->pre = queue_end; 20 | (*queue)->pre = tcb; 21 | } 22 | tcb->next = NULL; 23 | } 24 | 25 | /* 先頭エントリ削除関数 */ 26 | void tqueue_remove_top(TCB **queue) 27 | { 28 | TCB *top; 29 | 30 | if(*queue == NULL) return; // キューは空 31 | 32 | top = *queue; 33 | *queue = top->next; 34 | if(*queue != NULL) { 35 | (*queue)->pre = top->pre; 36 | } 37 | } 38 | 39 | /* 指定エントリ削除関数 */ 40 | void tqueue_remove_entry(TCB **queue, TCB *tcb) 41 | { 42 | if(*queue == tcb) { // 指定したエントリはキューの先頭 43 | tqueue_remove_top(queue); 44 | } else { // キューの途中から指定エントリを削除 45 | (tcb->pre)->next = tcb->next; 46 | if(tcb->next != NULL) { 47 | (tcb->next)->pre = tcb->pre; 48 | } else { 49 | (*queue)->pre = tcb->pre; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /part_3/sect_3/kernel/task_queue.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスクの待ち行列操作関数 4 | */ 5 | #include 6 | #include 7 | 8 | /* エントリ追加関数 */ 9 | void tqueue_add_entry(TCB **queue, TCB *tcb) 10 | { 11 | TCB *queue_end; 12 | 13 | if(*queue == NULL) { // キューは空なので先頭に追加 14 | *queue = tcb; 15 | tcb->pre = tcb; 16 | } else { // キューの終端に追加 17 | queue_end = (*queue)->pre; 18 | queue_end->next = tcb; 19 | tcb->pre = queue_end; 20 | (*queue)->pre = tcb; 21 | } 22 | tcb->next = NULL; 23 | } 24 | 25 | /* 先頭エントリ削除関数 */ 26 | void tqueue_remove_top(TCB **queue) 27 | { 28 | TCB *top; 29 | 30 | if(*queue == NULL) return; // キューは空 31 | 32 | top = *queue; 33 | *queue = top->next; 34 | if(*queue != NULL) { 35 | (*queue)->pre = top->pre; 36 | } 37 | } 38 | 39 | /* 指定エントリ削除関数 */ 40 | void tqueue_remove_entry(TCB **queue, TCB *tcb) 41 | { 42 | if(*queue == tcb) { // 指定したエントリはキューの先頭 43 | tqueue_remove_top(queue); 44 | } else { // キューの途中から指定エントリを削除 45 | (tcb->pre)->next = tcb->next; 46 | if(tcb->next != NULL) { 47 | (tcb->next)->pre = tcb->pre; 48 | } else { 49 | (*queue)->pre = tcb->pre; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /part_4/sect_1/kernel/task_queue.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスクの待ち行列操作関数 4 | */ 5 | #include 6 | #include 7 | 8 | /* エントリ追加関数 */ 9 | void tqueue_add_entry(TCB **queue, TCB *tcb) 10 | { 11 | TCB *queue_end; 12 | 13 | if(*queue == NULL) { // キューは空なので先頭に追加 14 | *queue = tcb; 15 | tcb->pre = tcb; 16 | } else { // キューの終端に追加 17 | queue_end = (*queue)->pre; 18 | queue_end->next = tcb; 19 | tcb->pre = queue_end; 20 | (*queue)->pre = tcb; 21 | } 22 | tcb->next = NULL; 23 | } 24 | 25 | /* 先頭エントリ削除関数 */ 26 | void tqueue_remove_top(TCB **queue) 27 | { 28 | TCB *top; 29 | 30 | if(*queue == NULL) return; // キューは空 31 | 32 | top = *queue; 33 | *queue = top->next; 34 | if(*queue != NULL) { 35 | (*queue)->pre = top->pre; 36 | } 37 | } 38 | 39 | /* 指定エントリ削除関数 */ 40 | void tqueue_remove_entry(TCB **queue, TCB *tcb) 41 | { 42 | if(*queue == tcb) { // 指定したエントリはキューの先頭 43 | tqueue_remove_top(queue); 44 | } else { // キューの途中から指定エントリを削除 45 | (tcb->pre)->next = tcb->next; 46 | if(tcb->next != NULL) { 47 | (tcb->next)->pre = tcb->pre; 48 | } else { 49 | (*queue)->pre = tcb->pre; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /part_4/sect_2/kernel/task_queue.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスクの待ち行列操作関数 4 | */ 5 | #include 6 | #include 7 | 8 | /* エントリ追加関数 */ 9 | void tqueue_add_entry(TCB **queue, TCB *tcb) 10 | { 11 | TCB *queue_end; 12 | 13 | if(*queue == NULL) { // キューは空なので先頭に追加 14 | *queue = tcb; 15 | tcb->pre = tcb; 16 | } else { // キューの終端に追加 17 | queue_end = (*queue)->pre; 18 | queue_end->next = tcb; 19 | tcb->pre = queue_end; 20 | (*queue)->pre = tcb; 21 | } 22 | tcb->next = NULL; 23 | } 24 | 25 | /* 先頭エントリ削除関数 */ 26 | void tqueue_remove_top(TCB **queue) 27 | { 28 | TCB *top; 29 | 30 | if(*queue == NULL) return; // キューは空 31 | 32 | top = *queue; 33 | *queue = top->next; 34 | if(*queue != NULL) { 35 | (*queue)->pre = top->pre; 36 | } 37 | } 38 | 39 | /* 指定エントリ削除関数 */ 40 | void tqueue_remove_entry(TCB **queue, TCB *tcb) 41 | { 42 | if(*queue == tcb) { // 指定したエントリはキューの先頭 43 | tqueue_remove_top(queue); 44 | } else { // キューの途中から指定エントリを削除 45 | (tcb->pre)->next = tcb->next; 46 | if(tcb->next != NULL) { 47 | (tcb->next)->pre = tcb->pre; 48 | } else { 49 | (*queue)->pre = tcb->pre; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /part_4/sect_3/kernel/task_queue.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスクの待ち行列操作関数 4 | */ 5 | #include 6 | #include 7 | 8 | /* エントリ追加関数 */ 9 | void tqueue_add_entry(TCB **queue, TCB *tcb) 10 | { 11 | TCB *queue_end; 12 | 13 | if(*queue == NULL) { // キューは空なので先頭に追加 14 | *queue = tcb; 15 | tcb->pre = tcb; 16 | } else { // キューの終端に追加 17 | queue_end = (*queue)->pre; 18 | queue_end->next = tcb; 19 | tcb->pre = queue_end; 20 | (*queue)->pre = tcb; 21 | } 22 | tcb->next = NULL; 23 | } 24 | 25 | /* 先頭エントリ削除関数 */ 26 | void tqueue_remove_top(TCB **queue) 27 | { 28 | TCB *top; 29 | 30 | if(*queue == NULL) return; // キューは空 31 | 32 | top = *queue; 33 | *queue = top->next; 34 | if(*queue != NULL) { 35 | (*queue)->pre = top->pre; 36 | } 37 | } 38 | 39 | /* 指定エントリ削除関数 */ 40 | void tqueue_remove_entry(TCB **queue, TCB *tcb) 41 | { 42 | if(*queue == tcb) { // 指定したエントリはキューの先頭 43 | tqueue_remove_top(queue); 44 | } else { // キューの途中から指定エントリを削除 45 | (tcb->pre)->next = tcb->next; 46 | if(tcb->next != NULL) { 47 | (tcb->next)->pre = tcb->pre; 48 | } else { 49 | (*queue)->pre = tcb->pre; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /part_2/sect_3/include/syslib.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSLIB_H 2 | #define SYSLIB_H 3 | /* 4 | *** Try Kernel 5 | * 共通ライブラリ関数定義 6 | */ 7 | 8 | /* 32bitレジスタからの入力 */ 9 | static inline UW in_w(UW adr) 10 | { 11 | return *(_UW*)adr; 12 | } 13 | 14 | /* 32bitレジスタへの出力 */ 15 | static inline void out_w(UW adr, UW data) 16 | { 17 | *(_UW*)adr = data; 18 | } 19 | 20 | /* 32bitレジスタへの出力(ビットクリア) */ 21 | #define OP_CLR 0x3000 22 | static inline void clr_w(UW adr, UW data) 23 | { 24 | *(_UW*)(adr + OP_CLR) = data; 25 | } 26 | 27 | /* 32bitレジスタへの出力(ビットセット) */ 28 | #define OP_SET 0x2000 29 | static inline void set_w(UW adr, UW data) 30 | { 31 | *(_UW*)(adr + OP_SET) = data; 32 | } 33 | 34 | /* 32bitレジスタへの出力(ビット排他的論理和) */ 35 | #define OP_XOR 0x1000 36 | static inline void xset_w(UW adr, UW data) 37 | { 38 | *(_UW*)(adr + OP_XOR) = data; 39 | } 40 | 41 | /* PRIMASKレジスタ制御インライン関数 */ 42 | static inline void set_primask( INT pm ) 43 | { 44 | __asm__ volatile("msr primask, %0":: "r"(pm)); 45 | } 46 | 47 | static inline UW get_primask( void ) 48 | { 49 | UW pm; 50 | __asm__ volatile("mrs %0, primask": "=r"(pm)); 51 | return pm; 52 | } 53 | 54 | /* 割込み禁止マクロ */ 55 | #define DI(intsts) (intsts=get_primask(), set_primask(1)) 56 | 57 | /* 割込み許可マクロ */ 58 | #define EI(intsts) (set_primask(intsts)) 59 | 60 | #endif /* STYLIB_H */ -------------------------------------------------------------------------------- /part_3/sect_2/application/usermain.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | UW tskstk_1[1024/sizeof(UW)]; // タスク1のスタック 4 | ID tskid_1; // タスク1のID番号 5 | 6 | /* タスク1生成情報 */ 7 | void task_1(INT stacd, void *exinf); 8 | T_CTSK ctsk_1 = { 9 | .tskatr = TA_HLNG | TA_RNG3 | TA_USERBUF, // タスク属性 10 | .task = task_1, 11 | .itskpri = 10, 12 | .stksz = 1024, 13 | .bufptr = tskstk_1, 14 | }; 15 | 16 | UW tskstk_2[1024/sizeof(UW)]; // タスク2のスタック 17 | ID tskid_2; // タスク2のID番号 18 | 19 | /* タスク2生成情報 */ 20 | void task_2(INT stacd, void *exinf); 21 | T_CTSK ctsk_2 = { 22 | .tskatr = TA_HLNG | TA_RNG3 | TA_USERBUF, // タスク属性 23 | .task = task_2, 24 | .itskpri = 10, 25 | .stksz = 1024, 26 | .bufptr = tskstk_2, 27 | }; 28 | 29 | /* タスク1の実行関数 */ 30 | void task_1(INT stacd, void *exinf) 31 | { 32 | tm_putstring("Start Task-1\n"); 33 | tk_ext_tsk(); 34 | } 35 | 36 | /* タスク2の実行関数 */ 37 | void task_2(INT stacd, void *exinf) 38 | { 39 | tm_putstring("Start Task-2\n"); 40 | tk_ext_tsk(); 41 | } 42 | 43 | int usermain(void) 44 | { 45 | tm_putstring("Start user-main\n"); 46 | 47 | /* タスク1の生成、実行 */ 48 | tskid_1 = tk_cre_tsk(&ctsk_1); 49 | tk_sta_tsk(tskid_1, 0); 50 | 51 | /* タスク2の生成、実行 */ 52 | tskid_2 = tk_cre_tsk(&ctsk_2); 53 | tk_sta_tsk(tskid_2, 0); 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /part_5/application/usermain.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "app.h" 3 | 4 | ID dd_i2c0, dd_i2c1; // I2Cデバイスディスクリプタ 5 | ID dd_adc; // A/DCデバイスディスクリプタ 6 | ID flgid_1; // イベントフラグID 7 | 8 | /* センサーデータ */ 9 | UW gsns_data; // ジェスチャセンサーのデータ 10 | UW lsns_data; // 光センサーのデータ 11 | 12 | int usermain(void) 13 | { 14 | /* イベントフラグの生成情報 */ 15 | T_CFLG cflg_1 = { 16 | .iflgptn = 0, 17 | }; 18 | 19 | /* イベントフラグの生成 */ 20 | flgid_1 = tk_cre_flg(&cflg_1); 21 | 22 | /* I/Oデバイスのオープン */ 23 | dd_i2c0 = tk_opn_dev((UB*)"iica",TD_UPDATE); 24 | if(dd_i2c0 < 0) tm_putstring("Error I2C0\n"); 25 | else tm_putstring("Open I2C0\n"); 26 | 27 | dd_i2c1 = tk_opn_dev((UB*)"iicb",TD_UPDATE); 28 | if(dd_i2c1 < 0) tm_putstring("Error I2C1\n"); 29 | else tm_putstring("Open I2C1\n"); 30 | 31 | dd_adc = tk_opn_dev((UB*)"adca",TD_READ); 32 | if(dd_adc < 0) tm_putstring("Error ADC\n"); 33 | else tm_putstring("Open ADC\n"); 34 | 35 | /* ジェスチャセンサー制御タスクの生成・実行*/ 36 | tskid_gsns = tk_cre_tsk(&ctsk_gsns); 37 | tk_sta_tsk(tskid_gsns, 0); 38 | 39 | /* 光センサー制御タスクの生成・実行 */ 40 | tskid_lsns = tk_cre_tsk(&ctsk_lsns); 41 | tk_sta_tsk(tskid_lsns, 0); 42 | 43 | /* LCD制御タスクの生成・実行 */ 44 | tskid_lcd = tk_cre_tsk(&ctsk_lcd); 45 | tk_sta_tsk(tskid_lcd, 0); 46 | 47 | tk_slp_tsk(TMO_FEVR); // 初期タスクを待ち状態に 48 | return 0; 49 | } -------------------------------------------------------------------------------- /part_5/include/syslib.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSLIB_H 2 | #define SYSLIB_H 3 | /* 4 | *** Try Kernel 5 | * 共通ライブラリ関数定義 6 | */ 7 | 8 | /* 32bitレジスタからの入力 */ 9 | static inline UW in_w(UW adr) 10 | { 11 | return *(_UW*)adr; 12 | } 13 | 14 | /* 32bitレジスタへの出力 */ 15 | static inline void out_w(UW adr, UW data) 16 | { 17 | *(_UW*)adr = data; 18 | } 19 | 20 | /* 32bitレジスタへの出力(ビットクリア) */ 21 | #define OP_CLR 0x3000 22 | static inline void clr_w(UW adr, UW data) 23 | { 24 | *(_UW*)(adr + OP_CLR) = data; 25 | } 26 | 27 | /* 32bitレジスタへの出力(ビットセット) */ 28 | #define OP_SET 0x2000 29 | static inline void set_w(UW adr, UW data) 30 | { 31 | *(_UW*)(adr + OP_SET) = data; 32 | } 33 | 34 | /* 32bitレジスタへの出力(ビット排他的論理和) */ 35 | #define OP_XOR 0x1000 36 | static inline void xset_w(UW adr, UW data) 37 | { 38 | *(_UW*)(adr + OP_XOR) = data; 39 | } 40 | 41 | /* PRIMASKレジスタ制御インライン関数 */ 42 | static inline void set_primask( INT pm ) 43 | { 44 | __asm__ volatile("msr primask, %0":: "r"(pm)); 45 | } 46 | 47 | static inline UW get_primask( void ) 48 | { 49 | UW pm; 50 | __asm__ volatile("mrs %0, primask": "=r"(pm)); 51 | return pm; 52 | } 53 | 54 | /* 割込み禁止マクロ */ 55 | #define DI(intsts) (intsts=get_primask(), set_primask(1)) 56 | 57 | /* 割込み許可マクロ */ 58 | #define EI(intsts) (set_primask(intsts)) 59 | 60 | /* デバッグ用シリアル通信 */ 61 | void tm_com_init(void); 62 | UINT tm_putstring(char* str); 63 | 64 | #endif /* STYLIB_H */ -------------------------------------------------------------------------------- /part_2/sect_4/include/syslib.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSLIB_H 2 | #define SYSLIB_H 3 | /* 4 | *** Try Kernel 5 | * 共通ライブラリ関数定義 6 | */ 7 | 8 | /* 32bitレジスタからの入力 */ 9 | static inline UW in_w(UW adr) 10 | { 11 | return *(_UW*)adr; 12 | } 13 | 14 | /* 32bitレジスタへの出力 */ 15 | static inline void out_w(UW adr, UW data) 16 | { 17 | *(_UW*)adr = data; 18 | } 19 | 20 | /* 32bitレジスタへの出力(ビットクリア) */ 21 | #define OP_CLR 0x3000 22 | static inline void clr_w(UW adr, UW data) 23 | { 24 | *(_UW*)(adr + OP_CLR) = data; 25 | } 26 | 27 | /* 32bitレジスタへの出力(ビットセット) */ 28 | #define OP_SET 0x2000 29 | static inline void set_w(UW adr, UW data) 30 | { 31 | *(_UW*)(adr + OP_SET) = data; 32 | } 33 | 34 | /* 32bitレジスタへの出力(ビット排他的論理和) */ 35 | #define OP_XOR 0x1000 36 | static inline void xset_w(UW adr, UW data) 37 | { 38 | *(_UW*)(adr + OP_XOR) = data; 39 | } 40 | 41 | /* PRIMASKレジスタ制御インライン関数 */ 42 | static inline void set_primask( INT pm ) 43 | { 44 | __asm__ volatile("msr primask, %0":: "r"(pm)); 45 | } 46 | 47 | static inline UW get_primask( void ) 48 | { 49 | UW pm; 50 | __asm__ volatile("mrs %0, primask": "=r"(pm)); 51 | return pm; 52 | } 53 | 54 | /* 割込み禁止マクロ */ 55 | #define DI(intsts) (intsts=get_primask(), set_primask(1)) 56 | 57 | /* 割込み許可マクロ */ 58 | #define EI(intsts) (set_primask(intsts)) 59 | 60 | /* デバッグ用シリアル通信 */ 61 | void tm_com_init(void); 62 | UINT tm_putstring(char* str); 63 | 64 | #endif /* STYLIB_H */ -------------------------------------------------------------------------------- /part_3/sect_1/include/syslib.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSLIB_H 2 | #define SYSLIB_H 3 | /* 4 | *** Try Kernel 5 | * 共通ライブラリ関数定義 6 | */ 7 | 8 | /* 32bitレジスタからの入力 */ 9 | static inline UW in_w(UW adr) 10 | { 11 | return *(_UW*)adr; 12 | } 13 | 14 | /* 32bitレジスタへの出力 */ 15 | static inline void out_w(UW adr, UW data) 16 | { 17 | *(_UW*)adr = data; 18 | } 19 | 20 | /* 32bitレジスタへの出力(ビットクリア) */ 21 | #define OP_CLR 0x3000 22 | static inline void clr_w(UW adr, UW data) 23 | { 24 | *(_UW*)(adr + OP_CLR) = data; 25 | } 26 | 27 | /* 32bitレジスタへの出力(ビットセット) */ 28 | #define OP_SET 0x2000 29 | static inline void set_w(UW adr, UW data) 30 | { 31 | *(_UW*)(adr + OP_SET) = data; 32 | } 33 | 34 | /* 32bitレジスタへの出力(ビット排他的論理和) */ 35 | #define OP_XOR 0x1000 36 | static inline void xset_w(UW adr, UW data) 37 | { 38 | *(_UW*)(adr + OP_XOR) = data; 39 | } 40 | 41 | /* PRIMASKレジスタ制御インライン関数 */ 42 | static inline void set_primask( INT pm ) 43 | { 44 | __asm__ volatile("msr primask, %0":: "r"(pm)); 45 | } 46 | 47 | static inline UW get_primask( void ) 48 | { 49 | UW pm; 50 | __asm__ volatile("mrs %0, primask": "=r"(pm)); 51 | return pm; 52 | } 53 | 54 | /* 割込み禁止マクロ */ 55 | #define DI(intsts) (intsts=get_primask(), set_primask(1)) 56 | 57 | /* 割込み許可マクロ */ 58 | #define EI(intsts) (set_primask(intsts)) 59 | 60 | /* デバッグ用シリアル通信 */ 61 | void tm_com_init(void); 62 | UINT tm_putstring(char* str); 63 | 64 | #endif /* STYLIB_H */ -------------------------------------------------------------------------------- /part_3/sect_2/include/syslib.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSLIB_H 2 | #define SYSLIB_H 3 | /* 4 | *** Try Kernel 5 | * 共通ライブラリ関数定義 6 | */ 7 | 8 | /* 32bitレジスタからの入力 */ 9 | static inline UW in_w(UW adr) 10 | { 11 | return *(_UW*)adr; 12 | } 13 | 14 | /* 32bitレジスタへの出力 */ 15 | static inline void out_w(UW adr, UW data) 16 | { 17 | *(_UW*)adr = data; 18 | } 19 | 20 | /* 32bitレジスタへの出力(ビットクリア) */ 21 | #define OP_CLR 0x3000 22 | static inline void clr_w(UW adr, UW data) 23 | { 24 | *(_UW*)(adr + OP_CLR) = data; 25 | } 26 | 27 | /* 32bitレジスタへの出力(ビットセット) */ 28 | #define OP_SET 0x2000 29 | static inline void set_w(UW adr, UW data) 30 | { 31 | *(_UW*)(adr + OP_SET) = data; 32 | } 33 | 34 | /* 32bitレジスタへの出力(ビット排他的論理和) */ 35 | #define OP_XOR 0x1000 36 | static inline void xset_w(UW adr, UW data) 37 | { 38 | *(_UW*)(adr + OP_XOR) = data; 39 | } 40 | 41 | /* PRIMASKレジスタ制御インライン関数 */ 42 | static inline void set_primask( INT pm ) 43 | { 44 | __asm__ volatile("msr primask, %0":: "r"(pm)); 45 | } 46 | 47 | static inline UW get_primask( void ) 48 | { 49 | UW pm; 50 | __asm__ volatile("mrs %0, primask": "=r"(pm)); 51 | return pm; 52 | } 53 | 54 | /* 割込み禁止マクロ */ 55 | #define DI(intsts) (intsts=get_primask(), set_primask(1)) 56 | 57 | /* 割込み許可マクロ */ 58 | #define EI(intsts) (set_primask(intsts)) 59 | 60 | /* デバッグ用シリアル通信 */ 61 | void tm_com_init(void); 62 | UINT tm_putstring(char* str); 63 | 64 | #endif /* STYLIB_H */ -------------------------------------------------------------------------------- /part_3/sect_3/include/syslib.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSLIB_H 2 | #define SYSLIB_H 3 | /* 4 | *** Try Kernel 5 | * 共通ライブラリ関数定義 6 | */ 7 | 8 | /* 32bitレジスタからの入力 */ 9 | static inline UW in_w(UW adr) 10 | { 11 | return *(_UW*)adr; 12 | } 13 | 14 | /* 32bitレジスタへの出力 */ 15 | static inline void out_w(UW adr, UW data) 16 | { 17 | *(_UW*)adr = data; 18 | } 19 | 20 | /* 32bitレジスタへの出力(ビットクリア) */ 21 | #define OP_CLR 0x3000 22 | static inline void clr_w(UW adr, UW data) 23 | { 24 | *(_UW*)(adr + OP_CLR) = data; 25 | } 26 | 27 | /* 32bitレジスタへの出力(ビットセット) */ 28 | #define OP_SET 0x2000 29 | static inline void set_w(UW adr, UW data) 30 | { 31 | *(_UW*)(adr + OP_SET) = data; 32 | } 33 | 34 | /* 32bitレジスタへの出力(ビット排他的論理和) */ 35 | #define OP_XOR 0x1000 36 | static inline void xset_w(UW adr, UW data) 37 | { 38 | *(_UW*)(adr + OP_XOR) = data; 39 | } 40 | 41 | /* PRIMASKレジスタ制御インライン関数 */ 42 | static inline void set_primask( INT pm ) 43 | { 44 | __asm__ volatile("msr primask, %0":: "r"(pm)); 45 | } 46 | 47 | static inline UW get_primask( void ) 48 | { 49 | UW pm; 50 | __asm__ volatile("mrs %0, primask": "=r"(pm)); 51 | return pm; 52 | } 53 | 54 | /* 割込み禁止マクロ */ 55 | #define DI(intsts) (intsts=get_primask(), set_primask(1)) 56 | 57 | /* 割込み許可マクロ */ 58 | #define EI(intsts) (set_primask(intsts)) 59 | 60 | /* デバッグ用シリアル通信 */ 61 | void tm_com_init(void); 62 | UINT tm_putstring(char* str); 63 | 64 | #endif /* STYLIB_H */ -------------------------------------------------------------------------------- /part_4/sect_1/include/syslib.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSLIB_H 2 | #define SYSLIB_H 3 | /* 4 | *** Try Kernel 5 | * 共通ライブラリ関数定義 6 | */ 7 | 8 | /* 32bitレジスタからの入力 */ 9 | static inline UW in_w(UW adr) 10 | { 11 | return *(_UW*)adr; 12 | } 13 | 14 | /* 32bitレジスタへの出力 */ 15 | static inline void out_w(UW adr, UW data) 16 | { 17 | *(_UW*)adr = data; 18 | } 19 | 20 | /* 32bitレジスタへの出力(ビットクリア) */ 21 | #define OP_CLR 0x3000 22 | static inline void clr_w(UW adr, UW data) 23 | { 24 | *(_UW*)(adr + OP_CLR) = data; 25 | } 26 | 27 | /* 32bitレジスタへの出力(ビットセット) */ 28 | #define OP_SET 0x2000 29 | static inline void set_w(UW adr, UW data) 30 | { 31 | *(_UW*)(adr + OP_SET) = data; 32 | } 33 | 34 | /* 32bitレジスタへの出力(ビット排他的論理和) */ 35 | #define OP_XOR 0x1000 36 | static inline void xset_w(UW adr, UW data) 37 | { 38 | *(_UW*)(adr + OP_XOR) = data; 39 | } 40 | 41 | /* PRIMASKレジスタ制御インライン関数 */ 42 | static inline void set_primask( INT pm ) 43 | { 44 | __asm__ volatile("msr primask, %0":: "r"(pm)); 45 | } 46 | 47 | static inline UW get_primask( void ) 48 | { 49 | UW pm; 50 | __asm__ volatile("mrs %0, primask": "=r"(pm)); 51 | return pm; 52 | } 53 | 54 | /* 割込み禁止マクロ */ 55 | #define DI(intsts) (intsts=get_primask(), set_primask(1)) 56 | 57 | /* 割込み許可マクロ */ 58 | #define EI(intsts) (set_primask(intsts)) 59 | 60 | /* デバッグ用シリアル通信 */ 61 | void tm_com_init(void); 62 | UINT tm_putstring(char* str); 63 | 64 | #endif /* STYLIB_H */ -------------------------------------------------------------------------------- /part_4/sect_2/include/syslib.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSLIB_H 2 | #define SYSLIB_H 3 | /* 4 | *** Try Kernel 5 | * 共通ライブラリ関数定義 6 | */ 7 | 8 | /* 32bitレジスタからの入力 */ 9 | static inline UW in_w(UW adr) 10 | { 11 | return *(_UW*)adr; 12 | } 13 | 14 | /* 32bitレジスタへの出力 */ 15 | static inline void out_w(UW adr, UW data) 16 | { 17 | *(_UW*)adr = data; 18 | } 19 | 20 | /* 32bitレジスタへの出力(ビットクリア) */ 21 | #define OP_CLR 0x3000 22 | static inline void clr_w(UW adr, UW data) 23 | { 24 | *(_UW*)(adr + OP_CLR) = data; 25 | } 26 | 27 | /* 32bitレジスタへの出力(ビットセット) */ 28 | #define OP_SET 0x2000 29 | static inline void set_w(UW adr, UW data) 30 | { 31 | *(_UW*)(adr + OP_SET) = data; 32 | } 33 | 34 | /* 32bitレジスタへの出力(ビット排他的論理和) */ 35 | #define OP_XOR 0x1000 36 | static inline void xset_w(UW adr, UW data) 37 | { 38 | *(_UW*)(adr + OP_XOR) = data; 39 | } 40 | 41 | /* PRIMASKレジスタ制御インライン関数 */ 42 | static inline void set_primask( INT pm ) 43 | { 44 | __asm__ volatile("msr primask, %0":: "r"(pm)); 45 | } 46 | 47 | static inline UW get_primask( void ) 48 | { 49 | UW pm; 50 | __asm__ volatile("mrs %0, primask": "=r"(pm)); 51 | return pm; 52 | } 53 | 54 | /* 割込み禁止マクロ */ 55 | #define DI(intsts) (intsts=get_primask(), set_primask(1)) 56 | 57 | /* 割込み許可マクロ */ 58 | #define EI(intsts) (set_primask(intsts)) 59 | 60 | /* デバッグ用シリアル通信 */ 61 | void tm_com_init(void); 62 | UINT tm_putstring(char* str); 63 | 64 | #endif /* STYLIB_H */ -------------------------------------------------------------------------------- /part_4/sect_3/include/syslib.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSLIB_H 2 | #define SYSLIB_H 3 | /* 4 | *** Try Kernel 5 | * 共通ライブラリ関数定義 6 | */ 7 | 8 | /* 32bitレジスタからの入力 */ 9 | static inline UW in_w(UW adr) 10 | { 11 | return *(_UW*)adr; 12 | } 13 | 14 | /* 32bitレジスタへの出力 */ 15 | static inline void out_w(UW adr, UW data) 16 | { 17 | *(_UW*)adr = data; 18 | } 19 | 20 | /* 32bitレジスタへの出力(ビットクリア) */ 21 | #define OP_CLR 0x3000 22 | static inline void clr_w(UW adr, UW data) 23 | { 24 | *(_UW*)(adr + OP_CLR) = data; 25 | } 26 | 27 | /* 32bitレジスタへの出力(ビットセット) */ 28 | #define OP_SET 0x2000 29 | static inline void set_w(UW adr, UW data) 30 | { 31 | *(_UW*)(adr + OP_SET) = data; 32 | } 33 | 34 | /* 32bitレジスタへの出力(ビット排他的論理和) */ 35 | #define OP_XOR 0x1000 36 | static inline void xset_w(UW adr, UW data) 37 | { 38 | *(_UW*)(adr + OP_XOR) = data; 39 | } 40 | 41 | /* PRIMASKレジスタ制御インライン関数 */ 42 | static inline void set_primask( INT pm ) 43 | { 44 | __asm__ volatile("msr primask, %0":: "r"(pm)); 45 | } 46 | 47 | static inline UW get_primask( void ) 48 | { 49 | UW pm; 50 | __asm__ volatile("mrs %0, primask": "=r"(pm)); 51 | return pm; 52 | } 53 | 54 | /* 割込み禁止マクロ */ 55 | #define DI(intsts) (intsts=get_primask(), set_primask(1)) 56 | 57 | /* 割込み許可マクロ */ 58 | #define EI(intsts) (set_primask(intsts)) 59 | 60 | /* デバッグ用シリアル通信 */ 61 | void tm_com_init(void); 62 | UINT tm_putstring(char* str); 63 | 64 | #endif /* STYLIB_H */ -------------------------------------------------------------------------------- /part_5/application/lsns.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 光センサー制御タスク 3 | */ 4 | 5 | #include 6 | #include "app.h" 7 | 8 | void task_lsns(INT stacd, void *exinf); // タスクの実行関数 9 | UW tskstk_lsns[1024/sizeof(UW)]; // タスクのスタック領域 10 | ID tskid_lsns; // タスクID 11 | 12 | /* タスク生成情報 */ 13 | T_CTSK ctsk_lsns = { 14 | .tskatr = TA_HLNG | TA_RNG3 | TA_USERBUF, 15 | .task = task_lsns, // タスクの実行関数 16 | .itskpri = 10, // タスク優先度 17 | .stksz = sizeof(tskstk_lsns), // スタックサイズ 18 | .bufptr = tskstk_lsns, // スタックへのポインタ 19 | }; 20 | 21 | /* タスクの実行関数*/ 22 | void task_lsns(INT stacd, void *exinf) 23 | { 24 | W data, pre_data, diff; 25 | SZ asz; 26 | ER err; 27 | 28 | lsns_data = pre_data = diff = 0; 29 | while(1) { 30 | err = tk_srea_dev(dd_adc, 0, &data, 1, &asz); // センサーデータの取得 31 | if(err >= E_OK) { 32 | diff = pre_data - data; 33 | if( diff >= 300 || diff <= -300) { 34 | lsns_data = data; // グローバル変数の更新 35 | tk_set_flg(flgid_1, FLG_LSNS); // イベントフラグのセット 36 | pre_data = data; 37 | } 38 | } else { 39 | tm_putstring("ERROR Read ADC\n"); 40 | } 41 | tk_dly_tsk(500); // 0.5秒間待ち状態に 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # Interface 2023年7月号 特集「ゼロから作るOS」配布プログラム 2 | 3 | ## 概要 4 | 5 | 本リポジトリは、CQ出版(株) Interface 2023年7月号の特集「ゼロから作るOS」の配布プログラムです。 6 | 特集記事にて記載した自作OS「Try Kernel」のプログラムです。ラズパイPicoにて動作します。プログラムの内容、開発環境や手順については記事をご覧ください。 7 | 特集の各部、各章で作成した完成プログラムのソースコードを以下のディレクトリに格納しています。ディレクトリ毎に実行プログラムをビルドすることができます。part_5が完成したTry Kernelのプログラムとアプリケーションとなります。 8 | 9 | part_2 第2部 起動処理を作る 10 | ├ sect_3 第3章 11 | └ sect_4 第4章 12 | 13 | part_3 第3部 マルチタスク機能を作る 14 | ├ sect_1 第1章 15 | ├ sect_2 第2章 16 | └ sect_3 第3章 17 | 18 | part_4 第4部 タスクの同期と通信機能を作る 19 | ├ sect_1 第1章 20 | ├ sect_2 第2章 21 | └ sect_3 第3章 22 | 23 | part_5 第5部 アプリケーションを作る 24 | 25 | ## 関連リンク 26 | 27 | Try Kernelの単独のリポジトリは以下です。不具合修正以外のメンテは以下で行います。 28 | 29 | 30 | 31 | ## ライセンスについて 32 | 33 | 本プログラムはMITライセンスの下でオープンソースとして公開します。著作権および許諾表示を記載すれば、非営利、商用を問わず、使用、改変、複製、再頒布が可能な制限の緩いライセンスですので、本プログラムをOSの自作に活用いただけたらと思います。ライセンスの詳細については、同梱のLICENSEをご参照ください。 34 | ただし、ブートコードの一部でPico C/C++ SDKのオブジェクトコードを利用してますので、それについてはPico C/C++ SDKのライセンスが適用されます。ソースファイルの冒頭に記載したライセンスに従ってください。このライセンスも厳しい制約はありません。該当するファイルは以下です。 35 | 36 | part_2\sect_3\boot\boot2.c 37 | part_2\sect_4\boot\boot2.c 38 | part_3\sect_1\boot\boot2.c 39 | part_3\sect_2\boot\boot2.c 40 | part_3\sect_3\boot\boot2.c 41 | part_4\sect_1\boot\boot2.c 42 | part_4\sect_2\boot\boot2.c 43 | part_4\sect_3\boot\boot2.c 44 | part_5\boot\boot2.c 45 | -------------------------------------------------------------------------------- /part_5/linker/pico_memmap.ld: -------------------------------------------------------------------------------- 1 | ENTRY(Reset_Handler) 2 | 3 | MEMORY { 4 | ROM (rx) : ORIGIN = 0x10000000, LENGTH = 2048K 5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K 6 | } 7 | 8 | SECTIONS { 9 | boot2 : { 10 | __boot2_start__ = .; 11 | KEEP (*(.boot2)) 12 | __boot2_end__ = .; 13 | } > ROM 14 | ASSERT(__boot2_end__ - __boot2_start__ == 256, 15 | "ERROR: Pico second stage bootloader must be 256 bytes in size") 16 | 17 | .text : { 18 | __vector_org = .; 19 | KEEP (*(.vector)) 20 | 21 | *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) 22 | 23 | __start = .; 24 | *(.text) 25 | *(.text.*) 26 | *(.rodata) 27 | *(.rodata.*) 28 | } >ROM 29 | 30 | .ARM.extab : 31 | { 32 | *(.ARM.extab* .gnu.linkonce.armextab.*) 33 | } > ROM 34 | 35 | __exidx_start = .; 36 | .ARM.exidx : 37 | { 38 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 39 | } > ROM 40 | __exidx_end = .; 41 | 42 | __data_org = .; 43 | .data : AT(__data_org) { 44 | __data_start = .; 45 | *(.data) 46 | *(.data.*) 47 | . = ALIGN(4); 48 | __data_end = .; 49 | } >RAM 50 | .bss ALIGN(4) (NOLOAD) : { 51 | __bss_start = .; 52 | *(.bss) 53 | *(.bss.*) 54 | *(COMMON) 55 | . = ALIGN(4); 56 | __bss_end = .; 57 | __end = .; 58 | } >RAM 59 | } 60 | -------------------------------------------------------------------------------- /part_2/sect_3/linker/pico_memmap.ld: -------------------------------------------------------------------------------- 1 | ENTRY(Reset_Handler) 2 | 3 | MEMORY { 4 | ROM (rx) : ORIGIN = 0x10000000, LENGTH = 2048K 5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K 6 | } 7 | 8 | SECTIONS { 9 | boot2 : { 10 | __boot2_start__ = .; 11 | KEEP (*(.boot2)) 12 | __boot2_end__ = .; 13 | } > ROM 14 | ASSERT(__boot2_end__ - __boot2_start__ == 256, 15 | "ERROR: Pico second stage bootloader must be 256 bytes in size") 16 | 17 | .text : { 18 | __vector_org = .; 19 | KEEP (*(.vector)) 20 | 21 | *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) 22 | 23 | __start = .; 24 | *(.text) 25 | *(.text.*) 26 | *(.rodata) 27 | *(.rodata.*) 28 | } >ROM 29 | 30 | .ARM.extab : 31 | { 32 | *(.ARM.extab* .gnu.linkonce.armextab.*) 33 | } > ROM 34 | 35 | __exidx_start = .; 36 | .ARM.exidx : 37 | { 38 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 39 | } > ROM 40 | __exidx_end = .; 41 | 42 | __data_org = .; 43 | .data : AT(__data_org) { 44 | __data_start = .; 45 | *(.data) 46 | *(.data.*) 47 | . = ALIGN(4); 48 | __data_end = .; 49 | } >RAM 50 | .bss ALIGN(4) (NOLOAD) : { 51 | __bss_start = .; 52 | *(.bss) 53 | *(.bss.*) 54 | *(COMMON) 55 | . = ALIGN(4); 56 | __bss_end = .; 57 | __end = .; 58 | } >RAM 59 | } 60 | -------------------------------------------------------------------------------- /part_2/sect_4/linker/pico_memmap.ld: -------------------------------------------------------------------------------- 1 | ENTRY(Reset_Handler) 2 | 3 | MEMORY { 4 | ROM (rx) : ORIGIN = 0x10000000, LENGTH = 2048K 5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K 6 | } 7 | 8 | SECTIONS { 9 | boot2 : { 10 | __boot2_start__ = .; 11 | KEEP (*(.boot2)) 12 | __boot2_end__ = .; 13 | } > ROM 14 | ASSERT(__boot2_end__ - __boot2_start__ == 256, 15 | "ERROR: Pico second stage bootloader must be 256 bytes in size") 16 | 17 | .text : { 18 | __vector_org = .; 19 | KEEP (*(.vector)) 20 | 21 | *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) 22 | 23 | __start = .; 24 | *(.text) 25 | *(.text.*) 26 | *(.rodata) 27 | *(.rodata.*) 28 | } >ROM 29 | 30 | .ARM.extab : 31 | { 32 | *(.ARM.extab* .gnu.linkonce.armextab.*) 33 | } > ROM 34 | 35 | __exidx_start = .; 36 | .ARM.exidx : 37 | { 38 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 39 | } > ROM 40 | __exidx_end = .; 41 | 42 | __data_org = .; 43 | .data : AT(__data_org) { 44 | __data_start = .; 45 | *(.data) 46 | *(.data.*) 47 | . = ALIGN(4); 48 | __data_end = .; 49 | } >RAM 50 | .bss ALIGN(4) (NOLOAD) : { 51 | __bss_start = .; 52 | *(.bss) 53 | *(.bss.*) 54 | *(COMMON) 55 | . = ALIGN(4); 56 | __bss_end = .; 57 | __end = .; 58 | } >RAM 59 | } 60 | -------------------------------------------------------------------------------- /part_3/sect_1/linker/pico_memmap.ld: -------------------------------------------------------------------------------- 1 | ENTRY(Reset_Handler) 2 | 3 | MEMORY { 4 | ROM (rx) : ORIGIN = 0x10000000, LENGTH = 2048K 5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K 6 | } 7 | 8 | SECTIONS { 9 | boot2 : { 10 | __boot2_start__ = .; 11 | KEEP (*(.boot2)) 12 | __boot2_end__ = .; 13 | } > ROM 14 | ASSERT(__boot2_end__ - __boot2_start__ == 256, 15 | "ERROR: Pico second stage bootloader must be 256 bytes in size") 16 | 17 | .text : { 18 | __vector_org = .; 19 | KEEP (*(.vector)) 20 | 21 | *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) 22 | 23 | __start = .; 24 | *(.text) 25 | *(.text.*) 26 | *(.rodata) 27 | *(.rodata.*) 28 | } >ROM 29 | 30 | .ARM.extab : 31 | { 32 | *(.ARM.extab* .gnu.linkonce.armextab.*) 33 | } > ROM 34 | 35 | __exidx_start = .; 36 | .ARM.exidx : 37 | { 38 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 39 | } > ROM 40 | __exidx_end = .; 41 | 42 | __data_org = .; 43 | .data : AT(__data_org) { 44 | __data_start = .; 45 | *(.data) 46 | *(.data.*) 47 | . = ALIGN(4); 48 | __data_end = .; 49 | } >RAM 50 | .bss ALIGN(4) (NOLOAD) : { 51 | __bss_start = .; 52 | *(.bss) 53 | *(.bss.*) 54 | *(COMMON) 55 | . = ALIGN(4); 56 | __bss_end = .; 57 | __end = .; 58 | } >RAM 59 | } 60 | -------------------------------------------------------------------------------- /part_3/sect_2/linker/pico_memmap.ld: -------------------------------------------------------------------------------- 1 | ENTRY(Reset_Handler) 2 | 3 | MEMORY { 4 | ROM (rx) : ORIGIN = 0x10000000, LENGTH = 2048K 5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K 6 | } 7 | 8 | SECTIONS { 9 | boot2 : { 10 | __boot2_start__ = .; 11 | KEEP (*(.boot2)) 12 | __boot2_end__ = .; 13 | } > ROM 14 | ASSERT(__boot2_end__ - __boot2_start__ == 256, 15 | "ERROR: Pico second stage bootloader must be 256 bytes in size") 16 | 17 | .text : { 18 | __vector_org = .; 19 | KEEP (*(.vector)) 20 | 21 | *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) 22 | 23 | __start = .; 24 | *(.text) 25 | *(.text.*) 26 | *(.rodata) 27 | *(.rodata.*) 28 | } >ROM 29 | 30 | .ARM.extab : 31 | { 32 | *(.ARM.extab* .gnu.linkonce.armextab.*) 33 | } > ROM 34 | 35 | __exidx_start = .; 36 | .ARM.exidx : 37 | { 38 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 39 | } > ROM 40 | __exidx_end = .; 41 | 42 | __data_org = .; 43 | .data : AT(__data_org) { 44 | __data_start = .; 45 | *(.data) 46 | *(.data.*) 47 | . = ALIGN(4); 48 | __data_end = .; 49 | } >RAM 50 | .bss ALIGN(4) (NOLOAD) : { 51 | __bss_start = .; 52 | *(.bss) 53 | *(.bss.*) 54 | *(COMMON) 55 | . = ALIGN(4); 56 | __bss_end = .; 57 | __end = .; 58 | } >RAM 59 | } 60 | -------------------------------------------------------------------------------- /part_3/sect_3/linker/pico_memmap.ld: -------------------------------------------------------------------------------- 1 | ENTRY(Reset_Handler) 2 | 3 | MEMORY { 4 | ROM (rx) : ORIGIN = 0x10000000, LENGTH = 2048K 5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K 6 | } 7 | 8 | SECTIONS { 9 | boot2 : { 10 | __boot2_start__ = .; 11 | KEEP (*(.boot2)) 12 | __boot2_end__ = .; 13 | } > ROM 14 | ASSERT(__boot2_end__ - __boot2_start__ == 256, 15 | "ERROR: Pico second stage bootloader must be 256 bytes in size") 16 | 17 | .text : { 18 | __vector_org = .; 19 | KEEP (*(.vector)) 20 | 21 | *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) 22 | 23 | __start = .; 24 | *(.text) 25 | *(.text.*) 26 | *(.rodata) 27 | *(.rodata.*) 28 | } >ROM 29 | 30 | .ARM.extab : 31 | { 32 | *(.ARM.extab* .gnu.linkonce.armextab.*) 33 | } > ROM 34 | 35 | __exidx_start = .; 36 | .ARM.exidx : 37 | { 38 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 39 | } > ROM 40 | __exidx_end = .; 41 | 42 | __data_org = .; 43 | .data : AT(__data_org) { 44 | __data_start = .; 45 | *(.data) 46 | *(.data.*) 47 | . = ALIGN(4); 48 | __data_end = .; 49 | } >RAM 50 | .bss ALIGN(4) (NOLOAD) : { 51 | __bss_start = .; 52 | *(.bss) 53 | *(.bss.*) 54 | *(COMMON) 55 | . = ALIGN(4); 56 | __bss_end = .; 57 | __end = .; 58 | } >RAM 59 | } 60 | -------------------------------------------------------------------------------- /part_4/sect_1/linker/pico_memmap.ld: -------------------------------------------------------------------------------- 1 | ENTRY(Reset_Handler) 2 | 3 | MEMORY { 4 | ROM (rx) : ORIGIN = 0x10000000, LENGTH = 2048K 5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K 6 | } 7 | 8 | SECTIONS { 9 | boot2 : { 10 | __boot2_start__ = .; 11 | KEEP (*(.boot2)) 12 | __boot2_end__ = .; 13 | } > ROM 14 | ASSERT(__boot2_end__ - __boot2_start__ == 256, 15 | "ERROR: Pico second stage bootloader must be 256 bytes in size") 16 | 17 | .text : { 18 | __vector_org = .; 19 | KEEP (*(.vector)) 20 | 21 | *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) 22 | 23 | __start = .; 24 | *(.text) 25 | *(.text.*) 26 | *(.rodata) 27 | *(.rodata.*) 28 | } >ROM 29 | 30 | .ARM.extab : 31 | { 32 | *(.ARM.extab* .gnu.linkonce.armextab.*) 33 | } > ROM 34 | 35 | __exidx_start = .; 36 | .ARM.exidx : 37 | { 38 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 39 | } > ROM 40 | __exidx_end = .; 41 | 42 | __data_org = .; 43 | .data : AT(__data_org) { 44 | __data_start = .; 45 | *(.data) 46 | *(.data.*) 47 | . = ALIGN(4); 48 | __data_end = .; 49 | } >RAM 50 | .bss ALIGN(4) (NOLOAD) : { 51 | __bss_start = .; 52 | *(.bss) 53 | *(.bss.*) 54 | *(COMMON) 55 | . = ALIGN(4); 56 | __bss_end = .; 57 | __end = .; 58 | } >RAM 59 | } 60 | -------------------------------------------------------------------------------- /part_4/sect_2/linker/pico_memmap.ld: -------------------------------------------------------------------------------- 1 | ENTRY(Reset_Handler) 2 | 3 | MEMORY { 4 | ROM (rx) : ORIGIN = 0x10000000, LENGTH = 2048K 5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K 6 | } 7 | 8 | SECTIONS { 9 | boot2 : { 10 | __boot2_start__ = .; 11 | KEEP (*(.boot2)) 12 | __boot2_end__ = .; 13 | } > ROM 14 | ASSERT(__boot2_end__ - __boot2_start__ == 256, 15 | "ERROR: Pico second stage bootloader must be 256 bytes in size") 16 | 17 | .text : { 18 | __vector_org = .; 19 | KEEP (*(.vector)) 20 | 21 | *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) 22 | 23 | __start = .; 24 | *(.text) 25 | *(.text.*) 26 | *(.rodata) 27 | *(.rodata.*) 28 | } >ROM 29 | 30 | .ARM.extab : 31 | { 32 | *(.ARM.extab* .gnu.linkonce.armextab.*) 33 | } > ROM 34 | 35 | __exidx_start = .; 36 | .ARM.exidx : 37 | { 38 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 39 | } > ROM 40 | __exidx_end = .; 41 | 42 | __data_org = .; 43 | .data : AT(__data_org) { 44 | __data_start = .; 45 | *(.data) 46 | *(.data.*) 47 | . = ALIGN(4); 48 | __data_end = .; 49 | } >RAM 50 | .bss ALIGN(4) (NOLOAD) : { 51 | __bss_start = .; 52 | *(.bss) 53 | *(.bss.*) 54 | *(COMMON) 55 | . = ALIGN(4); 56 | __bss_end = .; 57 | __end = .; 58 | } >RAM 59 | } 60 | -------------------------------------------------------------------------------- /part_4/sect_3/linker/pico_memmap.ld: -------------------------------------------------------------------------------- 1 | ENTRY(Reset_Handler) 2 | 3 | MEMORY { 4 | ROM (rx) : ORIGIN = 0x10000000, LENGTH = 2048K 5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K 6 | } 7 | 8 | SECTIONS { 9 | boot2 : { 10 | __boot2_start__ = .; 11 | KEEP (*(.boot2)) 12 | __boot2_end__ = .; 13 | } > ROM 14 | ASSERT(__boot2_end__ - __boot2_start__ == 256, 15 | "ERROR: Pico second stage bootloader must be 256 bytes in size") 16 | 17 | .text : { 18 | __vector_org = .; 19 | KEEP (*(.vector)) 20 | 21 | *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) 22 | 23 | __start = .; 24 | *(.text) 25 | *(.text.*) 26 | *(.rodata) 27 | *(.rodata.*) 28 | } >ROM 29 | 30 | .ARM.extab : 31 | { 32 | *(.ARM.extab* .gnu.linkonce.armextab.*) 33 | } > ROM 34 | 35 | __exidx_start = .; 36 | .ARM.exidx : 37 | { 38 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 39 | } > ROM 40 | __exidx_end = .; 41 | 42 | __data_org = .; 43 | .data : AT(__data_org) { 44 | __data_start = .; 45 | *(.data) 46 | *(.data.*) 47 | . = ALIGN(4); 48 | __data_end = .; 49 | } >RAM 50 | .bss ALIGN(4) (NOLOAD) : { 51 | __bss_start = .; 52 | *(.bss) 53 | *(.bss.*) 54 | *(COMMON) 55 | . = ALIGN(4); 56 | __bss_end = .; 57 | __end = .; 58 | } >RAM 59 | } 60 | -------------------------------------------------------------------------------- /part_3/sect_3/application/usermain.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | UW tskstk_1[1024/sizeof(UW)]; /* タスク1のスタック */ 4 | ID tskid_1; /* タスク1のID番号 */ 5 | 6 | /* タスク1生成情報 */ 7 | void task_1(INT stacd, void *exinf); 8 | T_CTSK ctsk_1 = { 9 | .tskatr = TA_HLNG | TA_RNG3 | TA_USERBUF, // タスク属性 10 | .task = task_1, 11 | .itskpri = 10, 12 | .stksz = 1024, 13 | .bufptr = tskstk_1, 14 | }; 15 | 16 | UW tskstk_2[1024/sizeof(UW)]; /* タスク2のスタック */ 17 | ID tskid_2; /* タスク2のID番号 */ 18 | 19 | /* タスク2生成情報 */ 20 | void task_2(INT stacd, void *exinf); 21 | T_CTSK ctsk_2 = { 22 | .tskatr = TA_HLNG | TA_RNG3 | TA_USERBUF, // タスク属性 23 | .task = task_2, 24 | .itskpri = 10, 25 | .stksz = 1024, 26 | .bufptr = tskstk_2, 27 | }; 28 | 29 | /* タスク1の実行関数 */ 30 | void task_1(INT stacd, void *exinf) 31 | { 32 | while(1) { 33 | out_w(GPIO_OUT_XOR, (1<<25)); // LEDの点灯 34 | tk_dly_tsk(500); // 0.5秒待ち 35 | } 36 | } 37 | 38 | /* タスク2の実行関数 */ 39 | void task_2(INT stacd, void *exinf) 40 | { 41 | while(1) { 42 | tm_putstring("hello\n"); // 文字出力 43 | tk_dly_tsk(1000); // 1秒待ち 44 | } 45 | } 46 | 47 | int usermain(void) 48 | { 49 | /* タスク1の生成、実行 */ 50 | tskid_1 = tk_cre_tsk(&ctsk_1); 51 | tk_sta_tsk(tskid_1, 0); 52 | 53 | /* タスク2の生成、実行 */ 54 | tskid_2 = tk_cre_tsk(&ctsk_2); 55 | tk_sta_tsk(tskid_2, 0); 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /part_3/sect_1/application/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* タスク管理データ */ 4 | UINT cur_task = 0; // 実行中のタスクのID番号 5 | UINT next_task = 0; // 次に実行するタスクのID番号 6 | 7 | #define MAX_FNC_ID 2 // タスクの数 8 | void *ctx_tbl[MAX_FNC_ID]; // 保存された実行コンテキストへのポインタ 9 | 10 | /* タスクのスタック */ 11 | #define STACK_SIZE 1024 12 | UW stack_1[STACK_SIZE/sizeof(UW)]; 13 | UW stack_2[STACK_SIZE/sizeof(UW)]; 14 | 15 | /* 時間待ち関数 */ 16 | static void delay_ms( UINT ms) 17 | { 18 | UINT cnt = ms/TIMER_PERIOD; 19 | 20 | while(cnt) { 21 | if((in_w(SYST_CSR) & SYST_CSR_COUNTFLAG)!=0) { // TIMER_PERIOD経過するとフラグがセット 22 | cnt--; 23 | } 24 | } 25 | } 26 | 27 | /* タスク 1*/ 28 | void task_1(void) 29 | { 30 | while(1){ 31 | out_w(GPIO_OUT_SET, (1<<25)); // LEDの点灯 32 | delay_ms(500); // 0.5秒待ち 33 | 34 | next_task = 2; // 次に実行するタスクを設定 35 | dispatch(); // ディスパッチャの実行 36 | } 37 | } 38 | 39 | /* タスク 2 */ 40 | void task_2(void) 41 | { 42 | while(1){ 43 | out_w(GPIO_OUT_CLR, (1<<25)); // LEDの消灯 44 | delay_ms(500); // 0.5秒待ち 45 | 46 | next_task = 1; // 次に実行するタスクを設定 47 | dispatch(); // ディスパッチャの実行 48 | } 49 | } 50 | 51 | /* メイン関数 */ 52 | int main(void) 53 | { 54 | /* タスクの初期化 */ 55 | ctx_tbl[0] = make_context(stack_1, sizeof(stack_1), task_1); 56 | ctx_tbl[1] = make_context(stack_2, sizeof(stack_2), task_2); 57 | 58 | next_task = 1; // ディスパッチにより実行する関数 59 | dispatch(); // ディスパッチャの実行 60 | 61 | return 0; // ここは実行されない 62 | } 63 | -------------------------------------------------------------------------------- /part_5/kernel/dispatch.S: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * ディスパッチャ 4 | */ 5 | .align 2 6 | .thumb_func 7 | .globl dispatch_entry 8 | 9 | dispatch_entry: 10 | mov r0, #1 11 | msr primask, r0 // 割込み禁止 12 | ldr r1, =disp_running 13 | str r0, [r1] 14 | 15 | /* ① 実行中の関数の実行コンテキスト情報をスタックに退避 */ 16 | push {r4-r7} 17 | mov r0, r8 18 | mov r1, r9 19 | mov r2, r10 20 | mov r3, r11 21 | push {r0-r3} 22 | 23 | /* ② 現在実行中のタスクの確認 */ 24 | ldr r0, =cur_task 25 | ldr r1, [r0] 26 | cmp r1, #0 27 | beq disp_010 // 実行中のタスク無し(cur_task == NULL) ならば disp_010へ 28 | 29 | /* ③ 実行コンテキスト情報へのポインタを実行中のタスクのTCBに格納 */ 30 | mov r2, sp 31 | str r2, [r1] 32 | 33 | disp_010: 34 | /* ④ 次に実行するタスクの確認 */ 35 | ldr r1, =sche_task 36 | ldr r2, [r1] 37 | cmp r2, #0 38 | bne disp_030 39 | 40 | /* ⑤ 次に実行するタスクが無かった場合の処理 */ 41 | str r2, [r0] 42 | disp_020: 43 | mov r3, #0 44 | msr primask, r3 // 割込み許可 45 | mov r3, #1 46 | msr primask, r3 // 割込み禁止 47 | 48 | ldr r2, [r1] 49 | cmp r2, #0 50 | beq disp_020 51 | 52 | /* ⑥ 実行するタスクの切り替え */ 53 | disp_030: 54 | str r2, [r0] 55 | ldr r0, [r2] 56 | mov sp, r0 57 | 58 | /* ⑦ スタック上のコンテキス情報の復元 */ 59 | pop {r0-r3} 60 | mov r11, r3 61 | mov r10, r2 62 | mov r9, r1 63 | mov r8, r0 64 | pop {r4-r7} 65 | 66 | /* 割込み許可 */ 67 | ldr r0, =disp_running 68 | mov r1, #0 69 | str r1, [r0] 70 | msr primask, r1 // 割込み許可 71 | 72 | bx lr 73 | -------------------------------------------------------------------------------- /part_3/sect_2/kernel/dispatch.S: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * ディスパッチャ 4 | */ 5 | .align 2 6 | .thumb_func 7 | .globl dispatch_entry 8 | 9 | dispatch_entry: 10 | mov r0, #1 11 | msr primask, r0 // 割込み禁止 12 | ldr r1, =disp_running 13 | str r0, [r1] 14 | 15 | /* ① 実行中の関数の実行コンテキスト情報をスタックに退避 */ 16 | push {r4-r7} 17 | mov r0, r8 18 | mov r1, r9 19 | mov r2, r10 20 | mov r3, r11 21 | push {r0-r3} 22 | 23 | /* ② 現在実行中のタスクの確認 */ 24 | ldr r0, =cur_task 25 | ldr r1, [r0] 26 | cmp r1, #0 27 | beq disp_010 // 実行中のタスク無し(cur_task == NULL) ならば disp_010へ 28 | 29 | /* ③ 実行コンテキスト情報へのポインタを実行中のタスクのTCBに格納 */ 30 | mov r2, sp 31 | str r2, [r1] 32 | 33 | disp_010: 34 | /* ④ 次に実行するタスクの確認 */ 35 | ldr r1, =sche_task 36 | ldr r2, [r1] 37 | cmp r2, #0 38 | bne disp_030 39 | 40 | /* ⑤ 次に実行するタスクが無かった場合の処理 */ 41 | str r2, [r0] 42 | disp_020: 43 | mov r3, #0 44 | msr primask, r3 // 割込み許可 45 | mov r3, #1 46 | msr primask, r3 // 割込み禁止 47 | 48 | ldr r2, [r1] 49 | cmp r2, #0 50 | beq disp_020 51 | 52 | /* ⑥ 実行するタスクの切り替え */ 53 | disp_030: 54 | str r2, [r0] 55 | ldr r0, [r2] 56 | mov sp, r0 57 | 58 | /* ⑦ スタック上のコンテキス情報の復元 */ 59 | pop {r0-r3} 60 | mov r11, r3 61 | mov r10, r2 62 | mov r9, r1 63 | mov r8, r0 64 | pop {r4-r7} 65 | 66 | /* 割込み許可 */ 67 | ldr r0, =disp_running 68 | mov r1, #0 69 | str r1, [r0] 70 | msr primask, r1 // 割込み許可 71 | 72 | bx lr 73 | 74 | -------------------------------------------------------------------------------- /part_3/sect_3/kernel/dispatch.S: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * ディスパッチャ 4 | */ 5 | .align 2 6 | .thumb_func 7 | .globl dispatch_entry 8 | 9 | dispatch_entry: 10 | mov r0, #1 11 | msr primask, r0 // 割込み禁止 12 | ldr r1, =disp_running 13 | str r0, [r1] 14 | 15 | /* ① 実行中の関数の実行コンテキスト情報をスタックに退避 */ 16 | push {r4-r7} 17 | mov r0, r8 18 | mov r1, r9 19 | mov r2, r10 20 | mov r3, r11 21 | push {r0-r3} 22 | 23 | /* ② 現在実行中のタスクの確認 */ 24 | ldr r0, =cur_task 25 | ldr r1, [r0] 26 | cmp r1, #0 27 | beq disp_010 // 実行中のタスク無し(cur_task == NULL) ならば disp_010へ 28 | 29 | /* ③ 実行コンテキスト情報へのポインタを実行中のタスクのTCBに格納 */ 30 | mov r2, sp 31 | str r2, [r1] 32 | 33 | disp_010: 34 | /* ④ 次に実行するタスクの確認 */ 35 | ldr r1, =sche_task 36 | ldr r2, [r1] 37 | cmp r2, #0 38 | bne disp_030 39 | 40 | /* ⑤ 次に実行するタスクが無かった場合の処理 */ 41 | str r2, [r0] 42 | disp_020: 43 | mov r3, #0 44 | msr primask, r3 // 割込み許可 45 | mov r3, #1 46 | msr primask, r3 // 割込み禁止 47 | 48 | ldr r2, [r1] 49 | cmp r2, #0 50 | beq disp_020 51 | 52 | /* ⑥ 実行するタスクの切り替え */ 53 | disp_030: 54 | str r2, [r0] 55 | ldr r0, [r2] 56 | mov sp, r0 57 | 58 | /* ⑦ スタック上のコンテキス情報の復元 */ 59 | pop {r0-r3} 60 | mov r11, r3 61 | mov r10, r2 62 | mov r9, r1 63 | mov r8, r0 64 | pop {r4-r7} 65 | 66 | /* 割込み許可 */ 67 | ldr r0, =disp_running 68 | mov r1, #0 69 | str r1, [r0] 70 | msr primask, r1 // 割込み許可 71 | 72 | bx lr 73 | 74 | -------------------------------------------------------------------------------- /part_4/sect_1/kernel/dispatch.S: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * ディスパッチャ 4 | */ 5 | .align 2 6 | .thumb_func 7 | .globl dispatch_entry 8 | 9 | dispatch_entry: 10 | mov r0, #1 11 | msr primask, r0 // 割込み禁止 12 | ldr r1, =disp_running 13 | str r0, [r1] 14 | 15 | /* ① 実行中の関数の実行コンテキスト情報をスタックに退避 */ 16 | push {r4-r7} 17 | mov r0, r8 18 | mov r1, r9 19 | mov r2, r10 20 | mov r3, r11 21 | push {r0-r3} 22 | 23 | /* ② 現在実行中のタスクの確認 */ 24 | ldr r0, =cur_task 25 | ldr r1, [r0] 26 | cmp r1, #0 27 | beq disp_010 // 実行中のタスク無し(cur_task == NULL) ならば disp_010へ 28 | 29 | /* ③ 実行コンテキスト情報へのポインタを実行中のタスクのTCBに格納 */ 30 | mov r2, sp 31 | str r2, [r1] 32 | 33 | disp_010: 34 | /* ④ 次に実行するタスクの確認 */ 35 | ldr r1, =sche_task 36 | ldr r2, [r1] 37 | cmp r2, #0 38 | bne disp_030 39 | 40 | /* ⑤ 次に実行するタスクが無かった場合の処理 */ 41 | str r2, [r0] 42 | disp_020: 43 | mov r3, #0 44 | msr primask, r3 // 割込み許可 45 | mov r3, #1 46 | msr primask, r3 // 割込み禁止 47 | 48 | ldr r2, [r1] 49 | cmp r2, #0 50 | beq disp_020 51 | 52 | /* ⑥ 実行するタスクの切り替え */ 53 | disp_030: 54 | str r2, [r0] 55 | ldr r0, [r2] 56 | mov sp, r0 57 | 58 | /* ⑦ スタック上のコンテキス情報の復元 */ 59 | pop {r0-r3} 60 | mov r11, r3 61 | mov r10, r2 62 | mov r9, r1 63 | mov r8, r0 64 | pop {r4-r7} 65 | 66 | /* 割込み許可 */ 67 | ldr r0, =disp_running 68 | mov r1, #0 69 | str r1, [r0] 70 | msr primask, r1 // 割込み許可 71 | 72 | bx lr 73 | 74 | -------------------------------------------------------------------------------- /part_4/sect_2/kernel/dispatch.S: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * ディスパッチャ 4 | */ 5 | .align 2 6 | .thumb_func 7 | .globl dispatch_entry 8 | 9 | dispatch_entry: 10 | mov r0, #1 11 | msr primask, r0 // 割込み禁止 12 | ldr r1, =disp_running 13 | str r0, [r1] 14 | 15 | /* ① 実行中の関数の実行コンテキスト情報をスタックに退避 */ 16 | push {r4-r7} 17 | mov r0, r8 18 | mov r1, r9 19 | mov r2, r10 20 | mov r3, r11 21 | push {r0-r3} 22 | 23 | /* ② 現在実行中のタスクの確認 */ 24 | ldr r0, =cur_task 25 | ldr r1, [r0] 26 | cmp r1, #0 27 | beq disp_010 // 実行中のタスク無し(cur_task == NULL) ならば disp_010へ 28 | 29 | /* ③ 実行コンテキスト情報へのポインタを実行中のタスクのTCBに格納 */ 30 | mov r2, sp 31 | str r2, [r1] 32 | 33 | disp_010: 34 | /* ④ 次に実行するタスクの確認 */ 35 | ldr r1, =sche_task 36 | ldr r2, [r1] 37 | cmp r2, #0 38 | bne disp_030 39 | 40 | /* ⑤ 次に実行するタスクが無かった場合の処理 */ 41 | str r2, [r0] 42 | disp_020: 43 | mov r3, #0 44 | msr primask, r3 // 割込み許可 45 | mov r3, #1 46 | msr primask, r3 // 割込み禁止 47 | 48 | ldr r2, [r1] 49 | cmp r2, #0 50 | beq disp_020 51 | 52 | /* ⑥ 実行するタスクの切り替え */ 53 | disp_030: 54 | str r2, [r0] 55 | ldr r0, [r2] 56 | mov sp, r0 57 | 58 | /* ⑦ スタック上のコンテキス情報の復元 */ 59 | pop {r0-r3} 60 | mov r11, r3 61 | mov r10, r2 62 | mov r9, r1 63 | mov r8, r0 64 | pop {r4-r7} 65 | 66 | /* 割込み許可 */ 67 | ldr r0, =disp_running 68 | mov r1, #0 69 | str r1, [r0] 70 | msr primask, r1 // 割込み許可 71 | 72 | bx lr 73 | 74 | -------------------------------------------------------------------------------- /part_4/sect_3/kernel/dispatch.S: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * ディスパッチャ 4 | */ 5 | .align 2 6 | .thumb_func 7 | .globl dispatch_entry 8 | 9 | dispatch_entry: 10 | mov r0, #1 11 | msr primask, r0 // 割込み禁止 12 | ldr r1, =disp_running 13 | str r0, [r1] 14 | 15 | /* ① 実行中の関数の実行コンテキスト情報をスタックに退避 */ 16 | push {r4-r7} 17 | mov r0, r8 18 | mov r1, r9 19 | mov r2, r10 20 | mov r3, r11 21 | push {r0-r3} 22 | 23 | /* ② 現在実行中のタスクの確認 */ 24 | ldr r0, =cur_task 25 | ldr r1, [r0] 26 | cmp r1, #0 27 | beq disp_010 // 実行中のタスク無し(cur_task == NULL) ならば disp_010へ 28 | 29 | /* ③ 実行コンテキスト情報へのポインタを実行中のタスクのTCBに格納 */ 30 | mov r2, sp 31 | str r2, [r1] 32 | 33 | disp_010: 34 | /* ④ 次に実行するタスクの確認 */ 35 | ldr r1, =sche_task 36 | ldr r2, [r1] 37 | cmp r2, #0 38 | bne disp_030 39 | 40 | /* ⑤ 次に実行するタスクが無かった場合の処理 */ 41 | str r2, [r0] 42 | disp_020: 43 | mov r3, #0 44 | msr primask, r3 // 割込み許可 45 | mov r3, #1 46 | msr primask, r3 // 割込み禁止 47 | 48 | ldr r2, [r1] 49 | cmp r2, #0 50 | beq disp_020 51 | 52 | /* ⑥ 実行するタスクの切り替え */ 53 | disp_030: 54 | str r2, [r0] 55 | ldr r0, [r2] 56 | mov sp, r0 57 | 58 | /* ⑦ スタック上のコンテキス情報の復元 */ 59 | pop {r0-r3} 60 | mov r11, r3 61 | mov r10, r2 62 | mov r9, r1 63 | mov r8, r0 64 | pop {r4-r7} 65 | 66 | /* 割込み許可 */ 67 | ldr r0, =disp_running 68 | mov r1, #0 69 | str r1, [r0] 70 | msr primask, r1 // 割込み許可 71 | 72 | bx lr 73 | 74 | -------------------------------------------------------------------------------- /part_5/include/typedef.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPEDEF_H 2 | #define TYPEDEF_H 3 | /* 4 | *** Try Kernel 5 | * データ型定義 6 | */ 7 | 8 | #include 9 | 10 | /* 符号付き整数 */ 11 | typedef int8_t B; /* 8 bit */ 12 | typedef int16_t H; /* 16 bit */ 13 | typedef int32_t W; /* 32 bit */ 14 | typedef int64_t D; /* 64 bit */ 15 | 16 | /* 符号無し整数 */ 17 | typedef uint8_t UB; /* 8 bit */ 18 | typedef uint16_t UH; /* 16 bit */ 19 | typedef uint32_t UW; /* 32 bit */ 20 | typedef uint64_t UD; /* 64 bit */ 21 | 22 | /* volatile 符号付き整数 */ 23 | typedef volatile int8_t _B; /* 8 bit */ 24 | typedef volatile int16_t _H; /* 16 bit */ 25 | typedef volatile int32_t _W; /* 32 bit */ 26 | typedef volatile int64_t _D; /* 64 bit */ 27 | 28 | /* volatole 符号無し整数 */ 29 | typedef volatile uint8_t _UB; /* 8 bit */ 30 | typedef volatile uint16_t _UH; /* 16 bit */ 31 | typedef volatile uint32_t _UW; /* 32 bit */ 32 | typedef volatile uint64_t _UD; /* 64 bit */ 33 | 34 | /* サイズ指定なし */ 35 | typedef int INT; /* 符号付き整数 */ 36 | typedef unsigned int UINT; /* 符号無し整数 */ 37 | 38 | /* 特別な意味を持つ整数 */ 39 | typedef INT ID; /* ID番号 */ 40 | typedef UW ATR; /* 属性 */ 41 | typedef INT ER; /* エラーコード */ 42 | typedef INT PRI; /* 優先順位 */ 43 | typedef W TMO; /* タイムアウト時間 */ 44 | typedef UW RELTIM; /* 相対時間 */ 45 | typedef W SZ; /* サイズ */ 46 | 47 | typedef void (*FP)(); /* 関数ポインタ */ 48 | 49 | #define NULL (0) 50 | 51 | typedef UINT BOOL; 52 | #define TRUE (1) /* True */ 53 | #define FALSE (0) /* False */ 54 | 55 | #endif /* TYPEDEF_H */ 56 | -------------------------------------------------------------------------------- /part_2/sect_3/include/typedef.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPEDEF_H 2 | #define TYPEDEF_H 3 | /* 4 | *** Try Kernel 5 | * データ型定義 6 | */ 7 | 8 | #include 9 | 10 | /* 符号付き整数 */ 11 | typedef int8_t B; /* 8 bit */ 12 | typedef int16_t H; /* 16 bit */ 13 | typedef int32_t W; /* 32 bit */ 14 | typedef int64_t D; /* 64 bit */ 15 | 16 | /* 符号無し整数 */ 17 | typedef uint8_t UB; /* 8 bit */ 18 | typedef uint16_t UH; /* 16 bit */ 19 | typedef uint32_t UW; /* 32 bit */ 20 | typedef uint64_t UD; /* 64 bit */ 21 | 22 | /* volatile 符号付き整数 */ 23 | typedef volatile int8_t _B; /* 8 bit */ 24 | typedef volatile int16_t _H; /* 16 bit */ 25 | typedef volatile int32_t _W; /* 32 bit */ 26 | typedef volatile int64_t _D; /* 64 bit */ 27 | 28 | /* volatole 符号無し整数 */ 29 | typedef volatile uint8_t _UB; /* 8 bit */ 30 | typedef volatile uint16_t _UH; /* 16 bit */ 31 | typedef volatile uint32_t _UW; /* 32 bit */ 32 | typedef volatile uint64_t _UD; /* 64 bit */ 33 | 34 | /* サイズ指定なし */ 35 | typedef int INT; /* 符号付き整数 */ 36 | typedef unsigned int UINT; /* 符号無し整数 */ 37 | 38 | /* 特別な意味を持つ整数 */ 39 | typedef INT ID; /* ID番号 */ 40 | typedef UW ATR; /* 属性 */ 41 | typedef INT ER; /* エラーコード */ 42 | typedef INT PRI; /* 優先順位 */ 43 | typedef W TMO; /* タイムアウト時間 */ 44 | typedef UW RELTIM; /* 相対時間 */ 45 | typedef W SZ; /* サイズ */ 46 | 47 | typedef void (*FP)(); /* 関数ポインタ */ 48 | 49 | #define NULL (0) 50 | 51 | typedef UINT BOOL; 52 | #define TRUE (1) /* True */ 53 | #define FALSE (0) /* False */ 54 | 55 | #endif /* TYPEDEF_H */ 56 | -------------------------------------------------------------------------------- /part_2/sect_4/include/typedef.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPEDEF_H 2 | #define TYPEDEF_H 3 | /* 4 | *** Try Kernel 5 | * データ型定義 6 | */ 7 | 8 | #include 9 | 10 | /* 符号付き整数 */ 11 | typedef int8_t B; /* 8 bit */ 12 | typedef int16_t H; /* 16 bit */ 13 | typedef int32_t W; /* 32 bit */ 14 | typedef int64_t D; /* 64 bit */ 15 | 16 | /* 符号無し整数 */ 17 | typedef uint8_t UB; /* 8 bit */ 18 | typedef uint16_t UH; /* 16 bit */ 19 | typedef uint32_t UW; /* 32 bit */ 20 | typedef uint64_t UD; /* 64 bit */ 21 | 22 | /* volatile 符号付き整数 */ 23 | typedef volatile int8_t _B; /* 8 bit */ 24 | typedef volatile int16_t _H; /* 16 bit */ 25 | typedef volatile int32_t _W; /* 32 bit */ 26 | typedef volatile int64_t _D; /* 64 bit */ 27 | 28 | /* volatole 符号無し整数 */ 29 | typedef volatile uint8_t _UB; /* 8 bit */ 30 | typedef volatile uint16_t _UH; /* 16 bit */ 31 | typedef volatile uint32_t _UW; /* 32 bit */ 32 | typedef volatile uint64_t _UD; /* 64 bit */ 33 | 34 | /* サイズ指定なし */ 35 | typedef int INT; /* 符号付き整数 */ 36 | typedef unsigned int UINT; /* 符号無し整数 */ 37 | 38 | /* 特別な意味を持つ整数 */ 39 | typedef INT ID; /* ID番号 */ 40 | typedef UW ATR; /* 属性 */ 41 | typedef INT ER; /* エラーコード */ 42 | typedef INT PRI; /* 優先順位 */ 43 | typedef W TMO; /* タイムアウト時間 */ 44 | typedef UW RELTIM; /* 相対時間 */ 45 | typedef W SZ; /* サイズ */ 46 | 47 | typedef void (*FP)(); /* 関数ポインタ */ 48 | 49 | #define NULL (0) 50 | 51 | typedef UINT BOOL; 52 | #define TRUE (1) /* True */ 53 | #define FALSE (0) /* False */ 54 | 55 | #endif /* TYPEDEF_H */ 56 | -------------------------------------------------------------------------------- /part_3/sect_1/include/typedef.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPEDEF_H 2 | #define TYPEDEF_H 3 | /* 4 | *** Try Kernel 5 | * データ型定義 6 | */ 7 | 8 | #include 9 | 10 | /* 符号付き整数 */ 11 | typedef int8_t B; /* 8 bit */ 12 | typedef int16_t H; /* 16 bit */ 13 | typedef int32_t W; /* 32 bit */ 14 | typedef int64_t D; /* 64 bit */ 15 | 16 | /* 符号無し整数 */ 17 | typedef uint8_t UB; /* 8 bit */ 18 | typedef uint16_t UH; /* 16 bit */ 19 | typedef uint32_t UW; /* 32 bit */ 20 | typedef uint64_t UD; /* 64 bit */ 21 | 22 | /* volatile 符号付き整数 */ 23 | typedef volatile int8_t _B; /* 8 bit */ 24 | typedef volatile int16_t _H; /* 16 bit */ 25 | typedef volatile int32_t _W; /* 32 bit */ 26 | typedef volatile int64_t _D; /* 64 bit */ 27 | 28 | /* volatole 符号無し整数 */ 29 | typedef volatile uint8_t _UB; /* 8 bit */ 30 | typedef volatile uint16_t _UH; /* 16 bit */ 31 | typedef volatile uint32_t _UW; /* 32 bit */ 32 | typedef volatile uint64_t _UD; /* 64 bit */ 33 | 34 | /* サイズ指定なし */ 35 | typedef int INT; /* 符号付き整数 */ 36 | typedef unsigned int UINT; /* 符号無し整数 */ 37 | 38 | /* 特別な意味を持つ整数 */ 39 | typedef INT ID; /* ID番号 */ 40 | typedef UW ATR; /* 属性 */ 41 | typedef INT ER; /* エラーコード */ 42 | typedef INT PRI; /* 優先順位 */ 43 | typedef W TMO; /* タイムアウト時間 */ 44 | typedef UW RELTIM; /* 相対時間 */ 45 | typedef W SZ; /* サイズ */ 46 | 47 | typedef void (*FP)(); /* 関数ポインタ */ 48 | 49 | #define NULL (0) 50 | 51 | typedef UINT BOOL; 52 | #define TRUE (1) /* True */ 53 | #define FALSE (0) /* False */ 54 | 55 | #endif /* TYPEDEF_H */ 56 | -------------------------------------------------------------------------------- /part_3/sect_2/include/typedef.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPEDEF_H 2 | #define TYPEDEF_H 3 | /* 4 | *** Try Kernel 5 | * データ型定義 6 | */ 7 | 8 | #include 9 | 10 | /* 符号付き整数 */ 11 | typedef int8_t B; /* 8 bit */ 12 | typedef int16_t H; /* 16 bit */ 13 | typedef int32_t W; /* 32 bit */ 14 | typedef int64_t D; /* 64 bit */ 15 | 16 | /* 符号無し整数 */ 17 | typedef uint8_t UB; /* 8 bit */ 18 | typedef uint16_t UH; /* 16 bit */ 19 | typedef uint32_t UW; /* 32 bit */ 20 | typedef uint64_t UD; /* 64 bit */ 21 | 22 | /* volatile 符号付き整数 */ 23 | typedef volatile int8_t _B; /* 8 bit */ 24 | typedef volatile int16_t _H; /* 16 bit */ 25 | typedef volatile int32_t _W; /* 32 bit */ 26 | typedef volatile int64_t _D; /* 64 bit */ 27 | 28 | /* volatole 符号無し整数 */ 29 | typedef volatile uint8_t _UB; /* 8 bit */ 30 | typedef volatile uint16_t _UH; /* 16 bit */ 31 | typedef volatile uint32_t _UW; /* 32 bit */ 32 | typedef volatile uint64_t _UD; /* 64 bit */ 33 | 34 | /* サイズ指定なし */ 35 | typedef int INT; /* 符号付き整数 */ 36 | typedef unsigned int UINT; /* 符号無し整数 */ 37 | 38 | /* 特別な意味を持つ整数 */ 39 | typedef INT ID; /* ID番号 */ 40 | typedef UW ATR; /* 属性 */ 41 | typedef INT ER; /* エラーコード */ 42 | typedef INT PRI; /* 優先順位 */ 43 | typedef W TMO; /* タイムアウト時間 */ 44 | typedef UW RELTIM; /* 相対時間 */ 45 | typedef W SZ; /* サイズ */ 46 | 47 | typedef void (*FP)(); /* 関数ポインタ */ 48 | 49 | #define NULL (0) 50 | 51 | typedef UINT BOOL; 52 | #define TRUE (1) /* True */ 53 | #define FALSE (0) /* False */ 54 | 55 | #endif /* TYPEDEF_H */ 56 | -------------------------------------------------------------------------------- /part_3/sect_3/include/typedef.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPEDEF_H 2 | #define TYPEDEF_H 3 | /* 4 | *** Try Kernel 5 | * データ型定義 6 | */ 7 | 8 | #include 9 | 10 | /* 符号付き整数 */ 11 | typedef int8_t B; /* 8 bit */ 12 | typedef int16_t H; /* 16 bit */ 13 | typedef int32_t W; /* 32 bit */ 14 | typedef int64_t D; /* 64 bit */ 15 | 16 | /* 符号無し整数 */ 17 | typedef uint8_t UB; /* 8 bit */ 18 | typedef uint16_t UH; /* 16 bit */ 19 | typedef uint32_t UW; /* 32 bit */ 20 | typedef uint64_t UD; /* 64 bit */ 21 | 22 | /* volatile 符号付き整数 */ 23 | typedef volatile int8_t _B; /* 8 bit */ 24 | typedef volatile int16_t _H; /* 16 bit */ 25 | typedef volatile int32_t _W; /* 32 bit */ 26 | typedef volatile int64_t _D; /* 64 bit */ 27 | 28 | /* volatole 符号無し整数 */ 29 | typedef volatile uint8_t _UB; /* 8 bit */ 30 | typedef volatile uint16_t _UH; /* 16 bit */ 31 | typedef volatile uint32_t _UW; /* 32 bit */ 32 | typedef volatile uint64_t _UD; /* 64 bit */ 33 | 34 | /* サイズ指定なし */ 35 | typedef int INT; /* 符号付き整数 */ 36 | typedef unsigned int UINT; /* 符号無し整数 */ 37 | 38 | /* 特別な意味を持つ整数 */ 39 | typedef INT ID; /* ID番号 */ 40 | typedef UW ATR; /* 属性 */ 41 | typedef INT ER; /* エラーコード */ 42 | typedef INT PRI; /* 優先順位 */ 43 | typedef W TMO; /* タイムアウト時間 */ 44 | typedef UW RELTIM; /* 相対時間 */ 45 | typedef W SZ; /* サイズ */ 46 | 47 | typedef void (*FP)(); /* 関数ポインタ */ 48 | 49 | #define NULL (0) 50 | 51 | typedef UINT BOOL; 52 | #define TRUE (1) /* True */ 53 | #define FALSE (0) /* False */ 54 | 55 | #endif /* TYPEDEF_H */ 56 | -------------------------------------------------------------------------------- /part_4/sect_1/include/typedef.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPEDEF_H 2 | #define TYPEDEF_H 3 | /* 4 | *** Try Kernel 5 | * データ型定義 6 | */ 7 | 8 | #include 9 | 10 | /* 符号付き整数 */ 11 | typedef int8_t B; /* 8 bit */ 12 | typedef int16_t H; /* 16 bit */ 13 | typedef int32_t W; /* 32 bit */ 14 | typedef int64_t D; /* 64 bit */ 15 | 16 | /* 符号無し整数 */ 17 | typedef uint8_t UB; /* 8 bit */ 18 | typedef uint16_t UH; /* 16 bit */ 19 | typedef uint32_t UW; /* 32 bit */ 20 | typedef uint64_t UD; /* 64 bit */ 21 | 22 | /* volatile 符号付き整数 */ 23 | typedef volatile int8_t _B; /* 8 bit */ 24 | typedef volatile int16_t _H; /* 16 bit */ 25 | typedef volatile int32_t _W; /* 32 bit */ 26 | typedef volatile int64_t _D; /* 64 bit */ 27 | 28 | /* volatole 符号無し整数 */ 29 | typedef volatile uint8_t _UB; /* 8 bit */ 30 | typedef volatile uint16_t _UH; /* 16 bit */ 31 | typedef volatile uint32_t _UW; /* 32 bit */ 32 | typedef volatile uint64_t _UD; /* 64 bit */ 33 | 34 | /* サイズ指定なし */ 35 | typedef int INT; /* 符号付き整数 */ 36 | typedef unsigned int UINT; /* 符号無し整数 */ 37 | 38 | /* 特別な意味を持つ整数 */ 39 | typedef INT ID; /* ID番号 */ 40 | typedef UW ATR; /* 属性 */ 41 | typedef INT ER; /* エラーコード */ 42 | typedef INT PRI; /* 優先順位 */ 43 | typedef W TMO; /* タイムアウト時間 */ 44 | typedef UW RELTIM; /* 相対時間 */ 45 | typedef W SZ; /* サイズ */ 46 | 47 | typedef void (*FP)(); /* 関数ポインタ */ 48 | 49 | #define NULL (0) 50 | 51 | typedef UINT BOOL; 52 | #define TRUE (1) /* True */ 53 | #define FALSE (0) /* False */ 54 | 55 | #endif /* TYPEDEF_H */ 56 | -------------------------------------------------------------------------------- /part_4/sect_2/include/typedef.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPEDEF_H 2 | #define TYPEDEF_H 3 | /* 4 | *** Try Kernel 5 | * データ型定義 6 | */ 7 | 8 | #include 9 | 10 | /* 符号付き整数 */ 11 | typedef int8_t B; /* 8 bit */ 12 | typedef int16_t H; /* 16 bit */ 13 | typedef int32_t W; /* 32 bit */ 14 | typedef int64_t D; /* 64 bit */ 15 | 16 | /* 符号無し整数 */ 17 | typedef uint8_t UB; /* 8 bit */ 18 | typedef uint16_t UH; /* 16 bit */ 19 | typedef uint32_t UW; /* 32 bit */ 20 | typedef uint64_t UD; /* 64 bit */ 21 | 22 | /* volatile 符号付き整数 */ 23 | typedef volatile int8_t _B; /* 8 bit */ 24 | typedef volatile int16_t _H; /* 16 bit */ 25 | typedef volatile int32_t _W; /* 32 bit */ 26 | typedef volatile int64_t _D; /* 64 bit */ 27 | 28 | /* volatole 符号無し整数 */ 29 | typedef volatile uint8_t _UB; /* 8 bit */ 30 | typedef volatile uint16_t _UH; /* 16 bit */ 31 | typedef volatile uint32_t _UW; /* 32 bit */ 32 | typedef volatile uint64_t _UD; /* 64 bit */ 33 | 34 | /* サイズ指定なし */ 35 | typedef int INT; /* 符号付き整数 */ 36 | typedef unsigned int UINT; /* 符号無し整数 */ 37 | 38 | /* 特別な意味を持つ整数 */ 39 | typedef INT ID; /* ID番号 */ 40 | typedef UW ATR; /* 属性 */ 41 | typedef INT ER; /* エラーコード */ 42 | typedef INT PRI; /* 優先順位 */ 43 | typedef W TMO; /* タイムアウト時間 */ 44 | typedef UW RELTIM; /* 相対時間 */ 45 | typedef W SZ; /* サイズ */ 46 | 47 | typedef void (*FP)(); /* 関数ポインタ */ 48 | 49 | #define NULL (0) 50 | 51 | typedef UINT BOOL; 52 | #define TRUE (1) /* True */ 53 | #define FALSE (0) /* False */ 54 | 55 | #endif /* TYPEDEF_H */ 56 | -------------------------------------------------------------------------------- /part_4/sect_3/include/typedef.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPEDEF_H 2 | #define TYPEDEF_H 3 | /* 4 | *** Try Kernel 5 | * データ型定義 6 | */ 7 | 8 | #include 9 | 10 | /* 符号付き整数 */ 11 | typedef int8_t B; /* 8 bit */ 12 | typedef int16_t H; /* 16 bit */ 13 | typedef int32_t W; /* 32 bit */ 14 | typedef int64_t D; /* 64 bit */ 15 | 16 | /* 符号無し整数 */ 17 | typedef uint8_t UB; /* 8 bit */ 18 | typedef uint16_t UH; /* 16 bit */ 19 | typedef uint32_t UW; /* 32 bit */ 20 | typedef uint64_t UD; /* 64 bit */ 21 | 22 | /* volatile 符号付き整数 */ 23 | typedef volatile int8_t _B; /* 8 bit */ 24 | typedef volatile int16_t _H; /* 16 bit */ 25 | typedef volatile int32_t _W; /* 32 bit */ 26 | typedef volatile int64_t _D; /* 64 bit */ 27 | 28 | /* volatole 符号無し整数 */ 29 | typedef volatile uint8_t _UB; /* 8 bit */ 30 | typedef volatile uint16_t _UH; /* 16 bit */ 31 | typedef volatile uint32_t _UW; /* 32 bit */ 32 | typedef volatile uint64_t _UD; /* 64 bit */ 33 | 34 | /* サイズ指定なし */ 35 | typedef int INT; /* 符号付き整数 */ 36 | typedef unsigned int UINT; /* 符号無し整数 */ 37 | 38 | /* 特別な意味を持つ整数 */ 39 | typedef INT ID; /* ID番号 */ 40 | typedef UW ATR; /* 属性 */ 41 | typedef INT ER; /* エラーコード */ 42 | typedef INT PRI; /* 優先順位 */ 43 | typedef W TMO; /* タイムアウト時間 */ 44 | typedef UW RELTIM; /* 相対時間 */ 45 | typedef W SZ; /* サイズ */ 46 | 47 | typedef void (*FP)(); /* 関数ポインタ */ 48 | 49 | #define NULL (0) 50 | 51 | typedef UINT BOOL; 52 | #define TRUE (1) /* True */ 53 | #define FALSE (0) /* False */ 54 | 55 | #endif /* TYPEDEF_H */ 56 | -------------------------------------------------------------------------------- /part_3/sect_2/include/knldef.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef KNLDEF_H 3 | #define KNLDEF_H 4 | /* 5 | *** Try Kernel 6 | * カーネル内部共通定義 7 | */ 8 | 9 | /* タスク状態 */ 10 | typedef enum { 11 | TS_NONEXIST = 0, // 未登録 12 | TS_READY = 1, // 実行状態 or 実行可能状態 13 | TS_WAIT = 2, // 待ち状態 14 | TS_DORMANT = 8 // 休止状態 15 | } TSTAT; 16 | 17 | /* TCB(Task Control Block)定義 */ 18 | typedef struct st_tcb { 19 | void *context; // コンテキスト情報へのポインタ 20 | 21 | /* キュー用ポインタ */ 22 | struct st_tcb *pre; // 一つ前の要素 23 | struct st_tcb *next; // 一つ後の要素 24 | 25 | TSTAT state; // タスク状態 26 | FP tskadr; // 実行開始アドレス 27 | PRI itskpri; // 実行優先度 28 | void *stkadr; // スタックのアドレス 29 | SZ stksz; // スタックのサイズ 30 | } TCB; 31 | 32 | extern TCB tcb_tbl[]; /* TCBテーブル */ 33 | extern TCB *ready_queue[]; /* タスクの実行待ち行列(優先度毎) */ 34 | extern TCB *cur_task; /* 実行中のタスク */ 35 | extern TCB *sche_task; /* 次に実行するタスク */ 36 | 37 | /* グローバル関数 */ 38 | extern void Reset_Handler(void); /* リセットハンドラ */ 39 | extern void dispatch_entry(void); /* ディスパッチャ */ 40 | 41 | /* ディスパッチャの呼出し */ 42 | #define SCB_ICSR 0xE000ED04 /* 割込み制御ステートレジスタのアドレス */ 43 | #define ICSR_PENDSVSET (1<<28) /* PendSV set-pending ビット */ 44 | static inline void dispatch( void ) 45 | { 46 | out_w(SCB_ICSR, ICSR_PENDSVSET); /* PendSV例外を発生 */ 47 | } 48 | 49 | extern void scheduler(void); /* スケジューラ */ 50 | 51 | extern void *make_context( UW *sp, UINT ssize, void (*fp)()); /* タスクコンテキストの作成*/ 52 | 53 | /* タスクの待ち行列操作関数 */ 54 | extern void tqueue_add_entry(TCB **queue, TCB *tcb); /* エントリ追加関数 */ 55 | extern void tqueue_remove_top(TCB **queue); /* 先頭エントリ削除関数 */ 56 | extern void tqueue_remove_entry(TCB **queue, TCB *tcb); /* エントリ削除関数 */ 57 | 58 | /* OSメイン関数 */ 59 | extern int main(void); 60 | 61 | /* ユーザメイン関数 */ 62 | extern int usermain(void); 63 | 64 | #endif /* KNLDEF_H */ -------------------------------------------------------------------------------- /part_4/sect_2/include/apidef.h: -------------------------------------------------------------------------------- 1 | #ifndef APIDEF_H 2 | #define APIDEF_H 3 | /* 4 | *** Try Kernel 5 | * API定義 6 | */ 7 | 8 | /* タイムアウト時間 */ 9 | #define TMO_POL (0) // タイムアウト時間 0 10 | #define TMO_FEVR (-1) // 無限待ち 11 | 12 | /*タスク生成情報 */ 13 | typedef struct { 14 | ATR tskatr; // タスク属性 15 | FP task; // タスク起動アドレス 16 | PRI itskpri; // タスク優先度 17 | SZ stksz; // スタックサイズ 18 | void *bufptr; // スタックのバッファポインタ 19 | } T_CTSK; 20 | 21 | /* タスク属性 */ 22 | #define TA_HLNG 0x0000001 23 | #define TA_USERBUF 0x0000020 24 | #define TA_RNG0 0x0000000 25 | #define TA_RNG1 0x0000100 26 | #define TA_RNG2 0x0000200 27 | #define TA_RNG3 0x0000300 28 | 29 | /* タスクの待ち属性 */ 30 | #define TA_TFIFO 0x00000000 // 待ちタスクをFIFO順で管理 31 | #define TA_TPRI 0x00000001 // 待ちタスクを優先度順で管理 32 | #define TA_FIRST 0x00000000 // 待ち行列先頭のタスクを優先 33 | #define TA_CNT 0x00000002 // 要求数の少ないタスクを優先 34 | #define TA_WSGL 0x00000000 // 複数タスクの待ちを許さない 35 | #define TA_WMUL 0x00000008 // 複数タスクの待ちを許す 36 | 37 | /* タスク管理API */ 38 | ID tk_cre_tsk( const T_CTSK *pk_ctsk ); 39 | ER tk_sta_tsk( ID tskid, INT stacd ); 40 | void tk_ext_tsk( void ); 41 | 42 | /* タスク付属同期API */ 43 | ER tk_dly_tsk( RELTIM dlytim ); 44 | ER tk_slp_tsk( TMO tmout ); 45 | ER tk_wup_tsk( ID tskid ); 46 | 47 | /* イベントフラグ生成情報 */ 48 | typedef struct t_cflg { 49 | ATR flgatr; // イベントフラグ属性 50 | UINT iflgptn; // イベントフラグ初期値 51 | } T_CFLG; 52 | 53 | /* イベントフラグ API */ 54 | ID tk_cre_flg( const T_CFLG *pk_cflg ); 55 | ER tk_set_flg( ID flgid, UINT setptn ); 56 | ER tk_clr_flg( ID flgid, UINT clrptn ); 57 | 58 | #define TWF_ANDW 0x00000000U // AND待ち 59 | #define TWF_ORW 0x00000001U // OR待ち 60 | #define TWF_CLR 0x00000010U // 全ビットのクリア 61 | #define TWF_BITCLR 0x00000020U // 条件ビットのみクリア 62 | 63 | ER tk_wai_flg( ID flgid, UINT waiptn, UINT wfmode, UINT *p_flgptn, TMO tmout ); 64 | 65 | #endif /* APIDEF_H */ -------------------------------------------------------------------------------- /part_5/device/adc/adc_sysdep.h: -------------------------------------------------------------------------------- 1 | #ifndef DEV_ADC_RP2040_H 2 | #define DEV_ADC_RP2040_H 3 | 4 | /* NUmber of A/DC chanels */ 5 | #define ADC_CH_NUM (5) 6 | 7 | /*---------------------------------------------------------------------- 8 | * A/DC レジスタ 9 | */ 10 | #define ADC_BASE (0x4004C000) 11 | 12 | #define ADC_CS (ADC_BASE+0x00) // ADC Control and Status 13 | #define ADC_RESULT (ADC_BASE+0x04) // Result of most recent ADC conversion 14 | #define ADC_FCS (ADC_BASE+0x08) // FIFO control and status 15 | #define ADC_FIFO (ADC_BASE+0x0C) // Conversion result FIFO 16 | #define ADC_DIV (ADC_BASE+0x10) // Clock divider 17 | #define ADC_INTR (ADC_BASE+0x14) // Raw Interrupts 18 | #define ADC_INTE (ADC_BASE+0x18) // Interrupt Enable 19 | #define ADC_INTF (ADC_BASE+0x1C) // Interrupt Force 20 | #define ADC_INTS (ADC_BASE+0x20) // Interrupt status after masking & forcing 21 | 22 | #define ADC_CS_EN (1<<0) // Power on ADC and enable its clock. 23 | #define ADC_CS_TS_EN (1<<1) // Power on temperature sensor. 24 | #define ADC_CS_STRAT_ONCE (1<<2) // Start a single conversion. 25 | #define ADC_CS_START_MANY (1<<3) // Continuously perform conversions. 26 | #define ADC_CS_READY (1<<8) // ADC is ready to start a new conversion. 27 | #define ADC_CS_ERR (1<<9) // The most recent ADC conversion encountered an error. 28 | #define ADC_CS_ERR_STICKY (1<<10) // Some past ADC conversion encountered an error. 29 | #define ADC_CS_AINSEL (0x00007000) // Select analog mux input. Updated automatically in roundrobin mode. 30 | #define ADC_CS_AINSEL_POS 12 31 | #define ADC_CS_RROBIN (0x001F0000) // Round-robin sampling. 32 | 33 | #define ADC_FCS_THRESH (0x0F000000) 34 | #define ADC_FCS_THRESH_POS 24 35 | #define ADC_FCS_LEVEL (0x000F0000) 36 | #define ADC_FCS_EN 1 37 | 38 | /* A/DC 割込み番号 */ 39 | #define INTNO_ADC 22 40 | 41 | /* クロック設定値 */ 42 | #define ADC_DIV_INI 0 43 | 44 | #endif /* DEV_ADC_RP2040_H */ -------------------------------------------------------------------------------- /part_5/device/devmgr/device.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "device.h" 3 | 4 | /* 文字列の比較 */ 5 | static BOOL nm_cmp(const UB *nm1, const UB *nm2) 6 | { 7 | for(INT i = 0; i < DEVNM_LEN; i++, nm1++, nm2++) { 8 | if(*nm2 == 0) break; 9 | if (*nm1 != *nm2) return FALSE; 10 | } 11 | return (*nm1 == 0)? TRUE: FALSE; 12 | } 13 | 14 | /* 15 | * デバイスのオープンAPI 16 | */ 17 | ID tk_opn_dev( const UB *devnm, UINT omode) 18 | { 19 | UINT intsts; 20 | INT i; 21 | ER err; 22 | 23 | /* デバイスドライバの検索*/ 24 | for(i = 0; i < DEV_NUM; i++) { 25 | if( nm_cmp(dev_tbl[i].devnm, devnm) == TRUE) break; 26 | } 27 | if(i >= DEV_NUM) return E_NOEXS; // デバイスは存在しない 28 | 29 | DI(intsts); // 割込み禁止 30 | if(dev_tbl[i].opncnt == 0) { // 最初のオープンのみオープン処理を実行 31 | err = (*dev_tbl[i].fn_opn)(dev_tbl[i].unit, omode); 32 | if(err == E_OK) { 33 | dev_tbl[i].opncnt++; 34 | dev_tbl[i].omode = omode; 35 | err = i; 36 | } 37 | } 38 | EI(intsts); // 割込み許可 39 | return err; 40 | } 41 | 42 | /* 43 | * デバイスの同期読込みAPI 44 | */ 45 | ER tk_srea_dev( ID dd, W start, void *buf, SZ size, SZ *asize) 46 | { 47 | ER err; 48 | 49 | /* エラーチェック */ 50 | if(dd >= DEV_NUM) return E_ID; // ddが不正 51 | if(dev_tbl[dd].opncnt == 0) return E_ID; // オープンされてない 52 | if((dev_tbl[dd].omode & TD_READ) == 0) return E_OACV; // オープンモードが読込みでない 53 | 54 | /* デバイスドライバのリード処理を呼出す*/ 55 | err = (*dev_tbl[dd].fn_srea)(dev_tbl[dd].unit, start, buf, size, asize); 56 | 57 | return err; 58 | } 59 | 60 | /* 61 | * デバイスの同期書込みAPI 62 | */ 63 | ER tk_swri_dev( ID dd, W start, const void *buf, SZ size, SZ *asize) 64 | { 65 | ER err; 66 | 67 | /* エラーチェック */ 68 | if(dd >= DEV_NUM) return E_ID; // ddが不正 69 | if(dev_tbl[dd].opncnt == 0) return E_ID; // オープンされてない 70 | if((dev_tbl[dd].omode & TD_WRITE) == 0) return E_OACV; // オープンモードが書込みでない 71 | 72 | /* デバイスドライバのリード処理を呼出す*/ 73 | err = (*dev_tbl[dd].fn_swri)(dev_tbl[dd].unit, start, buf, size, asize); 74 | 75 | return err; 76 | } 77 | -------------------------------------------------------------------------------- /part_4/sect_1/application/usermain.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* ボタン検出タスク生成情報 */ 4 | UW tskstk_btn[1024/sizeof(UW)]; /* ボタン検出タスクのスタック */ 5 | ID tskid_btn; /* ボタン検出タスクのID番号 */ 6 | void task_btn(INT stacd, void *exinf); 7 | T_CTSK ctsk_btn = { 8 | .tskatr = TA_HLNG | TA_RNG3 | TA_USERBUF, // タスク属性 9 | .task = task_btn, 10 | .itskpri = 10, 11 | .stksz = 1024, 12 | .bufptr = tskstk_btn, 13 | }; 14 | 15 | /* LED制御タスク生成情報 */ 16 | UW tskstk_led[1024/sizeof(UW)]; /* LED制御タスクのスタック */ 17 | ID tskid_led; /* LED制御タスクのID番号 */ 18 | void task_led(INT stacd, void *exinf); 19 | T_CTSK ctsk_led = { 20 | .tskatr = TA_HLNG | TA_RNG3 | TA_USERBUF, // タスク属性 21 | .task = task_led, 22 | .itskpri = 10, 23 | .stksz = 1024, 24 | .bufptr = tskstk_led, 25 | }; 26 | 27 | /* ボタン検出タスクの実行関数 */ 28 | void task_btn(INT stacd, void *exinf) 29 | { 30 | UW btn, btn0; 31 | 32 | /* GP14をスイッチ入力に設定 */ 33 | out_w(GPIO(14), (in_w(GPIO(14)) | GPIO_PUE) & ~GPIO_PDE); /* Pull-Up設定 */ 34 | out_w(GPIO_OE_CLR, (1<<14)); /* 出力無効 */ 35 | out_w(GPIO_CTRL(14), 5); /* SIO機能に設定 */ 36 | 37 | btn0 = in_w(GPIO_IN )& (1<<14); /* スイッチ読込み(初期値) */ 38 | while(1) { 39 | btn = in_w(GPIO_IN) & (1<<14); /* スイッチ読込み */ 40 | if(btn != btn0) { 41 | if(btn == 0) { 42 | tm_putstring("BTN ON\n"); 43 | tk_wup_tsk(tskid_led); /* タスクの起床 */ 44 | } 45 | btn0 = btn; 46 | } 47 | tk_dly_tsk(100); /* 0.1秒待ち */ 48 | } 49 | } 50 | 51 | /* LED制御タスクの実行関数 */ 52 | void task_led(INT stacd, void *exinf) 53 | { 54 | while(1) { 55 | tk_slp_tsk(TMO_FEVR); /* 起床待ち */ 56 | out_w(GPIO_OUT_SET, (1<<25)); /* LEDの点灯 */ 57 | tk_dly_tsk(1000); /* 1秒待ち */ 58 | out_w(GPIO_OUT_CLR, (1<<25)); /* LEDの消灯 */ 59 | } 60 | } 61 | 62 | int usermain(void) 63 | { 64 | /* ボタン検出タスクの生成、実行 */ 65 | tskid_btn = tk_cre_tsk(&ctsk_btn); 66 | tk_sta_tsk(tskid_btn, 0); 67 | 68 | /* LED制御タスクの生成、実行 */ 69 | tskid_led = tk_cre_tsk(&ctsk_led); 70 | tk_sta_tsk(tskid_led, 0); 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /part_5/kernel/task_mange.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスク管理 4 | */ 5 | #include 6 | #include 7 | 8 | TCB tcb_tbl[CNF_MAX_TSKID]; /* タスク管理ブロック (TCB) */ 9 | 10 | /* タスク生成API */ 11 | ID tk_cre_tsk( const T_CTSK *pk_ctsk ) 12 | { 13 | UINT intsts; 14 | ID tskid; 15 | INT i; 16 | 17 | /* 引数チェック */ 18 | if((pk_ctsk->tskatr & ~TA_RNG3) != (TA_HLNG|TA_USERBUF)) return E_RSATR; 19 | if(pk_ctsk->itskpri <= 0 || pk_ctsk->itskpri > CNF_MAX_TSKPRI) return E_PAR; 20 | if(pk_ctsk->stksz == 0) return E_PAR; 21 | 22 | DI(intsts); // 割込み禁止 23 | 24 | for(i = 0; i < CNF_MAX_TSKID; i++) { // 未使用のTCBを検索 25 | if(tcb_tbl[i].state == TS_NONEXIST) break; 26 | } 27 | /* TCBの初期化 */ 28 | if(i < CNF_MAX_TSKID) { 29 | tcb_tbl[i].state = TS_DORMANT; 30 | tcb_tbl[i].pre = NULL; 31 | tcb_tbl[i].next = NULL; 32 | 33 | tcb_tbl[i].tskadr = pk_ctsk->task; 34 | tcb_tbl[i].itskpri = pk_ctsk->itskpri; 35 | tcb_tbl[i].stksz = pk_ctsk->stksz; 36 | tcb_tbl[i].stkadr = pk_ctsk->bufptr; 37 | 38 | tskid = i+1; 39 | } else { 40 | tskid = (ID)E_LIMIT; // タスクが既に最大数 41 | } 42 | 43 | EI(intsts); // 割込み許可 44 | return tskid; 45 | } 46 | 47 | /* タスク実行API */ 48 | ER tk_sta_tsk( ID tskid, INT stacd ) 49 | { 50 | TCB *tcb; 51 | UINT intsts; 52 | ER err = E_OK; 53 | 54 | /* 引数チェック */ 55 | if(tskid <= 0 || tskid > CNF_MAX_TSKID) return E_ID; 56 | DI(intsts); // 割込み禁止 57 | 58 | tcb = &tcb_tbl[tskid-1]; 59 | if(tcb->state == TS_DORMANT) { // タスクを実行できる状態に変更 60 | tcb->state = TS_READY; 61 | tcb->context = make_context(tcb->stkadr, tcb->stksz, tcb->tskadr); 62 | tqueue_add_entry(&ready_queue[tcb->itskpri], tcb); 63 | scheduler(); // スケジューラを実行 64 | } else { 65 | err = E_OBJ; // タスクを実行できない(休止状態ではない) 66 | } 67 | 68 | EI(intsts); // 割込み許可 69 | return err; 70 | } 71 | 72 | /* タスクの動作終了API */ 73 | void tk_ext_tsk( void ) 74 | { 75 | UINT intsts; 76 | 77 | DI(intsts); // 割込み禁止 78 | 79 | cur_task->state = TS_DORMANT; // タスクを休止状態へ 80 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); 81 | 82 | scheduler(); // スケジューラを実行 83 | EI(intsts); // 割込み許可 84 | } 85 | 86 | -------------------------------------------------------------------------------- /part_3/sect_2/kernel/task_mange.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスク管理 4 | */ 5 | #include 6 | #include 7 | 8 | TCB tcb_tbl[CNF_MAX_TSKID]; /* タスク管理ブロック (TCB) */ 9 | 10 | /* タスク生成API */ 11 | ID tk_cre_tsk( const T_CTSK *pk_ctsk ) 12 | { 13 | UINT intsts; 14 | ID tskid; 15 | INT i; 16 | 17 | /* 引数チェック */ 18 | if((pk_ctsk->tskatr & ~TA_RNG3) != (TA_HLNG|TA_USERBUF)) return E_RSATR; 19 | if(pk_ctsk->itskpri <= 0 || pk_ctsk->itskpri > CNF_MAX_TSKPRI) return E_PAR; 20 | if(pk_ctsk->stksz == 0) return E_PAR; 21 | 22 | DI(intsts); // 割込み禁止 23 | 24 | for(i = 0; i < CNF_MAX_TSKID; i++) { // 未使用のTCBを検索 25 | if(tcb_tbl[i].state == TS_NONEXIST) break; 26 | } 27 | /* TCBの初期化 */ 28 | if(i < CNF_MAX_TSKID) { 29 | tcb_tbl[i].state = TS_DORMANT; 30 | tcb_tbl[i].pre = NULL; 31 | tcb_tbl[i].next = NULL; 32 | 33 | tcb_tbl[i].tskadr = pk_ctsk->task; 34 | tcb_tbl[i].itskpri = pk_ctsk->itskpri; 35 | tcb_tbl[i].stksz = pk_ctsk->stksz; 36 | tcb_tbl[i].stkadr = pk_ctsk->bufptr; 37 | 38 | tskid = i+1; 39 | } else { 40 | tskid = (ID)E_LIMIT; // タスクが既に最大数 41 | } 42 | 43 | EI(intsts); // 割込み許可 44 | return tskid; 45 | } 46 | 47 | /* タスク実行API */ 48 | ER tk_sta_tsk( ID tskid, INT stacd ) 49 | { 50 | TCB *tcb; 51 | UINT intsts; 52 | ER err = E_OK; 53 | 54 | /* 引数チェック */ 55 | if(tskid <= 0 || tskid > CNF_MAX_TSKID) return E_ID; 56 | DI(intsts); // 割込み禁止 57 | 58 | tcb = &tcb_tbl[tskid-1]; 59 | if(tcb->state == TS_DORMANT) { // タスクを実行できる状態に変更 60 | tcb->state = TS_READY; 61 | tcb->context = make_context(tcb->stkadr, tcb->stksz, tcb->tskadr); 62 | tqueue_add_entry(&ready_queue[tcb->itskpri], tcb); 63 | scheduler(); // スケジューラを実行 64 | } else { 65 | err = E_OBJ; // タスクを実行できない(休止状態ではない) 66 | } 67 | 68 | EI(intsts); // 割込み許可 69 | return err; 70 | } 71 | 72 | /* タスクの動作終了API */ 73 | void tk_ext_tsk( void ) 74 | { 75 | UINT intsts; 76 | 77 | DI(intsts); // 割込み禁止 78 | 79 | cur_task->state = TS_DORMANT; // タスクを休止状態へ 80 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); 81 | 82 | scheduler(); // スケジューラを実行 83 | EI(intsts); // 割込み許可 84 | } 85 | 86 | -------------------------------------------------------------------------------- /part_3/sect_3/kernel/task_mange.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスク管理 4 | */ 5 | #include 6 | #include 7 | 8 | TCB tcb_tbl[CNF_MAX_TSKID]; /* タスク管理ブロック (TCB) */ 9 | 10 | /* タスク生成API */ 11 | ID tk_cre_tsk( const T_CTSK *pk_ctsk ) 12 | { 13 | UINT intsts; 14 | ID tskid; 15 | INT i; 16 | 17 | /* 引数チェック */ 18 | if((pk_ctsk->tskatr & ~TA_RNG3) != (TA_HLNG|TA_USERBUF)) return E_RSATR; 19 | if(pk_ctsk->itskpri <= 0 || pk_ctsk->itskpri > CNF_MAX_TSKPRI) return E_PAR; 20 | if(pk_ctsk->stksz == 0) return E_PAR; 21 | 22 | DI(intsts); // 割込み禁止 23 | 24 | for(i = 0; i < CNF_MAX_TSKID; i++) { // 未使用のTCBを検索 25 | if(tcb_tbl[i].state == TS_NONEXIST) break; 26 | } 27 | /* TCBの初期化 */ 28 | if(i < CNF_MAX_TSKID) { 29 | tcb_tbl[i].state = TS_DORMANT; 30 | tcb_tbl[i].pre = NULL; 31 | tcb_tbl[i].next = NULL; 32 | 33 | tcb_tbl[i].tskadr = pk_ctsk->task; 34 | tcb_tbl[i].itskpri = pk_ctsk->itskpri; 35 | tcb_tbl[i].stksz = pk_ctsk->stksz; 36 | tcb_tbl[i].stkadr = pk_ctsk->bufptr; 37 | 38 | tskid = i+1; 39 | } else { 40 | tskid = (ID)E_LIMIT; // タスクが既に最大数 41 | } 42 | 43 | EI(intsts); // 割込み許可 44 | return tskid; 45 | } 46 | 47 | /* タスク実行API */ 48 | ER tk_sta_tsk( ID tskid, INT stacd ) 49 | { 50 | TCB *tcb; 51 | UINT intsts; 52 | ER err = E_OK; 53 | 54 | /* 引数チェック */ 55 | if(tskid <= 0 || tskid > CNF_MAX_TSKID) return E_ID; 56 | DI(intsts); // 割込み禁止 57 | 58 | tcb = &tcb_tbl[tskid-1]; 59 | if(tcb->state == TS_DORMANT) { // タスクを実行できる状態に変更 60 | tcb->state = TS_READY; 61 | tcb->context = make_context(tcb->stkadr, tcb->stksz, tcb->tskadr); 62 | tqueue_add_entry(&ready_queue[tcb->itskpri], tcb); 63 | scheduler(); // スケジューラを実行 64 | } else { 65 | err = E_OBJ; // タスクを実行できない(休止状態ではない) 66 | } 67 | 68 | EI(intsts); // 割込み許可 69 | return err; 70 | } 71 | 72 | /* タスクの動作終了API */ 73 | void tk_ext_tsk( void ) 74 | { 75 | UINT intsts; 76 | 77 | DI(intsts); // 割込み禁止 78 | 79 | cur_task->state = TS_DORMANT; // タスクを休止状態へ 80 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); 81 | 82 | scheduler(); // スケジューラを実行 83 | EI(intsts); // 割込み許可 84 | } 85 | 86 | -------------------------------------------------------------------------------- /part_4/sect_1/kernel/task_mange.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスク管理 4 | */ 5 | #include 6 | #include 7 | 8 | TCB tcb_tbl[CNF_MAX_TSKID]; /* タスク管理ブロック (TCB) */ 9 | 10 | /* タスク生成API */ 11 | ID tk_cre_tsk( const T_CTSK *pk_ctsk ) 12 | { 13 | UINT intsts; 14 | ID tskid; 15 | INT i; 16 | 17 | /* 引数チェック */ 18 | if((pk_ctsk->tskatr & ~TA_RNG3) != (TA_HLNG|TA_USERBUF)) return E_RSATR; 19 | if(pk_ctsk->itskpri <= 0 || pk_ctsk->itskpri > CNF_MAX_TSKPRI) return E_PAR; 20 | if(pk_ctsk->stksz == 0) return E_PAR; 21 | 22 | DI(intsts); // 割込み禁止 23 | 24 | for(i = 0; i < CNF_MAX_TSKID; i++) { // 未使用のTCBを検索 25 | if(tcb_tbl[i].state == TS_NONEXIST) break; 26 | } 27 | /* TCBの初期化 */ 28 | if(i < CNF_MAX_TSKID) { 29 | tcb_tbl[i].state = TS_DORMANT; 30 | tcb_tbl[i].pre = NULL; 31 | tcb_tbl[i].next = NULL; 32 | 33 | tcb_tbl[i].tskadr = pk_ctsk->task; 34 | tcb_tbl[i].itskpri = pk_ctsk->itskpri; 35 | tcb_tbl[i].stksz = pk_ctsk->stksz; 36 | tcb_tbl[i].stkadr = pk_ctsk->bufptr; 37 | 38 | tskid = i+1; 39 | } else { 40 | tskid = (ID)E_LIMIT; // タスクが既に最大数 41 | } 42 | 43 | EI(intsts); // 割込み許可 44 | return tskid; 45 | } 46 | 47 | /* タスク実行API */ 48 | ER tk_sta_tsk( ID tskid, INT stacd ) 49 | { 50 | TCB *tcb; 51 | UINT intsts; 52 | ER err = E_OK; 53 | 54 | /* 引数チェック */ 55 | if(tskid <= 0 || tskid > CNF_MAX_TSKID) return E_ID; 56 | DI(intsts); // 割込み禁止 57 | 58 | tcb = &tcb_tbl[tskid-1]; 59 | if(tcb->state == TS_DORMANT) { // タスクを実行できる状態に変更 60 | tcb->state = TS_READY; 61 | tcb->context = make_context(tcb->stkadr, tcb->stksz, tcb->tskadr); 62 | tqueue_add_entry(&ready_queue[tcb->itskpri], tcb); 63 | scheduler(); // スケジューラを実行 64 | } else { 65 | err = E_OBJ; // タスクを実行できない(休止状態ではない) 66 | } 67 | 68 | EI(intsts); // 割込み許可 69 | return err; 70 | } 71 | 72 | /* タスクの動作終了API */ 73 | void tk_ext_tsk( void ) 74 | { 75 | UINT intsts; 76 | 77 | DI(intsts); // 割込み禁止 78 | 79 | cur_task->state = TS_DORMANT; // タスクを休止状態へ 80 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); 81 | 82 | scheduler(); // スケジューラを実行 83 | EI(intsts); // 割込み許可 84 | } 85 | 86 | -------------------------------------------------------------------------------- /part_4/sect_2/kernel/task_mange.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスク管理 4 | */ 5 | #include 6 | #include 7 | 8 | TCB tcb_tbl[CNF_MAX_TSKID]; /* タスク管理ブロック (TCB) */ 9 | 10 | /* タスク生成API */ 11 | ID tk_cre_tsk( const T_CTSK *pk_ctsk ) 12 | { 13 | UINT intsts; 14 | ID tskid; 15 | INT i; 16 | 17 | /* 引数チェック */ 18 | if((pk_ctsk->tskatr & ~TA_RNG3) != (TA_HLNG|TA_USERBUF)) return E_RSATR; 19 | if(pk_ctsk->itskpri <= 0 || pk_ctsk->itskpri > CNF_MAX_TSKPRI) return E_PAR; 20 | if(pk_ctsk->stksz == 0) return E_PAR; 21 | 22 | DI(intsts); // 割込み禁止 23 | 24 | for(i = 0; i < CNF_MAX_TSKID; i++) { // 未使用のTCBを検索 25 | if(tcb_tbl[i].state == TS_NONEXIST) break; 26 | } 27 | /* TCBの初期化 */ 28 | if(i < CNF_MAX_TSKID) { 29 | tcb_tbl[i].state = TS_DORMANT; 30 | tcb_tbl[i].pre = NULL; 31 | tcb_tbl[i].next = NULL; 32 | 33 | tcb_tbl[i].tskadr = pk_ctsk->task; 34 | tcb_tbl[i].itskpri = pk_ctsk->itskpri; 35 | tcb_tbl[i].stksz = pk_ctsk->stksz; 36 | tcb_tbl[i].stkadr = pk_ctsk->bufptr; 37 | 38 | tskid = i+1; 39 | } else { 40 | tskid = (ID)E_LIMIT; // タスクが既に最大数 41 | } 42 | 43 | EI(intsts); // 割込み許可 44 | return tskid; 45 | } 46 | 47 | /* タスク実行API */ 48 | ER tk_sta_tsk( ID tskid, INT stacd ) 49 | { 50 | TCB *tcb; 51 | UINT intsts; 52 | ER err = E_OK; 53 | 54 | /* 引数チェック */ 55 | if(tskid <= 0 || tskid > CNF_MAX_TSKID) return E_ID; 56 | DI(intsts); // 割込み禁止 57 | 58 | tcb = &tcb_tbl[tskid-1]; 59 | if(tcb->state == TS_DORMANT) { // タスクを実行できる状態に変更 60 | tcb->state = TS_READY; 61 | tcb->context = make_context(tcb->stkadr, tcb->stksz, tcb->tskadr); 62 | tqueue_add_entry(&ready_queue[tcb->itskpri], tcb); 63 | scheduler(); // スケジューラを実行 64 | } else { 65 | err = E_OBJ; // タスクを実行できない(休止状態ではない) 66 | } 67 | 68 | EI(intsts); // 割込み許可 69 | return err; 70 | } 71 | 72 | /* タスクの動作終了API */ 73 | void tk_ext_tsk( void ) 74 | { 75 | UINT intsts; 76 | 77 | DI(intsts); // 割込み禁止 78 | 79 | cur_task->state = TS_DORMANT; // タスクを休止状態へ 80 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); 81 | 82 | scheduler(); // スケジューラを実行 83 | EI(intsts); // 割込み許可 84 | } 85 | 86 | -------------------------------------------------------------------------------- /part_4/sect_3/kernel/task_mange.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスク管理 4 | */ 5 | #include 6 | #include 7 | 8 | TCB tcb_tbl[CNF_MAX_TSKID]; /* タスク管理ブロック (TCB) */ 9 | 10 | /* タスク生成API */ 11 | ID tk_cre_tsk( const T_CTSK *pk_ctsk ) 12 | { 13 | UINT intsts; 14 | ID tskid; 15 | INT i; 16 | 17 | /* 引数チェック */ 18 | if((pk_ctsk->tskatr & ~TA_RNG3) != (TA_HLNG|TA_USERBUF)) return E_RSATR; 19 | if(pk_ctsk->itskpri <= 0 || pk_ctsk->itskpri > CNF_MAX_TSKPRI) return E_PAR; 20 | if(pk_ctsk->stksz == 0) return E_PAR; 21 | 22 | DI(intsts); // 割込み禁止 23 | 24 | for(i = 0; i < CNF_MAX_TSKID; i++) { // 未使用のTCBを検索 25 | if(tcb_tbl[i].state == TS_NONEXIST) break; 26 | } 27 | /* TCBの初期化 */ 28 | if(i < CNF_MAX_TSKID) { 29 | tcb_tbl[i].state = TS_DORMANT; 30 | tcb_tbl[i].pre = NULL; 31 | tcb_tbl[i].next = NULL; 32 | 33 | tcb_tbl[i].tskadr = pk_ctsk->task; 34 | tcb_tbl[i].itskpri = pk_ctsk->itskpri; 35 | tcb_tbl[i].stksz = pk_ctsk->stksz; 36 | tcb_tbl[i].stkadr = pk_ctsk->bufptr; 37 | 38 | tskid = i+1; 39 | } else { 40 | tskid = (ID)E_LIMIT; // タスクが既に最大数 41 | } 42 | 43 | EI(intsts); // 割込み許可 44 | return tskid; 45 | } 46 | 47 | /* タスク実行API */ 48 | ER tk_sta_tsk( ID tskid, INT stacd ) 49 | { 50 | TCB *tcb; 51 | UINT intsts; 52 | ER err = E_OK; 53 | 54 | /* 引数チェック */ 55 | if(tskid <= 0 || tskid > CNF_MAX_TSKID) return E_ID; 56 | DI(intsts); // 割込み禁止 57 | 58 | tcb = &tcb_tbl[tskid-1]; 59 | if(tcb->state == TS_DORMANT) { // タスクを実行できる状態に変更 60 | tcb->state = TS_READY; 61 | tcb->context = make_context(tcb->stkadr, tcb->stksz, tcb->tskadr); 62 | tqueue_add_entry(&ready_queue[tcb->itskpri], tcb); 63 | scheduler(); // スケジューラを実行 64 | } else { 65 | err = E_OBJ; // タスクを実行できない(休止状態ではない) 66 | } 67 | 68 | EI(intsts); // 割込み許可 69 | return err; 70 | } 71 | 72 | /* タスクの動作終了API */ 73 | void tk_ext_tsk( void ) 74 | { 75 | UINT intsts; 76 | 77 | DI(intsts); // 割込み禁止 78 | 79 | cur_task->state = TS_DORMANT; // タスクを休止状態へ 80 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); 81 | 82 | scheduler(); // スケジューラを実行 83 | EI(intsts); // 割込み許可 84 | } 85 | 86 | -------------------------------------------------------------------------------- /part_3/sect_3/include/knldef.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef KNLDEF_H 3 | #define KNLDEF_H 4 | /* 5 | * Try Kernel 6 | * カーネル内部共通定義 7 | */ 8 | 9 | /* タスク状態 */ 10 | typedef enum { 11 | TS_NONEXIST = 0, // 未登録 12 | TS_READY = 1, // 実行状態 or 実行可能状態 13 | TS_WAIT = 2, // 待ち状態 14 | TS_DORMANT = 8 // 休止状態 15 | } TSTAT; 16 | 17 | /* タスクの待ち要因 */ 18 | typedef enum { 19 | TWFCT_NON = 0, // 無し 20 | TWFCT_DLY = 1, // tk_dly_tskによる時間待ち 21 | } TWFCT; 22 | 23 | /* TCB(Task Control Block)定義 */ 24 | typedef struct st_tcb { 25 | void *context; // コンテキスト情報へのポインタ 26 | 27 | /* タスクキュー用ポインタ */ 28 | struct st_tcb *pre; // 一つ前の要素 29 | struct st_tcb *next; // 一つ後の要素 30 | 31 | /* タスク情報 */ 32 | TSTAT state; // タスク状態 33 | FP tskadr; // 実行開始アドレス 34 | PRI itskpri; // 実行優先度 35 | void *stkadr; // スタックのアドレス 36 | SZ stksz; // スタックのサイズ 37 | 38 | /* 時間待ち情報 */ 39 | TWFCT waifct; // 待ち要因 40 | RELTIM waitim; // 待ち時間 41 | ER *waierr; // 待ち解除のエラーコード 42 | } TCB; 43 | 44 | extern TCB tcb_tbl[]; // TCBテーブル 45 | extern TCB *ready_queue[]; // タスクの実行待ち行列(優先度毎) 46 | extern TCB *cur_task; // 実行中のタスク 47 | extern TCB *sche_task; // 次に実行するタスク 48 | extern TCB *wait_queue; // タスクの時間待ち行列 49 | 50 | /* グローバル関数 */ 51 | extern void Reset_Handler(void); // リセットハンドラ 52 | extern void dispatch_entry(void); // ディスパッチャ 53 | extern void systimer_handler(void); // システムタイマ割込みハンドラ 54 | 55 | /* ディスパッチャの呼出し */ 56 | #define SCB_ICSR 0xE000ED04 // 割込み制御ステートレジスタのアドレス 57 | #define ICSR_PENDSVSET (1<<28) // PendSV set-pending ビット 58 | static inline void dispatch( void ) 59 | { 60 | out_w(SCB_ICSR, ICSR_PENDSVSET); // PendSV例外を発生 61 | } 62 | 63 | extern void scheduler(void); // スケジューラ 64 | 65 | extern void *make_context( UW *sp, UINT ssize, void (*fp)()); // タスクコンテキストの作成 66 | 67 | /* タスクの待ち行列操作関数 */ 68 | extern void tqueue_add_entry(TCB **queue, TCB *tcb); // エントリ追加関数 69 | extern void tqueue_remove_top(TCB **queue); // 先頭エントリ削除関数 70 | extern void tqueue_remove_entry(TCB **queue, TCB *tcb); // エントリ削除関数 71 | 72 | /* OSメイン関数 */ 73 | extern int main(void); 74 | 75 | /* ユーザメイン関数 */ 76 | extern int usermain(void); 77 | 78 | #endif /* KNLDEF_H */ -------------------------------------------------------------------------------- /part_4/sect_1/include/knldef copy.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef KNLDEF_H 3 | #define KNLDEF_H 4 | /* 5 | * Try Kernel 6 | * カーネル内部共通定義 7 | */ 8 | 9 | /* タスク状態 */ 10 | typedef enum { 11 | TS_NONEXIST = 0, // 未登録 12 | TS_READY = 1, // 実行状態 or 実行可能状態 13 | TS_WAIT = 2, // 待ち状態 14 | TS_DORMANT = 8 // 休止状態 15 | } TSTAT; 16 | 17 | /* タスクの待ち要因 */ 18 | typedef enum { 19 | TWFCT_NON = 0, // 無し 20 | TWFCT_DLY = 1, // tk_dly_tskによる時間待ち 21 | TWFCT_SLP = 2, // tk_slp_tskによる起床待ち 22 | } TWFCT; 23 | 24 | /* TCB(Task Control Block)定義 */ 25 | typedef struct st_tcb { 26 | void *context; // コンテキスト情報へのポインタ 27 | 28 | /* タスクキュー用ポインタ */ 29 | struct st_tcb *pre; // 一つ前の要素 30 | struct st_tcb *next; // 一つ後の要素 31 | 32 | /* タスク情報 */ 33 | TSTAT state; // タスク状態 34 | FP tskadr; // 実行開始アドレス 35 | PRI itskpri; // 実行優先度 36 | void *stkadr; // スタックのアドレス 37 | SZ stksz; // スタックのサイズ 38 | INT wupcnt; // 起床要求数 39 | 40 | /* 時間待ち情報 */ 41 | TWFCT waifct; // 待ち要因 42 | RELTIM waitim; // 待ち時間 43 | ER *waierr; // 待ち解除のエラーコード 44 | } TCB; 45 | 46 | extern TCB tcb_tbl[]; // TCBテーブル 47 | extern TCB *ready_queue[]; // タスクの実行待ち行列(優先度毎) 48 | extern TCB *cur_task; // 実行中のタスク 49 | extern TCB *sche_task; // 次に実行するタスク 50 | extern TCB *wait_queue; // タスクの時間待ち行列 51 | 52 | /* グローバル関数 */ 53 | extern void Reset_Handler(void); // リセットハンドラ 54 | extern void dispatch_entry(void); // ディスパッチャ 55 | extern void systimer_handler(void); // システムタイマ割込みハンドラ 56 | 57 | /* ディスパッチャの呼出し */ 58 | #define SCB_ICSR 0xE000ED04 // 割込み制御ステートレジスタのアドレス 59 | #define ICSR_PENDSVSET (1<<28) // PendSV set-pending ビット 60 | static inline void dispatch( void ) 61 | { 62 | out_w(SCB_ICSR, ICSR_PENDSVSET); // PendSV例外を発生 63 | } 64 | 65 | extern void scheduler(void); // スケジューラ 66 | 67 | extern void *make_context( UW *sp, UINT ssize, void (*fp)()); // タスクコンテキストの作成 68 | 69 | /* タスクの待ち行列操作関数 */ 70 | extern void tqueue_add_entry(TCB **queue, TCB *tcb); // エントリ追加関数 71 | extern void tqueue_remove_top(TCB **queue); // 先頭エントリ削除関数 72 | extern void tqueue_remove_entry(TCB **queue, TCB *tcb); // エントリ削除関数 73 | 74 | /* OSメイン関数 */ 75 | extern int main(void); 76 | 77 | /* ユーザメイン関数 */ 78 | extern int usermain(void); 79 | 80 | #endif /* KNLDEF_H */ -------------------------------------------------------------------------------- /part_5/boot/vector_tbl.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 例外ベクターテーブル 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /* デフォルトハンドラ */ 12 | void Default_Handler(void) 13 | { 14 | while(1); 15 | } 16 | 17 | /* 例外ベクターテーブル */ 18 | void (* const vector_tbl[])() __attribute__((section(".vector"))) = { 19 | (void(*)()) (INITIAL_SP), // 0: Top of Stack 20 | Reset_Handler, // 1: Reset 21 | Default_Handler, // 2: NMI 22 | Default_Handler, // 3: Hard Fault 23 | 0, // 4: 未使用 24 | 0, // 5: 未使用 25 | 0, // 6: 未使用 26 | 0, // 7: 未使用 27 | 0, // 8: 未使用 28 | 0, // 9: 未使用 29 | 0, // 10: 未使用 30 | Default_Handler, // 11: Svcall 31 | 0, // 12: 未使用 32 | 0, // 13: 未使用 33 | dispatch_entry, // 14: Pend SV 34 | systimer_handler, // 15: Systick 35 | Default_Handler, // IRQ 0 36 | Default_Handler, // IRQ 1 37 | Default_Handler, // IRQ 2 38 | Default_Handler, // IRQ 3 39 | Default_Handler, // IRQ 4 40 | Default_Handler, // IRQ 5 41 | Default_Handler, // IRQ 6 42 | Default_Handler, // IRQ 7 43 | Default_Handler, // IRQ 8 44 | Default_Handler, // IRQ 9 45 | Default_Handler, // IRQ 10 46 | Default_Handler, // IRQ 11 47 | Default_Handler, // IRQ 12 48 | Default_Handler, // IRQ 13 49 | Default_Handler, // IRQ 14 50 | Default_Handler, // IRQ 15 51 | Default_Handler, // IRQ 16 52 | Default_Handler, // IRQ 17 53 | Default_Handler, // IRQ 18 54 | Default_Handler, // IRQ 19 55 | Default_Handler, // IRQ 20 56 | Default_Handler, // IRQ 21 57 | Default_Handler, // IRQ 22 58 | Default_Handler, // IRQ 23 59 | Default_Handler, // IRQ 24 60 | Default_Handler, // IRQ 25 61 | Default_Handler, // IRQ 26 62 | Default_Handler, // IRQ 27 63 | Default_Handler, // IRQ 28 64 | Default_Handler, // IRQ 29 65 | Default_Handler, // IRQ 31 66 | }; 67 | -------------------------------------------------------------------------------- /part_2/sect_3/boot/vector_tbl.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 例外ベクターテーブル 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /* デフォルトハンドラ */ 12 | void Default_Handler(void) 13 | { 14 | while(1); 15 | } 16 | 17 | /* 例外ベクターテーブル */ 18 | void (* const vector_tbl[])() __attribute__((section(".vector"))) = { 19 | (void(*)()) (INITIAL_SP), // 0: Top of Stack 20 | Reset_Handler, // 1: Reset 21 | Default_Handler, // 2: NMI 22 | Default_Handler, // 3: Hard Fault 23 | 0, // 4: 未使用 24 | 0, // 5: 未使用 25 | 0, // 6: 未使用 26 | 0, // 7: 未使用 27 | 0, // 8: 未使用 28 | 0, // 9: 未使用 29 | 0, // 10: 未使用 30 | Default_Handler, // 11: Svcall 31 | 0, // 12: 未使用 32 | 0, // 13: 未使用 33 | Default_Handler, // 14: Pend SV 34 | Default_Handler, // 15: Systick 35 | Default_Handler, // IRQ 0 36 | Default_Handler, // IRQ 1 37 | Default_Handler, // IRQ 2 38 | Default_Handler, // IRQ 3 39 | Default_Handler, // IRQ 4 40 | Default_Handler, // IRQ 5 41 | Default_Handler, // IRQ 6 42 | Default_Handler, // IRQ 7 43 | Default_Handler, // IRQ 8 44 | Default_Handler, // IRQ 9 45 | Default_Handler, // IRQ 10 46 | Default_Handler, // IRQ 11 47 | Default_Handler, // IRQ 12 48 | Default_Handler, // IRQ 13 49 | Default_Handler, // IRQ 14 50 | Default_Handler, // IRQ 15 51 | Default_Handler, // IRQ 16 52 | Default_Handler, // IRQ 17 53 | Default_Handler, // IRQ 18 54 | Default_Handler, // IRQ 19 55 | Default_Handler, // IRQ 20 56 | Default_Handler, // IRQ 21 57 | Default_Handler, // IRQ 22 58 | Default_Handler, // IRQ 23 59 | Default_Handler, // IRQ 24 60 | Default_Handler, // IRQ 25 61 | Default_Handler, // IRQ 26 62 | Default_Handler, // IRQ 27 63 | Default_Handler, // IRQ 28 64 | Default_Handler, // IRQ 29 65 | Default_Handler, // IRQ 31 66 | }; 67 | -------------------------------------------------------------------------------- /part_2/sect_4/boot/vector_tbl.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 例外ベクターテーブル 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /* デフォルトハンドラ */ 12 | extern void dispatch_entry(void); 13 | void Default_Handler(void) 14 | { 15 | while(1); 16 | } 17 | 18 | /* 例外ベクターテーブル */ 19 | void (* const vector_tbl[])() __attribute__((section(".vector"))) = { 20 | (void(*)()) (INITIAL_SP), // 0: Top of Stack 21 | Reset_Handler, // 1: Reset 22 | Default_Handler, // 2: NMI 23 | Default_Handler, // 3: Hard Fault 24 | 0, // 4: 未使用 25 | 0, // 5: 未使用 26 | 0, // 6: 未使用 27 | 0, // 7: 未使用 28 | 0, // 8: 未使用 29 | 0, // 9: 未使用 30 | 0, // 10: 未使用 31 | Default_Handler, // 11: Svcall 32 | 0, // 12: 未使用 33 | 0, // 13: 未使用 34 | Default_Handler, // 14: Pend SV 35 | Default_Handler, // 15: Systick 36 | Default_Handler, // IRQ 0 37 | Default_Handler, // IRQ 1 38 | Default_Handler, // IRQ 2 39 | Default_Handler, // IRQ 3 40 | Default_Handler, // IRQ 4 41 | Default_Handler, // IRQ 5 42 | Default_Handler, // IRQ 6 43 | Default_Handler, // IRQ 7 44 | Default_Handler, // IRQ 8 45 | Default_Handler, // IRQ 9 46 | Default_Handler, // IRQ 10 47 | Default_Handler, // IRQ 11 48 | Default_Handler, // IRQ 12 49 | Default_Handler, // IRQ 13 50 | Default_Handler, // IRQ 14 51 | Default_Handler, // IRQ 15 52 | Default_Handler, // IRQ 16 53 | Default_Handler, // IRQ 17 54 | Default_Handler, // IRQ 18 55 | Default_Handler, // IRQ 19 56 | Default_Handler, // IRQ 20 57 | Default_Handler, // IRQ 21 58 | Default_Handler, // IRQ 22 59 | Default_Handler, // IRQ 23 60 | Default_Handler, // IRQ 24 61 | Default_Handler, // IRQ 25 62 | Default_Handler, // IRQ 26 63 | Default_Handler, // IRQ 27 64 | Default_Handler, // IRQ 28 65 | Default_Handler, // IRQ 29 66 | Default_Handler, // IRQ 31 67 | }; 68 | -------------------------------------------------------------------------------- /part_4/sect_1/include/knldef.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef KNLDEF_H 3 | #define KNLDEF_H 4 | /* 5 | *** Try Kernel 6 | * カーネル内部共通定義 7 | */ 8 | 9 | /* タスク状態 */ 10 | typedef enum { 11 | TS_NONEXIST = 0, /* 未登録 */ 12 | TS_READY = 1, /* 実行状態 or 実行可能状態 */ 13 | TS_WAIT = 2, /* 待ち状態 */ 14 | TS_DORMANT = 8 /* 休止状態 */ 15 | } TSTAT; 16 | 17 | /* タスクの待ち要因 */ 18 | typedef enum { 19 | TWFCT_NON = 0, /* 無し */ 20 | TWFCT_DLY = 1, /* tk_dly_tskによる時間待ち */ 21 | TWFCT_SLP = 2, /* tk_slp_tskによる起床待ち */ 22 | } TWFCT; 23 | 24 | /* TCB(Task Control Block)定義 */ 25 | typedef struct st_tcb { 26 | void *context; /* コンテキスト情報へのポインタ */ 27 | 28 | /* キュー用ポインタ */ 29 | struct st_tcb *pre; /* 一つ前の要素 */ 30 | struct st_tcb *next; /* 一つ後の要素 */ 31 | 32 | /* タスク情報 */ 33 | TSTAT state; /* タスク状態 */ 34 | FP tskadr; /* 実行開始アドレス */ 35 | PRI itskpri; /* 実行優先度 */ 36 | void *stkadr; /* スタックのアドレス */ 37 | SZ stksz; /* スタックのサイズ */ 38 | INT wupcnt; /* 起床要求数 */ 39 | 40 | /* 時間待ち情報 */ 41 | TWFCT waifct; /* 待ち要因 */ 42 | RELTIM waitim; /* 待ち時間 */ 43 | ER *waierr; /* 待ち解除のエラーコード */ 44 | } TCB; 45 | 46 | extern TCB tcb_tbl[]; /* TCBテーブル */ 47 | extern TCB *ready_queue[]; /* タスクの実行待ち行列(優先度毎) */ 48 | extern TCB *cur_task; /* 実行中のタスク */ 49 | extern TCB *sche_task; /* 次に実行するタスク */ 50 | extern TCB *wait_queue; /* タスクの時間待ち行列 */ 51 | 52 | /* グローバル関数 */ 53 | extern void Reset_Handler(void); /* リセットハンドラ */ 54 | extern void dispatch_entry(void); /* ディスパッチャ */ 55 | extern void systimer_handler(void); /* システムタイマ割込みハンドラ */ 56 | 57 | /* ディスパッチャの呼出し */ 58 | #define SCB_ICSR 0xE000ED04 /* 割込み制御ステートレジスタのアドレス */ 59 | #define ICSR_PENDSVSET (1<<28) /* PendSV set-pending ビット */ 60 | static inline void dispatch( void ) 61 | { 62 | out_w(SCB_ICSR, ICSR_PENDSVSET); /* PendSV例外を発生 */ 63 | } 64 | 65 | extern void scheduler(void); /* スケジューラ */ 66 | 67 | extern void *make_context( UW *sp, UINT ssize, void (*fp)()); /* タスクコンテキストの作成*/ 68 | 69 | /* タスクの待ち行列操作関数 */ 70 | extern void tqueue_add_entry(TCB **queue, TCB *tcb); /* エントリ追加関数 */ 71 | extern void tqueue_remove_top(TCB **queue); /* 先頭エントリ削除関数 */ 72 | extern void tqueue_remove_entry(TCB **queue, TCB *tcb); /* エントリ削除関数 */ 73 | 74 | /* OSメイン関数 */ 75 | extern int main(void); 76 | 77 | /* ユーザメイン関数 */ 78 | extern int usermain(void); 79 | 80 | #endif /* KNLDEF_H */ -------------------------------------------------------------------------------- /part_3/sect_1/boot/vector_tbl.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 例外ベクターテーブル 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | extern void dispatch_entry(void); /* ディスパッチャ */ 12 | /* デフォルトハンドラ */ 13 | void Default_Handler(void) 14 | { 15 | while(1); 16 | } 17 | 18 | /* 例外ベクターテーブル */ 19 | void (* const vector_tbl[])() __attribute__((section(".vector"))) = { 20 | (void(*)()) (INITIAL_SP), // 0: Top of Stack 21 | Reset_Handler, // 1: Reset 22 | Default_Handler, // 2: NMI 23 | Default_Handler, // 3: Hard Fault 24 | 0, // 4: 未使用 25 | 0, // 5: 未使用 26 | 0, // 6: 未使用 27 | 0, // 7: 未使用 28 | 0, // 8: 未使用 29 | 0, // 9: 未使用 30 | 0, // 10: 未使用 31 | Default_Handler, // 11: Svcall 32 | 0, // 12: 未使用 33 | 0, // 13: 未使用 34 | dispatch_entry, // 14: Pend SV 35 | Default_Handler, // 15: Systick 36 | Default_Handler, // IRQ 0 37 | Default_Handler, // IRQ 1 38 | Default_Handler, // IRQ 2 39 | Default_Handler, // IRQ 3 40 | Default_Handler, // IRQ 4 41 | Default_Handler, // IRQ 5 42 | Default_Handler, // IRQ 6 43 | Default_Handler, // IRQ 7 44 | Default_Handler, // IRQ 8 45 | Default_Handler, // IRQ 9 46 | Default_Handler, // IRQ 10 47 | Default_Handler, // IRQ 11 48 | Default_Handler, // IRQ 12 49 | Default_Handler, // IRQ 13 50 | Default_Handler, // IRQ 14 51 | Default_Handler, // IRQ 15 52 | Default_Handler, // IRQ 16 53 | Default_Handler, // IRQ 17 54 | Default_Handler, // IRQ 18 55 | Default_Handler, // IRQ 19 56 | Default_Handler, // IRQ 20 57 | Default_Handler, // IRQ 21 58 | Default_Handler, // IRQ 22 59 | Default_Handler, // IRQ 23 60 | Default_Handler, // IRQ 24 61 | Default_Handler, // IRQ 25 62 | Default_Handler, // IRQ 26 63 | Default_Handler, // IRQ 27 64 | Default_Handler, // IRQ 28 65 | Default_Handler, // IRQ 29 66 | Default_Handler, // IRQ 31 67 | }; 68 | -------------------------------------------------------------------------------- /part_3/sect_2/boot/vector_tbl.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 例外ベクターテーブル 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | extern void dispatch_entry(void); /* ディスパッチャ */ 12 | /* デフォルトハンドラ */ 13 | void Default_Handler(void) 14 | { 15 | while(1); 16 | } 17 | 18 | /* 例外ベクターテーブル */ 19 | void (* const vector_tbl[])() __attribute__((section(".vector"))) = { 20 | (void(*)()) (INITIAL_SP), // 0: Top of Stack 21 | Reset_Handler, // 1: Reset 22 | Default_Handler, // 2: NMI 23 | Default_Handler, // 3: Hard Fault 24 | 0, // 4: 未使用 25 | 0, // 5: 未使用 26 | 0, // 6: 未使用 27 | 0, // 7: 未使用 28 | 0, // 8: 未使用 29 | 0, // 9: 未使用 30 | 0, // 10: 未使用 31 | Default_Handler, // 11: Svcall 32 | 0, // 12: 未使用 33 | 0, // 13: 未使用 34 | dispatch_entry, // 14: Pend SV 35 | Default_Handler, // 15: Systick 36 | Default_Handler, // IRQ 0 37 | Default_Handler, // IRQ 1 38 | Default_Handler, // IRQ 2 39 | Default_Handler, // IRQ 3 40 | Default_Handler, // IRQ 4 41 | Default_Handler, // IRQ 5 42 | Default_Handler, // IRQ 6 43 | Default_Handler, // IRQ 7 44 | Default_Handler, // IRQ 8 45 | Default_Handler, // IRQ 9 46 | Default_Handler, // IRQ 10 47 | Default_Handler, // IRQ 11 48 | Default_Handler, // IRQ 12 49 | Default_Handler, // IRQ 13 50 | Default_Handler, // IRQ 14 51 | Default_Handler, // IRQ 15 52 | Default_Handler, // IRQ 16 53 | Default_Handler, // IRQ 17 54 | Default_Handler, // IRQ 18 55 | Default_Handler, // IRQ 19 56 | Default_Handler, // IRQ 20 57 | Default_Handler, // IRQ 21 58 | Default_Handler, // IRQ 22 59 | Default_Handler, // IRQ 23 60 | Default_Handler, // IRQ 24 61 | Default_Handler, // IRQ 25 62 | Default_Handler, // IRQ 26 63 | Default_Handler, // IRQ 27 64 | Default_Handler, // IRQ 28 65 | Default_Handler, // IRQ 29 66 | Default_Handler, // IRQ 31 67 | }; 68 | -------------------------------------------------------------------------------- /part_3/sect_3/boot/vector_tbl.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 例外ベクターテーブル 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | extern void dispatch_entry(void); /* ディスパッチャ */ 12 | /* デフォルトハンドラ */ 13 | void Default_Handler(void) 14 | { 15 | while(1); 16 | } 17 | 18 | /* 例外ベクターテーブル */ 19 | void (* const vector_tbl[])() __attribute__((section(".vector"))) = { 20 | (void(*)()) (INITIAL_SP), // 0: Top of Stack 21 | Reset_Handler, // 1: Reset 22 | Default_Handler, // 2: NMI 23 | Default_Handler, // 3: Hard Fault 24 | 0, // 4: 未使用 25 | 0, // 5: 未使用 26 | 0, // 6: 未使用 27 | 0, // 7: 未使用 28 | 0, // 8: 未使用 29 | 0, // 9: 未使用 30 | 0, // 10: 未使用 31 | Default_Handler, // 11: Svcall 32 | 0, // 12: 未使用 33 | 0, // 13: 未使用 34 | dispatch_entry, // 14: Pend SV 35 | systimer_handler, // 15: Systick 36 | Default_Handler, // IRQ 0 37 | Default_Handler, // IRQ 1 38 | Default_Handler, // IRQ 2 39 | Default_Handler, // IRQ 3 40 | Default_Handler, // IRQ 4 41 | Default_Handler, // IRQ 5 42 | Default_Handler, // IRQ 6 43 | Default_Handler, // IRQ 7 44 | Default_Handler, // IRQ 8 45 | Default_Handler, // IRQ 9 46 | Default_Handler, // IRQ 10 47 | Default_Handler, // IRQ 11 48 | Default_Handler, // IRQ 12 49 | Default_Handler, // IRQ 13 50 | Default_Handler, // IRQ 14 51 | Default_Handler, // IRQ 15 52 | Default_Handler, // IRQ 16 53 | Default_Handler, // IRQ 17 54 | Default_Handler, // IRQ 18 55 | Default_Handler, // IRQ 19 56 | Default_Handler, // IRQ 20 57 | Default_Handler, // IRQ 21 58 | Default_Handler, // IRQ 22 59 | Default_Handler, // IRQ 23 60 | Default_Handler, // IRQ 24 61 | Default_Handler, // IRQ 25 62 | Default_Handler, // IRQ 26 63 | Default_Handler, // IRQ 27 64 | Default_Handler, // IRQ 28 65 | Default_Handler, // IRQ 29 66 | Default_Handler, // IRQ 31 67 | }; 68 | -------------------------------------------------------------------------------- /part_4/sect_1/boot/vector_tbl.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 例外ベクターテーブル 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | extern void dispatch_entry(void); /* ディスパッチャ */ 12 | /* デフォルトハンドラ */ 13 | void Default_Handler(void) 14 | { 15 | while(1); 16 | } 17 | 18 | /* 例外ベクターテーブル */ 19 | void (* const vector_tbl[])() __attribute__((section(".vector"))) = { 20 | (void(*)()) (INITIAL_SP), // 0: Top of Stack 21 | Reset_Handler, // 1: Reset 22 | Default_Handler, // 2: NMI 23 | Default_Handler, // 3: Hard Fault 24 | 0, // 4: 未使用 25 | 0, // 5: 未使用 26 | 0, // 6: 未使用 27 | 0, // 7: 未使用 28 | 0, // 8: 未使用 29 | 0, // 9: 未使用 30 | 0, // 10: 未使用 31 | Default_Handler, // 11: Svcall 32 | 0, // 12: 未使用 33 | 0, // 13: 未使用 34 | dispatch_entry, // 14: Pend SV 35 | systimer_handler, // 15: Systick 36 | Default_Handler, // IRQ 0 37 | Default_Handler, // IRQ 1 38 | Default_Handler, // IRQ 2 39 | Default_Handler, // IRQ 3 40 | Default_Handler, // IRQ 4 41 | Default_Handler, // IRQ 5 42 | Default_Handler, // IRQ 6 43 | Default_Handler, // IRQ 7 44 | Default_Handler, // IRQ 8 45 | Default_Handler, // IRQ 9 46 | Default_Handler, // IRQ 10 47 | Default_Handler, // IRQ 11 48 | Default_Handler, // IRQ 12 49 | Default_Handler, // IRQ 13 50 | Default_Handler, // IRQ 14 51 | Default_Handler, // IRQ 15 52 | Default_Handler, // IRQ 16 53 | Default_Handler, // IRQ 17 54 | Default_Handler, // IRQ 18 55 | Default_Handler, // IRQ 19 56 | Default_Handler, // IRQ 20 57 | Default_Handler, // IRQ 21 58 | Default_Handler, // IRQ 22 59 | Default_Handler, // IRQ 23 60 | Default_Handler, // IRQ 24 61 | Default_Handler, // IRQ 25 62 | Default_Handler, // IRQ 26 63 | Default_Handler, // IRQ 27 64 | Default_Handler, // IRQ 28 65 | Default_Handler, // IRQ 29 66 | Default_Handler, // IRQ 31 67 | }; 68 | -------------------------------------------------------------------------------- /part_4/sect_2/boot/vector_tbl.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 例外ベクターテーブル 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | extern void dispatch_entry(void); /* ディスパッチャ */ 12 | /* デフォルトハンドラ */ 13 | void Default_Handler(void) 14 | { 15 | while(1); 16 | } 17 | 18 | /* 例外ベクターテーブル */ 19 | void (* const vector_tbl[])() __attribute__((section(".vector"))) = { 20 | (void(*)()) (INITIAL_SP), // 0: Top of Stack 21 | Reset_Handler, // 1: Reset 22 | Default_Handler, // 2: NMI 23 | Default_Handler, // 3: Hard Fault 24 | 0, // 4: 未使用 25 | 0, // 5: 未使用 26 | 0, // 6: 未使用 27 | 0, // 7: 未使用 28 | 0, // 8: 未使用 29 | 0, // 9: 未使用 30 | 0, // 10: 未使用 31 | Default_Handler, // 11: Svcall 32 | 0, // 12: 未使用 33 | 0, // 13: 未使用 34 | dispatch_entry, // 14: Pend SV 35 | systimer_handler, // 15: Systick 36 | Default_Handler, // IRQ 0 37 | Default_Handler, // IRQ 1 38 | Default_Handler, // IRQ 2 39 | Default_Handler, // IRQ 3 40 | Default_Handler, // IRQ 4 41 | Default_Handler, // IRQ 5 42 | Default_Handler, // IRQ 6 43 | Default_Handler, // IRQ 7 44 | Default_Handler, // IRQ 8 45 | Default_Handler, // IRQ 9 46 | Default_Handler, // IRQ 10 47 | Default_Handler, // IRQ 11 48 | Default_Handler, // IRQ 12 49 | Default_Handler, // IRQ 13 50 | Default_Handler, // IRQ 14 51 | Default_Handler, // IRQ 15 52 | Default_Handler, // IRQ 16 53 | Default_Handler, // IRQ 17 54 | Default_Handler, // IRQ 18 55 | Default_Handler, // IRQ 19 56 | Default_Handler, // IRQ 20 57 | Default_Handler, // IRQ 21 58 | Default_Handler, // IRQ 22 59 | Default_Handler, // IRQ 23 60 | Default_Handler, // IRQ 24 61 | Default_Handler, // IRQ 25 62 | Default_Handler, // IRQ 26 63 | Default_Handler, // IRQ 27 64 | Default_Handler, // IRQ 28 65 | Default_Handler, // IRQ 29 66 | Default_Handler, // IRQ 31 67 | }; 68 | -------------------------------------------------------------------------------- /part_4/sect_3/boot/vector_tbl.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * 例外ベクターテーブル 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | extern void dispatch_entry(void); /* ディスパッチャ */ 12 | /* デフォルトハンドラ */ 13 | void Default_Handler(void) 14 | { 15 | while(1); 16 | } 17 | 18 | /* 例外ベクターテーブル */ 19 | void (* const vector_tbl[])() __attribute__((section(".vector"))) = { 20 | (void(*)()) (INITIAL_SP), // 0: Top of Stack 21 | Reset_Handler, // 1: Reset 22 | Default_Handler, // 2: NMI 23 | Default_Handler, // 3: Hard Fault 24 | 0, // 4: 未使用 25 | 0, // 5: 未使用 26 | 0, // 6: 未使用 27 | 0, // 7: 未使用 28 | 0, // 8: 未使用 29 | 0, // 9: 未使用 30 | 0, // 10: 未使用 31 | Default_Handler, // 11: Svcall 32 | 0, // 12: 未使用 33 | 0, // 13: 未使用 34 | dispatch_entry, // 14: Pend SV 35 | systimer_handler, // 15: Systick 36 | Default_Handler, // IRQ 0 37 | Default_Handler, // IRQ 1 38 | Default_Handler, // IRQ 2 39 | Default_Handler, // IRQ 3 40 | Default_Handler, // IRQ 4 41 | Default_Handler, // IRQ 5 42 | Default_Handler, // IRQ 6 43 | Default_Handler, // IRQ 7 44 | Default_Handler, // IRQ 8 45 | Default_Handler, // IRQ 9 46 | Default_Handler, // IRQ 10 47 | Default_Handler, // IRQ 11 48 | Default_Handler, // IRQ 12 49 | Default_Handler, // IRQ 13 50 | Default_Handler, // IRQ 14 51 | Default_Handler, // IRQ 15 52 | Default_Handler, // IRQ 16 53 | Default_Handler, // IRQ 17 54 | Default_Handler, // IRQ 18 55 | Default_Handler, // IRQ 19 56 | Default_Handler, // IRQ 20 57 | Default_Handler, // IRQ 21 58 | Default_Handler, // IRQ 22 59 | Default_Handler, // IRQ 23 60 | Default_Handler, // IRQ 24 61 | Default_Handler, // IRQ 25 62 | Default_Handler, // IRQ 26 63 | Default_Handler, // IRQ 27 64 | Default_Handler, // IRQ 28 65 | Default_Handler, // IRQ 29 66 | Default_Handler, // IRQ 31 67 | }; 68 | -------------------------------------------------------------------------------- /part_4/sect_3/include/apidef.h: -------------------------------------------------------------------------------- 1 | #ifndef APIDEF_H 2 | #define APIDEF_H 3 | /* 4 | *** Try Kernel 5 | * API定義 6 | */ 7 | 8 | /* タイムアウト時間 */ 9 | #define TMO_POL (0) // タイムアウト時間 0 10 | #define TMO_FEVR (-1) // 無限待ち 11 | 12 | /* 待ち関連属性 */ 13 | #define TA_TFIFO 0x00000000 // 待ちタスクをFIFO順で管理 14 | #define TA_TPRI 0x00000001 // 待ちタスクを優先度順で管理 15 | #define TA_FIRST 0x00000000 // 待ち行列先頭のタスクを優先 16 | #define TA_CNT 0x00000002 // 要求数の少ないタスクを優先 17 | 18 | /*タスク生成情報 */ 19 | typedef struct { 20 | ATR tskatr; // タスク属性 21 | FP task; // タスク起動アドレス 22 | PRI itskpri; // タスク優先度 23 | SZ stksz; // スタックサイズ 24 | void *bufptr; // スタックのバッファポインタ 25 | } T_CTSK; 26 | 27 | /* タスク属性 */ 28 | #define TA_HLNG 0x0000001 // タスクが高級言語で記述 29 | #define TA_USERBUF 0x0000020 // スタック領域としてユーザが指定した領域を使用 30 | #define TA_RNG0 0x0000000 // 保護レベル0 31 | #define TA_RNG1 0x0000100 // 保護レベル1 32 | #define TA_RNG2 0x0000200 // 保護レベル2 33 | #define TA_RNG3 0x0000300 // 保護レベル3 34 | 35 | /* タスクの待ち属性 */ 36 | #define TA_TFIFO 0x00000000 // 待ちタスクをFIFO順で管理 37 | #define TA_TPRI 0x00000001 // 待ちタスクを優先度順で管理 38 | #define TA_FIRST 0x00000000 // 待ち行列先頭のタスクを優先 39 | #define TA_CNT 0x00000002 // 要求数の少ないタスクを優先 40 | #define TA_WSGL 0x00000000 // 複数タスクの待ちを許さない 41 | #define TA_WMUL 0x00000008 // 複数タスクの待ちを許す 42 | 43 | /* タスク管理API */ 44 | ID tk_cre_tsk( const T_CTSK *pk_ctsk ); 45 | ER tk_sta_tsk( ID tskid, INT stacd ); 46 | void tk_ext_tsk( void ); 47 | 48 | /* タスク付属同期API */ 49 | ER tk_dly_tsk( RELTIM dlytim ); 50 | ER tk_slp_tsk( TMO tmout ); 51 | ER tk_wup_tsk( ID tskid ); 52 | 53 | /* イベントフラグ生成情報 */ 54 | typedef struct t_cflg { 55 | ATR flgatr; // イベントフラグ属性 56 | UINT iflgptn; // イベントフラグ初期値 57 | } T_CFLG; 58 | 59 | /* イベントフラグ API */ 60 | ID tk_cre_flg( const T_CFLG *pk_cflg ); 61 | ER tk_set_flg( ID flgid, UINT setptn ); 62 | ER tk_clr_flg( ID flgid, UINT clrptn ); 63 | 64 | #define TWF_ANDW 0x00000000U // AND待ち 65 | #define TWF_ORW 0x00000001U // OR待ち 66 | #define TWF_CLR 0x00000010U // 全ビットのクリア 67 | #define TWF_BITCLR 0x00000020U // 条件ビットのみクリア 68 | 69 | ER tk_wai_flg( ID flgid, UINT waiptn, UINT wfmode, UINT *p_flgptn, TMO tmout ); 70 | 71 | /* セマフォ生成情報 */ 72 | typedef struct t_csem { 73 | ATR sematr; // セマフォ属性 74 | INT isemcnt; // セマフォ資源数の初期値 75 | INT maxsem; // セマフォ資源数の最大値 76 | } T_CSEM; 77 | 78 | /* セマフォ API */ 79 | ID tk_cre_sem( const T_CSEM *pk_csem ); 80 | ER tk_sig_sem( ID semid, INT cnt ); 81 | ER tk_wai_sem( ID semid, INT cnt, TMO tmout ); 82 | 83 | #endif /* APIDEF_H */ -------------------------------------------------------------------------------- /part_5/kernel/task_sync.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスク付属同期機能 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | /* タスクの実行遅延 API */ 10 | ER tk_dly_tsk( RELTIM dlytim ) 11 | { 12 | UINT intsts; 13 | ER err = E_OK; 14 | 15 | DI(intsts); // 割込みの禁止 16 | if(dlytim > 0) { 17 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); // タスクをレディキューから外す 18 | 19 | /* TCBの各種情報を変更する */ 20 | cur_task->state = TS_WAIT; // タスクの状態を待ち状態に変更 21 | cur_task->waifct = TWFCT_DLY; // 待ち要因を設定 22 | cur_task->waitim = dlytim + TIMER_PERIOD; // 待ち時間を設定 23 | cur_task->waierr = &err; // 待ち解除時のエラーコード 24 | 25 | tqueue_add_entry(&wait_queue, cur_task); // タスクをウェイトキューに繋ぐ 26 | scheduler(); // スケジューラの実行 27 | } 28 | EI(intsts); // 割込みの許可 29 | return err; 30 | } 31 | 32 | /* タスク起床待ちAPI */ 33 | ER tk_slp_tsk( TMO tmout ) 34 | { 35 | UINT intsts; 36 | ER err = E_OK; 37 | 38 | DI(intsts); // 割込みの禁止 39 | if ( cur_task->wupcnt > 0 ) { // 起床要求有り 40 | cur_task->wupcnt--; 41 | } else { // 起床要求無し 42 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); // タスクをレディキューから外す 43 | 44 | /* TCBの各種情報を変更する */ 45 | cur_task->state = TS_WAIT; // タスクの状態を待ち状態に変更 46 | cur_task->waifct = TWFCT_SLP; // 待ち要因を設定 47 | cur_task->waitim = (tmout==TMO_FEVR)?tmout:(tmout+TIMER_PERIOD); // 待ち時間を設定 48 | cur_task->waierr = &err; 49 | 50 | tqueue_add_entry(&wait_queue, cur_task); // タスクをウェイトキューに繋ぐ 51 | scheduler(); // スケジューラの実行 52 | } 53 | EI(intsts); // 割込みの許可 54 | return err; 55 | } 56 | 57 | /* タスクの起床 API */ 58 | ER tk_wup_tsk( ID tskid ) 59 | { 60 | TCB *tcb; 61 | UINT intsts; 62 | ER err = E_OK; 63 | 64 | if(tskid <= 0 || tskid > CNF_MAX_TSKID) return E_ID; /* ID番号チェック */ 65 | 66 | DI(intsts); // 割込みの禁止 67 | tcb = &tcb_tbl[tskid-1]; 68 | if((tcb->state == TS_WAIT) && (tcb->waifct == TWFCT_SLP)) { // tk_slp_tskで待ち状態か? 69 | 70 | tqueue_remove_entry(&wait_queue, tcb); // タスクをウェイトキューから外す 71 | 72 | /* TCBの各種情報を変更する */ 73 | tcb->state = TS_READY; 74 | tcb->waifct = TWFCT_NON; 75 | 76 | tqueue_add_entry(&ready_queue[tcb->itskpri], tcb); // タスクをレディキューに繋ぐ 77 | scheduler(); // スケジューラの実行 78 | } else if(tcb->state == TS_READY || tcb->state == TS_WAIT) { // 実行できる状態の場合 79 | tcb->wupcnt++; // 起床要求数を増やす 80 | } else { 81 | err = E_OBJ; // 起床できるタスクの状態ではない 82 | } 83 | 84 | EI(intsts); // 割込みの許可 85 | return err; 86 | } 87 | -------------------------------------------------------------------------------- /part_4/sect_1/kernel/task_sync.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスク付属同期機能 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | /* タスクの実行遅延 API */ 10 | ER tk_dly_tsk( RELTIM dlytim ) 11 | { 12 | UINT intsts; 13 | ER err = E_OK; 14 | 15 | DI(intsts); // 割込みの禁止 16 | if(dlytim > 0) { 17 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); // タスクをレディキューから外す 18 | 19 | /* TCBの各種情報を変更する */ 20 | cur_task->state = TS_WAIT; // タスクの状態を待ち状態に変更 21 | cur_task->waifct = TWFCT_DLY; // 待ち要因を設定 22 | cur_task->waitim = dlytim + TIMER_PERIOD; // 待ち時間を設定 23 | cur_task->waierr = &err; // 待ち解除時のエラーコード 24 | 25 | tqueue_add_entry(&wait_queue, cur_task); // タスクをウェイトキューに繋ぐ 26 | scheduler(); // スケジューラの実行 27 | } 28 | EI(intsts); // 割込みの許可 29 | return err; 30 | } 31 | 32 | /* タスク起床待ちAPI */ 33 | ER tk_slp_tsk( TMO tmout ) 34 | { 35 | UINT intsts; 36 | ER err = E_OK; 37 | 38 | DI(intsts); // 割込みの禁止 39 | if ( cur_task->wupcnt > 0 ) { // 起床要求有り 40 | cur_task->wupcnt--; 41 | } else { // 起床要求無し 42 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); // タスクをレディキューから外す 43 | 44 | /* TCBの各種情報を変更する */ 45 | cur_task->state = TS_WAIT; // タスクの状態を待ち状態に変更 46 | cur_task->waifct = TWFCT_SLP; // 待ち要因を設定 47 | cur_task->waitim = (tmout==TMO_FEVR)?tmout:(tmout+TIMER_PERIOD); // 待ち時間を設定 48 | cur_task->waierr = &err; 49 | 50 | tqueue_add_entry(&wait_queue, cur_task); // タスクをウェイトキューに繋ぐ 51 | scheduler(); // スケジューラの実行 52 | } 53 | EI(intsts); // 割込みの許可 54 | return err; 55 | } 56 | 57 | /* タスクの起床 API */ 58 | ER tk_wup_tsk( ID tskid ) 59 | { 60 | TCB *tcb; 61 | UINT intsts; 62 | ER err = E_OK; 63 | 64 | if(tskid <= 0 || tskid > CNF_MAX_TSKID) return E_ID; /* ID番号チェック */ 65 | 66 | DI(intsts); // 割込みの禁止 67 | tcb = &tcb_tbl[tskid-1]; 68 | if((tcb->state == TS_WAIT) && (tcb->waifct == TWFCT_SLP)) { // tk_slp_tskで待ち状態か? 69 | 70 | tqueue_remove_entry(&wait_queue, tcb); // タスクをウェイトキューから外す 71 | 72 | /* TCBの各種情報を変更する */ 73 | tcb->state = TS_READY; 74 | tcb->waifct = TWFCT_NON; 75 | 76 | tqueue_add_entry(&ready_queue[tcb->itskpri], tcb); // タスクをレディキューに繋ぐ 77 | scheduler(); // スケジューラの実行 78 | } else if(tcb->state == TS_READY || tcb->state == TS_WAIT) { // 実行できる状態の場合 79 | tcb->wupcnt++; // 起床要求数を増やす 80 | } else { 81 | err = E_OBJ; // 起床できるタスクの状態ではない 82 | } 83 | 84 | EI(intsts); // 割込みの許可 85 | return err; 86 | } 87 | -------------------------------------------------------------------------------- /part_4/sect_2/kernel/task_sync.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスク付属同期機能 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | /* タスクの実行遅延 API */ 10 | ER tk_dly_tsk( RELTIM dlytim ) 11 | { 12 | UINT intsts; 13 | ER err = E_OK; 14 | 15 | DI(intsts); // 割込みの禁止 16 | if(dlytim > 0) { 17 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); // タスクをレディキューから外す 18 | 19 | /* TCBの各種情報を変更する */ 20 | cur_task->state = TS_WAIT; // タスクの状態を待ち状態に変更 21 | cur_task->waifct = TWFCT_DLY; // 待ち要因を設定 22 | cur_task->waitim = dlytim + TIMER_PERIOD; // 待ち時間を設定 23 | cur_task->waierr = &err; // 待ち解除時のエラーコード 24 | 25 | tqueue_add_entry(&wait_queue, cur_task); // タスクをウェイトキューに繋ぐ 26 | scheduler(); // スケジューラの実行 27 | } 28 | EI(intsts); // 割込みの許可 29 | return err; 30 | } 31 | 32 | /* タスク起床待ちAPI */ 33 | ER tk_slp_tsk( TMO tmout ) 34 | { 35 | UINT intsts; 36 | ER err = E_OK; 37 | 38 | DI(intsts); // 割込みの禁止 39 | if ( cur_task->wupcnt > 0 ) { // 起床要求有り 40 | cur_task->wupcnt--; 41 | } else { // 起床要求無し 42 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); // タスクをレディキューから外す 43 | 44 | /* TCBの各種情報を変更する */ 45 | cur_task->state = TS_WAIT; // タスクの状態を待ち状態に変更 46 | cur_task->waifct = TWFCT_SLP; // 待ち要因を設定 47 | cur_task->waitim = (tmout==TMO_FEVR)?tmout:(tmout+TIMER_PERIOD); // 待ち時間を設定 48 | cur_task->waierr = &err; 49 | 50 | tqueue_add_entry(&wait_queue, cur_task); // タスクをウェイトキューに繋ぐ 51 | scheduler(); // スケジューラの実行 52 | } 53 | EI(intsts); // 割込みの許可 54 | return err; 55 | } 56 | 57 | /* タスクの起床 API */ 58 | ER tk_wup_tsk( ID tskid ) 59 | { 60 | TCB *tcb; 61 | UINT intsts; 62 | ER err = E_OK; 63 | 64 | if(tskid <= 0 || tskid > CNF_MAX_TSKID) return E_ID; /* ID番号チェック */ 65 | 66 | DI(intsts); // 割込みの禁止 67 | tcb = &tcb_tbl[tskid-1]; 68 | if((tcb->state == TS_WAIT) && (tcb->waifct == TWFCT_SLP)) { // tk_slp_tskで待ち状態か? 69 | 70 | tqueue_remove_entry(&wait_queue, tcb); // タスクをウェイトキューから外す 71 | 72 | /* TCBの各種情報を変更する */ 73 | tcb->state = TS_READY; 74 | tcb->waifct = TWFCT_NON; 75 | 76 | tqueue_add_entry(&ready_queue[tcb->itskpri], tcb); // タスクをレディキューに繋ぐ 77 | scheduler(); // スケジューラの実行 78 | } else if(tcb->state == TS_READY || tcb->state == TS_WAIT) { // 実行できる状態の場合 79 | tcb->wupcnt++; // 起床要求数を増やす 80 | } else { 81 | err = E_OBJ; // 起床できるタスクの状態ではない 82 | } 83 | 84 | EI(intsts); // 割込みの許可 85 | return err; 86 | } 87 | -------------------------------------------------------------------------------- /part_4/sect_3/kernel/task_sync.c: -------------------------------------------------------------------------------- 1 | /* 2 | *** Try Kernel 3 | * タスク付属同期機能 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | /* タスクの実行遅延 API */ 10 | ER tk_dly_tsk( RELTIM dlytim ) 11 | { 12 | UINT intsts; 13 | ER err = E_OK; 14 | 15 | DI(intsts); // 割込みの禁止 16 | if(dlytim > 0) { 17 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); // タスクをレディキューから外す 18 | 19 | /* TCBの各種情報を変更する */ 20 | cur_task->state = TS_WAIT; // タスクの状態を待ち状態に変更 21 | cur_task->waifct = TWFCT_DLY; // 待ち要因を設定 22 | cur_task->waitim = dlytim + TIMER_PERIOD; // 待ち時間を設定 23 | cur_task->waierr = &err; // 待ち解除時のエラーコード 24 | 25 | tqueue_add_entry(&wait_queue, cur_task); // タスクをウェイトキューに繋ぐ 26 | scheduler(); // スケジューラの実行 27 | } 28 | EI(intsts); // 割込みの許可 29 | return err; 30 | } 31 | 32 | /* タスク起床待ちAPI */ 33 | ER tk_slp_tsk( TMO tmout ) 34 | { 35 | UINT intsts; 36 | ER err = E_OK; 37 | 38 | DI(intsts); // 割込みの禁止 39 | if ( cur_task->wupcnt > 0 ) { // 起床要求有り 40 | cur_task->wupcnt--; 41 | } else { // 起床要求無し 42 | tqueue_remove_top(&ready_queue[cur_task->itskpri]); // タスクをレディキューから外す 43 | 44 | /* TCBの各種情報を変更する */ 45 | cur_task->state = TS_WAIT; // タスクの状態を待ち状態に変更 46 | cur_task->waifct = TWFCT_SLP; // 待ち要因を設定 47 | cur_task->waitim = (tmout==TMO_FEVR)?tmout:(tmout+TIMER_PERIOD); // 待ち時間を設定 48 | cur_task->waierr = &err; 49 | 50 | tqueue_add_entry(&wait_queue, cur_task); // タスクをウェイトキューに繋ぐ 51 | scheduler(); // スケジューラの実行 52 | } 53 | EI(intsts); // 割込みの許可 54 | return err; 55 | } 56 | 57 | /* タスクの起床 API */ 58 | ER tk_wup_tsk( ID tskid ) 59 | { 60 | TCB *tcb; 61 | UINT intsts; 62 | ER err = E_OK; 63 | 64 | if(tskid <= 0 || tskid > CNF_MAX_TSKID) return E_ID; /* ID番号チェック */ 65 | 66 | DI(intsts); // 割込みの禁止 67 | tcb = &tcb_tbl[tskid-1]; 68 | if((tcb->state == TS_WAIT) && (tcb->waifct == TWFCT_SLP)) { // tk_slp_tskで待ち状態か? 69 | 70 | tqueue_remove_entry(&wait_queue, tcb); // タスクをウェイトキューから外す 71 | 72 | /* TCBの各種情報を変更する */ 73 | tcb->state = TS_READY; 74 | tcb->waifct = TWFCT_NON; 75 | 76 | tqueue_add_entry(&ready_queue[tcb->itskpri], tcb); // タスクをレディキューに繋ぐ 77 | scheduler(); // スケジューラの実行 78 | } else if(tcb->state == TS_READY || tcb->state == TS_WAIT) { // 実行できる状態の場合 79 | tcb->wupcnt++; // 起床要求数を増やす 80 | } else { 81 | err = E_OBJ; // 起床できるタスクの状態ではない 82 | } 83 | 84 | EI(intsts); // 割込みの許可 85 | return err; 86 | } 87 | -------------------------------------------------------------------------------- /part_5/device/adc/adc_rp2040.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "dev_adc.h" 3 | #include "adc_sysdep.h" 4 | 5 | /*---------------------------------------------------------------------- 6 | * デバイス制御データ 7 | */ 8 | typedef struct { 9 | ID semid; /* セマフォID */ 10 | UW init; /* 初期化フラグ */ 11 | UINT omode; /* オープンモード */ 12 | } T_ADC_LLDCB; 13 | static T_ADC_LLDCB ll_devcb; 14 | 15 | /*---------------------------------------------------------------------- 16 | * デバイス初期化 17 | */ 18 | static void adc_init(void) 19 | { 20 | set_w(RESETS_RESET, RESETS_RESET_ADC); 21 | clr_w(RESETS_RESET, RESETS_RESET_ADC); 22 | while((in_w(RESETS_RESET_DONE)&(RESETS_RESET_ADC))==0); 23 | 24 | /* アナログ入力端子初期化 */ 25 | /* P26 : ADC0 */ 26 | out_w(GPIO_CTRL(26),GPIO_CTRL_FUNCSEL_NULL); 27 | clr_w(GPIO(26), GPIO_IE|GPIO_PUE|GPIO_PDE); 28 | 29 | /* P27 : ADC1 */ 30 | // out_w(GPIO_CTRL(27),GPIO_CTRL_FUNCSEL_NULL); 31 | // clr_w(GPIO(27), GPIO_IE|GPIO_PUE|GPIO_PDE); 32 | 33 | /* P28 : ADC2 */ 34 | // out_w(GPIO_CTRL(28),GPIO_CTRL_FUNCSEL_NULL); 35 | // clr_w(GPIO(28), GPIO_IE|GPIO_PUE|GPIO_PDE); 36 | 37 | // out_w(GPIO_CTRL(29),GPIO_CTRL_FUNCSEL_NULL); 38 | // clr_w(GPIO(29), GPIO_IE|GPIO_PUE|GPIO_PDE); 39 | 40 | /* A/DC有効 */ 41 | set_w(ADC_CS, ADC_CS_EN); 42 | while(!(in_w(ADC_CS)&ADC_CS_READY)); 43 | } 44 | 45 | /*---------------------------------------------------------------------- 46 | * デバイスオープン関数 47 | */ 48 | ER dev_adc_open(UW unit, UINT omode) 49 | { 50 | T_CSEM csem = { 51 | .isemcnt = 1, 52 | .maxsem = 1, 53 | }; 54 | ER err; 55 | 56 | if(omode & TD_WRITE) return E_PAR; // オープンモードが書込みは不可 57 | 58 | if(ll_devcb.init == FALSE) { 59 | err = tk_cre_sem(&csem); // 排他制御用のセマフォ生成 60 | if(err < E_OK) return err; 61 | 62 | adc_init(); 63 | ll_devcb.semid = (ID)err; 64 | ll_devcb.omode = omode; 65 | ll_devcb.init = TRUE; 66 | 67 | out_w(ADC_DIV, ADC_DIV_INI); // クロック設定 68 | out_w(ADC_FCS, 1<(ADC_CH_NUM-1)) return E_PAR; 81 | if(size != 1) return E_PAR; 82 | 83 | err = tk_wai_sem( ll_devcb.semid, 1, TMO_FEVR); // 排他の開始 84 | if(err < E_OK) return err; 85 | 86 | while((in_w(ADC_CS)&ADC_CS_READY)==0); // ADCのレディ待ち 87 | 88 | out_w(ADC_CS, ch<