找回密码
 立即注册
查看: 2634|回复: 19

STC8H8K64U单片机bootloader无法跳转app程序

[复制链接]

6

主题

16

回帖

148

积分

注册会员

积分
148
发表于 2023-6-29 19:51:00 | 显示全部楼层 |阅读模式
经过验证我已经把外置flash的程序copy到eeprom的0x400地址上,

我在bootloader程序定义:

typedef void (*FunctionPointer)(void);
FunctionPointer entry_app = (FunctionPointer)0x0400;


然后在main函数中执行
entry_app();

并没有和想象中一样会跳转到这个地址执行我的代码。
求大牛们指点一下
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:38
  • 最近打卡:2025-04-30 14:38:57

25

主题

977

回帖

3599

积分

超级版主

积分
3599
发表于 2023-6-29 20:57:54 | 显示全部楼层
1、下载时EEPROM设置为多大?
      这关系到EEPROM的地址和ROM地址关系,EEPROM的地址0x400并不一定等于ROM的地址0x400
2、你存放在外部flash中的代码,在编译时目标地址是多少?
3、外置flash中的代码中是否有绝对调用(ACALL/LCALL)或者绝度跳转(AJMP/LJMP)指令?

上面的3点都有可能导致外部flash代码复制到EEPROM后无法正常运行
回复 支持 反对

使用道具 举报 送花

6

主题

16

回帖

148

积分

注册会员

积分
148
发表于 2023-6-30 09:15:39 | 显示全部楼层
zh*** 发表于 2023-6-29 20:57
1、下载时EEPROM设置为多大?
      这关系到EEPROM的地址和ROM地址关系,EEPROM的地址0x400并不一定等于RO ...

1、eeprom设置40k,片内flash大小是64k,这需要加上这24k的偏移吗,IAP访问eeprom的话我的代码就是放在0x400这个位置
2、外部代码编译时没有做其他任何设置
3、也没有调用跳转的命令,就正常编译出来一个bin文件
回复 支持 反对

使用道具 举报 送花

6

主题

16

回帖

148

积分

注册会员

积分
148
发表于 2023-6-30 11:35:46 | 显示全部楼层
本帖最后由 chenyl 于 2023-6-30 11:38 编辑
zh*** 发表于 2023-6-29 20:57
1、下载时EEPROM设置为多大?
      这关系到EEPROM的地址和ROM地址关系,EEPROM的地址0x400并不一定等于RO ...


我直接改上面这里启动是可以运行我拷过来的代码的,正常流程跳转的话要怎么改呢
截图_16880960118897.png

点评

根据你的情况,你的EEPROM必须设置为64K,让EEPROM和ROM完全重合 才能保证EEPROM的0x400地址对应到ROM的0x400  详情 回复 发表于 2023-6-30 18:07
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:38
  • 最近打卡:2025-04-30 14:38:57

25

主题

977

回帖

3599

积分

超级版主

积分
3599
发表于 2023-6-30 18:07:46 | 显示全部楼层
che*** 发表于 2023-6-30 11:35
我直接改上面这里启动是可以运行我拷过来的代码的,正常流程跳转的话要怎么改呢 ...

根据你的情况,你的EEPROM必须设置为64K,让EEPROM和ROM完全重合
才能保证EEPROM的0x400地址对应到ROM的0x400
回复 支持 反对

使用道具 举报 送花

6

主题

16

回帖

148

积分

注册会员

积分
148
发表于 2023-6-30 18:39:44 | 显示全部楼层
zh*** 发表于 2023-6-30 18:07
根据你的情况,你的EEPROM必须设置为64K,让EEPROM和ROM完全重合
才能保证EEPROM的0x400地址对应到ROM的0 ...

我刚刚试了,把EEPROM设置大小设置成64K,拷贝应用程序的地址挪到了0x5000,还是没跑起来

点评

将你的示例代码发出来看一下  详情 回复 发表于 2023-7-1 19:21
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:38
  • 最近打卡:2025-04-30 14:38:57

25

主题

977

回帖

3599

积分

超级版主

积分
3599
发表于 2023-7-1 19:21:13 | 显示全部楼层
che*** 发表于 2023-6-30 18:39
我刚刚试了,把EEPROM设置大小设置成64K,拷贝应用程序的地址挪到了0x5000,还是没跑起来 ...

将你的示例代码发出来看一下
回复 支持 反对

使用道具 举报 送花

6

主题

16

回帖

148

积分

注册会员

