なんと、私のブログで「共有メモリ」やら「プロセス間通信」なる言葉を使うとは、恐れを知らない素人プログラマー。だって趣味で自分使用のラズパイの話ですから、お構いなしです。

 

早めにお詫びして起きます。この投稿は無知な私が書いた物なので、全てが誤りかも知れません。

 

 

 

/*
 * zeroClock.cpp
 * 
 * プロセス間通信 共有メモリテスト
 * NTPチェック用プログラム(プロセス)が書き込んだ共有メモリに応じて表示を変える。
 * 
 * その別プロセスがntpq -p 実行結果に応じて
 * NTPサーバー参照同期中ならGを共有メモリに書き込み
 * そうでなければWを書き込む。
 * 
 * このプログラムは共有メモリを読み込んで
 * Gなら正常時計表示、Wの場合全桁ドット表示させる。
 *
 */
 
#include <iostream>
#include <pigpio.h>
#include <unistd.h>
#include <sys/shm.h>

#define H 0x1
#define L 0x0
#define SEG_ON 0x1
#define SEG_OFF 0x0

using namespace std;

int mainLoop(void);

int main(void)
{
    if(daemon(0, 0) == 0) { // デーモン関数
        mainLoop();
    } else {
        cout << "error" << endl;
    }
    return 0;
}

int mainLoop(void)
{    
    int i, j, disp;
    int num[7];
    struct timespec ts;
    struct tm lotm;
                       // 0.1秒1秒 10秒 1分 10分 1時 10時
                  // Common 1   2   3   4   5   6   7
    static int common[7] = {25, 24, 23, 18, 22, 27, 17};
                    // GPIO 25  24  23  18  22  27  17

                     // 7seg a   b   c   d   e   f  g  dp  NTP
    static int nanaseg[9] = {21, 20, 16, 26, 19, 6, 13, 5, 12};
                     // GPIO 21  20  16  26  19  6  13  5  12

    static int segdata[12][9] = { // 7セグメント & NTP用LED データ
    // a  b  c  d  e  f  g  dp NTP
      {H, H, H, H, H, H, L, L, H}, // 0
      {L, H, H, L, L, L, L, L, H}, // 1
      {H, H, L, H, H, L, H, L, H}, // 2
      {H, H, H, H, L, L, H, L, H}, // 3
      {L, H, H, L, L, H, H, L, H}, // 4
      {H, L, H, H, L, H, H, L, H}, // 5
      {H, L, H, H, H, H, H, L, H}, // 6
      {H, H, H, L, L, L, L, L, H}, // 7
      {H, H, H, H, H, H, H, L, H}, // 8
      {H, H, H, H, L, H, H, L, H}, // 9
      {L, L, L, L, L, L, L, L, H}, // Blank
      {L, L, L, L, L, L, L, H, L}, // dp
    };
    
    // pigpioライブラリ初期化
    if (gpioInitialise() < 0) exit(1);
    
    // コモン用GPIOピンをアウトプット設定
    for (i = 0; i < 7; i++) {
      gpioSetMode(common[i], PI_OUTPUT);
    }
    
    // セグメント用GPIOピンをアウトプット設定(NTP用LEDを含む)
    for (i = 0; i < 9; i++) {
      gpioSetMode(nanaseg[i], PI_OUTPUT);
    }
    
    /*
     *
     * 共有メモリ設定
     *
     */
    // 作成済みの共有メモリのIDを取得する
    const string file_path = "/home/pi/ntpCheck.dat";
    const int id = 50;

    const key_t key = ftok(file_path.c_str(), id);

    const int seg_id = shmget(key, 0, 0);
    if(seg_id == -1){
        cerr << "Failed to acquire segment" << endl;
        return EXIT_FAILURE;
    }

    // 共有メモリをプロセスにアタッチする
    char* const shared_memory = 
                reinterpret_cast<char*>(shmat(seg_id, 0, 0));
    
    
    /*
     *
     * 時刻取得及びダイナミック表示ルーチン(無限ループ)
     *
     * 時刻取得、1桁2ミリ秒表示×7、時刻取得、1桁2ミリ秒表示×7の繰り返し
     *
     * 共有メモリの文字が
     * G の場合はNTPサーバと参照同期中
     * W の場合はNTPサーバと参照同期していない
     *
     */
    while (1) {
      // 共有メモリから読み込んだ文字により表示を変える
      switch (*shared_memory) {
        case 0x47: // G (Good) G ASCII Code // G の場合正常時計表示
          clock_gettime(CLOCK_REALTIME, &ts); // 時刻の取得
          localtime_r(&ts.tv_sec, &lotm); // ローカル時間に変換
          num[0] = ts.tv_nsec / 100000000;    //0.1秒の桁取得
          num[1] = lotm.tm_sec % 10;          //  1秒の桁取得
          num[2] = lotm.tm_sec / 10;          // 10秒の桁取得
          num[3] = lotm.tm_min % 10;          //  1分の桁取得
          num[4] = lotm.tm_min / 10;          // 10分の桁取得
          num[5] = lotm.tm_hour % 10;         //  1時の桁取得
          num[6] = lotm.tm_hour / 10;         // 10時の桁取得
          disp = 2000; // 2ミリ秒
          break;
        case 0x57: // W (Wait) 0x57 ASCII Code // W の場合ドット表示
          for (i = 0; i < 7; i++) {
            num[i] = 11; // 全桁 D.P & NTP用LED消灯 セット
          }
          disp = 100000; // 100ミリ秒
          break;
      }
      for (j = 0; j < 7; j++) { // 7桁ダイナミック表示ルーチン
        for (i = 0; i < 9; i++) { // 7セグメントデータセット
          gpioWrite(nanaseg[i], segdata[num[j]][i]);
        }
        gpioWrite(common[j], SEG_ON);   // 7セグLED点灯
        gpioDelay(disp);                // 点灯維持
        gpioWrite(common[j], SEG_OFF);  // 7セグLED消灯
      }
    }
    //  ここから以降は無限ループに含まれないので不要?
    
    // pigpioライブラリ終了処理
    gpioTerminate();

    // 共有メモリをプロセスから切り離す
    shmdt(shared_memory);
    
    return 0;
}

2 Thoughts on “共有メモリでプロセス間通信して

  1. JN1JTN on 2020年1月19日 at 23:21 said:

    とうとうプログラマーですね!!!

    • JM1LXS on 2020年1月20日 at 23:42 said:

      生意気でしょ?

      期待通りに動いた時は嬉しいですね。

      それまでは超苦労しますけど。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Post Navigation