你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

在STM32F1片上 Flash 保存第一人称 3D 射击游戏

[复制链接]
eefishing 发布时间:2019-11-28 23:18
每当提到 3D 第一人称射击游戏,大家很自然就会联想到高性能独显,以及几个G甚至几十G的硬盘存储空间,那么有没有可能在 STM32F103RC 这样一块只有 256KB Flash 的小板子上保存一个大型第一人称射击游戏呢?
1.jpg
当我们用 USB 线把这块开发板连接到电脑上,就可以看到出现了一个只有100多KB的U盘,这就是 STM32 的片上 Flash 了。9 G! b: Q$ C' K# w; c/ F
2.jpg
然后可以看到U盘里有一个 90KB 的游戏。
3.jpg
如果我们双击它就启动了一个 STM32 上的第一人称射击游戏。: {% [  R! |9 C) Q4 e2 A0 C
9 R# w" ?" Y, w7 r7 }' G% _* m
这是完整的演示视频:如果你也有兴趣把这个游戏保存在 STM32 上,可以跟着后面的教程,或者也可以在这个项目里直接找到编译好的固件、游戏和项目源码。* n4 D: p0 h8 u0 h) M
链接地址:http://github.com/wuhanstudio/stm32-ufun-3d-game
* J, x; F2 b  F: Z1 T+ V9 d0 g
1. 运行 RT-ThreadRT-Thread 在 Github 上是开源的,源码可以在这里(链接:http://github.com/rt-Thread/rt-thread/找到,官网文档也很丰富这里就不重复了,总结一下需要的工具:
  • Git Bash
  • Keil 开发环境
  • STM32 开发板
  • RT-Thread 源码
  • env 工具2 t; C: y( E! |, B/ Z# {/ G3 p( V
如果觉得从 github 上面下载 RT-Thread 源码比较慢,可以先从 gitee 上面下载,然后修改项目地址。
1git clone https://gitee.com/rtthread/rt-thread
/ r- p, b6 |. Y* {4 {; w. B8 M2cd rt-thread
! r) V% K" O; p9 s! J  `! H  a# z5 ~3git remote rm origin* M: Y" j' v* j6 f* H
4git remote add origin https://github.com/RT-Thread/rt-thread * q8 X- b! w% Q, Y
5git pull origin master
2 q- g) P* s+ F/ n/ ~1 ]( @, _
+ Z. e  T( j7 ^/ \. J# M2. 片上 Flash 文件系统准备好第一步里面的工具后,首先我们需要把 STM32 的片上 flash 挂载为文件系统,首先需要在 CubeMX 里使能 USB。
4.jpg
打开 USB 后在时钟配置里确认外部晶振和板子上的晶振是一致的,并且 USB 的时钟是 48MHz,就可以点击生成代码了。由于我们修改了时钟,需要把 board/CubeMX_Config/Src/main.c 里面的 void SystemClock_Config(void) 函数复制到 board/board.c 里面替换。
接下来修改 bsp 下 board 目录里的 Kconfig 文件。1config BSP_USING_ON_CHIP_FLASH
! h6 ?/ b9 B( Z! I: V2    bool "Enable on-chip FLASH"
; p) H7 x8 c! N5 R2 _5 S) |7 c3    default n
2 r; O% }1 N* U9 }4/ @* l+ D! h5 [: G3 t5 c
5config BSP_USING_USBD_FS0 \0 i! F; }5 y3 F: D/ |
6    bool "Enable USBD as USB device"4 x' ~/ D( T. j
7    select RT_USING_USB_DEVICE# p/ T3 c9 R7 ]
8    default n
2 m% g* l5 y0 V6 A8 W5 ^
这样再在 bsp 目录下右键 ConEmu Here 就可以看到配置界面 (Env 教程:http://www.rt-thread.org/document/site/tutorial/env-video/),依次选中下面几个选项:
  • Hardware Drivers Config --> Enable on-chip Flash
    1 E  u( _9 J/ `
5.jpg

5 k- h: G" _; R" }3 S0 }5 v0 d8 x3 w
  • RT-thread Components --> Device Drivers --> Using MTD Nor Flash device drivers
    ; q, X3 |* f& ?9 u8 c% A
6.jpg
' r" f% J6 p8 \5 Y/ V: ^+ f) i, u$ T
  • RT-Thread online packages --> system packages 选中 fal 和 Littlefs% V; i$ |0 c4 }) G$ \2 p9 I. ^1 {& b
7.jpg

* R0 M! Z+ ^: j8 Q* ^4 @
  • RT-Thread Components --> Device virtual file system% e: j, E+ O) o. ]
8.jpg

# ?5 b7 |8 H7 O3 t" f4 p( D
保存配置退出,在 env 里面输入命令就可以自动生成 Keil 项目了:

9 o$ _( K2 n  {9 P1 w1 S1pkgs --update
, ~( s: e7 g' [; @- G& ]2 |/ o: K2scons --target=mdk5 -s
3 K$ [/ Z' |: l1 e3 v8 j# Z
! [# ^0 y! \3 p9 W2 k
我们需要先对 flash 进行规划,STM32F103RC 一共有 256KB,可以把最后的 128KB 作为文件系统使用,于是新建一个 fal_cfg.h 1extern const struct fal_flash_dev stm32_onchip_flash;3 N% p6 `% R! Z
2
0 p1 f. O+ |1 n& A2 ^0 g2 m2 l 3#define FAL_FLASH_DEV_TABLE                                          \
, Y5 `  Q$ U3 m/ ~ 4{                                                                    \# \. [: w" g" X4 `. c7 y% c
5    &stm32_onchip_flash,                                           \
1 C2 R4 h4 T& u, b$ W! B 6}

) K- ?' \& W  c: S 7
( b& n9 T- |- h0 }. a. e' q1 W2 m 8#define FAL_PART_TABLE                                                          \
- f8 V3 t$ b7 W" \6 i. Y3 { 9{                                                                               \
: E4 E* T3 g9 K( |. U: b10    {FAL_PART_MAGIC_WROD,       "app", "onchip_flash",         0,   128*1024, 0}, \
: [' ]& g. O$ E2 N11    {FAL_PART_MAGIC_WROD,      "flash0", "onchip_flash",   128*1024,  128*1024, 0}, \# Q+ a& y- t- J/ w
12}
* r9 _. D, w: t- n4 S3 E- }$ ~

