硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1187|回复: 9
收起左侧

[有问必答] 大哥,你好我目前的STM32F103C8T6的IAP升级老是失败,bin文件可以下载进去,但就是无法写入到FLASH的指定位置中,可以帮助我...

[复制链接]

1

主题

4

回帖

7

积分

新手上路

积分
7
发表于 2024-6-20 14:18:53 | 显示全部楼层 |阅读模式
大哥,你好我目前的STM32F103C8T6的IAP升级老是失败,bin文件可以下载进去,但就是无法写入到FLASH的指定位置中,可以帮助我一下吗
回复

使用道具 举报

34

主题

192

回帖

294

积分

高级会员

积分
294
发表于 2024-6-20 16:45:50 | 显示全部楼层
都不讲细节,你让你大哥怎么给你看
回复

使用道具 举报

7

主题

146

回帖

167

积分

初级会员

积分
167
发表于 2024-6-21 15:41:50 | 显示全部楼层
怎么帮助,检查下地址有没设置错了
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2024-6-22 14:16:28 | 显示全部楼层
LinY 发表于 2024-6-20 16:45
都不讲细节,你让你大哥怎么给你看

#include "stm32f10x.h"                  // Device header
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "stmflash.h"
#include "iap.h"
#include "OLED.h"
/************************************************
ALIENTEK战舰STM32开发板实验47
IAP实验 Bootloader V1.0 代码
技术支持:www.openedv.com
淘宝店铺:http://eboard.taobao.com
关注微信公众平台微信号:"正点原子",免费获取STM32资料。
广州市星翼电子科技有限公司  
作者:正点原子 @ALIENTEK
************************************************/
uint8_t KeyNum;//定义一个全局变量

