電子工作」カテゴリーアーカイブ

リアルタイムふうOSのデバッグツール

RTF-OS debugリアルタイムふうOSを使用したソフトウェアのデバッグツール。エクセルのマクロで作成した。右の画像はデモソフトと組み合わせて動作させた画面である。
エクセルのファイルはリアルタイムふうOSのページに置いた。
エクセルのシリアル通信部はアクティブセル/EasyCommを利用させて頂いている。使いやすくてお気に入りです。

小型版 便利ボード

20070817_benrie.jpg以前に製作した便利ボードはちょっと大きいので同じ機能の小型版を製作した。USBシリアル変換にはFT233Rを使用。プログラムの書き込み時にブートモードに設定するのは以前作ったソフトを利用した。

書込時のバッチファイルはこんなぐあい。

FT232RCBUS.exe w 1100   ' ブートモード、リセット状態
FT232RCBUS.exe w 1000   ' ブートモード、リセット解除
FDT.lnk          ' フラッシュ書き込みツールを起動
pause
echo ターゲットシステムを起動します。
FT232RCBUS.exe w 1100   ' ブートモード、リセット状態
FT232RCBUS.exe w 0100   ' ユーザモード、リセット状態
FT232RCBUS.exe w 0000   ' ユーザモード、リセット解除

回路図は下記。まだ問題あるかも。

リアルタイムふうOS

5月の連休の時、小規模な電子工作で使うリアルタイムふうなOSを作成した。
備忘録代わりに右にまとめた。「リアルタイムふうOS
いくつかの装置に利用したが今のところもくろみ通りに動作している。かといって細かいデバッグはしていない。

APIのプロトタイプ宣言を下記に示す。

/* Queueの初期化 割込禁止 */
void init_os( void );
/* メインルーチン */
void task_main( void );
/* TCB生成 割込禁止 */
tcb_type *create_tcb( void (*task)( byte state ));
/* メールボックス生成 割込禁止 */
mbx_type *create_mbx( char *msg_buff, byte size );
/* イベントフラグ生成 割込禁止 */
flag_type *create_flag( void );
/* セマフォ生成 */
sem_type *create_sem( byte size );
/* タスク起床 */
void start_task( tcb_type *tcb );
/* タスク起床 割込禁止 */
void start_task_i( tcb_type *tcb );
/* タスク終了とTCB解放 */
void exit_task( tcb_type *tcb );
/* タスク終了とTCB解放 割込禁止 */
void exit_task_i( tcb_type *tcb );
/* 起床事由の取得 */
byte get_trg( tcb_type *tcb );
/* 遅延遷移 */
void delay_task( tcb_type *tcb, word time );
/* タイムアウト設定 */
void set_timeout( tcb_type *tcb, word time );
/* タイムアウト解除 */
void clear_timeout( tcb_type *tcb );
/* 1msタイマ割込み 割込禁止 */
void timer_1ms_int( void );
/* メールボックスにメッセージ登録 */
byte send_msg( char *msg, byte len, mbx_type *mbx );
/* メールボックスにメッセージ登録 割込禁止 */
byte send_msg_i( char *msg, byte len, mbx_type *mbx );
/* メールボックスからメッセージ待ち */
void wait_msg( mbx_type *mbx, tcb_type *tcb );
/* メールボックスからメッセージポインタ取得 */
char *get_msg( mbx_type *mbx );
/* メールボックスからメッセージ長さ取得 */
byte get_msglen( mbx_type *mbx );
/* イベントフラグをセット */
void set_flag( flag_type *flag );
/* イベントフラグをセット 割込禁止 */
void set_flag_i( flag_type *flag );
/* メールボックスクリア */
void clear_msg( mbx_type *mbx );
/* イベントフラグをクリア */
void clear_flag( flag_type *flag );
/* イベントフラグをクリア 割込禁止 */
void clear_flag_i( flag_type *flag );
/* イベントフラグ待ち */
void wait_flag( flag_type *flag, tcb_type *tcb );
/* セマフォひとつ解放 */
void signal_sem( sem_type *sem );
/* セマフォで空き待ち */
void wait_sem( sem_type *sem, tcb_type *tcb );
/* タスクをスライスして継続実行 */
void slice_task( tcb_type *tcb );
/* 遷移時の状態変数を変更 */
void set_next_state( tcb_type *tcb, byte next_state );

