随着意法半导体功能强大的STM32F42X / 43X微控制器(MCU)的出现,以uClinux形式在STM32设备上运行Linux的话题变得前所未有的热门。在MCU世界中,嵌入式设计人员历来仅限使用RTOS甚至“裸机”固件。然而,对微控制器应用的需求正在以非常快的速度增长。如今,功能强大的嵌入式设备以及一组强大的复杂通信,存储和UI界面已成为一种规范。 , C( y2 Z$ P9 Y. O1 B 4 Z, k! D& O$ ? K% y7 C 通常,新的STM32设计并不是要添加现有实现中缺少的单个功能。设计人员通常面临添加对多个I / O接口的支持的任务,所有这些都必须由适当的设备驱动程序,软件堆栈和应用程序编程接口覆盖。 0 `0 Y6 W G) R# R7 M5 a- d, J / y5 c/ N% c$ V7 _" @) j& N% ] 考虑到一长串新软件需求,Linux确实开始具有吸引力,成为一种操作系统选择。通常,它将支持现成的现代MCU应用中可能需要的所有功能。对于那些立即无法立即获得支持的要求,工程师将能够找到一系列开源Linux项目,这些项目可以用作软件开发的起点。 当今的Linux提供了许多好处:它是免版税的;每个组件都有完整的源代码;它在所有计算领域中无处不在;知识渊博的开发人员相对容易找到;仅仅通过Google搜索,就可以在操作系统实现的几乎所有方面获得大量的资料;Internet上有大量工具,库和应用程序可供立即下载。显而易见,使用Linux可以如何显着降低项目成本并缩短上市时间。3 M# K: p- ?3 g5 n9 }: E: V 7 n& p( L7 j4 B7 G4 p2 X 综上所述,即使对于功能强大的MCU设备(如STM32F42X / 43X MCU系列),对于Cortex-M3 / M4设计,Linux仍可能过于“沉重”。的确,尽管上市时间和项目成本至关重要,但仍然需要考虑的事实是,MCU项目的决策过程还受到保持低组件数,最小物料清单(BOM)和微型印刷电路板(PCB)占用空间。 2 O0 d. Y g, `# F0 B 本文介绍了如何使用STM32F42X / 3X MCU开发实用的Linux平台。以成本最优化的形式,该平台实际上减少到只有两个芯片-特别是STM32F4 MCU本身和一个外部SDRAM器件。2 x' D& p, c( R! Y3 R2 c . q* ^. h' g; [+ J% }3 J Linux执行模型" Z' E6 \% ~. ^2 z 首先,重要的是要解释Linux的执行模型。按照Linux的习惯,事情可以用不同的方式完成。但是,可以通过以下引导顺序来描述部署在Cortex-M3 / M4 MCU上的默认执行模型:" Y! _# X4 U) h, y6 D* y& | " w, p6 v4 j+ j 1.上电复位时,Cortex-M3 / M4硬件从集成闪存调用U-Boot固件引导加载程序。U-Boot从片上闪存运行,并使用片上RAM来存储堆栈,易失数据和缓冲区。除非调用在外部闪存或外部RAM上运行的显式命令,否则它不需要外部存储器。 3 ~2 g% E0 f, D- a 2. U-Boot提供了可用于许多实例的命令界面,但是默认引导顺序是U-Boot运行命令的命令,该命令将可引导的Linux映像加载到外部RAM并将控制权传递给内核点。可引导的Linux映像可以驻留在任意的非易失性存储设备中,只要U-Boot具有它的设备驱动程序即可。它可以是并行闪存,SPI闪存,SD卡,USB记忆棒等,基本上是特定Cortex-M3 / M4 MCU和U-Boot支持的任何I / O接口都有随附的设备驱动程序。作为一种特殊情况(对于在软件开发阶段通常使用的接口),可引导映像可以驻留在TFTP主机上,并由U-Boot通过以太网加载到目标。 3.一旦被U-Boot调用,Linux内核将进行引导,初始化其内存管理系统,设备驱动程序,各种I / O堆栈等,并最终安装根文件系统。通常,根文件系统可以驻留在适当的Linux设备驱动程序支持的任何存储设备上,例如闪存,SD卡,USB记忆棒,NFS共享等。一种特殊类型的根文件系统(通常在嵌入式应用程序中使用)使用所谓的initramfs。在这种情况下,可引导的Linux映像是自足的。它不依赖于外部设备上根文件系统的可用性,它包括两个主要部分:Linux内核本身和根文件系统的cpio表示。无需赘述,cpio是一种Unix存档格式,无法直接挂载为文件系统, 0 ]+ Z$ Y2 Z4 A$ f( J; \ . Y P, y' p5 q/ k9 q. }7 \ 4.将initramfs根文件系统安装到RAM中后,Linux继续从rootfs运行init实用程序,该实用程序又调用特定应用程序所需的任何启动脚本。通常,启动脚本会在Linux控制台上生成一个交互式shell。但是,一般而言,在特定的嵌入式设计中,任何人都可以做有意义的事情。根文件系统中的任何用户空间工具和应用程序都是直接从RAM中的快速initramfs运行的,而无需从速度较慢的存储设备中复制它们。这不仅有助于减少启动时间,而且可以提高整体系统性能。 $ T+ ~; i+ v, e9 T 当使用STM32F42X / 43X器件时,会发生上述执行模型的一个有趣变化:可引导的Linux映像可以存储在片上闪存中,该闪存足够大(2 MB)以存储具有合理Linux功能的映像。 。只要可引导的Linux映像存储在片上闪存中,就无需设计其他存储设备。* Q7 _ g/ L% X. B9 y4 m 此外,当可引导Linux映像存储在片上闪存中时,可以直接从闪存中运行内核,而不是在调用内核入口点之前将映像复制到外部RAM。这实现了两个重要目标: 减少了Linux引导时间,因为不需要将可引导的Linux映像从相对较慢的存储设备复制到RAM。. o9 ^: {- h: C+ a+ K+ R0 N, w6 @ ' E& r% s. k) S9 f H ( d' W. W/ P) i) a •从集成的零等待状态闪存运行内核可以大大提高Linux的整体性能。: w) w/ [$ t! l0 g ' k( k/ _1 H- ]5 a( a3 T% d8 I/ h 可以看出,Linux确实可以通过两芯片设计在STM32F42X / 43X上运行。以下各节演示了使用此执行模型时可用的示例Linux功能。 硬件参考平台 8 B9 e0 @) p) ^* M* M & y! T$ e+ Q3 v* S 4 m# Z' Z P& w# s" U/ F 1.这里显示的是意法半导体 STM32F4模块上系统主机和STM32F4 Cortex-M4微控制器。/ h( }" B* K) h 以下各节提供的示例Linux会话在Emcraft Systems的 STM32F4模块上系统(SOM)上运行(图1)。STM32F4是一个微型(30 x 46毫米)夹层模块,包括以下组件:% m ?% Q7 {/ W •意法半导体的单芯片STM32F429 MCU:它将180MHz,32位ARM Cortex-M4处理器内核与集成的SDRAM接口和一组复杂的I / O外设结合在一起。 ( k" I8 r3 T) e • 12 MHz晶振: STM32F42X / 43X设计中需要参考时钟,而不管在STM32F4上运行Linux还是其他RTOS。* I/ _* a$ W/ a2 Z ; j9 [+ [ ^- ^0 V) |2 ]. o • 32 MB SDRAM: SDRAM是Linux必需的;但是,如果在STM32F4上运行RTOS或裸机固件,则可以省略。, T b h3 a: \/ B* U$ | • 16 MB NOR闪存:这是一个可选组件,用于添加非易失性存储。 4 h( n! X# H* q# b8 ]7 ~- R7 T, b • 以太网PHY和相关的25 MHz晶体:仅当设计实现以太网链路时才需要这些组件。 " E0 y' |& v6 {2 ~6 F 4 a: U0 z$ X3 D1 G. E% N# y • 32.786 kHz晶体:这是一个可选组件,用作STM32F4实时时钟(RTC)的参考。 在下面显示的测试中,将SOM安装到STM32F4 SOM入门套件随附的原型开发基板中。基板可立即访问关键的STM32F4 I / O接口,例如JTAG,使用UART的串行控制台,以太网,USB OTG等,并使所有其他STM32F4信号在面包板区域可用,以便于原型制作(图2)。 ( I2 J2 f' Y, v! k1 P9 ~. e! ~2 g 5 Y+ z8 r# y2 U# o; ?5 ` b: | / `7 t# \& _$ B/ M" V) H; @8 [ 2. STM32F4 SOM插入SOM-BSB-EXT基板。该模块将插入用于应用程序的定制载板上。 " s6 I! ~& \& ~# O8 N/ s8 f 示例Linux会话 以下示例会话演示了在STM32F42X / 43X上运行的Linux TCP / IP堆栈。Linux TCP / IP堆栈实现的一组复杂功能集为需要功能丰富且强大的连接性的任何MCU应用程序提供了现成的基础。在下面的示例中,TCP / IP通过以太网运行。但是,也可以将其配置为在其他类型的物理链接上运行。最明显的例子包括使用基于USB或SDIO的Wi-Fi模块的Wi-Fi或UART上的PPP。 u0 j: @' {* V% G- q1 Q 如上所述,Linux内核直接从快速片上闪存运行。结果,开机或重置后大约一秒钟即可使用Linux shell: ; `9 H8 V/ P1 n2 C' B$ p, e! O: e U-Boot 2010.03(2014年10月27日-12:55:43)" m: b! N% i6 Y5 ^5 c& `, ^5 M) f ... 启动内核...* ^/ i: F/ V! |! v' b$ k4 o! Q . {9 [9 x) |3 a9 ]+ A 7 u" y* H6 n- t" f+ {) L Linux版本2.6.33-arm1(vlad@ocean.emcraft.com)(gcc版本4.4.1(Sourcery G ++ Lite 2010q1-189))#38 Mon Dec 8 11:39:30 MSK 2014. u4 a; X! |6 U CPU:ARMv7-M处理器[410fc241]修订版1(ARMv7M) CPU:无数据缓存,无指令缓存$ }7 y* w, g* U! q0 l) Q 机器:STMicro STM321 O: m7 d, F! @+ Q 按区域顺序构建了1个区域列表,移动分组。总页数:8128 内核命令行:stm32_platform = stm32f4x9-som console = ttyS0,115200 panic = 10 ip = 172.17.4.206:172.17.0.1 ::: stm32f4x9-som:eth0:off ethaddr = C0:B1:3C:88:88:85 PID哈希表条目:128(顺序:-3,512字节) Dentry缓存哈希表条目:4096(顺序:2、16384字节) Inode缓存哈希表条目:2048(顺序:1、8192字节) 内存:32MB = 32MB+ Z# _! S* F T9 w, m/ _2 E8 S 内存:32296k / 32296k可用,472k保留,0K highmem1 h$ ^$ n, c5 f+ K& t7 W 虚拟内核内存布局: 向量:0x00000000-0x00001000(4 kB) fixmap:0xfff00000-0xfffe0000(896 kB) vmalloc:0x00000000-0xffffffff(4095 MB)3 A* B; [: K7 o8 R9 {) o! ~" ^ 低内存:0xc0000000-0xc2000000(32 MB) 模组:0xc0000000-0xc2000000(32 MB)9 G/ k3 d) ?/ g7 f/ j+ d( g .init:0xc0008000-0xc000a000(8 kB) .text:0xc000a000-0xc0016000(48 kB): M9 R3 }+ d) ^$ R8 |. z2 L" t .data:0xc0016000-0xc0025480(62 kB)8 ?" t8 F9 U; `8 A 分层RCU实施。5 Y: s& e1 x2 d3 ]* F' R4 C+ ]. r0 z9 J NR_IRQS:90 校准延迟回路... 156.87 BogoMIPS(lpj = 784384); }+ L; _/ X* S9 v3 `; `* O 装入高速缓存哈希表条目:512+ h. B% N- ^) ?+ t: q* e$ j NET:注册协议系列162 X5 C ]" h7 Y9 d 个人简介:创建平板 在0 切换到ClockSource cm3-systick NET:注册协议族2 IP路由缓存哈希表条目:1024(顺序:0、4096字节)- h9 E8 _6 b4 q! W) S( y+ c6 t; q7 e TCP建立的哈希表条目:1024(顺序:1、8192字节)8 b- @& u2 _( l9 ~ TCP绑定哈希表条目:1024(顺序:0、4096字节)8 C' B; d4 U, q3 L8 j3 ]( r O; w7 F TCP:已配置哈希表(建立1024绑定1024) TCP reno注册- A% }9 K6 i# `: d RPC:注册的udp传输模块。& \1 d; J ~5 z( M RPC:已注册的tcp传输模块。 RPC:已注册的tcp NFSv4.1反向通道传输模块。 加载了0.4版的块层SCSI通用(BSG)驱动程序(主要254) io Scheduler Noop已注册, Z4 M; C$ b0 n io Scheduler截止日期已注册 io调度程序cfq已注册(默认) 序列号:STM32 USART驱动程序5 s; M) l) c1 c5 I/ ~3 f9 {0 v Q stm32serial.0:MMIO 0x40011000(irq = 37)上的ttyS0是STM32 USART端口 控制台[ttyS0]已启用 初始化STM32F4映射器,将代码从c0026000复制到200001a8,大小560 使用SRAM作为起始20000400和大小400的缓冲区3 m; t/ A- S8 n. V4 Z stm32f4平台闪存设备:64000000 01000000; p2 u; |% N4 }# {9 V$ n stm32f4-flash:在16位存储区中的0x0处找到1个x16设备 Amd / Fujitsu扩展查询表位于0x00401 C- c2 |, l- V9 w' t CFI芯片数:1 RedBoot分区解析不可用. C- |- O4 b q$ w- W! K 使用stm32f4分区信息8 D- V: P+ ]6 k( `+ @( k } 在“ stm32f4-flash”上创建3个MTD分区: 0x000000000000-0x000000020000:“ flash_uboot_env”; H/ g$ T1 U: v 0x000000020000-0x000000300000:“ flash_linux_image”/ |+ V9 G4 ~2 z. D! B* f 0x000000300000-0x000001000000:“ flash_jffs2” blackfin-eth:从20001000开始使用SRAM作为DMA缓冲区* ]5 ~5 f: x" I6 M$ c blackfin-eth:在0x40028000处发现MAC,irq 61 blackfin_mii_bus:已探查$ j2 q! X9 S4 L" l$ ^. m6 J 找到PHY ID 0x221556地址0 eth0:使用MII接口 eth0:连接的PHY驱动程序[通用PHY](mii_bus:phy_addr = 00:00,irq = -1)& k) v: i8 J* }! V0 R JFFS2版本2.2。(与非)бâ??? 2001-2006 Red Hat,Inc. TCP三次方注册 NET:注册协议族17& q( g6 }, X! u0 }9 u! A- q, | IP配置:猜测网络掩码255.255.0.0# t4 O+ {; h" C2 G- R+ P IP配置:完成:3 C3 o% h4 L+ l2 h 设备= eth0,地址= 172.17.4.206,掩码= 255.255.0.0,gw = 255.255.255.255,2 E( g/ J1 p; ] host = stm32f4x9-som,domain =,nis-domain =(none), bootserver = 172.17.0.1,rootserver = 172.17.0.1,rootpath = 支持ARMv7-M VFP扩展; Z# `8 P$ P" W PHY:00:00-链接建立-100 /满/ L8 j; p, g& Q- d Z3 K 释放初始化内存:8K/ \5 o% z7 z. ^" j2 [6 s 初始化开始:BusyBox v1.17.0(2014-11-18 17:08:28 MSK)* R1 @9 u P$ B% ^$ {6 m 〜#, |& r& B8 R8 f% \& Y! j$ C' e( ` 4 |5 l' B2 I+ w6 U$ A $ ^ S: d: I7 r. T1 |, Z( f# r 现在让我们测试STM32F4上的TCP / IP堆栈。在开发主机上,使用ping验证STM32F4是否可见: # K+ X! ?$ s; u" |8 _ -bash-4.2 $ ping 172.17.4.206 {. U! f* u* P* i3 N8 ] PING 172.17.4.206(172.17.4.206)56(84)个字节的数据。 来自172.17.4.206的64个字节:icmp_seq = 1 ttl = 64时间= 1.53 ms s' A& V0 {: I6 ~" N4 p 来自172.17.4.206的64个字节:icmp_seq = 2 ttl = 64时间= 0.244 ms, t, [1 D0 ?. J \$ V 来自172.17.4.206的64个字节:icmp_seq = 3 ttl = 64时间= 0.257 ms 来自172.17.4.206的64个字节:icmp_seq = 4 ttl = 64时间= 0.229 ms8 w, T/ X6 |# A% v, Z: _( r$ T, q ^ C" I( D! f, [2 }9 @ -172.17.4.206 ping统计信息---: f2 j3 R- p" D/ m8 U t) Y2 Z# M) a 传输4个数据包,接收4个数据包,0%数据包丢失,时间3972ms rtt最小值/平均值/最大值/ mdev = 0.229 / 0.567 / 1.539 / 0.561 ms -bash-4.2 $8 `& ?+ x3 F2 V4 P; H$ d2 }' T" A" c' \ 为了从另一个方向测试连通性,让我们从STM32F4 ping开发主机: + P! g. C4 o+ b( S1 L2 k 〜#平172.17.0.12 |$ c% Z3 y: ^% } PING 172.17.0.1(172.17.0.1):56个数据字节" @" r" n* {$ P% J" R& t$ q 来自172.17.0.1的64个字节:seq = 0 ttl = 64 time = 3.302 ms 来自172.17.0.1的64个字节:seq = 1 ttl = 64 time = 8.921 ms' ]6 }2 {6 [* O 来自172.17.0.1的64个字节:seq = 2 ttl = 64 time = 8.977 ms3 M- U+ r3 G$ Q7 u 来自172.17.0.1的64个字节:seq = 3 ttl = 64 time = 9.438 ms 来自172.17.0.1的64个字节:seq = 4 ttl = 64 time = 0.516 ms4 s6 Y$ ^1 d/ @, T: C 来自172.17.0.1的64个字节:seq = 5 ttl = 64 time = 0.506 ms ^ C --- 172.17.0.1 ping统计信息--- 已发送6个数据包,已接收6个数据包,丢包率为0%; o7 y" z( a6 x; \" [9 Q) U 往返最小值/平均值/最大值= 0.506 / 5.276 / 9.438 ms3 P: A i0 W" T5 T 〜#9 r0 b6 C0 x+ a7 \ : V* r( o( T( r, v- [/ X/ W 在目标上,启动telnetd守护程序以允许与STM32F4的远程连接: ( I- r/ x7 {+ ~0 a0 k* N 〜#telnetd 〜#ps PID用户VSZ STAT命令 1根352 S初始化 2 root 0 SW [kthreadd]7 o) I: k' |: k+ V8 e 3根0 SW [ksoftirqd / 0] 4 root 0 SW [事件/ 0] 5 root 0 SW [khelper]3 `7 Y8 B( w$ S0 e. t 6根0 SW [async / mgr]' n3 K6 j$ u. R# a$ o o 7个根0 SW [sync_supers], ^6 U& P# U# |) R9 F8 O% T% G 8 root 0 SW [bdi-default] 9 root 0 SW [kblocked / 0]: P% K8 D- G1 ? 10 root 0 SW [rpciod / 0] 11根0 SW [kswapd0]: K7 u) c; q% V4 B7 g 12根0 SW [mtdblocked]( r( S5 A, R8 @2 O+ q$ r 13 root 0 SW [nfsiod] 19根367 S / bin / hush -i 22根332 S telnetd 23根348 R ps! T# l$ T- s2 D0 D# j! S4 d 〜# & S& k; n5 ?/ p. i! H * u, H$ y; ^) L- N8 C8 n 现在,我们可以使用telnet从开发主机连接到STM32F4。目标配置为接受root用户的空密码,因此在询问密码时只需按Enter键即可: -bash-4.2 $ telnet 172.17.4.206 正在尝试172.17.4.206 ...: c$ o5 j+ i! _: C 连接到172.17.4.206。/ }. G4 t: a) E7 Z/ M" t 转义字符为'^]'。# |( |8 e4 N( H8 m 4 x) G$ i3 {2 _; ]9 l% W& k' Q6 S* H stm32f4x9-som登录:root) n- t6 z5 }/ J 密码:1 [- m) _/ A9 d9 d 〜#ls! @8 u" p: J( [6 d5 w+ P bin dev等httpd init mnt proc root sys usr var 〜#退出- x, e! L0 G; l 外部主机关闭连接。6 _* u3 E6 M7 c' N# i: a$ P! h -bash-4.2 $' t2 c( B4 ~! g6 |* \7 T 让我们在STM32F4上配置默认网关和名称解析器。请注意下面的示例配置如何使用Google提供的公共名称服务器。还要注意使用vi编辑器在目标上编辑文件:1 e ?* q* s" A0 q 〜#route添加默认gw 172.17.0.1 〜#vi /etc/resolv.conf( k/ H6 I' h) \, @- X 域名服务器8.8.8.8! G U- h) @! T& L% Y0 f5 Q 1 I3 E5 Z! H6 F+ J M 〜& y! a& ^3 s, l' D! M 〜# w* d5 r* H! J7 j6 f 7 `, n2 ]7 I2 z 让我们运行ntpd将STM32F4上的时间与公共服务器提供的时间同步:5 |: b3 y$ J" T3 P: X9 [ % E& p# ` m" Z9 Z 1 |! H: ^5 S# D# J$ r% W. i$ g) X 〜#日期 1970年1月1日星期四00:07:470 Z: M! Z9 n( ~+ r6 Y 〜#ntpd -p 0.fedora.pool.ntp.org; 睡5 〜#日期0 |# j# O, o% h 2014年12月8日星期一08:54:10 UTC 〜# 这是我们使用wget从远程服务器下载文件的方式: 5 n r+ W4 P9 [7 L2 y. U 〜#wget ftp://ftp.gnu.org/README 连接到ftp.gnu.org(208.118.235.20:21)0 [4 K) _2 ? ?' N! f5 S# l 自述文件100%| ******************************* || 1962年-:-:-ETA& U1 n" y2 i9 q$ s) O7 c8 U$ X, F7 D9 p 〜#猫自述 这是ftp.gnu.org,它是GNU项目的FTP服务器。 ...4 i* o7 [$ \( \/ F/ w! u& J 〜# ( |( ]( A- Y, P J. k _ 0 z/ X* n* T7 M; W, r$ h 我们可以挂载开发主机通过NFS导出的目录。这使我们可以立即访问主机上的文件。例如,我们可以在主机上构建目标应用程序,然后立即通过NFS在目标上运行它们,而无需重新引导或刷新目标:, N2 Y6 |: F) m: a( u & F$ w% n$ L, E c5 U t) W ~: \ h O9 L; v0 h6 w/ t! M% t5 u 〜#mount -o nolock,rsize = 1024 172.17.0.1:/home/vlad / mnt 〜#ls -lta / mnt drwxr-xr-x 12 root root 0 Dec 8 08:54 ..1 z" ^- O+ @; B8 s drwxr-xr-x 17 19270 19270 4096 12月8日08:41。) O M; W9 D8 z- _0 o9 c* z -rw ------- 1 19270 19270 12594 12月8日08:41 .viminfo drwxr-xr-x 18 19270 19270 12288 Dec 8 08:35 .ccache -rw ------- 1 19270 19270 16500 12月4日09:21 .bash_history9 a) B3 [! j, ~, m! y5 a ...1 t" H. U+ r2 F& ~8 q& E 〜# 4 U ]5 N7 r9 e2 f4 x+ l 这是我们启动HTTP守护程序的方式:% K& I- Y3 `8 u- h, C7 z& \ $ S7 i, ]0 z; X5 l4 K7 s ' J1 `: r' B: R5 n0 y+ i: q% m6 w 〜#httpd -h / httpd / html /% T9 _5 f* K- }2 K7 }! d 〜#9 j' `2 D5 _, K4 }. s2 p( ~( Z 现在,我们已经在STM32F4上运行了Web服务器,我们可以在开发主机上打开Web浏览器,并观看目标提供的演示网页(图3)。 / z: U; K+ a9 V: O) i 3 A- _+ _" Q' S1 S( X: u4 Q, k q : z6 A# W" a: w* @' F 3. STM32F4在演示Web页面上显示当前时间和日期以及当前正在运行的进程的列表。5 t n# v; K* L; e* `, m . o3 I; G' n3 Z* L. g5 q g Linux在STM32F4上的最小占用空间是多少? 8 _; U, z% ]7 _ {6 q 这可能是有关Cortex-M3 / M4上Linux的最常见问题之一。让我们专门针对STM32F4进行讨论。1 W( x- _' G8 V% \/ y) F. ~0 q8 j0 ~ " N- c3 X8 r' Y' N7 s% U5 _$ w+ E5 [4 [2 n - G7 v! t9 f+ T; z 首先,外部RAM对于Linux是必须的。即使最小的Linux配置也至少需要数MB的RAM才能运行。所有Cortex-M3 / M4器件(至少作者意识到)至少将其内部SRAM限制为数百千字节-STM32F42X / 43X也不例外。无法从如此大量的RAM运行Linux。含义是,截至撰写本文时,Linux不能从单芯片Cortex-M3 / M4设备运行。) Y- P! R6 k. g( |$ F3 @. n8 ^ 但是,如前所述,可以采用两芯片设计(Cortex-M +外部RAM)。需要考虑两个单独的“足迹”指标: : T5 a$ m1 H* t • 可引导Linux映像的大小:如前所述,可引导映像由两个主要部分组成-Linux内核本身和根文件系统的cpio表示形式。对于真正最小的配置,可引导映像的大小可能从512 KB开始,并且取决于根文件系统中的内容以及(在较小程度上)内核中启用了哪些配置选项的范围。4 L* A, }" Y* }( G& ` q; { ! z; [3 J K. N 带有以太网,TCP / IP以及配置的一组合理的用户空间工具和应用程序的实际可引导映像的大小为1.5到2 MB。如上所示,该尺寸的图像可以放入STM32F42X / 43X器件的集成闪存中。 • 运行时Linux操作所需的外部RAM大小:当我们的客户询问需要多少RAM时,我们回答“越多越好,但不少于8 MB”。从NFS或某些外部设备挂载的rootfs,甚至不超过2 MB。坦白说,这不仅仅是玩具,还不如一种玩具可以构筑实用的设计。- b- m5 `; V9 d; v+ F5 \2 A" p8 e $ m f6 O( F5 F9 R $ {2 \9 [9 o: B1 a; }% O0 W" l* e0 d 根据经验,如果您打算在严肃的产品中使用Linux,则至少要考虑32 MB RAM。如果很明显在进行部署时可以容纳更少的RAM,则有可能缩小为兼容的16 MB甚至8 MB RAM设备。不过,安全的建议是从更多的RAM而不是更少的RAM开始。嵌入式应用程序的需求以惊人的速度增长,几乎可以肯定的是,您将在一年的时间内想要向产品中添加新的软件功能。 O1 a3 W- G( n) L 底线是,如果您正在考虑将Linux用于您的MCU应用程序,则希望避免MCU开发人员经常遇到的“如果我只有另外512 KB RAM”这种情况。如果您需要Linux和“功能”,请计划合理数量的RAM。 2 }) O# \" U. x# y. v9 X 在实际方面,考虑到与STM32F42X / 43X MCU兼容的SDRAM存储器的特定上下文,通常可以容忍8 MB,16 MB和32 MB SDRAM设备之间的BOM差异。同样,我们的建议是安全玩游戏,并计划增加内存而不是减少内存。- m ^8 j% f0 R6 ^) h5 {$ _ 考虑到这一背景,让我们看一下运行上一节中显示的示例Linux会话后还剩下多少RAM。首先,这是我们目前正在运行的进程的列表:% U9 |0 D2 _4 f$ G3 [+ ]$ Y * _. B. e* n3 [! d$ U C8 L& o 〜#ps" T# m. ]* C7 x' i PID用户VSZ STAT命令 1根352 S初始化 2 root 0 SW [kthreadd] 3根0 SW [ksoftirqd / 0]- ?$ V T) ]: ~( p1 Z 4 root 0 SW [事件/ 0] 5 root 0 SW [khelper]( }# X: m' }0 W# Y; q+ G2 v- g+ g8 q 6根0 SW [async / mgr] 7个根0 SW [sync_supers]1 q" u! T$ X8 h 8 root 0 SW [bdi-default] 9 root 0 SW [kblocked / 0] 10 root 0 SW [rpciod / 0]* V. x. L6 I6 g% X. g+ P 11根0 SW [kswapd0]$ ?3 H- J( s0 ~" I; y7 F 12根0 SW [mtdblocked] J8 V# E& ~, w) l 13 root 0 SW [nfsiod]! `8 f9 r4 i9 L; _; j. c+ E 19根375 S / bin / hush -i2 l i- C; u' w1 l3 J 22根340 S telnetd& L. h7 d: Y! Q G 56根348 S ntpd -p 0.fedora.pool.ntp.org7 J! ^5 w+ |% u! k. L) F 65根336 SÐ¥ttpd -h / httpd / html /: g5 n: O2 @+ M/ X6 o 506根348 R ps$ Y( n+ O) Z8 k9 T. f 〜# : u9 i* K% j: I0 B: n 这是可用RAM的情况:) `0 p! k; _: Y/ ?) G0 F" @$ t! x* y $ S/ V& i$ \, _: T ( [' s6 Y. h1 A* u6 J 〜#猫/ proc / meminfo 内存总量:32304 kB% K3 u! }9 j. |; ~( G& t: S0 K 无内存:27120 kB# i7 D" I' g- |' Y H 缓冲器:0 kB) h6 e" i1 ^$ J3 }" {2 l 缓存的:620 kB 交换快取:0 kB* j" i! j1 Q# I/ H1 o: o 活动的:440 kB" J, l7 H5 N5 u. b5 B 无效:180 kB% A2 o' A& R! D0 w v; J l 活动的(匿名):0 kB3 u9 M* ]/ X9 s9 R0 g+ D: {$ x6 r 无效(匿名):0 kB 活动的(文件):440 kB: _ Q+ V; D5 a, V 无效(文件):180 kB' E9 A. H& c: j, w& r. e 无法清除:0 kB 锁定:0 kB Mmap复制:3196 kB 交换总数:0 kB 免交换:0 kB& T! G) s* [) a& S 脏:0 kB/ _ l2 }; x( p8 T2 s |9 m s/ G* _ 回写:0 kB+ m0 J' X/ B$ J t( `- E AnonPages:0 kB' V4 i3 j0 m& Q. T" M# V 映射:0 kB" |0 z, u% D% R$ S; ?5 [ Shmem:0 kB 平板:1196 kB+ f6 a/ @1 l! c( N8 ]8 t 可再生的:148 kB 回收:1048 kB9 {2 \) Y3 E, V3 C9 E 内核堆栈:144 kB9 b3 q/ E3 c5 X9 x, z8 x 页表:0 kB- y0 L7 T. I: l. Q, a NFS_不稳定:0 kB 弹跳:0 kB$ T8 B$ m# t$ }7 b; m0 { WritebackTmp:0 kB 提交限制:16152 kB Committed_AS:0 kB VmallocTotal:0 KB# K/ O4 O/ U6 K1 F. D; D7 ^: E Vmalloc使用:0 kB% O) _$ k U/ a+ e! A" ]/ e5 _5 e* ? VmallocChunk:0 KB4 |% a% n/ { K& ]: ` 〜#2 t% `% Y4 [+ i+ H9 l0 I7 t$ \ 可以看出,我们还有很多RAM。但是,随着您添加新功能并并行运行进程,内存将迅速消耗。再次强调这一点,我们建议您设计更多的RAM,而不是更少的RAM。 |
STM32固件库分享,超全系列整理
【中文文档】AN3965_STM32F40x和STM32F41x基于串口的IAP
STM32F4-DISC 实现USB主机(U盘)和USB设备(虚拟串口)自动切换
STM32F4中文用户手册
基于STM32F407的FreeRTOS阶段性的总结(13)
STM32F400、STM32F402 Cortex-M4超值单片机
基于STM32F407的FreeRTOS获取各任务运行时间及占用情况(4)
基于STM32F407的FreeRTOS任务的挂起与恢复(3)
基于STM32F407的FreeRTOS任务的创建与删除经验分享(2)
基于STM32F407的FreeRTOS环境搭建经验分享(1)