int main(void)
{               
        for(long int  i=0;i<1000000;i++)
    __NOP();
        //char Serial_RxPacket[100];
        //#define USART_REC_LEN                          10*1024 //定义最大接收字节数 55K
       
        Init_Key();
        KeyNum = key_GetNum();
//        u8 key;
        u16 oldcount=0;                                //老的串口接收数据值
        u16 applenth=0;                                //接收到的app代码长度
//        u8 clearflag=0;  
        u8 flagtest=0;
         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
       
        GPIO_InitTypeDef GPIO_InitStructure;//先定义结构体的类型和名称
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 ;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        //GPIO_ResetBits(GPIOA, GPIO_Pin_0);//给0引脚置0灯亮
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
        Uart_Init();        //串口初始化为115200
        delay_init();                            //延时初始化
        LED_Init();                                          //初始化与LED连接的硬件接口
        //KEY_Init();                                        //初始化按键
        //显示提示信息
       
        while(1)
        {
                 if(USART_RX_CNT)
                {
                        if(oldcount==USART_RX_CNT)//新周期内,没有收到任何数据,认为本次数据接收完成.
                        {
                                applenth=USART_RX_CNT;
                                oldcount=0;
                                USART_RX_CNT=0;
                                printf("用户程序接收完成!\r\n");
                                printf("代码长度:%dBytes\r\n",applenth);
                                flagtest=0;
                        }
                        else
                                oldcount=USART_RX_CNT;                       
                }
                delay_ms(10);

                if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)        //按键按下
                {
                        if(applenth&&flagtest==0)
                        {
                                flagtest=1;
                                printf("开始更新固件...\r\n");       
                                if(((*(vu32*)(0X20001000+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
                                {         
                                        iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,applenth);//更新FLASH代码  
                                        printf("固件更新完成!\r\n");       
                                       
                                        GPIO_SetBits(GPIOA, GPIO_Pin_0);//给0引脚置0灯亮
                                        if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
                        {         
                                printf("开始执行FLASH用户代码!!\r\n");
                                iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码
                                GPIO_ResetBits(GPIOA, GPIO_Pin_1);//给1引脚置0灯亮
                                delay_ms(1000);
                                GPIO_SetBits(GPIOA, GPIO_Pin_1);//给1引脚置0灯亮
                        }
                                       
                                       
                                }else
                                {
                                        printf("非FLASH应用程序!\r\n");
                          }
                        }
                        else
                        {
                                printf("没有可以更新的固件!\r\n");
                        }                                                         
                }
        //        else
                //{
                        //flagtest=0;
               
                        else
                        {
                                //printf("非FLASH应用程序,无法执行!\r\n");
                        }               
                                       
        //        }
        }  
}
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2024-6-22 14:17:32 | 显示全部楼层
mygod 发表于 2024-6-21 15:41
怎么帮助,检查下地址有没设置错了

地址是没有错的,
[C] 纯文本查看 复制代码
#include "stm32f10x.h"                  // Device header
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "stmflash.h"
#include "iap.h"
 #include "OLED.h"
/************************************************
 ALIENTEK战舰STM32开发板实验47
 IAP实验 Bootloader V1.0 代码 
 技术支持:[url]www.openedv.com[/url]
 淘宝店铺:[url]http://eboard.taobao.com[/url] 
 关注微信公众平台微信号:"正点原子",免费获取STM32资料。
 广州市星翼电子科技有限公司  
 作者:正点原子 @ALIENTEK
************************************************/
uint8_t KeyNum;//定义一个全局变量

int main(void)
{		
	for(long int  i=0;i<1000000;i++)
    __NOP(); 
	//char Serial_RxPacket[100];
	//#define USART_REC_LEN  			10*1024 //定义最大接收字节数 55K
	
	Init_Key();
	KeyNum = key_GetNum();
//	u8 key;
	u16 oldcount=0;				//老的串口接收数据值
	u16 applenth=0;				//接收到的app代码长度
//	u8 clearflag=0;  
	u8 flagtest=0;
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;//先定义结构体的类型和名称
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 ;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	//GPIO_ResetBits(GPIOA, GPIO_Pin_0);//给0引脚置0灯亮
 // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	Uart_Init();	//串口初始化为115200
	delay_init();	   	 	//延时初始化 
 	LED_Init();		  			//初始化与LED连接的硬件接口
	//KEY_Init();					//初始化按键
	//显示提示信息
	
	while(1)
	{
	 	if(USART_RX_CNT)
		{
			if(oldcount==USART_RX_CNT)//新周期内,没有收到任何数据,认为本次数据接收完成.
			{
				applenth=USART_RX_CNT;
				oldcount=0;
				USART_RX_CNT=0;
				printf("用户程序接收完成!\r\n");
				printf("代码长度:%dBytes\r\n",applenth);
				flagtest=0;
			}
			else 
				oldcount=USART_RX_CNT;			
		}
		delay_ms(10);

		if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)	//按键按下
		{
			if(applenth&&flagtest==0)
			{
				flagtest=1;
				printf("开始更新固件...\r\n");	
 				if(((*(vu32*)(0X20001000+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
				{	 
					iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,applenth);//更新FLASH代码  
					printf("固件更新完成!\r\n");	
					
					GPIO_SetBits(GPIOA, GPIO_Pin_0);//给0引脚置0灯亮
					if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.
			{	 
				printf("开始执行FLASH用户代码!!\r\n");
				iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码
				GPIO_ResetBits(GPIOA, GPIO_Pin_1);//给1引脚置0灯亮
				delay_ms(1000);
				GPIO_SetBits(GPIOA, GPIO_Pin_1);//给1引脚置0灯亮
			}
					
					
				}else 
				{ 
					printf("非FLASH应用程序!\r\n");
		  	}
 			} 
			else 
			{
				printf("没有可以更新的固件!\r\n");
			}							 
		}
	//	else
		//{
			//flagtest=0;
		
			else 
			{
				//printf("非FLASH应用程序,无法执行!\r\n"); 
			}		
					
	//	} 
	}  
}
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2024-6-22 14:18:31 | 显示全部楼层
mygod 发表于 2024-6-21 15:41
怎么帮助,检查下地址有没设置错了

[C] 纯文本查看 复制代码
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "stmflash.h"
#include "iap.h"
//////////////////////////////////////////////////////////////////////////////////	 
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK战舰STM32开发板
//IAP 代码	   
//正点原子@ALIENTEK
//技术论坛:[url]www.openedv.com[/url]
//修改日期:2012/9/24
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved									  
//////////////////////////////////////////////////////////////////////////////////	

iapfun jump2app; 
u16 iapbuf[512];   
//appxaddr:应用程序的起始地址
//appbuf:应用程序CODE.
//appsize:应用程序大小(字节).
void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 appsize)
{
	u16 t;
	u16 i=0;
	u16 temp;
	u32 fwaddr=appxaddr;//当前写入的地址
	u8 *dfu=appbuf;
	for(t=0;t<appsize;t+=2)
	{						    
		temp=(u16)dfu[1]<<8;
		temp+=(u16)dfu[0];	  
		dfu+=2;//偏移2个字节
		iapbuf[i++]=temp;
//		if(i==1024)	    
		if(i==512)       //修改地方1   1024->512
		{
		    i=0;
//		    STMFLASH_Write(fwaddr,iapbuf,1024);	
//		    fwaddr+=2048;//偏移2048  16=2*8.所以要乘以2.
		    STMFLASH_Write(fwaddr,iapbuf,512);    //修改地方2  1024->512
		    fwaddr+=1024;//偏移1024  16=2*8.所以要乘以2.//修改地方3 2048->1024
		}
	}
	if(i)STMFLASH_Write(fwaddr,iapbuf,i);//将最后的一些内容字节写进去.  
}

//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(u32 appxaddr)
{
	if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)	//检查栈顶地址是否合法.
	{ 
		jump2app=(iapfun)*(vu32*)(appxaddr+4);		//用户代码区第二个字为程序开始地址(复位地址)		
		MSR_MSP(*(vu32*)appxaddr);					//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
		jump2app();									//跳转到APP.
	}
}		 
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2024-6-22 14:19:16 | 显示全部楼层
mygod 发表于 2024-6-21 15:41
怎么帮助,检查下地址有没设置错了

[C] 纯文本查看 复制代码
#ifndef __IAP_H__
#define __IAP_H__
#include "sys.h"  
//////////////////////////////////////////////////////////////////////////////////	 
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK战舰STM32开发板
//IAP 代码	   
//正点原子@ALIENTEK
//技术论坛:[url]www.openedv.com[/url]
//修改日期:2012/9/24
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved									  
//////////////////////////////////////////////////////////////////////////////////	
typedef  void (*iapfun)(void);				//定义一个函数类型的参数.

#define FLASH_APP1_ADDR		0x08004000  	//第一个应用程序起始地址(存放在FLASH)
											//保留0X08000000~0X0800FFFF的空间为IAP使用

void iap_load_app(u32 appxaddr);			//执行flash里面的app程序起始地址
void iap_load_appsram(u32 appxaddr);		//执行sram里面的app程序
void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 applen);	//在指定地址开始,写入bin,待跳转数值,长度
#endif
回复

使用道具 举报

0

主题

7

回帖

7

积分

新手上路

积分
7
发表于 2024-6-24 18:31:35 | 显示全部楼层
写的时候解锁了吗??
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
116230
QQ
发表于 2024-6-25 15:11:13 | 显示全部楼层
有可能是编程内部Flash失败了
回复

使用道具 举报

2

主题

13

回帖

19

积分

新手上路

积分
19
发表于 2024-6-28 14:47:09 | 显示全部楼层
FLASH大小和地址对不对?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-6-11 05:47 , Processed in 0.314839 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表