質問
* アップデート *
これが私が見つけたものです。そこにその機能があるときはいつでも、実際にはコードをロックアップしません。実際に読み取りRTCI²C機能を実行するのが非常に遅くなりますが、コードはまだ適切に実行されますが、RTCを読むたびに過ぎ去るのに非常に長い時間を待たなければなりませんでした。
そのため、RTCにはアラーム割り込みがあり、これによりISR内の他のI²C相互作用がトリガーされていたため、同時に2つのI²C通信を実行しようとしているように見えたため、プロセスが遅くなりました。 ISRの関数を削除しましたが、現在機能しています。調査を続けます。
IAR 5.40を使用してSTM32F103マイクロコントローラーをプログラミングする際に、この問題があります。この関数は、ローカル変数を印刷しようとすると、問題の関数に到達する前に、コードが別の点でフリーズします。
これを引き起こす可能性がありますか?
これが関数です:
u8 GSM_Telit_ReadSms(u8 bSmsIndex)
{
char bTmpSms[3] = {0};
itoa(bSmsIndex, bTmpSms, 10); // Converts the smsindex into a string
printf("index = %s\n", bTmpSms); // This printf caused the code to get stuck in the RTC // byte read function!
GSM_Telit_RequestModem("AT+CMGR=""1", 10, "CMGR", 5, 0);
return 1;
}
私もこれを試しましたが、これは私が経験したロックを引き起こしません。
u8 GSM_Telit_ReadSms(u8 bSmsIndex)
{
char bTmpSms[3] = {0};
itoa(bSmsIndex, bTmpSms, 10);
printf("index = 2\n");
GSM_Telit_RequestModem("AT+CMGR=""1", 10, "CMGR", 5, 0);
return 1;
}
最適化が有効になることはまったくありません。I²CRTCからバイトを読み取ろうとするとコードが止まりますが、これを削除するとすぐに printf("index = %s\n", bTmpSms);
または、代わりにこれを使用します printf("index = 2\n");
その後、すべてが幸せです。何か案は?
BSMSINDINDEXは実際には30を超えることはありません。また、この関数が呼び出される前に、ロックアップがWayyyyになります。
解決 4
変数btmpsmsを何かに初期化しないと、問題が発生するようです。
また、問題であるのはprintfではないことにも気付きました。 ITOA関数です。それが問題だとは思わなかったにもかかわらず、ITOA関数にコメントしたとき、コード全体が機能したことを確認する必要がありました。
だから私はこれをすることになりました:
u8 GSM_Telit_ReadSms(u8 bSmsIndex)
{
char bTmpSms[4] = "aaa"; // I still need to find out why this is !!!
itoa(bSmsIndex, bTmpSms, 10); // Converts the smsindex into a string
printf("index = %s\n", bTmpSms); // This printf caused the code to get stuck in the RTC // byte read function!
GSM_Telit_RequestModem("AT+CMGR=""1", 10, "CMGR", 5, 0);
return 1;
}
これは私が得たitoa関数です:
char itoa(int value, char* result, int base)
{
// Check that the base if valid
if (base < 2 || base > 36) {
*result = '\0';
return 0;
}
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do
{
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsr
qponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz [35 +(tmp_value- value * base)];} while(value);
// Apply negative sign
if (tmp_value < 0)
*ptr++ = '-';
*ptr-- = '\0';
while(ptr1 < ptr)
{
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
return 1;
}
他のヒント
char bTmpSms[3]
「99」のスペースのみがあります。 BSMSINDINDEXが100以上の場合、自分に属さないメモリに書き込もうとします。
更新後に編集します
私は参照を持っていません itoa
私の地元のマシンで、しかし私はこれを見つけました( http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/ )。その参照によると、宛先配列 可能な価値に十分な長さでなければなりません. 。ドキュメントを確認してください:あなたの特定 itoa
違うかもしれません。
または使用します sprintf
, snprintf
, 、または標準で説明されている関数。
いくつかのアイデア:
もしも itoa()
文字列を適切に終了するわけではないので、printfへの呼び出しにより、マシンが永遠にNULを探している場合があります。
PMGには非常に良い点があります。
また、最初の引数のタイプを検討してください itoa()
は。署名されていて、署名されていない整数を通過した場合、BTMPSMで予期しないマイナスサインを取得する可能性があります。使用してみてください sprintf()
代わりは。
コードの変更は、コードの残りをメモリ内に移動しています。私の推測では、ここにリストされていないコードの他の部分は、いくつかのランダムな場所を叩いていると思います。最初のケースでは、場所に重要なものが含まれていることがありますが、2番目のケースではそうではありません。
これらは、追跡するための最悪の種類の問題です*。幸運を。
*最悪ではないかもしれません - それが週に一度だけ現れた複数のスレッド間の人種条件であれば、それはさらに悪いかもしれません。まだ私のお気に入りのバグではありません。
の価値は何ですか bSmsIndex
あなたは印刷しようとしていますか?
99を超えている場合、あなたは bTmpSms
配列。
それが役に立たない場合は、IARのかなり良いデバッガーを使用します - 私はどこでアセンブリウィンドウにドロップします printf()
物事が雑草に入るまで、シングルステップと呼ばれています。それはおそらく問題が何であるかを明確にするでしょう。
または、迅速なdirtyトラブルシューティングとして、アレイを大きいもの(たぶん8)にサイズ化して、何が起こるかを確認してください。
BSMSINDEXの価値は何ですか?
99を超える場合、文字列に変換すると3桁になります。ゼロが終了すると4文字になりますが、3つしかbtmpsmsに割り当てられないため、nullが上書きされ、printfが次のnullまでbtmpsmsの後に印刷しようとします。それは本当に何でもアクセスできます。
この領域をindex =で分解してみてください 2
vs. index = %s
.