アットウィキロゴ

省エネ対策

 地球のために、今何かしよう! (..って言うか、本当は自分のためなんだが。)

 タイマなどでインターバルに割り込みハンドラを起動する様な処理では、main関数の中のwhile(1)の無限ループの中身が空になる事がある。

#include "monitor.h"
......

#pragma interrupt(timer_handler)
void timer_handler()
{
    ....
}

int main()
{
  ......

    while(1)
    {
      // 空っぽ
    }
}

 これって意味あるんだろうか?

 仮に、この無限ループが無かったら、いったい何が起こるんだろうか。
   ...という疑問に答える前に、mainも関数である事は、C言語のプログラマにとっては常識である。関数である以上は、どこかから呼び出されているはずだ。いったい誰が呼び出しているのかと思った皆さん。 あなたは偉い!
 本稿のプログラミングでは、monitor.hというヘッダファイルを必ずincludeしている。これは、ルネサスエレクトロニクスが開発したH8用モニタを使うために必要なもので、この中身を見てみると、

#include < machine.h >

#define  printf  ((int (*)(const char *,...))0x00002b52)
#define  scanf  ((int (*)(const char *,...))0x00002ba4)

#pragma section VECTBL

void PowerON_Reset();

typedef void (*fp)(void);

const fp VectorTable[] =     // ベクタテーブルの定義
{
    (fp)PowerON_Reset,       //  vector  0 Reset

  ...  略 ...

    (fp)0L                   //  vector 60 ADI
};

#pragma section /*
                          * セクション名を省略すると、プログラム領域はP、定数領域はC、
                          * 初期化データ領域はR,D(初期値のあるグローバル変数)、
                          * 未初期化データ領域はB(初期値の無いグローバル変数)となる。
                          */            

int main(void);

__entry voidPowerON_Reset(void)
{
   main();    //スタートルーチンを呼び出し
    printf("program ended. push reset");
   or_ccr(0x80);  // ソフトウエアスタンバイモードに遷移
                         // スリープモードにする場合は、and_ccr(0x7F);とする。
   sleep();    

}

   なんていう風になっている。一番下を見てみると、PowerOnReset()と言う関数があって、その中にmain();と言う記述が見つかる。 
 要するに、main()はPowerOnResetから呼び出される関数と言うことだ。 ... と言う事は、while(1)の無限ループが無かったとすると、main()はPowerOnResetにreturnする事になる。
 returnした後はどうなるのか。printfでプログラム終了を表示した後、sleep()と言う関数を実行しているが、sleepって何?
  sleep()は、CPUを停止して低消費電力モードに移行させる関数である。sleep()で制御可能な低消費電力モードには2つあって、

  1. スリープ・モード
    CPUは動作を停止する。周辺回路は動作する。全てのデータは保持される。(ただし、電源が供給されていれば)
    割り込みの発生、もしくは#RES信号線が有効になった場合に、CPUは動作を再開する。
    (信号の前の#は、負論理を表す。つまり、low信号が入力された時に有効になるということ。)
    インターバルタイマなどで、定期的に割り込みを発生する場合は、こちらを使用する。
     
  2. ソフトウエア・スタンバイ・モード
    CPUと周辺回路は動作を停止する。全てのデータは保持される。(ただし、電源が供給されていれば)
    #NMI、#IRQ0~#IRQ2、#RES信号線が有効になった場合にCPUは動作を再開する。

  つまり、sleep()を実行する事によって、CPUは動作を停止し、消費電力少なくするモードに移行するということ。
 この処理を行わないと、どういうことになるかと言うと、この先はプログラムが無いので、CPUは暴走状態になる。
 

※CPUを停止すると、何故、エコなのかと言うと、何をするにしても、「何かをするにはエネルギーが必要だ。」 と言うことに尽きる。真のエコとは、「何もしない事」と同義である。

 

 さて、だいぶ回り道をしてしまったが、これまでの議論で、main()の中にあるwhileの無限ループを終了すると、CPUが停止する事がわかった。スリープ・モードやソフトウエア・スタンバイ・モードの様なエコなモードがある事も知った。

 while(1)の無限ループは、プログラムを終了させないために、ムダにCPUを動作させている状態と見ることもできる。であれば、この間CPUを止めちゃうのもエコじゃないか?
 ということで、

#include "monitor.h"
......

#pragma interrupt(timer_handler)
void timer_handler()
{
    ....
}

int main()
{
  ......

   and_ccr(0x7F);// sleep()を呼んだ時に、スリープ・モードに遷移
   while(1)
    {
      sleep();
    }
}

 とするのが、これからの技術者としては、正しい姿勢と思われる。(本当は、もっと色々と細かい設定があるが、詳細はマニュアルに譲る)
 小さなマイコンで削減できる電力は、僅かなものであるが、「塵も積もれば」であるし、バッテリ駆動の場合は、死活問題(スマホのユーザならすぐに想像がつくであろう)でもある。

最終更新:2014年10月07日 16:09