「プログラミング」カテゴリーアーカイブ

誰も教えてくれない「組込みC言語」 3

定数の命名ルール

#define 定義する定数名は大文字にする

これは変数と混同しない為のコーディングルールとして良く使われています。

1
2
#define		signal_max		200
#define		signal_min		100

ではなく

1
2
#define		SIGNAL_MAX		200
#define		SIGNAL_MIN		100

のように定義します。

この定数にも前回の変数の型をいれると

1
2
#define		U1_SIGNAL_MAX		200
#define		U1_SIGNAL_MIN		100

となります。

例えば

1
if(u1_port_00 > u1_signal_max)

だと u1_signal_max は 定数なのか 変数なのかパッと見わかりませんが
定数は大文字にするというルールを決めておけば
この場合の u1_signal_max は 変数だとすぐにわかります。
当然

1
if(u1_port_00 > U1_SIGNAL_MAX)

だと U1_SIGNAL_MAX は 定数だとすぐにわかります。

余談ですが
定数の読み「じょうすう」、「ていすう」どっちで読んでいますか?
自分は昔は「ていすう」と読んでいましたが、今は「じょうすう」とよんでいます。

誰も教えてくれない「組込みC言語」 2

組込みプログラムではバグを早期に発見できるように
変数名はサイズが分かるように命名します。

例えば

1
2
3
4
5
6
7
8
9
10
11
void main(void){
	unsigned char	i;
 
	while (1U)
	{
		P3.0 = 0;
		for(i=0;i<50000;i++){};
		P3.0 = 1;
		for(i=0;i<50000;i++){};
	}
}

このプログラムにはバグが有ります。
iは符号なし8bitの変数(0 ~ 255)ですが
その範囲を超えた 50000 と比較しています。
このサンプルの場合は宣言部と比較している箇所が近いために気付きやすいのですが
変数がグローバル変数で別のファイルに定義されている場合はちょっと見気付きません。

これをちょっと見でもバグだと気付くように変数名を変えてみましょう。

1
2
3
4
5
6
7
8
9
10
11
void main(void){
	unsigned char	u1_i;
 
	while (1U)
	{
		P3.0 = 0;
		for(u1_i=0;u1_i<50000;u1_i++){};
		P3.0 = 1;
		for(u1_i=0;u1_i<50000;u1_i++){};
	}
}

変数名を i から u1_i に変えました。
もうお気づきかと思いますが u1_i の u1 は この変数が符号なしの1バイトの変数を意味しています。

このように変数名に型を表すワードを明示しておけば、
u1_i<50000 この部分を見ただけで 変数が符号なしの1バイトの変数 と 1バイトの範囲を超えた値と比較しているのが一目瞭然となります。u1 s1 u2 s2 s4 f4 f8 を変数の接頭語として良く使用します。 意味は以下のようになります。 u1 符号なし1バイト s1 符号あり1バイト u2 符号なし2バイト s2 符号あり2バイト u4 符号なし4バイト s4 符号あり4バイト f4  単精度実数 f8  倍精度実数

誰も教えてくれない「組込みC言語」 1

■組込み現場では int型は使わない。

組込み系のC言語の本にも
unsigned int i;
int j;
とかサンプルプログラムに書かれているが
これは間違いではないが実際に組込みプログラムに携わっているプログラマーは使わない(はず)

なぜならば int型は マイクロプロセッサに依存する為
16ビットだったり、32ビットだったりするからです。

他のプロセッサに移植する際に見つけにくいバグの1つとなってしまいます。

よって以下のプログラムは

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void main(void){
	unsigned int	i;
 
	while (1U)
	{
		P3.0 = 0;
		for(i=0;i<50000;i++){};
		P3.0 = 1;
		for(i=0;i<50000;i++){};
	}
}
 
void main(void){
	unsigned short	i;
 
	while (1U)
	{
		P3.0 = 0;
		for(i=0;i<50000;i++){};
		P3.0 = 1;
		for(i=0;i<50000;i++){};
	}
}

と書くべきだと思います。

サンプルプルプログラムに int型の宣言がある組込み向けc言語の解説書は自分的にはアウトです。
ただマイコンチップを特定の機種に絞っている本は別です。

ド・モルガンの法則

ド・モルガンの法則ってご存知でしょうか
もしかしたら組込み制御プログラマーの中に知らない人もいるのではと思ってしまいました。

