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    //复位
Created with Raphaël 2.1.2PCPCBSLBSL解锁BSLBSL检验。检验成功解锁BSL成功返回0x00;失败返回0x05擦除整块flash成功返回0x00;失败返回0x04写flash成功返回0x00;失败返回0x04获取bsl version成功返回version;失败返回0x04读flash成功返回flash数据;失败返回0x04flash数据记录到文件复位

数据结构

数据结构

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); //恢复出厂设置
posted @ 2017-06-13 17:06  thomas_blog  阅读(231)  评论(0编辑  收藏  举报