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

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

[复制链接]
eefishing 发布时间:2019-11-28 23:18
每当提到 3D 第一人称射击游戏,大家很自然就会联想到高性能独显,以及几个G甚至几十G的硬盘存储空间,那么有没有可能在 STM32F103RC 这样一块只有 256KB Flash 的小板子上保存一个大型第一人称射击游戏呢?
1.jpg
当我们用 USB 线把这块开发板连接到电脑上,就可以看到出现了一个只有100多KB的U盘,这就是 STM32 的片上 Flash 了。
* G% w9 G3 l& {1 y2 H" p6 ?4 m
2.jpg
然后可以看到U盘里有一个 90KB 的游戏。
3.jpg
如果我们双击它就启动了一个 STM32 上的第一人称射击游戏。
9 f7 L: y6 v; A( y

) y/ S) R0 W7 o# y6 ^; l. U0 n& g这是完整的演示视频:如果你也有兴趣把这个游戏保存在 STM32 上,可以跟着后面的教程,或者也可以在这个项目里直接找到编译好的固件、游戏和项目源码。$ u+ J1 m( A3 v" y  m' [
链接地址:http://github.com/wuhanstudio/stm32-ufun-3d-game

: i5 F" Y& B1 M1 J/ {" X7 m9 K  j1. 运行 RT-ThreadRT-Thread 在 Github 上是开源的,源码可以在这里(链接:http://github.com/rt-Thread/rt-thread/找到,官网文档也很丰富这里就不重复了,总结一下需要的工具:
  • Git Bash
  • Keil 开发环境
  • STM32 开发板
  • RT-Thread 源码
  • env 工具
    % `/ y! X  o: @% y) E; Q
如果觉得从 github 上面下载 RT-Thread 源码比较慢,可以先从 gitee 上面下载,然后修改项目地址。
1git clone https://gitee.com/rtthread/rt-thread
0 @# o% m1 G# N9 U2cd rt-thread; A, A  O3 c/ F4 e' H5 _
3git remote rm origin
6 L+ L9 V( L; h. S7 K( R0 {4git remote add origin https://github.com/RT-Thread/rt-thread
' x/ m" z2 S9 _$ m& K0 }5git pull origin master
0 K' s0 R! A5 Y3 }* a9 R! F; l; ~& }4 P/ X$ A
2. 片上 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
8 x. o% s% _5 ]" S2    bool "Enable on-chip FLASH"
. }4 Y0 Q6 ^& y7 ?) I( M6 R+ T3    default n & _3 t3 z: }: q! @4 V
40 d7 D+ T; I+ M# C) S7 C
5config BSP_USING_USBD_FS
, Z) a3 C9 j+ F7 ]9 O2 S: z6    bool "Enable USBD as USB device"
5 ?) F1 z3 ~( a% i: v! D8 c7    select RT_USING_USB_DEVICE
; @6 u  j: U0 e% z, L8    default n, l7 J  t' d) F. {/ l
这样再在 bsp 目录下右键 ConEmu Here 就可以看到配置界面 (Env 教程:http://www.rt-thread.org/document/site/tutorial/env-video/),依次选中下面几个选项:
  • Hardware Drivers Config --> Enable on-chip Flash( e9 h, J$ F' w7 }/ r
5.jpg

2 g, i/ O# P4 z! y% G: m2 f
  • RT-thread Components --> Device Drivers --> Using MTD Nor Flash device drivers
    & S+ ^% v9 g+ b5 ~5 T% N# O
6.jpg

9 r7 d! s$ M: u) o- r' T% E. k' M. Z
  • RT-Thread online packages --> system packages 选中 fal 和 Littlefs7 ?6 _. H! l7 l1 o$ y% b3 D
7.jpg
4 j6 {/ T" ?5 X  Q% T+ P
  • RT-Thread Components --> Device virtual file system
    % ^9 o1 k7 t3 n. Y- u# f
8.jpg
5 n0 G8 ~3 W$ `: k
保存配置退出,在 env 里面输入命令就可以自动生成 Keil 项目了:

; q& A0 m- d5 [5 M/ l6 p% P1pkgs --update& V* I- p+ K, d
2scons --target=mdk5 -s
4 k, p9 s& _7 {+ _
6 }* |6 i" m. i
我们需要先对 flash 进行规划,STM32F103RC 一共有 256KB,可以把最后的 128KB 作为文件系统使用,于是新建一个 fal_cfg.h 1extern const struct fal_flash_dev stm32_onchip_flash;
0 p/ B% U0 m+ O5 j. M 28 c( Z3 D& j# {/ s" |
3#define FAL_FLASH_DEV_TABLE                                          \
! f  G( ~9 @" I1 ]0 q' K  p; l" k 4{                                                                    \
6 _& f, Z; m( K% ? 5    &stm32_onchip_flash,                                           \6 n7 G2 h$ q& e; |8 L
6}

8 O7 @1 P+ g" o7 @  B% R1 @4 I% g 7
; Y! ]  e& ^! O! ]* x% X: e 8#define FAL_PART_TABLE                                                          \
; E' P% a. J/ ^# m) @: Q8 } 9{                                                                               \. N! a  v+ n6 |$ ~' B
10    {FAL_PART_MAGIC_WROD,       "app", "onchip_flash",         0,   128*1024, 0}, \7 [( |: U" Z! m* z8 A8 }% a
11    {FAL_PART_MAGIC_WROD,      "flash0", "onchip_flash",   128*1024,  128*1024, 0}, \/ y% ~0 G+ F/ @% S" t, U
12}
$ E) n! {9 u  G& M) ]  s
* }) m0 |$ W" W  K. e  v* V# a
再修改 main.c 挂载文件系统:
1#include <rtthread.h>
4 h! m! d- \, D1 `$ k( O9 T8 I 2#include <rtdevice.h>  t1 N% t: y! G& E/ O/ s( }2 m
3#include <board.h>
8 w0 Y6 y5 C2 h( `6 ^/ S8 x7 |& @( b 4#include <fal.h>
1 p( @# ~+ A8 i! e- H 5#include <dfs_posix.h>
1 P0 L$ ]) u8 B, ^4 H 6
8 `0 K0 C1 t( q 7/* defined the LED0 pin: PC13 */9 W2 n9 r+ Q5 F0 N- T8 n+ ]
8#define LED0_PIN    GET_PIN(C, 13)
: r. U. H% g. z" g) S) V5 N 9; j- [2 X# W6 ^/ D
10#define FS_PARTITION_NAME  "flash0"
1 G0 c$ \% i" I( {3 a11
# Z! a" t8 c* ?. z3 g. Y. w12int main(void)0 _5 }, X4 W, {
13
{
# @% N/ d7 f" z/ F14    int count = 1;8 k+ z% j7 _9 e9 j' \. b
15    /* set LED0 pin mode to output */5 D$ R/ B% F/ q1 m
16    rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);/ l9 p0 ~( e7 }9 H- F
177 |$ U. B, H$ ^% U0 O
18    fal_init();+ Q  a$ @- Z$ q5 u- [) O# f
19# E6 g) ]1 |$ e/ |7 ~
20#ifdef RT_USB_DEVICE_MSTORAGE
! i, i; `5 J4 ~21    struct rt_device *flash_dev = fal_blk_device_create(FS_PARTITION_NAME);6 z  M( \4 r5 i* L. P! D/ w/ Q( V
22#else
5 h! l+ f1 r2 U* R23    struct rt_device *flash_dev = fal_mtd_nor_device_create(FS_PARTITION_NAME);8 S! Z  T' Z% {
24#endif
1 j) F* O* M5 |! o  J252 G0 R2 ^6 G  N4 P) @
26    if (flash_dev == NULL)
1 F% u  U+ m4 S27    {
/ U4 H5 y8 @/ l8 T7 n# k% x28        rt_kprintf("Can't create a block device on '%s' partition.\n", FS_PARTITION_NAME);  |+ ]9 L, G( r/ A8 M8 r% E+ p
29    }
, ]( y2 \6 n; M3 {30    else
2 M! W. g4 t# Q+ p1 A31    {
5 g8 o! A% i: d, L! {32        rt_kprintf("Create a block device on the %s partition of flash successful.\n", FS_PARTITION_NAME);; `6 V3 ?+ H7 E
33    }
1 G  Q$ l  Q: }6 y& L34$ V4 U* f7 I( Z$ F$ m
35    while (count++)" \  |: I- w) t( h# y! b. J  R) k8 b
36    {1 r+ t! d) n8 I) b
37#ifndef RT_USB_DEVICE_MSTORAGE
1 i" B8 m# F) C" ]8 K1 _38        if(rt_device_find(FS_PARTITION_NAME) != RT_NULL)
) d; k( p1 a. {4 f4 e! s39        {
$ R. c! Y8 P2 a40            dfs_mkfs("lfs", FS_PARTITION_NAME);% B( p+ Q& ~6 ?2 Q) Q! L! p2 E3 L
418 ?& w4 X3 I( }3 F
42            if (dfs_mount(FS_PARTITION_NAME, "/", "lfs", 0, 0) == RT_EOK)
  [" g' I! W" K3 @) t& B43            {
4 `! t0 ?) P# w0 [44                rt_kprintf("sd card mount to '/'\n");: c- a  N" t/ o( R( W$ s+ e  P& p
45                break;- g  E# N, ^2 Q, n' E1 U/ R
46            }
$ m# m  b; o* J( W# Z) f% h47            else
5 i6 x2 y) Q% h5 v, M: o4 n! i. h; r48            {4 H$ ]' s# z  ~/ M
49                rt_kprintf("sd card mount to '/' failed!\n");$ D2 k4 I1 P  S! ~& T* S
50            }- K  V% O' I0 X0 b9 `! o) I
51        }
0 }0 D- Z+ `- f52#endif& `8 [9 C  Z# r
53        rt_pin_write(LED0_PIN, PIN_HIGH);5 y' `/ D3 T+ }) g6 A2 O1 G
54        rt_thread_mdelay(500);
/ A+ Z0 e8 _: d/ M55        rt_pin_write(LED0_PIN, PIN_LOW);- H+ ?9 j! P# R; l3 e3 G
56        rt_thread_mdelay(500);2 n" W8 S+ |3 Q6 G0 R8 x# p0 J
57    }
; O) O. Q/ I" ~5 P+ f58
1 D5 L+ u6 z! l( t% |  b# n  r59    return RT_EOK;9 j# Q) N0 E' @( D# F1 J
60}5 [9 F  D- c' b

+ t7 N7 l. L- y3 t0 n1 Z项目编译下载到板子上,串口连接上去在 msh 里输入 fal probe 应当就可以看到分区表了:
9.jpg
Linux 下常用的命令 lscatmkdircd 也都是支持的,这样我们就把 stm32 的片上 flash 挂载为文件系统了, 下一步就是让它识别为 U盘。

1 `3 W2 p$ F' i; n) u3. 挂载片上 Flash 为 U盘同样的,我们在 env 的配置目录里面依次选中:
  • Hardware Drivers Config --> On-chip Peripheral Drivers0 m- u  ^$ I2 T4 B; Z5 f
10.jpg
  • RT-Thread Components --> Device Drivers --> Using USB
    ; b' y& y* Z" C3 i" o/ V6 ]& S# G
11.jpg
12.jpg
这样保存配置,在 env 下生成项目文件:
1scons --target=mdk5 -s/ E  d- i# V% m4 e& x* A4 |
编译上传到板子上,接上 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 手机版