自分はもともとロジックICやリレー回路での制御が入口だったので
当然ド・モルガンの法則を使って回路を簡略化していました。
その流れでマイコンでの制御に入っていったので、
当然のごとく入出力に対して真理値表を書いてド・モルガンの法則とかを使って整理してからプログラムを興していました。

今は辞めてしまったのですが、某大手自動車関連企業に派遣で働いていたとき、
当然のごとく先の手順で設計をして、それのレビューをした時ですが
チームのリーダーが「なんでそんなことをしているのですが?仕様書通りにして下さい。」
と言われて設計しなおしました。当然、仕様は満足していましたが。

その修正した設計書で客先レビューを行ったとき、
飛び入りでお偉い人(部長クラス)がさんかされて、
この処理部分を見て、「なんでここ、こんな風にしているの。これ簡略化できるでしょう。」との指摘。

自分心の中で「ですよね~」(笑)。

グループリーダーは35歳位で、お偉い方はたぶん自分と同じ位の50過ぎだと思います。

大丈夫なのか日本の組込み制御の将来。

ちなみにド・モルガンの法則 とは
NOT (A AND B) = NOT(A) OR NOT(B)
NOT (A OR B) = NOT(A) AND NOT(B)

こんなやつです。

CQ出版社 西沢昭 著 「Z80上級プログラミング」と言う本

懐かしい本をオークションで入手しました。

CQ出版社 西沢昭 著 「Z80上級プログラミング」

もう25年以上前、自分がFAの仕事をメインでやっていた頃
機械の制御はZ80をCPUに使ったマイコンボードとアセンブラ言語が主流でした。

当時すでにC言語での記述も一部にはありましたが、
プログラム領域のメモリサイズが16kB程度だったので、
プログラムサイズがC言語で書くと大きくなりすぎて現実的では有りませんでした。

この本は当時自分のバイブル的な本でした。
幾度かの引越しと制御系から離れていた性もあって、無くなっていました。

3年ほど前に、組込み制御の業務に戻り、当然言語もC言語だったのですが、
入力信号のフィルタリング処理に3度一致というフィルタリングとしてはしょぼいプログラムにびっくりしました。
自動車関連企業の最大手の会社がです。

ただ、制御系から離れていたので、自分が使っていたフィルタリングの処理をはっきりとは覚えていませんでした。
ネットでこの本を見かけたとき、「あっ、この本に確か入力フィルタリングに関しての記述があった」と思い、
タイミング良く、ヤフオクに出品されていたので直ぐに落札した次第です。

この本で解説してあるフィルタリングと3度一致の処理に関しては改めて記事を書きます。

「Z80上級プログラミング」

ソースコード表示プラグインのテスト

ブログにそーコードを表示するためのプラグイン

WP-Syntax

をインストールしたので、そのテストです。

c言語のソース表示です。

1
2
3
4
5
6
7
8
9
10
11
12
13
#define TIMER_COUNTER_MAX_NUM 120
unsigned char count;
 
/************* タイマー割り込み処理関数 ************/
void timer_int(){
    if(INTCONbits.TMR0IF){
        INTCONbits.TMR0IF = 0;            // 割り込みフラグクリア
        WriteTimer0(0xFE0C);            // タイマ0再設定
        if(++count >= TIMER_COUNTER_MAX_NUM){
            count = 0;
        }
    }
}

うまく表示されているみたいです。

ちなみに対応している言語
abap, actionscript, actionscript3, ada, apache, applescript, apt_sources, asm, asp, autoit, avisynth, bash, bf, bibtex, blitzbasic, bnf, boo, c, c_mac, caddcl, cadlisp, cil, cfdg, cfm, cmake, cobol, cpp-qt, cpp, csharp, css, d, dcs, delphi, diff, div, dos, dot, eiffel, email, erlang, fo, fortran, freebasic, genero, gettext, glsl, gml, bnuplot, groovy, haskell, hq9plus, html4strict, idl, ini, inno, intercal, io, java, java5, javascript, kixtart, klonec, klonecpp, latex, lisp, locobasic, lolcode lotusformulas, lotusscript, lscript, lsl2, lua, m68k, make, matlab, mirc, modula3, mpasm, mxml, mysql, nsis, oberon2, objc, ocaml-brief, ocaml, oobas, oracle11, oracle8, pascal, per, pic16, pixelbender, perl, php-brief, php, plsql, povray, powershell, progress, prolog, properties, providex, python, qbasic, rails, rebol, reg, robots, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty, sql, tcl, teraterm, text, thinbasic, tsql, typoscript, vb, vbnet, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xml, xorg_conf, xpp, z80