Upgrading binary packages by iap on xidatong-arm32

This commit is contained in:
wgzAIIT 2023-04-12 19:59:35 +08:00
parent d615793063
commit 85105cb65d
8 changed files with 1042 additions and 40 deletions

View File

@ -6,6 +6,9 @@ endif
ifeq ($(CONFIG_BSP_USING_OTA),y)
SRC_FILES += fsl_romapi.c flash.c mcuboot.c
ifeq ($(CONFIG_MCUBOOT_BOOTLOADER),y)
SRC_FILES += common.c ymodem.c
endif
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,275 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file: common.c
* @brief: file common.c
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2023/3/24
*/
#include "common.h"
/**
* @brief Convert an Integer to a string
* @param str: The string
* @param intnum: The intger to be converted
* @retval None
*/
void Int2Str(uint8_t* str, int32_t intnum)
{
uint32_t i, Div = 1000000000, j = 0, Status = 0;
for (i = 0; i < 10; i++)
{
str[j++] = (intnum / Div) + 48;
intnum = intnum % Div;
Div /= 10;
if ((str[j-1] == '0') & (Status == 0))
{
j = 0;
}
else
{
Status++;
}
}
}
/**
* @brief Convert a string to an integer
* @param inputstr: The string to be converted
* @param intnum: The intger value
* @retval 1: Correct
* 0: Error
*/
uint32_t Str2Int(uint8_t *inputstr, int32_t *intnum)
{
uint32_t i = 0, res = 0;
uint32_t val = 0;
if (inputstr[0] == '0' && (inputstr[1] == 'x' || inputstr[1] == 'X'))
{
if (inputstr[2] == '\0')
{
return 0;
}
for (i = 2; i < 11; i++)
{
if (inputstr[i] == '\0')
{
*intnum = val;
/* return 1; */
res = 1;
break;
}
if (ISVALIDHEX(inputstr[i]))
{
val = (val << 4) + CONVERTHEX(inputstr[i]);
}
else
{
/* return 0, Invalid input */
res = 0;
break;
}
}
/* over 8 digit hex --invalid */
if (i >= 11)
{
res = 0;
}
}
else /* max 10-digit decimal input */
{
for (i = 0;i < 11;i++)
{
if (inputstr[i] == '\0')
{
*intnum = val;
/* return 1 */
res = 1;
break;
}
else if ((inputstr[i] == 'k' || inputstr[i] == 'K') && (i > 0))
{
val = val << 10;
*intnum = val;
res = 1;
break;
}
else if ((inputstr[i] == 'm' || inputstr[i] == 'M') && (i > 0))
{
val = val << 20;
*intnum = val;
res = 1;
break;
}
else if (ISVALIDDEC(inputstr[i]))
{
val = val * 10 + CONVERTDEC(inputstr[i]);
}
else
{
/* return 0, Invalid input */
res = 0;
break;
}
}
/* Over 10 digit decimal --invalid */
if (i >= 11)
{
res = 0;
}
}
return res;
}
/**
* @brief Get an integer from the HyperTerminal
* @param num: The inetger
* @retval 1: Correct
* 0: Error
*/
uint32_t GetIntegerInput(int32_t * num)
{
uint8_t inputstr[16];
while (1)
{
GetInputString(inputstr);
if (inputstr[0] == '\0') continue;
if ((inputstr[0] == 'a' || inputstr[0] == 'A') && inputstr[1] == '\0')
{
Serial_PutString("User Cancelled \r\n");
return 0;
}
if (Str2Int(inputstr, num) == 0)
{
Serial_PutString("Error, Input again: \r\n");
}
else
{
return 1;
}
}
}
/**
* @brief Test to see if a key has been pressed on the HyperTerminal
* @param key: The key pressed
* @retval 1: Correct
* 0: Error
*/
uint32_t SerialKeyPressed(uint8_t *key)
{
if ((kLPUART_RxDataRegFullFlag)&LPUART_GetStatusFlags(LPUART1))
{
*key = LPUART_ReadByte(LPUART1);
return 1;
}
else
{
return 0;
}
}
/**
* @brief Get a key from the HyperTerminal
* @param None
* @retval The Key Pressed
*/
uint8_t GetKey(void)
{
uint8_t key = 0;
/* Waiting for user input */
while (1)
{
if (SerialKeyPressed((uint8_t*)&key)) break;
}
return key;
}
/**
* @brief Print a character on the HyperTerminal
* @param c: The character to be printed
* @retval None
*/
void SerialPutChar(uint8_t c)
{
LPUART_WriteByte(LPUART1,c);
while(!(kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1)))
{
}
}
/**
* @brief Print a string on the HyperTerminal
* @param s: The string to be printed
* @retval None
*/
void Serial_PutString(uint8_t *s)
{
while (*s != '\0')
{
SerialPutChar(*s);
s++;
}
}
/**
* @brief Get Input string from the HyperTerminal
* @param buffP: The input string
* @retval None
*/
void GetInputString (uint8_t * buffP)
{
uint32_t bytes_read = 0;
uint8_t c = 0;
do
{
c = GetKey();
if (c == '\r')
break;
if (c == '\b') /* Backspace */
{
if (bytes_read > 0)
{
Serial_PutString("\b \b");
bytes_read --;
}
continue;
}
if (bytes_read >= CMD_STRING_SIZE )
{
Serial_PutString("Command string size overflow\r\n");
bytes_read = 0;
continue;
}
if (c >= 0x20 && c <= 0x7E)
{
buffP[bytes_read++] = c;
SerialPutChar(c);
}
}
while (1);
Serial_PutString(("\n\r"));
buffP[bytes_read] = '\0';
}

