在ST下载了个IAP程序,做了些修改,可以通过YMODEM方式正常下载程序到FLASH里,程序位于0X80002000,用仿真器单部调还能跑完初始化部分,全速运行的话程序初始化都没完就退出了. 调试用的是KEIL+ULINK,用IAR编译产生BIN文件. 修改后的代码如下:
/******************** (C) COPYRIGHT 2006 STMicroelectronics ******************** * File Name : ymodem.c * Author : MCD Application Team * Date First Issued : 10/25/2004 * Description : This file provides all the software functions related to * the ymodem protocol. ******************************************************************************** * History: * 09/15/2006 : IAP Version 3.0 * 02/01/2006 : IAP Version 2.0 * 11/24/2004 : IAP Version 1.0 ******************************************************************************** * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. *******************************************************************************/
/* Includes ------------------------------------------------------------------*/ #include "common.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ u8 file_name[FILE_NAME_LENGTH]; u32 Flash_Destination = ApplicationAddress; /* Flash user program offset */ u32 Ram_Source; u32 Sector_Mask = 0; u8 RAM_CODE[200]; u32 FLASH_Address; //写入FLASH的目标地址 u32 FLASH_Data; //写入FLASH的数据 s32 size;
#define FLASH_SER_MASK 0x08000000 #define FLASH_WPG_MASK 0x20000000 #define FLASH_WMS_MASK 0x80000000 #define FLASH_FLAG_LOCKBSY 0x12
const u8 segtab[] = { 0xC0, /*0*/ 0xF9, /*1*/ 0xA4, /*2*/ 0xB0, /*3*/ 0x99, /*4*/ 0x92, /*5*/ 0x82, /*6*/ 0xF8, /*7*/ 0x80, /*8*/ 0x90, /*9*/ 0x88, /*A*/ 0x83, /*b*/ 0xc6, //A7,/*c*/ 0xA1, /*d*/ 0x86, /*E*/ 0x8E /*F*/ }; void prog_to_ram(void (*funcP)()) { u32 i=200; void (*funcPtr)(); u8 *src,*dest; funcPtr =funcP; src= (u8 *) funcPtr; dest= (u8 *)&RAM_CODE[0];
do { *dest++ = *src++; } while(--i); }
void FLASH_WW(void) { /* Reset the Flash control registers */ FLASH->CR0 = 0x00000000; FLASH->CR1 = 0x00000000; /* Reset the Flash data registers */ FLASH->DR0 = 0xFFFFFFFF; FLASH->DR1 = 0xFFFFFFFF; /* Reset the Flash address register */ FLASH->AR = 0x00000000; /* Reset the Flash error register */ FLASH->ER = 0x00000000;
/* Set the word programming bit */ FLASH->CR0 |= FLASH_WPG_MASK; /* Load the destination address */ FLASH->AR = Flash_Destination; /* Load DATA to be programmed */ FLASH->DR0 = *(u32*)Ram_Source; /* Start the operation */ FLASH->CR0 |= FLASH_WMS_MASK; while((FLASH->CR0 & FLASH_FLAG_LOCKBSY) != RESET); }
//#define FLASH_SPR_MASK 0x01000000 //#define FLASH_SER_MASK 0x08000000 //#define FLASH_DWPG_MASK 0x10000000 //#define FLASH_SUSP_MASK 0x40000000
void FLASH_ES(void) { // FLASH->CR0 = 0x00000000; // FLASH->CR1 = 0x00000000; // Reset the Flash control registers // FLASH->DR0 = 0xFFFFFFFF; // FLASH->DR1 = 0xFFFFFFFF; // Reset the Flash data registers // FLASH->AR = 0x00000000; // Reset the Flash address register // FLASH->ER = 0x00000000; // Reset the Flash error register
// Disable write protection FLASH->CR0 |= 0x01000000; // Set the set protection bit FLASH->AR = FLASH_NVWPAR_ADDRESS; // Set the write protection register address FLASH->DR0 |= Sector_Mask ; // Data to be programmed to the protection register FLASH->CR0 |= 0x80000000; // Start the sequence while((FLASH->CR0 & FLASH_FLAG_LOCKBSY) != RESET); //wait for the end of the last operation
// Erase the needed sectors FLASH->CR0 |= FLASH_SER_MASK; // Set the sector erase bit FLASH->CR1 |= Sector_Mask; // Select the sectors to be erased FLASH->CR0 |= FLASH_WMS_MASK; // Start the operation while((FLASH->CR0 & FLASH_FLAG_LOCKBSY) != RESET); }
/* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /******************************************************************************* * Function Name : Receive_Byte * Description : Receive byte from sender * Input : - c: Character * - timeout: Timeout * Output : None * Return : 0: Byte received * -1: Timeout *******************************************************************************/ static s32 Receive_Byte (u8 *c, u32 timeout) { while (timeout-- > 0) { if (SerialKeyPressed(c) == 1) { return 0; } } return -1; }
/******************************************************************************* * Function Name : Send_Byte * Description : Send a byte * Input : - c: Character * Output : None * Return : 0: Byte sent *******************************************************************************/ static u32 Send_Byte (u8 c) { SerialPutChar(c); return 0; }
/******************************************************************************* * Function Name : Receive_Packet * Description : Receive a packet from sender * Input 1 : - data * Input 2 : - length * Input 3 : - timeout * Output : *length: * 0: end of transmission * -1: abort by sender * >0: packet length * Return : 0: normally return * -1: timeout or packet error * 1: abort by user *******************************************************************************/ static s32 Receive_Packet (u8 *data, s32 *length, u32 timeout) { u16 i, packet_size; u8 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; } *length = packet_size; return 0; } /******************************************************************************* * Function Name : Ymodem_Receive * Description : Receive a file using the ymodem protocol * Input : Address of the first byte * Output : None * Return : The size of the file *******************************************************************************/ s32 Ymodem_Receive (u8 *buf) { pFunction myfun;
u8 packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr; s32 i, j, packet_length, session_done, file_done, packets_received, errors, session_begin; u32 dp; s32 x; size = 0;
for (session_done = 0, errors = 0, session_begin = 0; ;) { for (packets_received = 0, file_done = 0, buf_ptr = buf; ;) { x = Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT); switch (x) { case 0: errors = 0; switch (packet_length) { case - 1: /* Abort by sender */ Send_Byte(ACK); return 0; case 0: /* End of transmission */ Send_Byte(ACK); file_done = 1; break; default: /* Normal packet */ 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);) { file_name[i++] = *file_ptr++; } file_name[i++] = '\0'; for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);) { file_size[i++] = *file_ptr++; } file_size[i++] = '\0'; Str2Int(file_size, &size);
// Test the size of the image to be sent if (size > 0x3E000) // Image size is greater than (bank0 - sector0) size { // End session Send_Byte(CA); Send_Byte(CA); return -1; } GPIO_WordWrite(GPIO2,0x348e); //F Sector_Mask = FLASH_SectorMask(size); prog_to_ram(FLASH_ES); myfun = (pFunction) RAM_CODE; myfun(); Send_Byte(ACK); Send_Byte(CRC16); } else /* Filename packet is empty; end session */ { Send_Byte(ACK); file_done = 1; session_done = 1; break; } } else /* Data packet */ { memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length); Ram_Source = 0xA0002000;
for (j = 0;(j < packet_length) && (Flash_Destination < ApplicationAddress + size);j += 4) { prog_to_ram(FLASH_WW); myfun = (pFunction) RAM_CODE; myfun(); if (*(u32*)Flash_Destination != *(u32*)Ram_Source) { // End session GPIO_WordWrite(GPIO2,0x3488); //a Send_Byte(CA); Send_Byte(CA); return -2; } Flash_Destination += 4; Ram_Source += 4; } Send_Byte(ACK); } packets_received ++; session_begin = 1;
dp = packets_received & 0xf; dp = segtab[dp]; dp |= 0x3400; GPIO_WordWrite(GPIO2,dp);
} } break; case 1: Send_Byte(CA); Send_Byte(CA); return -3; default: if (session_begin > 0) { errors ++; } if (errors > MAX_ERRORS) { GPIO_WordWrite(GPIO2,0x3486); //e Send_Byte(CA); Send_Byte(CA); return 0; } Send_Byte(CRC16); break; } if (file_done != 0) { break; } } if (session_done != 0) { break; } } return (s32)size; }
|
|