realtime process control with RTOS

Fork of mbed-os-example-mbed5-blinky by mbed-os-examples

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