View File

@ -25,7 +25,7 @@
/*******************************************************************************
* Prototypes
******************************************************************************/
uint8_t NorFlash_BUFFER[4096]; //4K buffer cache
uint8_t buffer[FLASH_PAGE_SIZE]; //256 bytes buffer cache
/*******************************************************************************
* Variables
@ -264,13 +264,13 @@ status_t FLASH_EraseSector(uint32_t addr)
* @param len :
* @retval kStatus_Success
*/
status_t FLASH_WritePage(uint32_t addr, const uint8_t *buf, uint32_t len)
status_t FLASH_WritePage(uint32_t addr, const uint32_t *buf, uint32_t len)
{
status_t status;
addr &= 0x0FFFFFFF;
__disable_irq();
norConfig.pageSize = len;
status = ROM_FLEXSPI_NorFlash_ProgramPage(0, &norConfig, addr, (const uint32_t *)buf);
status = ROM_FLEXSPI_NorFlash_ProgramPage(0, &norConfig, addr, buf);
__enable_irq();
return status;
@ -282,7 +282,7 @@ status_t FLASH_WritePage(uint32_t addr, const uint8_t *buf, uint32_t len)
* @param len :
* @retval kStatus_Success
*/
status_t FLASH_Read(uint32_t addr, const uint8_t *buf, uint32_t len)
status_t FLASH_Read(uint32_t addr, uint32_t *buf, uint32_t len)
{
status_t status;
flexspi_xfer_t flashXfer;
@ -294,7 +294,7 @@ status_t FLASH_Read(uint32_t addr, const uint8_t *buf, uint32_t len)
flashXfer.seqId = NOR_CMD_LUT_SEQ_IDX_READ;
flashXfer.baseAddress = addr;
flashXfer.isParallelModeEnable = false;
flashXfer.rxBuffer = (uint32_t *)buf;
flashXfer.rxBuffer = buf;
flashXfer.rxSize = len;
__disable_irq();
@ -338,7 +338,7 @@ status_t flash_erase(uint32_t start_addr, uint32_t byte_cnt)
*/
status_t flash_write(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt)
{
return FLASH_WritePage(start_addr, buf, byte_cnt);
return FLASH_WritePage(start_addr, (void *)buf, byte_cnt);
}
/**
@ -353,7 +353,7 @@ status_t flash_read(uint32_t addr, uint8_t *buf, uint32_t len)
/* For FlexSPI Memory ReadBack, use IP Command instead of AXI command for security */
if((addr >= 0x60000000) && (addr < 0x70000000))
{
return FLASH_Read(addr, buf, len);
return FLASH_Read(addr, (void *)buf, len);
}
else
@ -433,4 +433,184 @@ status_t flash_copy(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize)
}
return (status_t)kStatus_Success;
}
}
status_t NOR_FLASH_Erase(uint32_t app_base_addr,uint32_t imageSize)
{
uint16_t i;
uint32_t sectorNum = (imageSize%4096 != 0)? (imageSize/4096 + 1):(imageSize/4096);
for(i=0;i<sectorNum;i++)
{
status_t status = FLASH_EraseSector(app_base_addr+i*SECTOR_SIZE);
if (status != kStatus_Success)
{
KPrintf("Erase_Sector 0x%x faild!\r\n",i*SECTOR_SIZE);
return status;
}
}
return kStatus_Success;
}
void NorFlash_Write_PageProgram(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
uint8_t temp_data[256] = {0xff};
memcpy(temp_data,pBuffer,NumByteToWrite);
status_t status = FLASH_WritePage(WriteAddr,(void *)temp_data,FLASH_PAGE_SIZE);
if (status != kStatus_Success)
{
KPrintf("Write_PageProgram 0x%x faild!\r\n",WriteAddr);
}
}
void NorFlash_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
uint16_t pageRemain;
pageRemain = 256 - WriteAddr%256;//单页剩余的字节数
if(NumByteToWrite <= pageRemain)
{
pageRemain = NumByteToWrite;//不大于256个字节
}
while(1)
{
NorFlash_Write_PageProgram(pBuffer,WriteAddr,pageRemain);
if(NumByteToWrite == pageRemain)
{
break;//写入结束了
}
else //NumByteToWrite>pageRemain
{
pBuffer += pageRemain;
WriteAddr += pageRemain;
NumByteToWrite -= pageRemain;//减去已经写入了的字节数
if(NumByteToWrite > 256)
{
pageRemain = 256;//一次可以写入256个字节
}
else
{
pageRemain = NumByteToWrite;//不够256个字节了
}
}
}
}
void NorFlash_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
uint32_t secPos;
uint16_t secOff;
uint16_t secRemain;
uint16_t i;
uint8_t *NorFlash_BUF = 0;
NorFlash_BUF = NorFlash_BUFFER;//RAM缓冲区4K
WriteAddr &= 0x0FFFFFFF;
secPos = WriteAddr/SECTOR_SIZE;//扇区地址
secOff = WriteAddr%SECTOR_SIZE;//在扇区内的偏移
secRemain = SECTOR_SIZE - secOff;//扇区剩余空间大小
if(NumByteToWrite <= secRemain)
{
secRemain = NumByteToWrite;//不大于4096个字节
}
while(1)
{
FLASH_Read(FLASH_BASE + secPos*SECTOR_SIZE, (void *)NorFlash_BUF, SECTOR_SIZE);//读出整个扇区的内容
for(i=0;i<secRemain;i++)//校验数据
{
if(NorFlash_BUF[secOff+i] != 0xFF)
{
break;//需要擦除
}
}
if(i < secRemain)//需要擦除
{
FLASH_EraseSector(FLASH_BASE + secPos*SECTOR_SIZE);
for(i=0;i<secRemain;i++)//复制
{
NorFlash_BUF[i+secOff] = pBuffer[i];
}
NorFlash_Write_NoCheck(NorFlash_BUF,FLASH_BASE + secPos*4096,4096);//写入整个扇区
}
else
{
NorFlash_Write_NoCheck(pBuffer,FLASH_BASE + WriteAddr,secRemain);//写已经擦除了的,直接写入扇区剩余区间.
}
if(NumByteToWrite == secRemain)
{
break;//写入结束了
}
else//写入未结束
{
secPos++;//扇区地址增1
secOff=0;//偏移位置为0
pBuffer += secRemain;//指针偏移
WriteAddr += secRemain;//写地址偏移
NumByteToWrite -= secRemain;//字节数递减
if(NumByteToWrite > 4096)
{
secRemain = 4096;//下一个扇区还是写不完
}
else
{
secRemain = NumByteToWrite;//下一个扇区可以写完了
}
}
}
}
#ifndef USE_HIGHT_SPEED_TRANS
uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength)
{
uint32_t WriteAddr;
WriteAddr = *FlashAddress;
NorFlash_Write(Data,WriteAddr,DataLength);
*FlashAddress += DataLength;
return 0;
}
#else
uint8_t packetNum = 0;
uint32_t dataLen = 0;
uint32_t WriteAddr;
uint8_t dataBuff[5*1024];
uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength,uint8_t doneFlag)
{
if(!doneFlag)
{
memcpy(&dataBuff[dataLen],Data,DataLength);
dataLen += DataLength;
packetNum ++;
if(1 == packetNum)
{
WriteAddr = *FlashAddress;
}
if(dataLen>=4096)
{
NorFlash_Write(dataBuff,WriteAddr,dataLen);
packetNum = 0;
dataLen = 0;
}
*FlashAddress += DataLength;
}
else
{
NorFlash_Write(dataBuff,WriteAddr,dataLen);
packetNum = 0;
dataLen = 0;
}
return (0);
}
#endif

