硬汉嵌入式论坛

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

[MDK] 分享STM32如何运行存储在SPI FLASH中的代码

  [复制链接]

8

主题

42

回帖

71

积分

初级会员

积分
71
发表于 2018-1-10 09:30:11 | 显示全部楼层 |阅读模式
本帖最后由 zwmasdf 于 2018-8-31 07:58 编辑

大家都知道STM32的代码是保存在内部FLASH中,执行也在内部FLASH中。那有没有设想一下,代码保存在外部SPI FLASH,执行在内部RAM?
了解过UBOOT的童鞋应该知道,刚才的那种设想在UBOOT上体现的淋漓尽致,那么STM32应该也可以实现。
在阅读本文之前,建议先阅读我的几片帖子
1. 如何将代码烧录到外部FLASH
2.如何在RAM中执行代码
然后对执行域和加载域有深入了解,如不了解则百度

有了以上2片文章和执行域与加载域的阅读基础,接下来可以开干了
我使用的是STM32F103RCT6,板载SPI FLASH,并且PA4(CS),PA5(SCK),PA6(MISO),PA7(MOSI)连到W25Q32FV上,PA2接到LED上
使用STMCubeMX新建工程,定义SPI4根线、配置SPI相关参数、定义LED端口,生成工程,然后加入SPI FLASH的驱动
修改总工程属性Option for File Target,勾选并定义ROM1:0xC0000000, 0x100,由于测试代码较小,这里只分配256个字节
IRAM字段由于要放一部分用来执行代码,则将原先长度0xC000缩小为0x8000
如图: 无标题.png
然后新建test.c文件,该文件用于保存在SPI FLASH、执行在RAM的代码
修改test.c文件属性Option for File Target,如图
无标题.png
然后编辑test.c,加入翻转LED灯代码:
  1. #include "main.h"
  2. #include "stm32f1xx_hal.h"

  3. void led_test(void)
  4. {
  5.     while(1)
  6.     {
  7.         HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
  8.         HAL_Delay(1000);
  9.     }
  10. }
复制代码
编译没问题后,重新修改总工程属性Option for File Target,切换到Link选项,取消勾选Use Memory Layout from Target Dialog,并点击Edit编辑sct文件
如图 无标题.png
sct编辑内容如下:
LR_IROM1 0x08000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00008000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

LR_ROM1 0xC0000000 0x00000100  {
  ER_ROM1 0x20008000 0x00000100  {  ; load address = execution address
    test.o (+RO)
   .ANY (+RO)
  }
}


然后编辑main.c
添加以下代码//由于代码存在外部的SPI FLASH,因此代码搬移工作必须手动完成,即加载域到执行域的拷贝工作必须自己完成
W25QXX_Read((uint8_t*)0x20008000,0x0, 100);//注释该语句将进入HardFault_Handler
led_test();

重新完全编译
然后烧录选项添加SPI FLASH的烧录算法,见之前的帖子
烧录后上电,点灯间隔1秒闪烁成功,大功告成!

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2018-1-10 11:14:32 | 显示全部楼层
非常感谢楼主分享,置酷
回复

使用道具 举报

8

主题

42

回帖

71

积分

初级会员

积分
71
 楼主| 发表于 2018-1-10 13:23:30 | 显示全部楼层
eric2013 发表于 2018-1-10 11:14
非常感谢楼主分享,置酷

这种方法还是具有实战意义的,可以把有些能证明正版的代码加密后放在外部Flash,这样,别人解密的成本就很高。
不过目前只能用MDK配合烧录算法下载
好像Jlink的JFlash目前还没找到如何加载外部FLASH的烧录算法,如果可以的话量产问题也解决了
此外还可以用JLINK做外部FLASH的编程器,完全可以取代V9的JFlashSPI直接用SPI连到FLASH上烧录的方式
希望后续有人能攻克
回复

使用道具 举报

2

主题

569

回帖

575

积分

金牌会员

积分
575
发表于 2018-1-21 22:18:30 | 显示全部楼层
这个ST自己就有例程的,只是没有实际意义。
回复

使用道具 举报

8

主题

42

回帖

71

积分

初级会员

积分
71
 楼主| 发表于 2018-1-26 08:33:57 | 显示全部楼层
leiyitan 发表于 2018-1-21 22:18
这个ST自己就有例程的,只是没有实际意义。

