あれの開発記 30ページ目 沈黙のSilentC [SilentC]
UDPで通信を連続して行っていると、数分で突如SilentCが反応しなくなる。この時このボードに向けてPINGを打っても応答無しとなる。(※応答を返さないし、LED2も点滅しない。)
うーん、困ったなぁ。
特にスクリプトの中では無限ループに陥る様には記述していないし(多分)、特にアクションを起こさない場面では”SystemSleep”を入れているし。
そもそも別で動いている筈のPINGの応答等も止まっている所からしておかしい。
なんだろうね、内部的にデッドロックでもしているのかなぁ。
Main:
DTutil:
SCI:
Analog:
strutil:
うーん、困ったなぁ。
特にスクリプトの中では無限ループに陥る様には記述していないし(多分)、特にアクションを起こさない場面では”SystemSleep”を入れているし。
そもそも別で動いている筈のPINGの応答等も止まっている所からしておかしい。
なんだろうね、内部的にデッドロックでもしているのかなぁ。
Main:
char years,mons,days,weeks,hours,mins,secs; int temper,bright; main( void ) { #stop 0 int len,mode; char c,*p; char *s_buf = MemoryAlloc( 128 ); char *basic = MemoryAlloc( 32 ); char soc = CreateSocket( 0 ); SCI::HardFlowSet(); mode = 0; for(;;) { while( (c = Getc( 0 )) > 0 ) { if( c == 0x1b ) { CloseSocket( soc ); MemoryFree( basic ); MemoryFree( s_buf ); return; } else if( c == 0x02 ) { mode = 1; len = 1; p = s_buf; *p++ = c; } else if( c == 0x03 ) { if( mode == 1 ) { len++; *p = c; if( *(s_buf + 3) == 0x01 && *(s_buf + 1) == netcfg::MyID() ) { if( DTutil::DT2Num( "192.168.1.30", soc ) <= 0 ) { CloseSocket( soc ); Sleep( 10 ); soc = CreateSocket( 0 ); } else { temper = Analog::GetTemper(); bright = Analog::GetBright(); ResFrame( basic, *(s_buf + 2) ); SCI::BlkSend( basic, 31 ); } } } mode = 0; } else { if( mode == 1 ) { len++; *p++ = c; } } } SystemSleep(); } CloseSocket( soc ); MemoryFree( basic ); MemoryFree( s_buf ); } ResFrame( char *buf, char did ) { *buf = 0x02; *(buf + 1) = did; *(buf + 2) = netcfg::MyID(); *(buf + 3) = 0x01; *(buf + 4) = '1'; *(buf + 5) = '6'; DTutil::DtStr( buf + 6 ); *(buf + 18) = ','; GetDigit( Analog::GetTemper(), buf + 19 ); *(buf + 23) = ','; GetDigit( Analog::GetBright(), buf + 24 ); strutil::CheckSum( buf + 28, buf + 1, 27 ); *(buf + 30) = 0x03; }
DTutil:
int dg_daytime_cli( char *s, char *dst, char soc ) { char *buf; long dip = GetIP( s ); int len; len = SendTo( soc, dip, 13, "hello", 6 ); if( len == 0 ) { Sleep( 10 ); if( (len = SendTo( soc, dip, 13, "hello", 6 )) <= 0 ) return len; } if( (len = RecvFrom( soc, 2 )) > 0 ) { buf = GetReceiveBuffer( soc, 1 ); BufCopy( dst, buf, 30 ); MemoryFree( buf ); } else return (-1); return 1; } int DT2Num( char *s, char soc ) { int ret; char *buf = MemoryAlloc( 4 ); char *src = MemoryAlloc( 30 ); if( (ret = dg_daytime_cli( s, src, soc )) <= 0 ) { MemoryFree( buf ); MemoryFree( src ); return ret; } BufCopy( buf, src, 4 ); *(buf + 3) = 0; if( StrCmp( buf, "Sun" ) == 0 ){ weeks = 0;} else if( StrCmp( buf, "Mon" ) == 0 ){ weeks = 1;} else if( StrCmp( buf, "Tue" ) == 0 ){ weeks = 2;} else if( StrCmp( buf, "Wed" ) == 0 ){ weeks = 3;} else if( StrCmp( buf, "Thu" ) == 0 ){ weeks = 4;} else if( StrCmp( buf, "Fri" ) == 0 ){ weeks = 5;} else if( StrCmp( buf, "Sat" ) == 0 ){ weeks = 6;} src = src + 4; BufCopy( buf, src, 4 ); *(buf + 3) = 0; if( StrCmp( buf, "Jan" ) == 0 ){ mons = 1; } else if( StrCmp( buf, "Feb" ) == 0 ){ mons = 2; } else if( StrCmp( buf, "Mar" ) == 0 ){ mons = 3; } else if( StrCmp( buf, "Apr" ) == 0 ){ mons = 4; } else if( StrCmp( buf, "May" ) == 0 ){ mons = 5; } else if( StrCmp( buf, "Jun" ) == 0 ){ mons = 6; } else if( StrCmp( buf, "Jul" ) == 0 ){ mons = 7; } else if( StrCmp( buf, "Aug" ) == 0 ){ mons = 8; } else if( StrCmp( buf, "Sep" ) == 0 ){ mons = 9; } else if( StrCmp( buf, "Oct" ) == 0 ){ mons = 10; } else if( StrCmp( buf, "Nov" ) == 0 ){ mons = 11; } else if( StrCmp( buf, "Dec" ) == 0 ){ mons = 12; } src = src + 4; MemoryFree( buf ); days = *src++ - '0'; if( *src != ' ' ) { days *= 10; days += *src++ - '0'; } src++; hours = *src++ - '0'; if( *src != ':' ) { hours *= 10; hours += *src++ - '0'; } src++; mins = *src++ - '0'; if( *src != ':' ) { mins *= 10; mins += *src++ - '0'; } src++; secs = *src++ - '0'; if( *src != ' ' ) { secs *= 10; secs += *src++ - '0'; } src++; src += 2; years = *src++ - '0'; years *= 10; years += *src - '0'; MemoryFree( src ); return 1; } char *DtStr( char *dst ) { strutil::I2ASC02( dst, years ); strutil::I2ASC02( dst + 2, mons ); strutil::I2ASC02( dst + 4, days ); strutil::I2ASC02( dst + 6, hours ); strutil::I2ASC02( dst + 8, mins ); strutil::I2ASC02( dst + 10, secs ); *(dst + 12) = 0; return dst; }
SCI:
void HardFlowSet( void ) { char *ptapar = 0x4010006E; *ptapar = 0; } void BlkSend( char *src, int size ) { char *setta = 0x4010003E; for( ; size > 0; size-- ) { while( *setta & 0x02 ) SystemSleep(); PrChar( *src++ ); } }
Analog:
int GetTemper( void ){ InitAd( 0x03 ); return GetAd( 0 ); } int GetBright( void ){ InitAd( 0x03 ); return GetAd( 1 ); }
strutil:
char I2HEX01( int value ) { if( value <= 9 ) return value + '0'; return value + 55; } void I2HEX02( char *dst, int value ) { *dst++ = I2HEX01( value / 16 ); *dst = I2HEX01( value % 16 ); } void I2ASC02( char *dst, int value ) { *dst++ = (value / 10) + '0'; *dst = ( value % 10 ) + '0'; } int CheckSum( char *dst, char *src, int size ) { int i,c_sum = 0; for( i = 0; i < size; i++ ) c_sum += *src++; c_sum = (-c_sum) & 0xff; I2HEX02( dst, c_sum ); return c_sum; }
2008-09-08 14:12
nice!(0)
コメント(8)
トラックバック(0)
DTutil:DT2Numの最後から3行目
MemoryFree( src );
変数srcは、さんざんインクリメントされてきているので、ここでヒープ構造を破壊してしまっているのではないでしょうか。
by noritan (2008-09-08 18:22)
久しぶりに見ましたら写真が大きく見られるようになりまして
また訪れることが多くなりました。
前のプログのあの写真では何をしているのか素人の私には
解かりませんでした。
写真が大きくなったところで記事の内容はとても理解できませんが
眼(頭)の保養になります。
by 1wby (2008-09-08 18:49)
> 変数srcは、さんざんインクリメントされてきているので、ここでヒープ
> 構造を破壊してしまっているのではないでしょうか。
うわ!本当だ。情け無い事に全然気付けなかった。
by hamayan (2008-09-08 19:59)
> 久しぶりに見ましたら
あああ、思い出しました。MSP430の時の!。
その節はお世話になりました。
あれ以来、雑誌と販売が連動するようになってしまって、雑誌が出る前に部品や基板の販売がアナウンスされるので、なかなか個人で企画して賛同者を募集するようなやり方が難くなっていますが、またやりたいですね。
by hamayan (2008-09-08 21:23)
SCI::BlkSendの7行目
while( *setta & 0x02 ) SystemSleep();
Analog::GetTemper で、 InitAd( 0x03 ); を使っていますが、これをやると DDRTA[3:1] がセットされて PTA[3:1] が、出力になります。このため、 PTA[2] は、入力端子として使われていないのじゃじゃいかと思います。 DDRTA の値を確認してみてください。
参考記事
http://noritan-micon.blog.so-net.ne.jp/2008-08-22
MCF52233付録基板 - SilentCが使っていないモジュールを探せ(1)
by noritan (2008-09-09 08:40)
うわ!本当だ。
加速度センサーは使用していないので、物理的にはこのままで良いのだけれど、ソフトウエア的にはADの設定の後、負けずにポートの設定を変更するか、フロー制御自体を諦めるか。
現状は出力になってもLOWのままみたいで、SCIからの出力が行われないと言う事は無いのですが。
by hamayan (2008-09-09 09:06)
この UDP ソケットには、ポート番号が Bind されていないようなんですが、それでもパケットを受信することはできるのでしょうか? Bind() 関数の第三引数に与えられた数を使って、ワークエリアを確保しているなんて事はありませんか?
# 一般的な datagram 通信では、どうなんでしょう?
by noritan (2008-09-09 12:03)
bindするのはサーバー目的でポート番号を固定したい場合で、今回はクライアントなのです。
サーバー側では受けたパケットからクライアントのポート番号を特定できますので、受けたIPアドレスとポート番号にちゃんと返信してくれる、と言うかサーバーアプリ側をそう言うふうに作った。
by hamayan (2008-09-09 12:28)