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

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

[复制链接]
eefishing 发布时间:2019-11-28 23:18
每当提到 3D 第一人称射击游戏,大家很自然就会联想到高性能独显,以及几个G甚至几十G的硬盘存储空间,那么有没有可能在 STM32F103RC 这样一块只有 256KB Flash 的小板子上保存一个大型第一人称射击游戏呢?
1.jpg
当我们用 USB 线把这块开发板连接到电脑上,就可以看到出现了一个只有100多KB的U盘,这就是 STM32 的片上 Flash 了。
( S' q0 ]) Y  {) y) _
2.jpg
然后可以看到U盘里有一个 90KB 的游戏。
3.jpg
如果我们双击它就启动了一个 STM32 上的第一人称射击游戏。
- h( Y& s1 X( D4 _( t7 m: j
3 j/ c4 @; J/ N5 n& q  u" P3 h
这是完整的演示视频:如果你也有兴趣把这个游戏保存在 STM32 上,可以跟着后面的教程,或者也可以在这个项目里直接找到编译好的固件、游戏和项目源码。6 d' j5 s7 j7 t; J. k/ D1 R
链接地址:http://github.com/wuhanstudio/stm32-ufun-3d-game

1 [; e+ J. R* v$ {7 P1. 运行 RT-ThreadRT-Thread 在 Github 上是开源的,源码可以在这里(链接:http://github.com/rt-Thread/rt-thread/找到,官网文档也很丰富这里就不重复了,总结一下需要的工具:
  • Git Bash
  • Keil 开发环境
  • STM32 开发板
  • RT-Thread 源码
  • env 工具$ m5 X' e  K" g$ [$ d- g$ x+ ^2 _- q
如果觉得从 github 上面下载 RT-Thread 源码比较慢,可以先从 gitee 上面下载,然后修改项目地址。
1git clone https://gitee.com/rtthread/rt-thread$ o/ x2 [2 i2 H! Y% ~) s- y+ R
2cd rt-thread* X% ^( f$ b4 q3 ~  U) F
3git remote rm origin
6 h# `* }4 Y0 @3 l4git remote add origin https://github.com/RT-Thread/rt-thread
2 {& ]- H& {7 l1 {  y5git pull origin master
3 U9 W* Q9 B1 e+ g( e" C9 K( e9 L) a& f- e+ c
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_FLASH9 V2 i  x  V' a4 x# y7 g
2    bool "Enable on-chip FLASH"/ ~; [9 c$ ?; A' U( L, J; F
3    default n 5 L3 [* N5 K+ A6 a
4
! ^& D4 `! Y9 n+ b; c* `9 Z  [8 U5config BSP_USING_USBD_FS/ l; S  M! v3 m6 `, T) ]
6    bool "Enable USBD as USB device"
7 c. ^. n# L) J0 h7    select RT_USING_USB_DEVICE4 j( |! R7 z6 J& J) @. }/ I
8    default n8 K+ T5 [$ H- G8 _
这样再在 bsp 目录下右键 ConEmu Here 就可以看到配置界面 (Env 教程:http://www.rt-thread.org/document/site/tutorial/env-video/),依次选中下面几个选项:
  • Hardware Drivers Config --> Enable on-chip Flash- P; ?! S' A: b
5.jpg
" X( g* B+ [- B$ t! G
  • RT-thread Components --> Device Drivers --> Using MTD Nor Flash device drivers

    + ]2 M3 X. C: g. b
6.jpg

2 H6 U+ v2 o% q' k" N
  • RT-Thread online packages --> system packages 选中 fal 和 Littlefs+ m/ [9 ^2 f' ]
7.jpg
9 b- j2 ^9 N6 U; {9 D8 f, O0 M
  • RT-Thread Components --> Device virtual file system# q9 L0 Z: e/ G$ N  g3 w
8.jpg
6 e. L1 o6 a5 U
保存配置退出,在 env 里面输入命令就可以自动生成 Keil 项目了:

7 j% {) [  [" W+ x# ^1pkgs --update  E' O! x( F1 G- Q( j
2scons --target=mdk5 -s) f) Z. M  u" {

) H; C$ Q8 g: a- z: @9 P. ]
我们需要先对 flash 进行规划,STM32F103RC 一共有 256KB,可以把最后的 128KB 作为文件系统使用,于是新建一个 fal_cfg.h 1extern const struct fal_flash_dev stm32_onchip_flash;
) Y  I/ G0 T5 Y 28 x, J' `) U* N! ^( e( D
3#define FAL_FLASH_DEV_TABLE                                          \
% b" r3 g& O3 E 4{                                                                    \
9 |& `& y; o+ |- K 5    &stm32_onchip_flash,                                           \; h/ s- _" w* q
6}

1 `7 i) _. s; s! h$ A4 }# f( A 7
- L3 \1 c! ?8 V& d9 l. Y 8#define FAL_PART_TABLE                                                          \3 W6 v. `; q. q9 `3 Q' @
9{                                                                               \' J* o+ g: `" a- V
10    {FAL_PART_MAGIC_WROD,       "app", "onchip_flash",         0,   128*1024, 0}, \
" s1 R8 _0 v3 T$ |9 z% f  U11    {FAL_PART_MAGIC_WROD,      "flash0", "onchip_flash",   128*1024,  128*1024, 0}, \; l  ?+ U) b. R, `& p
12}
1 m9 B, A- l0 K4 ^6 |
2 D6 L6 z7 `3 _. I/ a# \5 H$ x" @
再修改 main.c 挂载文件系统:
1#include <rtthread.h>
, m. P2 a) P& `: ]" U! ?0 i$ p1 C% } 2#include <rtdevice.h># T! m$ F# |) q
3#include <board.h>/ n. A0 ~  U3 [' I9 q, D
4#include <fal.h>1 R; ?; j, p3 b6 t7 v+ t# e& w
5#include <dfs_posix.h>$ z" ]  U4 Q# E3 k+ N7 _
6
9 A! n. c: O1 i; h- z3 z3 Q 7/* defined the LED0 pin: PC13 */" C1 c: i' [. G! P- G5 A
8#define LED0_PIN    GET_PIN(C, 13)4 B( U% |2 w# E; u1 J- W! |
9: M: F# j" F5 }& y, f: i8 R
10#define FS_PARTITION_NAME  "flash0"
5 ~  `( a) i7 ~9 r, O11
0 A3 Y/ T6 U/ T3 H% F12int main(void)
$ n/ o. {7 L; n* `8 E- I% V13
{7 t$ i" A! m7 ]% Q9 O
14    int count = 1;* q3 G1 `) n/ ~3 E1 w) \
15    /* set LED0 pin mode to output */$ T. ~& h- T/ p: Y# d# X
16    rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
- }% |% c: O9 r, R17! v% z; p, j" ~6 V+ J& g2 s; t% T
18    fal_init();, V% ], i+ }5 R4 l
19
( U: I. `/ m8 _8 p  M9 o* z7 E; ?- |20#ifdef RT_USB_DEVICE_MSTORAGE
! y" m: J& t* X/ H* f( Q/ G21    struct rt_device *flash_dev = fal_blk_device_create(FS_PARTITION_NAME);
# [4 O6 i8 |' I: q22#else
: J$ ]; t0 U7 o) Q23    struct rt_device *flash_dev = fal_mtd_nor_device_create(FS_PARTITION_NAME);# Y6 L; x5 A+ X
24#endif
  R( R! |, C5 d, @2 b, L( @25) D% W* X* B0 Z& {; E9 D+ \8 `
26    if (flash_dev == NULL)
( Y" k3 o2 L! U27    {8 e7 V8 N, Z' w6 z8 I
28        rt_kprintf("Can't create a block device on '%s' partition.\n", FS_PARTITION_NAME);
  R  X$ X( G5 s29    }$ {& C! d! c5 |+ f8 m
30    else1 I  L- C6 c( i
31    {
  C& j" A% ]: B32        rt_kprintf("Create a block device on the %s partition of flash successful.\n", FS_PARTITION_NAME);
2 c2 A% S/ v" @$ l0 \33    }/ D, ~, n5 r1 f* k8 v5 A9 n. s
34' i. x  n2 |) X; n* D
35    while (count++)2 A& c. J/ y( o- {6 I
36    {& H8 G1 I2 Y! W: m4 v5 a
37#ifndef RT_USB_DEVICE_MSTORAGE) n+ g7 w# K3 ]
38        if(rt_device_find(FS_PARTITION_NAME) != RT_NULL)
/ E8 j- @) o& n$ e9 D' E39        {' Y' D6 r- }5 Q- K' [* r
40            dfs_mkfs("lfs", FS_PARTITION_NAME);
- M7 S! ^7 l# Z41
; O' ~  s! [; j" X6 r. C42            if (dfs_mount(FS_PARTITION_NAME, "/", "lfs", 0, 0) == RT_EOK)3 p  T- G2 `$ \2 g2 J: E/ B
43            {9 w4 N$ u+ q5 G( _
44                rt_kprintf("sd card mount to '/'\n");
5 [; l, x& W$ a8 ^  I9 U+ M8 K45                break;
2 X+ U' U; T- E3 G' W5 ~46            }
! k0 `6 s/ d0 u5 l1 \7 t, v: i6 A47            else; j) o9 g" ^6 @' S9 H9 K
48            {
8 Y; M1 S, X' m4 s7 x) @49                rt_kprintf("sd card mount to '/' failed!\n");- l( J8 u  \8 ~8 J# R2 P
50            }+ \$ ]: h) P# ?5 i# I0 u
51        }
$ d# ]7 ]# ~) ~1 `9 Y( a52#endif' t8 R+ `) X5 A: t! N) P! v
53        rt_pin_write(LED0_PIN, PIN_HIGH);$ z  x9 h4 l/ \6 e! j1 [. T0 d" X% C
54        rt_thread_mdelay(500);
0 V) U) c1 H* y; X& V( N: o7 s55        rt_pin_write(LED0_PIN, PIN_LOW);3 ]; r9 F6 n% s) j% m. `5 m& B
56        rt_thread_mdelay(500);. L" q3 Q, f* Z: W' X9 x: h
57    }# Y5 ?' A( T8 H/ S8 g8 y/ m
58
4 z: g- P+ M8 ?' C' Y0 y59    return RT_EOK;6 y, Z" p2 V$ o8 O0 s
60}: R0 x# d6 h& c7 c2 E; W" K; }

2 D! n) K1 M7 w4 B: M) w项目编译下载到板子上,串口连接上去在 msh 里输入 fal probe 应当就可以看到分区表了:
9.jpg
Linux 下常用的命令 lscatmkdircd 也都是支持的,这样我们就把 stm32 的片上 flash 挂载为文件系统了, 下一步就是让它识别为 U盘。
4 s; Y/ E6 i7 z
3. 挂载片上 Flash 为 U盘同样的,我们在 env 的配置目录里面依次选中:
  • Hardware Drivers Config --> On-chip Peripheral Drivers
    0 W- {8 y, W2 W: a5 n' R9 k
10.jpg
  • RT-Thread Components --> Device Drivers --> Using USB/ E  c+ M/ F' Z9 O
11.jpg
12.jpg
这样保存配置,在 env 下生成项目文件:
1scons --target=mdk5 -s
8 R2 C' b$ U, [' E' M2 O1 ?; l4 y编译上传到板子上,接上 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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版