FTDI社製FT232Rの汎用I/Oポートの操作

先月試した SiliconLabs製のCP2103は汎用I/Oが4ビット付いている。電圧仕様は3.3Vなので気を使った。似たようなものにFTDI社製のFT232RLがある。こちらはI/O電圧が3.3Vと5Vより選択できる。なかなかよさそうなのでFT232Rを試してみる。まずはFT232RLの汎用I/O(CBUS)を操作する簡単なソフトを作成した。
1.環境

WindowsXP
VisualC++Express
MicrosoftPlatformSDK

2.必要なもの:FTDI社より下記ファイル

CDM 2.00.00.zip (ドライバ、DLL、Lib、ヘッダファイル)
MProg3.0_Setup.exe (EEPROM書き換えツール)

3.ソースリスト

#include < windows.h >
#include < stdio.h >
#include "FTD2XX.H"
int main(int argc, char *argv[])
{
char    cmd;
LPSTR   pos;
BYTE    data;
HANDLE  hc;
int     res;
char    Buf[64];
Buf[0] = 0;
if( argc < 2 || (toupper(*argv[1])=='W' && argc < 3 )) {
printf_s("FT232RCBUS r\nFT232RCBUS w 1100\n");
return( 0 );
}
cmd = *argv[1];
res = FT_ListDevices( 0,
Buf,
FT_LIST_BY_INDEX | FT_OPEN_BY_DESCRIPTION );
hc = FT_W32_CreateFile( Buf,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED
| FT_OPEN_BY_DESCRIPTION,
NULL );
if( hc == INVALID_HANDLE_VALUE ) {
printf_s( "Open Error:%s\n", Buf);
res = 11;
} else {
switch( toupper( cmd )) {
case 'R':
res = FT_GetBitMode( hc, &data );
if( res == FT_OK ) {
printf_s( "%x\n", data );
} else {
printf_s( "R command Error %d\n", res );
}
break;
case 'W':
pos = argv[2];
data = 0;
if( pos[0] == '1' ) data |= 0x08;
if( pos[1] == '1' ) data |= 0x04;
if( pos[2] == '1' ) data |= 0x02;
if( pos[3] == '1' ) data |= 0x01;
res = FT_SetBitMode( hc, 0xf0 | data, 0x20 );
if( res != FT_OK ) {
printf_s("W command Error %x\ndata %x\n", res, data );
}
break;
default:
printf_s( "FT232RCBUS r\nFT232RCBUS w 1100\n" );
break;
}
FT_W32_CloseHandle( hc );
}
return( res );
}

4.使い方。(PCに1つだけFT232RLを接続した場合を想定)
まずMProgツールでCBUSのビットをI/Oに設定してEEPROMを書き換えておく。
CBUS の出力状態を読む。

FT232RCBUS.exe r

CBUSの出力を変更する。(例:bit3とbit2を1に、bit1とbit0を0にする)

FT232RCBUS.exe w 1100

これをバッチファイルなどで利用する。

CP2103GPIOを利用したフラッシュROMへの書き込み

CP2103GPIO.exeを利用してワンチップCPUのフラッシュROMへ書き込みを行う。
作成した便利ボードではGPIOのビット3をブートモード切り替えに、ビット2をリセットにつなげた。

GPIO3   1ならブートモード、0ならユーザモード
GPIO2   1ならリセット状態、0ならリセット解除状態

フラッシュROMへの書き込みは次のバッチファイルを起動している。