积分
148
发表于 2023-7-2 22:29:33 | 显示全部楼层
zh*** 发表于 2023-7-1 19:21
将你的示例代码发出来看一下
  1. // 定义EEPROM的起始地址和大小
  2. #define EEPROM_START_ADDRESS 0x5000
  3. #define EEPROM_SIZE 0x5000
  4. // 定义接收和发送数据的缓冲区
  5. #define BUFFER_SIZE 256
  6. uint8_t recv_buf[BUFFER_SIZE];
  7. uint8_t send_buf[BUFFER_SIZE];
  8. typedef void (*FunctionPointer)(void);
  9. FunctionPointer entry_app = (FunctionPointer)0x5000;
  10. void IapProgram(int addr, int dat)
  11. {
  12.     IAP_CONTR = 0x80;                           //使能IAP
  13.     IAP_TPS = 12;                               //设置等待参数12MHz
  14.     IAP_CMD = 2;                                //设置IAP写命令
  15.     IAP_ADDRL = addr;                           //设置IAP低地址
  16.     IAP_ADDRH = addr >> 8;                      //设置IAP高地址
  17.     IAP_DATA = dat;                             //写IAP数据
  18.     IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
  19.     IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
  20.     _nop_();
  21.     IapIdle();                                  //关闭IAP功能
  22. }
  23. // 接收一个字节的数据
  24. uint8_t receive_byte() {
  25.         SPDAT = 0xff;
  26.     while((SPSTAT & SPIF) == 0) ;
  27.     SPSTAT = SPIF + WCOL;   //清0 SPIF和WCOL标志
  28.     return (SPDAT);
  29. }
  30. // 定义一个函数从外置SPI Flash中读取数据
  31. void read_flash(uint32_t address, uint8_t *dat, uint32_t sz)
  32. {
  33.         if(sz == 0)   return;
  34.     while(CheckFlashBusy() > 0);        //Flash忙检测
  35.     SPI_CS = 0;                       //enable device
  36.     send_byte(0x03);            //read command
  37.     send_byte(((u8 *)&address)[1]);    //设置起始地址
  38.     send_byte(((u8 *)&address)[2]);
  39.     send_byte(((u8 *)&address)[3]);
  40.     do{
  41.         *dat = receive_byte();       //receive byte and store at buffer
  42.         dat++;
  43.     }while(--sz);                     //read until no_bytes is reached
  44.     SPI_CS = 1;                      //disable device
  45. }
  46. // 定义一个函数将应用程序从外置SPI Flash中拷贝到EEPROM中
  47. void copy_app_to_eeprom() {
  48.             uint32_t app_size;
  49.         uint16_t addr;
  50.         uint16_t rev;
  51.         uint32_t k;
  52.        
  53.         uint32_t offset;
  54.         uint32_t sz;
  55.         uint8_t TEST = 0x55;
  56.        
  57.         Get_App_Size((unsigned int*)&app_size);
  58.        
  59.     // 擦除EEPROM
  60.         for (addr = EEPROM_SIZE; addr <  EEPROM_SIZE+ EEPROM_SIZE; )
  61.         {
  62.                 IapErase(addr);
  63.                 addr = addr+512;
  64.             }
  65.        
  66.         app_size = 0x4800;//暂时手动设置读取的大小
  67.         sz = BUFFER_SIZE;
  68.         for (k = 0; k < app_size; ) {
  69.                 offset = 0 + k;
  70.         read_flash(offset, recv_buf, sz);
  71.         for (rev = 0; rev < sz; rev++) {
  72.                 IapProgram(EEPROM_START_ADDRESS + k + rev, recv_buf[rev]);
  73.         }
  74.         k += BUFFER_SIZE;
  75.     }       
  76. }
  77. void SPI_init(void)
  78. {
  79.     P2M0 &= ~0x3e;
  80.         P2M1 &= ~0x3e;
  81.         SPCTL |=  (1 << 7); //忽略 SS 引脚功能,使用 MSTR 确定器件是主机还是从机
  82.     SPCTL |=  (1 << 6); //使能 SPI 功能
  83.     SPCTL &= ~(1 << 5); //先发送/接收数据的高位( MSB)
  84.     SPCTL |=  (1 << 4); //设置主机模式
  85.     SPCTL &= ~(1 << 3); //SCLK 空闲时为低电平,SCLK 的前时钟沿为上升沿,后时钟沿为下降沿
  86.     SPCTL &= ~(1 << 2); //数据 SS 管脚为低电平驱动第一位数据并在 SCLK 的后时钟沿改变数据
  87.     SPCTL = (SPCTL & ~3) | 3;   //SPI 时钟频率选择, 0: 4T, 1: 8T,  2: 16T,  3: 32T
  88.     P_SW1 = (P_SW1 & ~(3<<2)) | (1<<2);     //IO口切换. 0: P1.2/P5.4 P1.3 P1.4 P1.5, 1: P2.2 P2.3 P2.4 P2.5, 2: P5.4 P4.0 P4.1 P4.3, 3: P3.5 P3.4 P3.3 P3.2
  89.        
  90.     SPI_CLK = 0;    // set clock to low initial state
  91.     SPI_SI = 1;
  92.     SPSTAT = SPIF + WCOL;   //清0 SPIF和WCOL标志
  93. }
  94. void main() {       
  95.         // 初始化SPI
  96.         SPI_init();
  97. //        FlashCheckID();
  98. //        FlashCheckID();
  99.     should_copy_app_to_eeprom = 1;  // 判断是否需要将应用程序拷贝到EEPROM中
  100.     if (should_copy_app_to_eeprom) {
  101.         copy_app_to_eeprom();
  102.     }
  103.        
  104.     // 跳转到应用程序的地址
  105.         EA = 0;
  106.         entry_app();
  107. }
复制代码
回复 支持 反对

使用道具 举报 送花

6

主题

16

回帖

148

积分

注册会员

积分
148
发表于 2023-7-2 22:30:18 | 显示全部楼层
zh*** 发表于 2023-7-1 19:21
将你的示例代码发出来看一下

大概是这样,麻烦帮看一下

点评

主要是要看你放到外部Flash中的代码、项目设置以及 你将外置代码写入到外部Flash中的一些步骤  详情 回复 发表于 2023-7-3 08:56
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:38
  • 最近打卡:2025-04-30 14:38:57

25

主题

977

回帖

3599

积分

超级版主

积分
3599
发表于 2023-7-3 08:56:07 | 显示全部楼层
che*** 发表于 2023-7-2 22:30
大概是这样,麻烦帮看一下

主要是要看你放到外部Flash中的代码、项目设置以及
你将外置代码写入到外部Flash中的一些步骤
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 11:11 , Processed in 0.209927 second(s), 118 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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