有意义啊,假如把STM32判断唯一ID的判断代码放到SPI FLASH中,并对代码进行加密,那就会增加破解者的难度
回复

使用道具 举报

5

主题

519

回帖

534

积分

金牌会员

积分
534
发表于 2018-1-27 08:41:53 | 显示全部楼层
谢谢分享。,
回复

使用道具 举报

6

主题

636

回帖

654

积分

金牌会员

积分
654
QQ
发表于 2018-3-23 09:54:06 | 显示全部楼层
楼主牛逼的不要不要的
回复

使用道具 举报

334

主题

2032

回帖

3039

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3039
发表于 2018-3-26 14:03:50 | 显示全部楼层
由于stm32系列的内部RAM都小于flash,感觉这种折腾意义不大啊。。。
回复

使用道具 举报

3

主题

58

回帖

67

积分

初级会员

积分
67
发表于 2018-4-9 00:30:58 | 显示全部楼层
楼主,我测试的有点问题,数据在外部flash没问题,代码在外部flash单片机就无法启动,不只是不是启动文件中__main函数有对代码进行加载导致无法启动?
回复

使用道具 举报

8

主题

42

回帖

71

积分

初级会员

积分
71
 楼主| 发表于 2018-4-10 10:49:02 | 显示全部楼层
ruboss 发表于 2018-4-9 00:30
楼主,我测试的有点问题,数据在外部flash没问题,代码在外部flash单片机就无法启动,不只是不是启动文件中 ...

你外部ram的代码有没有单独用一个c文件存放,必须隔离开来的
回复

使用道具 举报

9

主题

103

回帖

130

积分

初级会员

积分
130
发表于 2018-4-11 15:03:26 | 显示全部楼层
弱弱的问下大多数MCU RAM本来就小,为什么还要把代码加载到RAM中运行?
回复

使用道具 举报

7

主题

114

回帖

135

积分

初级会员

积分
135
发表于 2018-4-26 19:41:56 | 显示全部楼层
准备尝试一下看看
记录本身,即已是反抗!
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2018-5-1 23:24:33 | 显示全部楼层
放在外部FLASH有什么好处
回复

使用道具 举报

9

主题

78

回帖

105

积分

初级会员

积分
105
发表于 2018-5-10 17:54:37 | 显示全部楼层
66666666666666
回复

使用道具 举报

29

主题

514

回帖

606

积分

金牌会员

积分
606
QQ
发表于 2018-5-21 14:15:23 | 显示全部楼层
顶帖支持。
Releasing your creativity
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
发表于 2018-8-30 16:42:55 | 显示全部楼层
楼主方便交流下吗
回复

使用道具 举报

39

主题

928

回帖

1050

积分

至尊会员

积分
1050
发表于 2018-8-30 21:17:53 | 显示全部楼层
为何回帖全是“仅作者可见”
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2021-2-28 11:45:37 | 显示全部楼层
厉害,这样就能弥补片内flash太小的缺点。把不同的函数写入spi flash,使用时加载不同的函数实现不同的功能,类似APP应用程序一样。如果把公共驱动写入片内,其他功能代码都放入spi flash。实现一个可以安装APP的功能就太强了。
回复

使用道具 举报

19

主题

371

回帖

428

积分

高级会员

积分
428
发表于 2021-3-1 00:06:07 | 显示全部楼层
假设IRAM为4K bytes,外部程序的大小如果大于4k bytes,就要设计载入算法(跟PC差不多了),太复杂了。
“操作系统教程”好像有个经典算法:如何设置只有2根铁轨让火车跑起来。大致的意思是,确保每根铁轨都比火车长,将后面的铁轨拆下来铺在火车的前面(非常快速),一直循环,火车就一直往前开。
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2021-8-14 20:55:57 | 显示全部楼层
为什么我按照你的方法在407单片机上试了下,数据我核对了是正确的,只能下载不能运行,一运行,执行完SystemInit函数就进硬件错误中断了
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2022-9-18 23:36:17 | 显示全部楼层
不错不错,我这个周末也在搞这个,现在遇到了一点问题,下载后无法调用在外部flash的函数,看到你的分享我又有点思路了.
回复

使用道具 举报

1

主题

7

回帖

10

积分

新手上路

积分
10
发表于 2023-9-21 16:07:54 | 显示全部楼层
楼主能发一下工程文件吗
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-28 20:44 , Processed in 0.327698 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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