forked from xuos/xiuos
				
			Upgrading binary packages by iap on xidatong-arm32
This commit is contained in:
		
							parent
							
								
									d615793063
								
							
						
					
					
						commit
						85105cb65d
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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';
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -434,3 +434,183 @@ 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
 | 
			
		||||
| 
						 | 
				
			
			@ -13,21 +13,15 @@
 | 
			
		|||
* @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);
 | 
			
		||||
 | 
			
		||||
    SerialPutString("BOOTLOADER START AND JUMP TO APP[0x60100000]\n");
 | 
			
		||||
    SCB->VTOR = (uint32_t)0x60100000;
 | 
			
		||||
    JumpToApp();
 | 
			
		||||
    Serial_PutString("Please press 'space' key into menu in 5s !!!\r\n");
 | 
			
		||||
    
 | 
			
		||||
    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
 | 
			
		||||
| 
						 | 
				
			
			@ -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");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
		Loading…
	
		Reference in New Issue