View File

@ -12,22 +12,16 @@
* @author AIIT XUOS Lab
* @date 2023-04-03
*/
#include <stdint.h>
#include <xs_base.h>
#include "flash.h"
#include "stdint.h"
#include "mcuboot.h"
#include "ymodem.h"
#include "common.h"
#ifdef MCUBOOT_BOOTLOADER
static void JumpToApp(void)
{
asm volatile("LDR R0, = 0x60100000");
asm volatile("LDR R0, [R0]");
asm volatile("MOV SP, R0");
asm volatile("LDR R0, = 0x60100000+4");
asm volatile("LDR R0, [R0]");
asm volatile("BX R0");
}
extern void ImxrtMsDelay(uint32 ms);
static uint32_t UartSrcFreq(void)
{
@ -55,32 +49,72 @@ static void UartConfig(void)
LPUART_Init(LPUART1, &config, UartSrcFreq());
}
static void SerialPutC(uint8_t c)
static void jump_to_application(void)
{
LPUART_WriteByte(LPUART1, c);
while(!(kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1)))
{
}
}
SCB->VTOR = (uint32_t)0x60100000;
static void SerialPutString(uint8_t *s)
{
while (*s != '\0') {
SerialPutC(*s);
s++;
}
asm volatile("LDR R0, = 0x60100000");
asm volatile("LDR R0, [R0]");
asm volatile("MOV SP, R0");
asm volatile("LDR R0, = 0x60100000+4");
asm volatile("LDR R0, [R0]");
asm volatile("BX R0");
}
void BootLoaderJumpApp(void)
{
uint8_t ch1, ch2;
uint32_t ret;
uint32_t timeout = 500;
BOARD_ConfigMPU();
BOARD_InitPins();
BOARD_BootClockRUN();
UartConfig();
SysTick_Config(SystemCoreClock / TICK_PER_SECOND);
Serial_PutString("Please press 'space' key into menu in 5s !!!\r\n");
SerialPutString("BOOTLOADER START AND JUMP TO APP[0x60100000]\n");
SCB->VTOR = (uint32_t)0x60100000;
JumpToApp();
while(timeout)
{
ret = (SerialKeyPressed((uint8_t*)&ch1));
if(ret) break;
timeout--;
ImxrtMsDelay(10);
}
while(1)
{
if((ret)&&(ch1 == 0x20))
{
Serial_PutString("\r\nPlease slecet:");
Serial_PutString("\r\n 1:run app");
Serial_PutString("\r\n 2:update app");
Serial_PutString("\r\n 3:reboot \r\n");
ch2 = GetKey();
switch(ch2)
{
case 0x31:
jump_to_application();
break;
case 0x32:
FLASH_Init();
SerialDownload();
FLASH_DeInit();
break;
case 0x33:
__set_FAULTMASK(1);
NVIC_SystemReset();
default:
break;
}
}
else
{
jump_to_application();
}
}
}
#endif

