很多人不知道,STM32中内嵌了一段自举程序
网站:bbs.21ic.com
02.System memory:系统存储器
03.Embedded SRAM:内置SRAM
三种模式是通过不同配置来实现,一般通过BOOT引脚和BOOT位来配置启动模式。不同的芯片配置有差异,有些芯片没有BOOT1引脚,会结合BOOT位来实现。
STM32内嵌的自举程序存放在系统存储区,由ST在生产线上写入,用户不能修改。我们选择System memory(系统存储器)启动模式,就会进入系统存储区执行自举程序,内嵌的自举程序主要用于通过串行、IIC、SPI、USB、CAN等接口与外部通讯。不同型号MCU支持的串行接口不一样,具体请参看应用笔记 AN2606。
5.自举程序上位机(自己使用Qt编写的,主要用于测试)
读取Hex文件 和拼Hex文件代码开源给大家
// 读取芯片内部flash数据
// 地址范围:0x0800 0000 ~ 0x0801 ffff 128K Byte
// 循环读取,每次读取16个字节,读取128K Byte /16Byte = 8000 次
int base = 0x08000000;
for(int i =0;i<8000;i++)
{
//1.发送读内存命令
UartSendHex('11ee');
Sleep(5);
//2.发送地址和校验和
int offer = base + i*16;
QString offer_str = QString::number(offer,16);
if(offer_str.size()<8)
offer_str.insert(0,'0');
QString check_str;
check_str = getXORresult(offer_str.mid(0,2), offer_str.mid(2,2));
check_str = getXORresult(check_str, offer_str.mid(4,2));
check_str = getXORresult(check_str, offer_str.mid(6,2));
UartSendHex(offer_str+check_str);
Sleep(5);
//3.发送要读取的字节数和效验和
QByteArray ByteNum = '0ff0';
UartSendHex(ByteNum);
Sleep(5);
ui->progressBar->setFormat(QString::fromLocal8Bit('%1%').arg(QString::number((i+1)/10, 'f', 1)));
ui->progressBar->setValue((i+1)/10);
}
// Qt flash数据 转 hex文件算法
int t = 0,g = 0;
QString text = ui->textEdit_Recv->toPlainText();
QStringList number_list = text.split('\n');
QStringList result_list;
// 遍历字符串列表,滤除全ffff.........结尾,记录行数
for(int i = 0; i < number_list.size(); ++i)
{
if(number_list.at(i) == 'ffffffffffffffffffffffffffffffff')
{
t = i;
break;
}
}
// 遍历字符串列表斩断行,滤除改行的 ffff.........
text.clear();
text = number_list.at(t-1);
for(int i =0;i<text.size();i++)
{
if((text.at(i) == 'f')&&(text.at(i+1) == 'f')&&(i%2 == 0))
{
g = i;
break;
}
}
// 拼接新的全数据的字符串列表
for(int i =0;i<t-1;i++)
{
result_list<<number_list.at(i);
}
if(g!=0)
{
text = text.remove(g,32-g);
result_list<<text;
}
//生成HEX文件
//1.添加 10 字节数
text.clear();
QStringList result_list1;
for(int i = 0; i < t; ++i)
{
text = result_list.at(i);
if(i!=t-1)
text = text.insert(0,'10');
else
{
QString str = QString::number(text.size()/2,16);
if(str.size()<2)
str.insert(0,'0');
text = text.insert(0,str);
}
result_list1 << text;
}
//2.添加地址偏移
QStringList result_list2;
int offer = 0x0000;
QString offer_str;
text.clear();
for(int i = 0; i < t; ++i)
{
offer = i*16;
offer_str = QString::number(offer,16);
if(offer_str.size()<4)
{
if(offer_str.size() == 1)
offer_str.insert(0,'000');
if(offer_str.size() == 2)
offer_str.insert(0,'00');
if(offer_str.size() == 3)
offer_str.insert(0,'0');
}
text = result_list1.at(i);
text = text.insert(2,offer_str);
result_list2 << text;
}
//3.添加效验和
// 以020000040003F7为例子
//具体算法为 0x100-((0x02+0x00+0x00+0x04+0x00+0x03)%256)= 0xF7
text.clear();
bool ok;
int check;
QString check_str;
QStringList result_list3;
for(int i = 0; i < t; ++i)
{
text = result_list2.at(i);
check = 0;
for(int j=0;j<text.size();j++)
{
check += text.mid(j*2,2).toInt(&ok,16);
}
check = (0x100 - check%256);
check_str = QString::number(check,16);
if(check_str.size()<2)
check_str = check_str.insert(0,'0');
text = text.insert(text.size(),check_str);
result_list3<<text;
}
//4.添加冒号 :
QStringList result_list4;
text.clear();
for(int i = 0; i < t; ++i)
{
text = result_list3.at(i);
text = text.insert(0,':');
result_list4<<text;
}
//5.添加HEX头部
QString hear=':020000040800f2';
//QStringList result_list5;
result_list4.insert(0,hear);
//6.添加HEX尾部
QString tail1=':04000005080001cd21';
QString tail2=':00000001ff';
result_list4.insert(t+2,tail1);
result_list4.insert(t+3,tail2);
//7.保存数据为.hex文件
...............