zoukankan      html  css  js  c++  java
  • 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); //恢复出厂设置
  • 相关阅读:
    软件测试理论基础
    使用Pycharm官方统计代码行插件统计代码总行数
    Jmeter的配置文件解析
    python异常整理
    python2与python3的区别
    tomcat的server.xml配置
    异常:Error response from daemon: conflict: unable to delete 6fa48e047721 (cannot be forced)
    前端 -- 定位和z-index
    前端 -- background
    前端 -- 超链接导航栏案例
  • 原文地址:https://www.cnblogs.com/zhangxuechao/p/11709648.html
Copyright © 2011-2022 走看看