MSP432 BSL流程(UART)
升级流程
PC程序会解析脚本中的命令,根据命令码做相应的操作。数据来自于命令后的文件(当前目录下的数据文件)
# cat script_P4xx_uart.txt
LOG //记录日志
MODE P4xx UART 9600 COM25 PARITY //初始化串口
RX_PASSWORD_32 .\pass256_wrong.txt //解锁BSL
RX_PASSWORD_32 .\pass256_default.txt
MASS_ERASE //擦除整块flash
RX_DATA_BLOCK_32 Blink_LED.txt //写flash
//RX_DATA_BLOCK_32 Blink_LED.hex
TX_BSL_VERSION_32 //获取bsl version
TX_DATA_BLOCK_32 0x0000 0x4000 ReadBlock_MSP432P401R.txt //读flash
//TX_DATA_BLOCK_32 0x0000 0x4000 ReadBlock_MSP432P401R.hex
REBOOT_RESET //复位
数据结构
PC侧
COMMANDS
需要处理的命令列表,所有的操作都是以命令形式触发
#define COMMANDS(DO) \
DO(LOG) \
DO(MODE) \
DO(RX_DATA_BLOCK) \
DO(RX_PASSWORD) \
DO(ERASE_SEGMENT) \
DO(TOGGLE_INFO) \
DO(ERASE_BLOCK) \
DO(MASS_ERASE) \
DO(CRC_CHECK) \
DO(SET_PC) \
DO(TX_DATA_BLOCK) \
DO(TX_BSL_VERSION) \
DO(TX_BUFFER_SIZE) \
DO(RX_DATA_BLOCK_FAST) \
DO(RX_DATA_BLOCK_32) \
DO(RX_PASSWORD_32) \
DO(ERASE_SEGMENT_32) \
DO(REBOOT_RESET) \
DO(CRC_CHECK_32) \
DO(SET_PC_32) \
DO(TX_DATA_BLOCK_32) \
DO(TX_BSL_VERSION_32) \
DO(RX_SECURE_DATA_BLOCK) \
DO(CHANGE_BAUD_RATE) \
DO(FACTORY_RESET) \
DO(JTAG_LOCK) \
DO(JTAG_PASSWORD) \
DO(VERBOSE) \
DO(DELAY) \
DO(CUSTOM_COMMAND)
主要函数
命令处理中,主要命令处理函数是:接收命令处理函数和发送命令处理函数
void Interpreter::executeCommand(CommandParams cmd); //命令处理
void Interpreter::executeRxCommand(); //接收命令
void Interpreter::executeTxCommand(); //发送命令
void UartComm::transmitBuffer(std::vector<uint8_t>* txBuffer); //发送数据
std::vector<uint8_t>* UartComm::receiveBuffer(int32_t size); //接收数据
init
初始化的时候,PC发送一个字节“0xFF”,MSP432去计算波特率,然后回应PC一个字节“0x00”,初始化成功。连续发送10次,直到初始化成功,否则初始化失败
void UartComm::init(ModeParams* modeParams);
void UartComm::transmitP4xxInitialization();
const uint8_t loopInitialization = 10;
transmitBuffer
每当发送数据完成,PC端都会验证MSP432回应的ACK是否正确,如果不正确,很可能MSP432没有接收到数据
Header = 0x80
txBuffer->size() & 0xFF
(txBuffer->size() >> 8) & 0xFF
txBuffer //数据
getCheckSumLow()
getCheckSumHigh()
receiveBuffer
接收数据格式和发送数据格式一致。接收延时1000ms,接收端会首先接收并检查ack是否正确,接收buf是256个字节
uint32_t msDelay = 1000;
this->setTimer(msDelay);
this->startReadAck(&ack, expSize);
Header = 0x80
rxUartBuffer = 256
MSP432侧
中断注册
#define BSL432_MAX_BUFFER_SIZE 262 //buf大小262个字节
volatile uint8_t BSL432_RAM_TX_Buf[BSL432_MAX_BUFFER_SIZE + 6]; //6:Header + Buffersize + CheckSum
MAP_GPIO_registerInterrupt(BSL432_UART_PORT, BSL432_PI_UARTdetect);
BSL432_PI_initUART(BSL432_UARTBaudRates9600);
BSL432_PI_sendByteUART(BSL432_ACK);
BSL432_PI_UARTdetect:中断处理函数。响应PC端初始化流程,计算波特率并初始化UART,最后回应PC ACK
MAP_UART_registerInterrupt(BSL432_UART_MODULE, BSL432_PI_IRQ_UART);
void BSL432_PI_IRQ_UART(void);
uint8_t receivedData = MAP_UART_receiveData(BSL432_UART_MODULE);
BSL432_ReceiveBuffer[BSL432_PI_IRQ_RxDataCnt++] = receivedData;
BSL432_PI_IRQ_UART:接收中断处理函数。当有中断触发,MSP432开始接收数据,把数据保存到BSL432_ReceiveBuffer中,直到接收完成
数据解析
BSL432_eventFlags BSL432_PI_receivePacketUART();
数据解析由BSL432_PI_receivePacketUART函数完成。主要功能是校验头,记录数据大小,校验checksum
BSL循环去接收串口数据,直到收完指定Buffersize大小,做一次处理
数据处理
void BSL432_CI_interpretCommand();
当一个正确的包接收并解析完成,由BSL432_CI_interpretCommand做数据处理并回应PC ACK
BSL432 Commands
BSL侧命令列表,和PC侧是一一对应的
#define BSL432_RX_DATA_BLOCK 0x10
#define BSL432_RX_DATA_BLOCK_32 0x20
#define BSL432_RX_PASSWORD 0x21
#define BSL432_ERASE_SECTOR 0x12
#define BSL432_ERASE_SECTOR_32 0x22
#define BSL432_RX_MASS_ERASE 0x15
#define BSL432_REBOOT_RESET 0x25
#define BSL432_RX_CRC_CHECK 0x16
#define BSL432_RX_CRC_CHECK_32 0x26
#define BSL432_RX_LOAD_PC 0x17
#define BSL432_RX_LOAD_PC_32 0x27
#define BSL432_TX_DATA_BLOCK 0x18
#define BSL432_TX_DATA_BLOCK_32 0x28
#define BSL432_TX_BSL_VERSION 0x19
#define BSL432_FACTORY_RESET 0x30
#define BSL432_CHANGE_BAUD_RATE 0x52
BSL432_RX_DATA_BLOCK
void BSL432_CI_receiveDataBlock(uint32_t addr, uint8_t *data)
{
uint8_t returnValue = BSL432_API_openMemory(); //flash写使能
// Check if there is data in buffer (cmd + addr take 4 bytes, 24 bit addr)
if((returnValue == BSL432_SUCCESSFUL_OPERATION) & (BSL432_ReceiveBufferSize > 4))
{
returnValue = BSL432_API_writeMemory(addr, BSL432_ReceiveBufferSize - 4, data); //写flash
}
BSL432_CI_sendMessage(returnValue); //回应PC
BSL432_API_closeMemory(); //flash写锁定
}
BSL432_CI_receivePassword
解锁BSL。对flash操作首先需要flash为非锁定状态,否则操作失败
void BSL432_CI_receivePassword()
{
if (BSL432_API_unlockBSL(&BSL432_ReceiveBuffer[4]) == BSL432_SUCCESSFUL_OPERATION)
{
BSL432_CI_sendMessage(BSL432_ACK); //回应PC
}
else
{
BSL432_CI_sendMessage(BSL432_PASSWORD_ERROR);
}
}
BSL432_ERASE_SECTOR
uint8_t BSL432_API_eraseSector(uint32_t addr)
{
uint8_t exceptions = BSL432_LOCKED;
if(BSL432_LockedStatus == BSL432_STATUS_UNLOCKED)
{
exceptions = BSL432_SUCCESSFUL_OPERATION;
exceptions = BSL432_API_openMemory();
#ifdef __MSP432P401R__
MAP_FlashCtl_eraseSector(addr); //擦除指定扇区
#elif defined __MSP432P4111__
MAP_FlashCtl_A_eraseSector(addr);
#else
#error Device not defined.
#endif
exceptions = BSL432_API_closeMemory();
}
else
{
exceptions = BSL432_LOCKED;
}
return exceptions;
}
BSL432_RX_MASS_ERASE
uint8_t BSL432_API_massErase(uint32_t locked); //擦除整块扇区
BSL432_RX_CRC_CHECK
void BSL432_CI_CRCCheck(uint32_t addr, uint32_t length); //CRC校验
BSL432_RX_LOAD_PC
uint8_t BSL432_API_callAddress(uint32_t addr); //加载指定地址程序
BSL432_TX_DATA_BLOCK
void BSL432_CI_sendDataBlock(uint32_t addr, uint32_t length); //获取指定地址数据,发送给PC
BSL432_TX_BSL_VERSION
BSL432_CI_sendDataBlock((uint32_t)(&BSL432_VersionVendor), 10); //获取版本,发送给PC
BSL432_REBOOT_RESET
void BSL432_API_rebootReset(); //重启
BSL432_FACTORY_RESET
uint8_t BSL432_API_factoryReset(uint8_t *data); //恢复出厂设置
MSP432 BSL流程(UART)的更多相关文章
- MSP下载方式
MSP430无论是仿真还是烧写程序,一般可以通过:JTAG.SBW.BSL接口进行. 1.JTAG是利用边界扫描技术,在430内部有逻辑接口给JTAG使用,内部有若干个寄存器连接到了430内部数据地址 ...
- MSP430常见问题之开发工具类
Q1:我自己做了一块MSP430F149的试验板,以前用下载线进行调试没有出现过问题,但是,最近我每次make后用下载线调试时,总是弹出一个窗口,给我提示:Could not find target ...
- [tty与uart]2.tty和uart的函数调用流程
以下是在include/uapi/linux/tty.h中定义了现有的线规号,如果需要定义新的,则需要在后面添加新的 /* line disciplines */ #define N_TTY 0 #d ...
- 【转】Android bluetooth介绍(二): android blueZ蓝牙代码架构及其uart 到rfcomm流程
原文网址:http://blog.sina.com.cn/s/blog_602c72c50102uzoj.html 关键词:蓝牙blueZ UART HCI_UART H4 HCI L2CAP ...
- [uart]2.tty和uart的函数调用流程
以下是在include/uapi/linux/tty.h中定义了现有的线规号,如果需要定义新的,则需要在后面添加新的 /* line disciplines */ #define N_TTY 0 #d ...
- AM335X UBOOT(以UART为例分析UBOOT主要流程)
UBOOT2016.05 UART初始化及设置 SPL阶段 第一部分C函数 |- s_init //(arch/arm/cpu/armv7/am33xx/board.c) |- set_uart_mu ...
- [ZigBee] 8、ZigBee之UART剖析·二(串口收发)
前言:上一节讲UART基本知识介绍完了,并深入剖析了一个串口发送工程,本节将进一步介绍串口收发! 1.初始化 在串口初始化部分,和上一节不同的地方是: 51 U0CSR |= 0x40; //允许接收 ...
- 1、CC2541蓝牙4.0芯片中级教程——基于OSAL操作系统的运行流程了解+定时器和串口例程了解
本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...
- 嵌入式Linux驱动学习之路(五)u-boot启动流程分析
这里说的u-boot启动流程,值得是从上电开机执行u-boot,到u-boot,到u-boot加载操作系统的过程.这一过程可以分为两个过程,各个阶段的功能如下. 第一阶段的功能: 硬件设备初始化. 加 ...
随机推荐
- 阶段5 3.微服务项目【学成在线】_day05 消息中间件RabbitMQ_11.RabbitMQ研究-工作模式-路由工作模式测试
先常见生产者 复制02的代码 先改一下交换机的名称 还需要制定routingKey.因为是两个消息 所以指定了两个routingKey 这里修改为当前指定的交换机名称 交换机和队列在绑定的时候指定我们 ...
- mfc递归删除文件夹
BOOL myDeleteDirectory(CString directory_path) //删除一个文件夹下的所有内容 { BOOL ret=TRUE; CFileFind finder; CS ...
- Qt编写安防视频监控系统11-动态换肤
一.前言 Qt中的动态换肤技术是非常一流的,直接调用qApp->setStyleSheet(qss);就可以对整个应用程序进行换肤,如果样式表内容不多,或者对应的贴图不对,效率还是蛮好的,不过据 ...
- [译] NAT - 网络地址转换(2016)
[译] NAT - 网络地址转换(2016) Published at 2019-02-17 | Last Update 译者序 本文翻译自 2016 年的一篇英文博客 NAT - Network A ...
- python 内置数据结构 字符串
字符串 一个个字符组成的有序的序列,是字符的集合 使用单引号,双引号,三引号引住的字符序列 字符串是不可变对象 Python3起,字符串就是Unicode类型 字符串定义 初始化 s1 = 'stri ...
- vue项目中使用v-for的方法莫名提示错误
错误示例: 解决方法一: 在v-for后面绑定key,示例如下→ 解决方法二: 点击左下角“设置”>“用户设置”内添加一下代码片段: { "vetur.validation.templ ...
- VC.VS版本&VC版本&OpenCV版本
1.VS版本 与 VC版本 的对应关系,以及opencv 对 VC版本 的支持情况 - 魔法学徒 - CSDN博客.html(https://blog.csdn.net/yefcion/article ...
- 在HTML5 中使用 kindeditor 的方法
1.打开:http://kindeditor.net/ke4/examples/default.html 2.查看源代码,另存为 3.打开http://kindeditor.net/demo.php, ...
- JavaScript 检测值
了解常见的真值和假值,可以增强判断能力.在使用if判断时,提升编码速度. 了解常见的检测和存在,一样可以增强判断能力,而且是必须掌握的. 数组和对象被视为真值 1 2 3 4 5 6 7 8 9 10 ...
- [LuoguP2151][SDOI2009]HH去散步_递推_矩阵乘法_图论
HH去散步 题目链接:https://www.luogu.org/problem/P2151 数据范围:略. 题解: 数据范围好小,让人不禁想用一些毒瘤算法,但是失败了. 这种类似时间啊这种有点重复味 ...