今回のプログラムでは、親機が子機から来たデータでその子機に対して、SYN+ACKを行うかどうかを親機のEEPROM内に、子機のシリアル番号の登録があるかどうかを確認して行うようにしています。このときに親機への子機シリアル番号の登録などはPC側からRS232C通信で設定ができるようにしています。EEPROMへの子機1台分のデータとしては4バイトを使用しており、構成は
typedef struct _reg_slave_
{
u8 serial[3];
u8 slave_ctl_set;
}reg_slave;
このようになっています。
子機は100台分をEEPROMに登録できるようにします。
reg_slave EEPROM greg_slave[100];
これで、100台分の登録を設定しています。
プログラムの細かい部分を見ていきたいと思います。 コマンド文字列(例えば”wr_env_00_1122AF_00(cr)”)を取得した場合、(cr)を検知すると、ステート管理の gClient.status.statusこの変数に”MS_UART_RECV”(コマンド受信実行ステート)に移行し、下のプログラムが実行されます。
if(gClient.status.status==MS_UART_RECV)
{
ret = 0;
memset(gWCmd,0,sizeof(gWCmd));
pC = strtok(rx_char," ");
i=0;
while(pC != NULL)
{
strcpy(&gWCmd[i][0],pC);
pC = strtok(NULL," ");
putstr(&gWCmd[i][0]);
i++;
}
if(i != 0)
{
if(strstr(&gWCmd[0][0],"wr") != NULL)
{
if(strstr(&gWCmd[1][0],"env") != NULL)
{
int id=0;
id = AscToInt(&gWCmd[2][0]);
if(id >= 0 && id < 100)
{
tSlave.serial[0] = AscToHex(&gWCmd[3][0]);
tSlave.serial[1] = AscToHex(&gWCmd[3][2]);
tSlave.serial[2] = AscToHex(&gWCmd[3][4]);
tSlave.slave_ctl_set = AscToHex(&gWCmd[4][0]);
eeprom_busy_wait(); //EEPROM使用可能まで待機
eeprom_write_block(&tSlave, &greg_slave[id], sizeof(reg_slave)); //write 8byte
ret = 1;
}
}
}
else if(strstr(&gWCmd[0][0],"rd") != NULL)
{
}
else
{
}
}
if(ret == 1)
{
putstr("ok\a");
}
else
{
putstr("err\a");
}
memset(rx_char,0,40);
gClient.status.status = MS_BOOT;
}
まず、u8 gWCmd710;このグローバル構造体変数にすべて0を入れるため 1.memset(gWCmd,0,sizeof(gWCmd));を実行する。
次に、char * pC;に送られて来たコマンド文字列の入っているrx_charのアドレスstrtok関数で渡す。
char * pC;
if(gClient.status.status==MS_UART_RECV)
{
ret = 0;
memset(gWCmd,0,sizeof(gWCmd)); //1
pC = strtok(rx_char," ");
i=0;
while(pC != NULL)
{
strcpy(&gWCmd[i][0],pC);
pC = strtok(NULL," ");
putstr(&gWCmd[i][0]);
i++;
}
iが0よりも大きければ、
gWCmd内にコマンド文字列があるとして判断し、下のプログラムを実行します。 gWCmd00でwrが入っているかを
if(strstr(&gWCmd00,"wr") != NULL)
ここで確認します。
strstr関数の使い方はここで確認 http://www9.plala.or.jp/sgwr-t/lib/strstr.html
if(i != 0)
{
if(strstr(&gWCmd[0][0],"wr") != NULL)
{
if(strstr(&gWCmd[1][0],"env") != NULL)
{
int id=0;
id = AscToInt(&gWCmd[2][0]);
if(id >= 0 && id < 100)
{
tSlave.serial[0] = AscToHex(&gWCmd[3][0]);
tSlave.serial[1] = AscToHex(&gWCmd[3][2]);
tSlave.serial[2] = AscToHex(&gWCmd[3][4]);
tSlave.slave_ctl_set = AscToHex(&gWCmd[4][0]);
eeprom_busy_wait(); //EEPROM使用可能まで待機
eeprom_write_block(&tSlave, &greg_slave[id], sizeof(reg_slave)); //write 8byte
ret = 1;
}
}
}
}
if(strstr(&gWCmd10,"env") != NULL) この条件がTRUEであった場合は、実際に、EEPROMにデータを登録していきます。
idには、EEPROMに登録する子機の0~99の番地を選択する数値を設定します。
それから、tslaveの構造体変数に取得したシリアル番号とctlデータの4バイトを設定する。 これが完了したら、
void eeprom_write_block (const void *__src, void *__dst, size_t __n)
この関数を使う。
eeprom_busy_wait(); //EEPROM使用可能まで待機 eeprom_write_block(&tSlave, &greg_slave[id], sizeof(reg_slave)); //write 8byte
if(strstr(&gWCmd[1][0],"env") != NULL)
{
int id=0;
id = AscToInt(&gWCmd[2][0]);
if(id >= 0 && id < 100)
{
tSlave.serial[0] = AscToHex(&gWCmd[3][0]);
tSlave.serial[1] = AscToHex(&gWCmd[3][2]);
tSlave.serial[2] = AscToHex(&gWCmd[3][4]);
tSlave.slave_ctl_set = AscToHex(&gWCmd[4][0]);
eeprom_busy_wait(); //EEPROM使用可能まで待機
eeprom_write_block(&tSlave, &greg_slave[id], sizeof(reg_slave)); //write 8byte
ret = 1;
}
}
コマンドプログラムに関する解説についての投稿。