: Y& M, }  W6 Y( p: w% i
再修改 main.c 挂载文件系统:
1#include <rtthread.h>
3 D1 u9 f6 c3 v" l  d 2#include <rtdevice.h>( `* F* G9 }/ Z
3#include <board.h>
2 V! X: g+ y+ u: j* Q9 b5 Q. F 4#include <fal.h>
0 L7 |% [  w7 S. I 5#include <dfs_posix.h>9 C. A* y/ j& y
6. ?$ ~9 a9 e- ]5 M2 V% a: p! l
7/* defined the LED0 pin: PC13 */
5 i4 y" t" W% f3 Q. @ 8#define LED0_PIN    GET_PIN(C, 13)3 g- b* t# J$ D8 g
9
& V* i2 v% \2 H+ u( g10#define FS_PARTITION_NAME  "flash0"
; B- G/ B8 \" X2 e11
# R% z; J: L& A8 R# l- ]12int main(void)
  Q! ^4 ~5 _1 A  b: e2 d( X/ z13
{
, R1 p* y7 J5 @' s; o; D14    int count = 1;
% }1 M2 _3 \* l15    /* set LED0 pin mode to output */
9 }3 E3 F+ S! M" K; ^16    rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);0 b, R- x6 \9 G% C0 g
17$ `) ]% w1 I$ M: O
18    fal_init();# H. q' `1 N& n, b6 `
192 p  c1 w" E3 Y, K: {
20#ifdef RT_USB_DEVICE_MSTORAGE6 I/ d: H0 U, Q
21    struct rt_device *flash_dev = fal_blk_device_create(FS_PARTITION_NAME);
  k5 c' w$ q, d% k, e5 H22#else8 s7 V/ T& C* {+ l7 L! r
23    struct rt_device *flash_dev = fal_mtd_nor_device_create(FS_PARTITION_NAME);" s# \0 k# ]  k. _! e
24#endif1 W& D" u" M2 ]; Z0 a) o
253 s! k5 F  a5 h2 c; e/ N
26    if (flash_dev == NULL)
- r9 n2 b4 p1 x; L27    {) N6 p* X* E: a# [- g; H
28        rt_kprintf("Can't create a block device on '%s' partition.\n", FS_PARTITION_NAME);
3 d$ n2 d: \. [+ g29    }
+ f0 _* b# e, B  t  w30    else2 j# y4 p/ i1 S0 U* Y' ~
31    {* B* w. w! y" q
32        rt_kprintf("Create a block device on the %s partition of flash successful.\n", FS_PARTITION_NAME);
4 N2 |1 \+ C6 p% b) H1 Z33    }1 {0 r% Q8 [5 S9 u* Y& ^0 I  {
34
- k# g' _. U' v6 K5 w6 f  n35    while (count++)- ~, z7 f' u+ P# ~/ q
36    {$ M0 ~, }' j. |$ w5 e
37#ifndef RT_USB_DEVICE_MSTORAGE" B3 F3 W  T" y2 E  i
38        if(rt_device_find(FS_PARTITION_NAME) != RT_NULL)
& y9 m. L+ ]" {: W3 Y: \39        {  e: p8 W. M6 b6 k% J& j
40            dfs_mkfs("lfs", FS_PARTITION_NAME);8 I& e+ F2 S* G3 f' f9 N- ^  n
41
- L& G- E# X. ?7 S" r42            if (dfs_mount(FS_PARTITION_NAME, "/", "lfs", 0, 0) == RT_EOK)& e1 v% S  ]6 g
43            {
4 s, {& Q$ |% k44                rt_kprintf("sd card mount to '/'\n");
/ E  `6 Z6 L2 \- m7 a8 d( k45                break;( l. s* V+ _& R) u5 \- @& {
46            }
) ]3 d8 o5 I1 C3 x* M0 j/ ~47            else
) N2 J7 A9 ?  q+ Q- l  \48            {
, S1 B% e- M$ z49                rt_kprintf("sd card mount to '/' failed!\n");
( u1 D9 @% `! H50            }
) j% q$ c4 M* s8 j% }. O51        }% ^( v5 Z% u8 i8 Y- n7 W
52#endif
+ J$ n. Z5 ^8 `8 `53        rt_pin_write(LED0_PIN, PIN_HIGH);  y; q8 r+ i# k; t$ \0 T- T
54        rt_thread_mdelay(500);1 N, l2 F1 Q, R% d" s  ]
55        rt_pin_write(LED0_PIN, PIN_LOW);4 _0 f' k/ k7 m, b' d- {  j
56        rt_thread_mdelay(500);* |8 Q) I0 j% h1 e1 j( J
57    }
4 K8 V/ C8 ?8 z& I# \( C, ?58
. W2 Z% o7 B% I* z. S9 b59    return RT_EOK;9 _- o+ h! G) O% N) I, S
60}+ @- ^  M* J& N$ D3 n6 |: w4 g
, k; J6 S1 A9 j) z* _
项目编译下载到板子上,串口连接上去在 msh 里输入 fal probe 应当就可以看到分区表了:
9.jpg
Linux 下常用的命令 lscatmkdircd 也都是支持的,这样我们就把 stm32 的片上 flash 挂载为文件系统了, 下一步就是让它识别为 U盘。
/ b2 m. |0 Q: [0 x0 g5 M
3. 挂载片上 Flash 为 U盘同样的,我们在 env 的配置目录里面依次选中:
  • Hardware Drivers Config --> On-chip Peripheral Drivers1 N( y0 V9 W4 [9 M! ]" ]
10.jpg
  • RT-Thread Components --> Device Drivers --> Using USB: M9 u6 J7 l, l$ v
11.jpg
12.jpg
这样保存配置,在 env 下生成项目文件:
1scons --target=mdk5 -s) O; I: W8 ?1 Q* T' e! L7 J, c% l
编译上传到板子上,接上 USB 到电脑,例如 STM32F103 的 USB 引脚是 PA11 和 PA12,就可以看到电脑识别到一个新的 U盘了,第一次使用可能需要先格式化。
13.jpg
最后其实就只是把高压的游戏复制进去,就把它装进 STM32 的片上 flash 了,其实还是挺简单的。完整的项目地址在这里:http://github.com/wuhanstudio/stm32-ufun-3d-game
收藏 评论2 发布时间:2019-11-28 23:18

举报

2个回答
qianfan 回答时间:2019-11-29 08:46:45
这不就是做了个U盘,跟游戏有毛线关系
李康1202 回答时间:2019-11-29 08:48:45
我还以为能运行呢

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版