C語言PIC18 serial bootloader和C#語言bootloader PC端串口通信程序
新PIC18 Bootloader
PhsBoot_v3.0是我最新用C語言實現(xiàn)的PIC bootloader, 采用串口通信,適用于PIC18, 并為其用C#寫了PC端通信程序PhsLoader_v3.0。PhsLoader_v3.0通過串口按照自定義的通信協(xié)定發(fā)送數(shù)據(jù)PhsBoot_v3.0, PhsBoot_v3.0接收數(shù)據(jù),按照通信協(xié)定解讀數(shù)據(jù),解讀出其中Hex數(shù)據(jù),并將其燒錄到正確的位置。
通信協(xié)定
PIC18單片機端PhsBoot_v3.0和PC端PhsLoader_v3.0之間的通信數(shù)據(jù)包采用以下協(xié)定
定義如下:
STX - Start of packet indicator
ETX - End of packet indicator
LEN - The length of true data
DATA - General data 16 bytes, only first LEN of datas are true
CMD - Base command
ADDR - Address up to 24 bits ( ADDRL , ADDRH , ADDRH)
具體有以下Base command:
RD-VER: 0x00 -- Read Version Information (最終版本刪除了此命令)
RD_MEM: 0x01 -- Read Program Memory (最終版本刪除了此命令)
ER_MEM: 0x03 -- Erase Program Memory
WR_MEM: 0x02 -- Write Program Memory
WR_CFG: 0x04 -- Write Configuration Registers
PhsLoader_v3.0 功能
定義好了通訊協(xié)定, 接著就按照協(xié)定去實現(xiàn)PhsLoader_v3.0。 PhsLoader_v3.0的具體功能包括選擇COM端口和BAUD RATE, 連接COM, 加載應(yīng)用程序Hex文件,Parse 應(yīng)用程序的Hex文件,一行一行解讀Hex文件,然后按照通訊協(xié)定通過串口發(fā)送Hex記錄到單片機,接收單片機發(fā)送回來的Response,發(fā)送完畢后斷開COM連接,發(fā)送期間出現(xiàn)問題就立馬結(jié)束發(fā)送。
PhsLoader_v3.0 主要代碼段
PhsLoader_v3.0是用C#實現(xiàn)的,是我在利用空余時間自學(xué)C#后寫的,上面提到的功能都實現(xiàn)了。
private void btnDownload_Click(object sender, EventArgs e)
{
btnDownload.Enabled = false;
pBarLoading.Visible = false;
if (!this.connect())
{
btnDownload.Enabled = true;
return;
}
try
{
loaderReader = new StreamReader(textBoxFile.Text);
}
catch (Exception ex)
{
Debug.WriteLine("Error: " + ex.Message);
textBoxStatus.ForeColor = Color.Red;
textBoxStatus.AppendText("Read hex file unsuccessfullyrn");
textBoxStatus.ForeColor = Color.Black;
loaderReader.Close();
loaderSerial.Close();
btnDownload.Enabled = true;
return;
}
loaderFrame = new SerialFrame();
if (!erase())
{
textBoxStatus.ForeColor = Color.Red;
textBoxStatus.AppendText("Erase unsuccessfullyrn");
textBoxStatus.ForeColor = Color.Black;
loaderReader.Close();
loaderSerial.Close();
btnDownload.Enabled = true;
return;
}
pBarLoading.Refresh();
pBarLoading.Visible = true;
pBarLoading.Value = 0;
pBarLoading.Maximum = loaderLines;
pBarLoading.Step = 1;
string recordLine;
Address_U = 0;
bool isNextLineUserID = false;
bool isNextLineConfigBits = false;
textBoxStatus.AppendText("rnDownloading hex file ...rn");
try
{
while (loaderReader.Peek() >= 0)
{
pBarLoading.PerformStep();
recordLine = loaderReader.ReadLine();
//if (recordLine.Contains(USER_ID_TOKEN) == true)
//{
// isNextLineUserID = true;
// continue;
//}
//else if (recordLine.Contains(CONFIG_BITS_TOKEN) == true)
//{
// isNextLineConfigBits = true;
// continue;
//}
if (recordLine.Contains(EXTEND_TOKEN) == true)
{
if (recordLine.Contains(USER_ID_TOKEN) == true)
{
isNextLineUserID = true;
continue;
}
else if (recordLine.Contains(CONFIG_BITS_TOKEN) == true)
{
isNextLineConfigBits = true;
continue;
}
else
{
const int ADDR_U_START_INDEX = 9;
const int ADDR_U_LENGTH = 4;
string addrU = recordLine.Substring(ADDR_U_START_INDEX, ADDR_U_LENGTH);
Address_U = Convert.ToInt32(addrU, 16) << 16;
continue;
}
}
else if (recordLine.Contains(END_OF_HEX_FILE_TOKEN) == true)
{
break;
}
if (isNextLineUserID)
{
isNextLineUserID = false;
// do nothing;
}
else if (isNextLineConfigBits)
{
if (!DownloadConfigLine(recordLine))
{
Debug.WriteLine("Error found during configuration bits programming");