View File

@ -0,0 +1,391 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file: ymodem.c
* @brief: file ymodem.c
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2023/3/24
*/
#include "common.h"
#include "ymodem.h"
#include "string.h"
#include "flash.h"
#define BL_APP_VECTOR_TABLE_ADDRESS 0x60100000
uint8_t tab_1024[1024] ={0};
uint8_t FileName[FILE_NAME_LENGTH];
/**
* @brief Receive byte from sender
* @param c: Character
* @param timeout: Timeout
* @retval 0: Byte received
* -1: Timeout
*/
static int32_t Receive_Byte (uint8_t *c, uint32_t timeout)
{
while (timeout-- > 0)
{
if (SerialKeyPressed(c) == 1)
{
return 0;
}
}
return -1;
}
/**
* @brief Send a byte
* @param c: Character
* @retval 0: Byte sent
*/
static uint32_t Send_Byte (uint8_t c)
{
SerialPutChar(c);
return 0;
}
/**
* @brief Update CRC16 for input byte
* @param CRC input value
* @param input byte
* @retval Updated CRC value
*/
uint16_t UpdateCRC16(uint16_t crcIn, uint8_t byte)
{
uint32_t crc = crcIn;
uint32_t in = byte|0x100;
do
{
crc <<= 1;
in <<= 1;
if(in&0x100)
{
++crc;
}
if(crc&0x10000)
{
crc ^= 0x1021;
}
} while(!(in&0x10000));
return (crc&0xffffu);
}
/**
* @brief Cal CRC16 for YModem Packet
* @param data
* @param length
* @retval CRC value
*/
uint16_t Cal_CRC16(const uint8_t* data, uint32_t size)
{
uint32_t crc = 0;
const uint8_t* dataEnd = data+size;
while(data<dataEnd)
{
crc = UpdateCRC16(crc,*data++);
}
crc = UpdateCRC16(crc,0);
crc = UpdateCRC16(crc,0);
return (crc&0xffffu);
}
/**
* @brief Cal Check sum for YModem Packet
* @param data
* @param length
* @retval None
*/
uint8_t CalChecksum(const uint8_t* data, uint32_t size)
{
uint32_t sum = 0;
const uint8_t* dataEnd = data+size;
while(data < dataEnd)
{
sum += *data++;
}
return (sum&0xffu);
}
/**
* @brief Receive a packet from sender
* @param data
* @param length
* @param timeout
* 0: end of transmission
* -1: abort by sender
* >0: packet length
* @retval 0: normally return
* -1: timeout or packet error
* 1: abort by user
*/
static int32_t Receive_Packet (uint8_t *data, int32_t *length, uint32_t timeout)
{
uint16_t i, packet_size, computedcrc;
uint8_t c;
*length = 0;
if (Receive_Byte(&c, timeout) != 0)
{
return -1;
}
switch (c)
{
case SOH:
packet_size = PACKET_SIZE;
break;
case STX:
packet_size = PACKET_1K_SIZE;
break;
case EOT:
return 0;
case CA:
if ((Receive_Byte(&c, timeout) == 0) && (c == CA))
{
*length = -1;
return 0;
}
else
{
return -1;
}
case ABORT1:
case ABORT2:
return 1;
default:
return -1;
}
*data = c;
for (i = 1; i < (packet_size + PACKET_OVERHEAD); i ++)
{
if (Receive_Byte(data + i, timeout) != 0)
{
return -1;
}
}
if (data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff))
{
return -1;
}
/* Compute the CRC */
computedcrc = Cal_CRC16(&data[PACKET_HEADER], (uint32_t)packet_size);
/* Check that received CRC match the already computed CRC value
data[packet_size+3]<<8) | data[packet_size+4] contains the received CRC
computedcrc contains the computed CRC value */
if (computedcrc != (uint16_t)((data[packet_size+3]<<8) | data[packet_size+4]))
{
/* CRC error */
return -1;
}
*length = packet_size;
return 0;
}
/**
* @brief Receive a file using the ymodem protocol
* @param buf: Address of the first byte
* @retval The size of the file
*/
int32_t Ymodem_Receive (uint8_t *buf)
{
uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr;
int32_t i, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0;
uint32_t flashdestination;
/* Initialize flashdestination variable */
flashdestination = BL_APP_VECTOR_TABLE_ADDRESS;
for (session_done = 0, errors = 0, session_begin = 0; ;)
{
for (packets_received = 0, file_done = 0, buf_ptr = buf; ;)
{
switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT))
{
case 0:
errors = 0;
switch (packet_length)
{
/* Abort by sender */
case - 1:
Send_Byte(ACK);
return 0;
/* End of transmission */
case 0:
Send_Byte(ACK);
file_done = 1;
break;
/* Normal packet */
default:
if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff))
{
Send_Byte(NAK);
}
else
{
if (packets_received == 0)
{
/* Filename packet */
if (packet_data[PACKET_HEADER] != 0)
{
/* Filename packet has valid data */
for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);)
{
FileName[i++] = *file_ptr++;
}
FileName[i++] = '\0';
for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < (FILE_SIZE_LENGTH - 1));)
{
file_size[i++] = *file_ptr++;
}
file_size[i++] = '\0';
Str2Int(file_size, &size);
/* Test the size of the image to be sent */
/* Image size is greater than Flash size */
if (size > (USER_FLASH_SIZE + 1))
{
/* End session */
Send_Byte(CA);
Send_Byte(CA);
return -1;
}
/* erase user application area */
NOR_FLASH_Erase(BL_APP_VECTOR_TABLE_ADDRESS,size);
Send_Byte(ACK);
Send_Byte(CRC16);
}
/* Filename packet is empty, end session */
else
{
Send_Byte(ACK);
file_done = 1;
session_done = 1;
break;
}
}
/* Data packet */
else
{
memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length);
/* Write received data in Flash */
#ifndef USE_HIGHT_SPEED_TRANS
if (NOR_FLASH_Write(&flashdestination, buf, (uint16_t) packet_length) == 0)
#else
if (NOR_FLASH_Write(&flashdestination, buf, (uint16_t) packet_length,0) == 0)
#endif
{
Send_Byte(ACK);
}
else /* An error occurred while writing to Flash memory */
{
/* End session */
Send_Byte(CA);
Send_Byte(CA);
return -2;
}
}
packets_received ++;
session_begin = 1;
}
}
break;
case 1:
Send_Byte(CA);
Send_Byte(CA);
return -3;
default:
if (session_begin > 0)
{
errors ++;
}
if (errors > MAX_ERRORS)
{
Send_Byte(CA);
Send_Byte(CA);
return 0;
}
Send_Byte(CRC16);
break;
}
if (file_done != 0)
{
break;
}
}
if (session_done != 0)
{
break;
}
}
#ifdef USE_HIGHT_SPEED_TRANS
NOR_FLASH_Write(&flashdestination, buf, (uint16_t) packet_length,1);
#endif
return (int32_t)size;
}
/**
* @brief Download a file via serial port
* @param None
* @retval None
*/
void SerialDownload(void)
{
uint8_t Number[10] = {0};
int32_t Size = 0;
Serial_PutString("Waiting for the file to be sent ... (press 'a' to abort)\n\r");
Size = Ymodem_Receive(&tab_1024[0]);
if (Size > 0)
{
Serial_PutString("\n\n\r Programming Completed Successfully!\n\r--------------------------------\r\n Name: ");
Serial_PutString(FileName);
Int2Str(Number, Size);
Serial_PutString("\n\r Size: ");
Serial_PutString(Number);
Serial_PutString(" Bytes\r\n");
Serial_PutString("-------------------\n");
}
else if (Size == -1)
{
Serial_PutString("\n\n\rThe image size is higher than the allowed space memory!\n\r");
}
else if (Size == -2)
{
Serial_PutString("\n\n\rVerification failed!\n\r");
}
else if (Size == -3)
{
Serial_PutString("\r\n\nAborted by user.\n\r");
}
else
{
Serial_PutString("\n\rFailed to receive the file!\n\r");
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file: common.h
* @brief: file common.h
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2023/3/24
*/
#ifndef _COMMON_H
#define _COMMON_H
#include "fsl_common.h"
#include "fsl_lpuart.h"
#define CMD_STRING_SIZE 128
#define IS_AF(c) ((c >= 'A') && (c <= 'F'))
#define IS_af(c) ((c >= 'a') && (c <= 'f'))
#define IS_09(c) ((c >= '0') && (c <= '9'))
#define ISVALIDHEX(c) IS_AF(c) || IS_af(c) || IS_09(c)
#define ISVALIDDEC(c) IS_09(c)
#define CONVERTDEC(c) (c - '0')
#define CONVERTHEX_alpha(c) (IS_AF(c) ? (c - 'A'+10) : (c - 'a'+10))
#define CONVERTHEX(c) (IS_09(c) ? (c - '0') : CONVERTHEX_alpha(c))
void Int2Str(uint8_t* str,int32_t intnum);
uint32_t Str2Int(uint8_t *inputstr,int32_t *intnum);
uint32_t GetIntegerInput(int32_t * num);
uint32_t SerialKeyPressed(uint8_t *key);
uint8_t GetKey(void);
void SerialPutChar(uint8_t c);
void Serial_PutString(uint8_t *s);
void GetInputString(uint8_t * buffP);
#endif

View File

@ -19,18 +19,32 @@
#include <stdint.h>
#include "fsl_romapi.h"
#define USE_HIGHT_SPEED_TRANS 1
#define FLASH_BASE 0x60000000
#define SECTOR_SIZE 0x1000
#define FLASH_PAGE_SIZE 256
void FLASH_Init(void);
void FLASH_DeInit(void);
uint32_t FLASH_GetSectorSize(void);
status_t FLASH_WritePage(uint32_t addr, const uint8_t *buf, uint32_t len);
status_t FLASH_WritePage(uint32_t addr, const uint32_t *buf, uint32_t len);
status_t FLASH_EraseSector(uint32_t addr);
status_t FLASH_Read(uint32_t addr, const uint8_t *buf, uint32_t len);
uint32_t FLASH_Test(uint32_t startAddr, uint32_t len);
uint32_t FLASH_GetProgramCmd(void);
status_t FLASH_Read(uint32_t addr, uint32_t *buf, uint32_t len);
status_t flash_erase(uint32_t start_addr, uint32_t byte_cnt);
status_t flash_write(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt);
status_t flash_read(uint32_t addr, uint8_t *buf, uint32_t len);
status_t flash_copy(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize);
status_t NOR_FLASH_Erase(uint32_t app_base_addr,uint32_t imageSize);
status_t NOR_FLASH_Erase(uint32_t app_base_addr,uint32_t imageSize);
void NorFlash_Write_PageProgram(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite);
void NorFlash_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite);
void NorFlash_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite);
#ifndef USE_HIGHT_SPEED_TRANS
uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength);
#else
uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength,uint8_t doneFlag);
#endif
#endif

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file: ymodem.h
* @brief: file ymodem.h
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2023/3/24
*/
#ifndef _YMODEM_H_
#define _YMODEM_H_
#include <stdint.h>
#define BL_APP_VECTOR_TABLE_ADDRESS 0x60100000 //Application start address
#define USER_FLASH_SIZE 0x100000 //Application package size is limited to 1M
#define PACKET_SEQNO_INDEX (1)
#define PACKET_SEQNO_COMP_INDEX (2)
#define PACKET_HEADER (3)
#define PACKET_TRAILER (2)
#define PACKET_OVERHEAD (PACKET_HEADER + PACKET_TRAILER)
#define PACKET_SIZE (128)
#define PACKET_1K_SIZE (1024)
#define FILE_NAME_LENGTH (256)
#define FILE_SIZE_LENGTH (16)
#define SOH (0x01) /* start of 128-byte data packet */
#define STX (0x02) /* start of 1024-byte data packet */
#define EOT (0x04) /* end of transmission */
#define ACK (0x06) /* acknowledge */
#define NAK (0x15) /* negative acknowledge */
#define CA (0x18) /* two of these in succession aborts transfer */
#define CRC16 (0x43) /* 'C' == 0x43, request 16-bit CRC */
#define ABORT1 (0x41) /* 'A' == 0x41, abort by user */
#define ABORT2 (0x61) /* 'a' == 0x61, abort by user */
#define NAK_TIMEOUT (0x100000)
#define MAX_ERRORS (5)
void SerialDownload(void);
int32_t Ymodem_Receive (uint8_t *);
#endif