CP2103GPIO.exe com3 w 1100   ' ブートモード、リセット状態
CP2103GPIO.exe com3 w 1000   ' ブートモード、リセット解除
FDT.lnk          ' フラッシュ書き込みツールを起動
echo ターゲットシステムを起動します。
pause
CP2103GPIO.exe com3 w 1100   ' ブートモード、リセット状態
CP2103GPIO.exe com3 w 0100   ' ユーザモード、リセット状態
CP2103GPIO.exe com3 w 0000   ' ユーザモード、リセット解除

参考回路図(部品がなく動作未確認)

これでブートモードスイッチが不要になった。(それだけなのにかなり苦労してしまった)

SiliconLabs製CP2103のGPIO出力操作

便利ボードのためにCP2103のGPIOの出力を操作する簡単なソフトをWin32コンソールプログラムで作成した。
1.環境

WindowsXP
VisualC++Express
MicrosoftPlatformSDK

2.必要なもの:SiliconLabs社のアプリケーションノートAN223より下記ファイル。

CP210xRuntimeDLL.h
CP210xRuntimeDLL.def
CP210xRuntime.lib
CP210xRuntime.dll

3.ソースリスト

#include < windows.h >
#include < stdio.h >
#include < tchar.h >
#include "CP210xRuntimeDLL.h"
int execute_command( TCHAR cmd, LPBYTE data, TCHAR* port);
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR   portName[20];
int     res;
TCHAR   cmd;
TCHAR*  pos;
BYTE    result, outdata;
if( argc < 3 ) {
printf_s("CP2103GPIO COM1 r\nCP2103GPIO COM1 w 1000\n");
return( 0 );
}
swprintf_s( portName, 20, L"\\\\.\\%c%c%c%c",
argv[1][0],argv[1][1],argv[1][2],argv[1][3]);
cmd = *argv[2];
switch( toupper( cmd )) {
case 'R':
res = execute_command( cmd, &result, portName );
if( res == CP210x_SUCCESS ) {
printf_s( "%x\n", result );
}
break;
case 'W':
pos = argv[3];
outdata = 0;
if( pos[0] == '1' ) outdata |= 0x08;
if( pos[1] == '1' ) outdata |= 0x04;
if( pos[2] == '1' ) outdata |= 0x02;
if( pos[3] == '1' ) outdata |= 0x01;
res = execute_command( cmd, &outdata, portName );
break;
default:
printf_s( "CP2103GPIO COM1 r\nCP2103GPIO COM1 w 1000\n" );
break;
}
return( res );
}
int execute_command( TCHAR cmd, LPBYTE data, TCHAR* port)
{
HANDLE  hc;
int     res;
BYTE    readData;
hc = CreateFile(    port,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL );
if( hc == INVALID_HANDLE_VALUE ) {
wprintf_s( L"Open Error:%s\n", port );
res = 11;
} else {
switch( toupper( cmd )) {
case 'R':
res = CP210xRT_ReadLatch( hc, &readData );
if( res == CP210x_SUCCESS ) {
*data = readData;
res = 0;
} else {
printf_s( "Error %d\n", res );
res = 12;
}
break;
case 'W':
res = CP210xRT_WriteLatch( hc, 0x0f, *data );
if( res == CP210x_SUCCESS ) {
res = 0;
} else {
printf_s("Data %x\n",*data );
printf_s("Error %x\n", res );
res = 13;
}
break;
default:
res = 15;
break;
}
CloseHandle( hc );
}
return( res );
}

4.使い方。(以下、対象ポートをCOM3とする)
GPIOの出力状態を読む。

CP2103GPIO.exe com3 r

GPIOの出力を変更する。(例:ビット3とビット2を1に、ビット1とビット0を0にする)

CP2103GPIO.exe com3 w 1100

これをバッチファイルなどで利用する。

便利ボード

