これが私の問題の明確な説明であることを願っています.1週間強の間、さまざまなマニュアルを調べてきましたが、これを解決しようとしています:
最近、STM32 Nucleo-F334R8 でフィードバックとテストを行った後、クラス プロジェクトのソフトウェア設計を再設計しています (私の最初のコードはメモリとタイミングのエラーでいっぱいでした)。
現在、2 つの主なエラーが発生しています。
(この問題は解決済みです)
私は sprintf を使用していましたが、割り当てられたメモリの外側に書き込まれる末尾の null 文字を考慮していませんでした。
115200 ボーレートで非同期モードで USART 1 を使用して USART データを処理する場合:
プログラム受信シグナル SIGTRAP、トレース/ブレークポイント トラップ。memset () の 0x08002c08
プログラム受信シグナル SIGTRAP、トレース/ブレークポイント トラップ。memset () の 0x08002c08
プログラム受信シグナル SIGTRAP、トレース/ブレークポイント トラップ。memset () の 0x08002c08
プログラム受信シグナル SIGTRAP、トレース/ブレークポイント トラップ。memset () の 0x08002c08
プログラム受信シグナル SIGTRAP、トレース/ブレークポイント トラップ。std.isra の 0x080056b4 ()
問題のアドレス 0x08002c08 に格納されている値は通常、10 進数で 134228385 のような非常に大きな値です。また、問題を強制的に実行しても、プログラムは引き続き正常に動作し、問題が再び発生することはありません。奇妙な原因が考えられますか?
更新: memset の問題を少し追跡したところ、
setOutputBuffer
メソッド中に発生することがわかりました。String>,%5d,%8s,%3d,%3d,%3d,%4d,%4d,%4d,%10.6f,%11.6f,%7.1f,%3d,%3.1f\n",uptime,timeString,temperature,pressure,humidity,acc1,acc2,acc3,latitude,longitude,altitude,current,voltage); } ``` Which leads me to believe the issue lies in finding a value that is being used to set the Output buffer message. I would like advice on how to further troubleshoot these two issues and whether there is a chance that the memset error is related the later bss error. My String Tokenizing code(edited): ```c void tokenize(char* in){ const char *p = in; const char delim[] = ","; char *token = NULL; uint8_t n = 0; do{ size_t length = strcspn(p, delim); if(length > 0){ if(token == NULL){ token = malloc(sizeof(char)*length); // create memory space for the token memset(token, 0, length); // ensure initialized memory is blank sprintf(token, "%.*s",(int)length,p); // store the token from a substring of Input Buffer p+=length; // move pointer to next ',' parseToken(token, n); // extract information from the token be it latitude, longitude etc memset(token, 0, length); // clear the token free(token); // free up the token's spot in memory token = NULL; // set token pointer to null n++; } } }while(*((++p)+1) != '*'); // The expected string ends with a checksum character '*' after the last ',' } ``` I've re-examined the function and made a lot of changes now I can successfully step through the entire function without issue, the program then returns to my main loop, and I let it run for a while but then I suddenly run back into the same memset issue, even without receiving any bytes over USART here is the code for my main loop and the subsequent function calls it makes: ```c while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if (byteFlag){ byteRecieved(); byteFlag = 0; } if(msgFlag){ msgRecieved(); msgFlag = 0; } if(secFlag){ setOutputBuffer(); HAL_UART_Transmit(&huart1, (uint8_t *)bufferOut, 91, 1000); secFlag = 0; } } ``` byteReceived: ```c if((char) byteIn == '$'){ clearInputBuffer(); } else if((char) byteIn == '\n'){ msgFlag = 1; } else{ storeChar(); } ``` msgReceived: ```c if(isValid()){ if (checksum()) { tokenize(bufferIn); clearInputBuffer(); } } ``` isValid: ```c char substr[5]; strncpy(substr, (bufferIn+1), 5); if(!strcmp(substr, "GPGGA")){ return 1; } return 0; ``` checksum: ```c int checksum(){ int calc_checksum = 0; int in_checksum; int i = 0; char checkstr[2]; uint8_t hasCheckSum = 0; for(int j = 0; j<91; j++){ if (bufferIn[j] == '*') { hasCheckSum = 1; i = 1; } } if (hasCheckSum) { while (bufferIn[i] != '*'){ calc_checksum ^= bufferIn[i]; i++; } checkstr[0] = bufferIn[i+1]; checkstr[1] = bufferIn[i+2]; } else {return 0;} in_checksum = parseStr_HexToInt(checkstr); if (calc_checksum == in_checksum){ return 1; } else { return 0; } } ``` clearInputBuffer: ```c void clearInputBuffer(){ int i = 0; for(i = 0; i < 100; i++){ bufferIn[i] = ' '; } bufferIn[0] = '$'; } ```
(この問題は解決済みです)
本質的に私の問題の原因は、sprintf
プログラムコードの誤用とnull文字での上書きでした
ボードのメモリの bss セグメントを埋めているときに、ブレークポイント トラップが発生しました。
そして、4 ビット モードの LCD (すなわち、PA12、PA11、PB12、PB11、PB2、PB1、PB15) 用に 7 つの GPIO ポートを追加し、DMA モードの 2 チャネル ADC (PA1、PA0) 用に 2 つ追加した後:
プログラム受信シグナル SIGTRAP、トレース/ブレークポイント トラップ。LoopFillZerobss () at ..\startup/startup_stm32f334x8.s:103 103 cmp r2, r3 LCD と ADC 機能を実装しようとしているときに、スタートアップのLoopF illZerobss 関数でブレークポイント トラップ エラーが発生しました。まったく(ただし、バイトを割り込みとして受信し、トークンを処理することはできますなど、送信を拒否するだけです)、bss セグメントを読み取った後、可能な限り多くのグローバル変数をゼロ以外の値に初期化して問題を解決しようとしましたが、これは機能しませんでした。STM32CubeMx 設定を追加した後に問題が観察されましたADC と LCD で使用される 7 つの GPIO ピンの場合、ただし、CubeMX によって生成された事前定義されたコードがメモリの bss セグメントの境界を超えていて、bss セグメントのサイズが大きすぎる場合を除き、私の知る限り、これらのいずれも初期化された変数を使用しません。ボードのメモリが大きくなっています (可能性は低いと思われますが、除外することはできません)。
基本的に、このプロジェクトのアイデアは、USART、ADC、およびその後の I2C を介してさまざまなデータを受信し、USART および LCD を介してデータのさまざまな側面を表示することです。ADC および LCD エラーを破棄すると、USART コードは memset() エラーとして機能します。致命的ではありませんが、そのままにしておくと後で問題が発生するだけだと思いますが、トークン化コードをどこで修正すればよいかわかりません。これが問題の根本であると仮定します。