realtime process control with RTOS
Fork of mbed-os-example-mbed5-blinky by
Diff: main.cpp
- Revision:
- 23:bc5ad77d56bb
- Parent:
- 22:f0164a2a09b0
- Child:
- 24:e414c7234bcc
--- a/main.cpp Thu Oct 04 03:23:22 2018 +0000 +++ b/main.cpp Sun Oct 07 12:51:03 2018 +0000 @@ -7,12 +7,12 @@ // #include "mbed.h" -const int DELTA_T = 1000; // mainスレッドの時間間隔の設定[ms](デフォルトは1ms) +const int DELTA_T = 1; // mainスレッドの時間間隔の設定[ms](デフォルトは1ms) int delta_t = DELTA_T; int qbits = 6; // 量子化シフト値 DigitalOut led1(LED1); DigitalOut led2(LED2); -DigitalOut led3(LED3); +//PwmOut led3(LED3); DigitalOut led4(LED4); // p11,12 サンプリング周期設定ピン(デフォルトは0) @@ -37,41 +37,85 @@ PwmOut squarewave(p23); PwmOut pulsewave(p24); +const int SIG_ST = 0x1; // signal番号 +Thread* sthread; +EventQueue queue; +int id = 0; + // サンプリング処理をするスレッド(時間管理された処理) -void sampling_job(const void* arg) { +void sampling_job(void* v) +{ unsigned short a_data = ain.read_u16(); // AD入力(ADは12ビット) aout.write_u16((a_data>>qbits)<<qbits);// DA出力(量子化粒度はピンにより設定) - led4=!led4; + led4 = !led4; +} + +void setup_thread(void const* arg) // 設定処理をするスレッド +{ + while(true) { + Thread::signal_wait(SIG_ST); // シグナルを待つ + + // ピンの状態を読み取り,2ビット値に変換 + int s_msb = 0, s_lsb = 0; + int q_msb = 0, q_lsb = 0; + const int RETRY = 1000; + for(int i=0; i<RETRY; i++) { + s_msb += samplingtime_MSB; + s_lsb += samplingtime_LSB; + q_msb += quantization_MSB; + q_lsb += quantization_LSB; + } + s_msb /= RETRY; s_lsb /= RETRY; + q_msb /= RETRY; q_lsb /= RETRY; + + int samplingtime = (s_msb<<1)&0x2 | s_lsb&0x1; + + // 制御周期を10^nとする(n=0:1s, n=1:0.1s, n=2:0.01s, n=3:0.001s) + delta_t = (int)pow(10.0,(double)samplingtime); + + + squarewave.period_ms(delta_t); // 方形波の周期の設定 + pulsewave.period_ms(delta_t); // パルス波の周期の設定 + squarewave.write(0.5F); // duty比 + pulsewave.write(0.1F); // duty比 + + // 量子化設定ピン(p13,14)の設定を読んで量子化粒度を決定する + // 設定ピンの状態を読み取り,2ビット値に変換 + int quantization = (q_msb<<1)&0x2 | q_lsb&0x1; + qbits = 6+quantization*4; // 量子化サイズの決定 + // (デジタル出力時の量子化サイズは 0:1024, 1:256, 2:64, 3:16 steps) + + + queue.cancel(id); + printf("delta_t = %d, qbits = %d\n", delta_t, qbits); + id = queue.call_every(delta_t, sampling_job, (void*)0); + } } // 量子化粒度設定ハンドラ -void qsize_handler(void) { - // 量子化設定ピン(p13,14)の設定を読んで量子化粒度を決定する - // 設定ピンの状態を読み取り,2ビット値に変換 - int quantization = (quantization_MSB<<1)&0x2|quantization_LSB&0x1; - qbits = 6+quantization*4; // 量子化サイズの決定 - // (デジタル出力時の量子化サイズは 0:1024, 1:256, 2:64, 3:16 steps) +void qsize_handler(void) +{ + sthread->signal_set(SIG_ST); // スレッドへ再開シグナルを送る } // サンプリングタイム設定割り込みハンドラ...時間設定ピンの状態が変化した時に呼び出される -void pinstate_handler(void) { - // ピンの状態を読み取り,2ビット値に変換 - int samplingtime = (samplingtime_MSB<<1)&0x2|samplingtime_LSB&0x1; - // 制御周期を10^nとする(n=0:1s, n=1:0.1s, n=2:0.01s, n=3:0.001s) - delta_t = (int)pow(10.0,(double)samplingtime); - squarewave.period_ms(delta_t); // 方形波の周期の設定 - pulsewave.period_ms(delta_t); // パルス波の周期の設定 - squarewave.write(0.5F); // duty比 - pulsewave.write(0.1F); // duty比 +void pinstate_handler(void) +{ + sthread->signal_set(SIG_ST); // スレッドへ再開シグナルを送る } // デジタル入力割り込みハンドラ...デジタル入力信号の状態が変化した時に呼び出される -void din_handler(void) { +void din_handler(void) +{ led1 = din1; // ピンの状態をそのままLEDの点灯状態にする led2 = din2; } -int main() { +int main() +{ + sthread = new Thread(setup_thread); // 設定用スレッドを起動 + + squarewave.period_ms(delta_t); // 初期周期の設定 pulsewave.period_ms(delta_t); // 初期周期の設定 squarewave.write(0.5F); // 初期duty比(方形波=50%) @@ -82,23 +126,37 @@ samplingtime_MSB.rise(pinstate_handler);// 周期設定ハンドラの設定. samplingtime_MSB.fall(pinstate_handler);// 設定ピンの状態変化で samplingtime_MSB.enable_irq(); - + samplingtime_LSB.disable_irq(); samplingtime_LSB.mode(PullDown); samplingtime_LSB.rise(pinstate_handler);// ハンドラが呼び出される samplingtime_LSB.fall(pinstate_handler);// ようにする samplingtime_LSB.enable_irq(); - + + quantization_MSB.disable_irq(); + quantization_MSB.mode(PullDown); quantization_MSB.rise(qsize_handler); // 量子化粒度設定ハンドラの設定 quantization_MSB.fall(qsize_handler); + quantization_MSB.enable_irq(); + + quantization_LSB.disable_irq(); + quantization_LSB.mode(PullDown); quantization_LSB.rise(qsize_handler); quantization_LSB.fall(qsize_handler); + quantization_LSB.enable_irq(); + + din1.disable_irq(); + din1.mode(PullDown); din1.rise(&din_handler); // デジタル入力ハンドラの設定 din1.fall(&din_handler); // din1,2の状態変化でハンドラ + din1.enable_irq(); + + din2.disable_irq(); + din2.mode(PullDown); din2.rise(&din_handler); // が呼ばれる din2.fall(&din_handler); + din2.enable_irq(); - EventQueue queue; - queue.call_every(DELTA_T, sampling_job, (void*)0); + id = queue.call_every(delta_t, sampling_job, (void*)0); queue.dispatch(); } \ No newline at end of file