20070526_benrie.jpg便利ボードがほぼ完成した。今回はハードウェアよりソフトウェアにこだわってみた。リアルタイム風?マルチタスクの小規模なOSを作ってからその上で動くLCDライブラリとキー入力ライブラリ、A/D変換ライブラリを作り、それらを利用したメインルーチンを動かしている。キー入力があると左の画面に表示する。A/D変換値は0.5s周期で右側に表示する。じつは無駄にディスパッチが激しいけど趣味だからいいのだ。
電源はUSBのバスパワーにしてしまった。あまり良くないよな?と思いつつ。

eclipse+gccでH8のコードをビルド

JAVAのIDEで有名なeclipse
eclipse上ではWideStudioを使って小物を作ったことがある。
最近は組み込みマイコンでも利用する方がいるようだ。
下記サイトを参考に環境を構築してみた。
http://hp.vector.co.jp/authors/VA022386/
http://www.takamisawa.org/gcc/development.html
http://www.kikaiken.org/lib/junk/h8dev-doc-linux/index.html
使用したバージョンは次の通り
cygwin1.dll-1.5.24  :WindowsでGNUツールを使う
eclipse-SDK-3.2-win32  :エクリプス本体
NLpack1-eclipse-SDK-3.2-win32  :エクリプスの日本語化
CDT-3.1.0  :エクリプスでC/C++を使うプラグイン
binutils-2.15  :GNUツール
gcc-3.4.3  :コンパイラ
newlib-1.13.0  :小型のCライブラリ
設定をメモ。
1.エクリプスのPATH設定
 プロジェクト>プロパティー>C/C++MakeProject>Environment で環境変数に下記を追加。
 Variable: PATH
 Value:  c:\cygwin\bin;c:\cygwin\usr\local\h8\bin
 注釈: cygwinのコマンドとH8用gccのコマンドへパスを通す。
2.エクリプスのスキャナの設定
 プロジェクト>プロパティー>C/C++MakeProject>DiscoveryOptionの
 Enable generate scanner info command にチェックを入れて
 h8300h-hms-gcc と入力
 注釈: 検索基準をgccでなくh8300h-hms-gccに変更する。
3.スタートアップルーチン
 対象をH8/Tinyシリーズとする場合はH8/300Hノーマルモードなので
.h8300hn
 を冒頭に付ける。
 スタックポインタの設定は16ビットアドレスなので、
mov.w #_stack, sp
 となる。
4.LDスクリプト
 こちらも対象をH8/Tinyシリーズとする場合はH8/300Hノーマルモードなので
OUTPUT_ARCH( “h8300hn” )
 とした。
5.試しにビルド
対象CPU: H8/3664F(H8 Tinyシリーズ)
makefileは下記
————————————
# makefile H8 300H tiny
NM = iotester
SRC = start.S os.c timer.c lcds.c key16.c init.c main.c
OBJS = start.o os.o timer.o lcds.o key16.o init.o main.o
LDSCRIPT = H8_3664F.x
CC = /usr/local/h8/bin/h8300-hms-gcc.exe
OBJCOPY = /usr/local/h8/bin/h8300-hms-objcopy.exe
MAP = $(NM).map
CFLAGS = -mh -mn -O2 -Wall
LDFLAGS = -nostartfiles -mrelax -T$(LDSCRIPT) -Wl,-Map,$(MAP)
all : $(NM)
$(NM) : $(SRC)
$(CC) -o $(NM).coff $(CFLAGS) $(LDFLAGS) $(SRC)
$(OBJCOPY) -Osrec $(NM).coff $(NM).mot
clean :
rm -f $(NM).mot $(OBJS)
————————————
コードはできたので実機で試そう。
ハードウェア作ってないな。
つづく...。

便利ボード

20070503_benrie.jpg連休を使って久しぶりに電子工作をしている。秋月電子のH8/3664汎用ボードとキャラクタ表示の液晶、それにUSBシリアル変換ICのCP2103を組み合わせて何か便利な小物を作るのだ。何か便利?って目的が適当だが、とりあえずCP2103のシリアル通信とGPIOを使うのが目標。GPIOでブートモードと通常起動を切り替えられるか?まずは部品配置だけ決めた。