我为一个器件构建了一个固件更新器应用程序,主机应用程序通过串行连接连接到器件。该应用程序一直在小应用程序(〜18KB)上工作,我最近将固件大小提高到〜200KB。在串行端口上获取调试器中断写入命令
现在,主机应用程序(C#)挂在串行端口上,并在调试中暂停程序显示一个Debugger Break。
下面的代码逐行读取一个.HEX文件(未显示),并使用UART(串行通信)一次写入一个字节的256字节块。在256字节之后,为块发送校验和,并且留下循环以设置下一次传输。
什么可能是应用程序挂在写命令的原因?是否需要在块之间进行一些端口或缓冲区维护?我可以看到该块的字节计数器(0到255),它不会挂在相同的字节数上。
此应用程序正在连接到STM32F417IGT开发板上的ARM处理器。
感谢您的帮助!
完成写入功能,在代码:
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个字节的块。它现在写入两个块,不会写入第三个块。程序执行到写入行,字节缓冲区已满,但不会启动写入。
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;
}
请张贴代码,而不是代码的截图。 –
为什么VS说,调试器断点?您在SerialPort的Write方法上设置了一个断点? –
这是程序挂起的地方。此时串行连接已停止工作,当我点击暂停按钮时,Debugger Break显示串行端口写入代码行。我没有任何类型的中断线。 – Gordon