2017-07-28 3 views
0

私はデバイス用のファームウェアアップデータアプリケーションを構築し、ホストアプリケーションはシリアル接続を介してデバイスに接続します。アプリは小さなアプリ(〜18KB)で作業していましたが、最近はファームウェアのサイズを〜200KBに引き上げました。SerialPort書き込みコマンドでデバッガを中断する

これで、ホストアプリケーション(C#)はシリアルポートでハングし、デバッグでプログラムを一時停止するとデバッガブレークが表示されます。

以下のコードは、.HEXファイルを1行ずつ(図示せず)読み込み、UART(シリアル通信)を使用して1バイトずつ256バイトのブロックを書き込みます。 256バイト後、ブロックに対してチェックサムが送信され、ループは次の転送をセットアップするために残されます。

アプリが書き込みコマンドでハングする理由は何ですか?ブロック間で行わなければならないポートやバッファのメンテナンスはありますか?私はブロック(0から255)のバイトカウンタを見ることができ、同じバイト番号でハングしません。

このアプリケーションは、STM32F417IGT開発ボードのARMプロセッサに接続しています。

ありがとうございました!コード内

code block showing debug break on serialPort Write

完全ライト機能、:

public void WriteNewAppToFlash(SerialPort _serialPort) 
    { 
     int byte_read = 0; 
     long checksum = 0; 
     var ff = new byte[] { 0xFF }; 

     // ------------------------------------------------------------------------------ 
     // -------- WRITE MEMORY -------------------------------------------------------- 
     // ------------------------------------------------------------------------------ 

     // for Address 
     int baseAddress = 0x08004000; 
     int offset = 0; 

     // for string from HEX file 
     string line; 
     int length; 
     int type; 
     int hexChecksum = 0; 

     bool sendAddress = true; 

     int counter = 0;   // Counting the number of lines in the file 
     int byteCounter = 0;  // Counting nmumber of bytes in the current block 

     // Read the file and process one line at a time 
     System.IO.StreamReader file = new System.IO.StreamReader(path); 
     while ((line = file.ReadLine()) != null) 
     { 
      if (sendAddress == true) 
      { 
       /* 
    ------------------------------------------------------------------------------------------------------- 
        SEND WRITE COMMAND 
    -----------------------------------------------------------------------------------------------------*/ 

       // Send 0x43 (erase memory) and 0xBC 
       var writeMem = new byte[] { 0x31 }; 
       var ce = new byte[] { 0xCE }; 

       _serialPort.Write(writeMem, 0, 1); 
       //Console.WriteLine("writeMem = 0x" + BitConverter.ToInt32(writeMem, 0).ToString("X")); 

       _serialPort.Write(ce, 0, 1); 
       //Console.WriteLine("CE = 0x" + BitConverter.ToInt32(writeMem, 0).ToString("X")); 

       // Receive ACK byte 
       byte_read = _serialPort.ReadByte(); 
       //Console.WriteLine("ACK = 0x" + byte_read.ToString("X")); 
       //Console.WriteLine(""); 

       if (byte_read == NACK) 
       { 
        //Console.WriteLine("NACK received for WRITE MEMORY start"); 
        //Console.WriteLine(""); 
       } 


       // -- end SEND 0x31 and 0xCE and wait for ACK ----------------------------------------- 


    ------------------------------------------------------------------------------------------------------- 
       SEND CURRENT ADDRESS AND CHECKSUM TO FLASH MEMORY 
    -----------------------------------------------------------------------------------------------------*/ 

       Byte[] currentAddr = BitConverter.GetBytes(baseAddress + offset); 

       // Increment offset by 0x100 (256 bytes) 
       offset = offset + 0x00000100; 

       //int msb; 

       // Reset Checksum and XOR address 
       checksum = 0; 
       foreach (byte b in currentAddr) 
       { 
        checksum ^= b; 
       } 

       //Console.WriteLine("cksum = " + checksum); 

       Byte[] cksum = BitConverter.GetBytes(checksum); 

       // Send address, MSB first, LSB last 
       _serialPort.Write(currentAddr, 3, 1); 
       _serialPort.Write(currentAddr, 2, 1); 
       _serialPort.Write(currentAddr, 1, 1); 
       _serialPort.Write(currentAddr, 0, 1); 

       // Send checksum of address bytes 
       _serialPort.Write(cksum, 0, 1); 

       // Receive ACK byte 
       byte_read = _serialPort.ReadByte(); 
       //Console.WriteLine("ACK = 0x" + byte_read.ToString("X")); 
       //Console.WriteLine(""); 

       if (byte_read == NACK) 
       { 
        //Console.WriteLine("NACK received for WRITE MEMORY address received"); 
        //Console.WriteLine(""); 
       } 
       // -- end addr or increment --------------------------------------------------------- 

       sendAddress = false; 

       // Send number of bytes, always 256, the last group will be padded with 0xFF 
       _serialPort.Write(ff, 0, 1); 

       hexChecksum = 0; 

      } // end IF for WRITE COMMAND and ADDRESS 
      /* 
      ------------------------------------------------------------------------------------------------------- 
      WRITE 256 BYTES FROM HEX FILE TO FLASH MEMORY 
      -----------------------------------------------------------------------------------------------------*/ 
      // FIRST CHARACTER in HEX FILE 
      // The colon indicates the start of a "record" 
      // Remove colon from beginning of string 
      line = line.Substring(1, line.Length - 1); 
      //Console.WriteLine(line); 

      // Create byte array from string 
      var bytes = GetBytesFromByteString(line).ToArray(); 

      // Assign values to variables from byte array 
      type = bytes[3]; 

      /* Next TWO CHARACTERS in HEX FILE  00-data 
       are the record type:     01-EOF 
                02- 
                03- 
                04-  
                05-        */ 

      // Check type for data = 00 
      if (type == 0) 
      { 
       // The first two characters represent the number of data bytes for the record 
       // Obtain length, convert to int (counter for sending data) 

       length = bytes[0]; 

       for (int i = 0; i < length; i++) 
       { 
        // Send individual characters to device 
        _serialPort.Write(bytes, 4 + i, 1); 

        //Thread.Sleep(100); 

        // increment counter 
        byteCounter++; 

        if(byteCounter % 32 == 0) 
        { 
         Thread.Sleep(40); 
        } 

        // Add byte to checksum 
        hexChecksum ^= bytes[4 + i]; 
        //Console.WriteLine("cum checksum = " + hexChecksum); 


        // If counter == 256, reset counter, send checksum 
        if (byteCounter == 256) 
        { 
         sendAddress = true; 
         byteCounter = 0; 
         //Console.WriteLine("checksum = " + hexChecksum.ToString("X")); 

         // Convert checksum to a byte value and send 
         hexChecksum = hexChecksum^0xFF; 
         byte csByte = Convert.ToByte(hexChecksum); 
         //Console.WriteLine("CSBYTE = " + Convert.ToInt32(csByte)); 

         Byte[] csByte_arr = BitConverter.GetBytes(csByte); 
         _serialPort.Write(csByte_arr, 0, 1); 


         // Receive ACK byte 
         byte_read = _serialPort.ReadByte(); 
         //Console.WriteLine("ACK = 0x" + byte_read.ToString("X")); 
         //Console.WriteLine(""); 

         if (byte_read == NACK) 
         { 
          //Console.WriteLine("NACK received for write memory DATA received"); 
          //Console.WriteLine(""); 
         } 
        } // end IF byteCounter == 256 

        //Console.WriteLine(byteCounter); 

       } // end FOR loop 

      } 
      else if (type == 5) 
      { 
       // Address thingy 
       //Console.WriteLine("Hit address thingy"); 
       //Console.WriteLine(""); 
      } 
      else if (type == 1) // Check for end of file 
      { 
       // End of file 

       while (byteCounter != 0) 
       { 

        // Send individual bytes to device 
        _serialPort.Write(ff, 0, 1); 

        // increment counter 
        byteCounter++; 

        // Add byte to checksum 
        hexChecksum ^= 0xFF; 
        //Console.WriteLine("cum checksum = " + hexChecksum); 

        if (byteCounter == 256) 
        { 
         byteCounter = 0; 
         hexChecksum = hexChecksum^0xFF; 
         byte csByte = Convert.ToByte(hexChecksum); 
         //Console.WriteLine("CSBYTE = " + Convert.ToInt32(csByte)); 

         Byte[] csByte_arr = BitConverter.GetBytes(csByte); 
         _serialPort.Write(csByte_arr, 0, 1); 

         // Receive ACK byte 
         byte_read = _serialPort.ReadByte(); 
         //Console.WriteLine("ACK = 0x" + byte_read.ToString("X")); 
         //Console.WriteLine(""); 

         if (byte_read == NACK) 
         { 
          //Console.WriteLine("NACK received for write memory DATA received"); 
          //Console.WriteLine(""); 
         } 
        } 
       } 
      } // end ELSE if TYPE == 1 

      counter++; 
     } // end WHILE loop for loading hex file 

     file.Close(); 
     //System.Console.WriteLine("There were {0} lines.", counter); 
     //Console.WriteLine(""); 

     // -- end WRITE MEMORY ------------------------------------------------------ 

    } // end WriteNewAppToFlash 

256バイトのブロックを書き込むためのコードを変更しました。これで2つのブロックが書き込まれ、3番目のブロックは書き込まれません。プログラムはWrite行に実行され、バイトバッファはいっぱいですが、書き込みを開始しません。

if (byteCounter >= 255) 
       { 

        // Convert checksum to a byte value 
        hexChecksum = hexChecksum^0xFF; 
        byte csByte = Convert.ToByte(hexChecksum); 
        Byte[] csByte_arr = BitConverter.GetBytes(csByte); 

        do 
        { 
         // send byte array 
         _serialPort.Write(buffer256, 0, 256); 
         Thread.Sleep(70); 

         // send checksum 
         _serialPort.Write(csByte_arr, 0, 1); 

         // Receive ACK byte 
         byte_read = _serialPort.ReadByte(); 
         Thread.Sleep(100); 

         if (byte_read == NACK) 
         { 
          //Console.WriteLine("NACK received for write memory DATA received"); 
          //Console.WriteLine(""); 
         } 
        } while (byte_read != ACK);  

        // Clear buffer, reset byte count, set flag to send write cmd and send new addr 
        Array.Clear(buffer256, 0, buffer256.Length); 
        byteCounter = 0; 
        sendAddress = true; 
       } 
+0

コードのスクリーンショットではなく、コードを投稿してください。 –

+0

なぜVSはデバッガのブレークポイントと言っていますか? SerialPortの書き込みメソッドにブレークポイントが設定されていますか? –

+0

これは、プログラムがハングしている場所です。その時点でシリアル接続が機能しなくなり、一時停止ボタンを押すとデバッガブレークがシリアルポート書き込みコード行に表示されます。私はその行にどんなタイプのブレークをも持っていません。 – Gordon

答えて

0

私は最終的にこのアプリケーションを動作させましたが、それが動作する正確な理由は不明です。ここで私が見たものと私が行った変更は次のとおりです。

バッファに256を配置して一度にすべてを送信し、次にチェックサムを送信するまで、1バイトを送信してから256バイトの最後にチェックサムを切り替えます。この方法は最初は失敗していましたが、以前の方法より速くなっていました。

HEXコードの行の処理順序を変更し、ブロックが送信準備ができていることを確認しました(下のコードを参照)。違いは小さいですが、何よりもすべてが機能するようになっているようです。以前は、256バイトを送信し、それを送信してから256行の次のブロックにデータを入れました。私はコードをステップ実行して失敗するようなものは見ませんでしたが、完了しているに違いありません何か。

それ以来、このアプリはうまくいきました。組み込みデバイスで.NET SerialPortクラスを使用することについて、私はもはや心配していません。

// BLOCK WRITE TO MEMORY 
      if (type == 0) 
      { 
       // Length of line is stored at byte 0, in this case 0x10, or 16 bytes of data 
       length = bytes[0]; 

       // Add data from current line to buffer of 256 bytes 
       for (int i = 0; i < length; i++) 
       { 
        // Stuff all bytes from line into buffer of 256 bytes 
        buffer256[byteCounter++] = bytes[4 + i]; 

        // Add byte to checksum 
        hexChecksum ^= bytes[4 + i]; 
       } 

       // When buffer is full, send block of 256 bytes and checksum, reset variables for next block 
       if (byteCounter >= 255) 
       { 

        // Convert checksum to a byte value 
        hexChecksum = hexChecksum^0xFF; 
        byte csByte = Convert.ToByte(hexChecksum); 
        Byte[] csByte_arr = BitConverter.GetBytes(csByte); 

        // Send byte array 
        _serialPort.Write(buffer256, 0, 256); 

        // For testing 
        // Console.WriteLine("block number [{0}]", ++blockCount); 

        //send checksum 
        _serialPort.Write(csByte_arr, 0, 1); 

        //Receive ACK byte 
        byte_read = _serialPort.ReadByte(); 
        Console.WriteLine("block/ACK = [{0}] | {1}", ++blockCount, byte_read); 

        while (byte_read != ACK) 
        { 
         Array.Clear(buffer256, 0, buffer256.Length); 
         hexChecksum = 0; 
         lineCount = 0; 

         // reprocess the previous 16 lines stored in the line buffer 
         for (int j = 0; j < 16; j++) 
         { 
          line = lineBuffer[j]; 

          line = line.Substring(1, line.Length - 1); 
          var bytesLocal = GetBytesFromByteString(line).ToArray(); 

          length = bytesLocal[0]; 
          for (int i = 0; i < length; i++) 
          { 
           buffer256[byteCounter++] = bytesLocal[4 + i]; 
           hexChecksum ^= bytesLocal[4 + i]; 
          } 
         } 

         // Convert checksum to a byte value 
         hexChecksum = hexChecksum^0xFF; 
         byte csByteLocal = Convert.ToByte(hexChecksum); 
         Byte[] csByte_arrLocal = BitConverter.GetBytes(csByteLocal); 

         // Send byte array 
         _serialPort.Write(buffer256, 0, 256); 

         //send checksum 
         _serialPort.Write(csByte_arrLocal, 0, 1); 

         //Receive ACK byte 
         byte_read = _serialPort.ReadByte(); 
         Console.WriteLine("block/ACK = [{0}] | {1}", ++blockCount, byte_read); 

        } 

        // Clear buffer, reset byte count, clear checksum, set flag to send write cmd/send new addr 
        Array.Clear(buffer256, 0, buffer256.Length); 
        byteCounter = 0; 
        hexChecksum = 0; 
        lineCount = 0; 
        sendAddress = true; 
       } 

      } // end BLOCK WRITE TO MEMORY 
関連する問題