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

将UBOOT的命令行功能移植到STM32F407

[复制链接]
wujique 发布时间:2018-5-15 10:51
本帖最后由 huangxuejia-29212 于 2018-5-15 11:02 编辑
+ R9 s: l) t7 P* x2 V) |; o. v
5 o, R9 R2 w+ q5 M  R7 E& u
够用的硬件( {4 e0 G9 w8 w
能用的代码) ]; H0 v0 \: i" z
实用的教程
4 y4 o* ?0 `' P9 y0 B6 S屋脊雀工作室编撰 -20180418
) S6 P3 a  h6 L$ t! y官网:www.wujique.com- ~" l8 o# m* K7 R  A
github:http://github.com/wujique/stm32f407$ D! E3 H& O2 E5 B: b
资料下载:https://pan.baidu.com/s/1pQrKr2_Jufd-cEYV4ZYAFw2 c$ k/ Q' t. l3 h
本文章资料在stm32f407\4 教程--其他系统模块\移植uboot命令行目录

今天开始移植uboot中的命令行功能到STM32上,使用的是MDK(KEIL)编译器。# ~% C2 @) ?5 y# d
其实以前移植过一次,平台是K21+IAR。由于代码中有部分与编译器有关,折腾了半天才实现。特地记录。
UBOOT CMD
UBOOT CMD的代码中,有一个比较特殊的定义。0 N" p$ w  ^+ c% P: [
命令的定义通过一个宏声明一个结构体,这个结构体如下
  1. #define REGISTER_CMD(name,maxargs,rep,cmd,usage,help) \      __root  const cmd_tbl_t strcmd_##name @ ".cmd" =  {#name, maxargs, rep, cmd, usage,help}
复制代码
* J: u6 B+ b$ u
我们先分析这个宏的功能
6 T0 d4 F/ c$ P: K3 Q# x- __root:
* _- K5 e9 S: ^被修饰的变量或者函数在用户程序里面没有显式调用情况下,也不会被优化掉。9 f  p0 y1 Z3 M
- const:
8 O: E& V) b$ z* @( q0 y, V4 C这个大家应该常用,就是将变量定义为常量,保存在FLASH,不占用RAM。
" M  `- B/ g4 f! |- cmd_tbl_t:- l  A' Z. r- [& }1 G; R1 E  t
结构体定义
/ x$ Y* U1 C1 U- strcmd_##name:
+ _6 Z* K" {# ^0 q  v4 ~" `9 `1 @宏名字,例如宏第一个参数是test,编译后得结构体名字就是strcmd__test5 [$ i" F- I/ M# m8 x
- @ ".cmd":
$ C+ j; h- y$ n5 u+ O定义的结构体保存在.cmd段,这个段是在IAR工程的.icf文件中定义。
剩下的就是赋值给结构体了。
这样定义的结果就是:
定义了一个放在.cmd段的结构体,就算这个结构体没有显式调用,也不会被程序优化。
MDK(KEIL)定义
那么在MDK下要怎么定义呢?
6 p  o! t. D6 R6 A2 a$ h- 首先是如下,通过attribute 关键字将结构体放到cmd段中。
  1. #define REGISTER_CMD(name,maxargs,rep,cmd,usage,help) \            const cmd_tbl_t strcmd_##name __attribute__ ((section ("cmd"))) =  {#name, maxargs, rep, cmd, usage,help}
复制代码

* p( y+ q9 P5 m% G8 a2 [1 b
  • 第二,就是要使用自定义的分散加载文件. J; G, _4 A0 t1 u: e+ A

    ! G. {: L/ K+ n( F把左上角的use memory layout from target Dialog前面的勾去掉。" k& l' e! Q: `2 D% U4 \  _
    然后点击右边中间的Edit按钮,关掉窗口,就可以编辑.sct文件了。0 t( `- d% W$ }0 R; L

# F9 K! ]: f) b0 d: \
  1. LR_IROM1 0x08000000 0x00100000  {    ; load region size_region' S1 i, e' T8 h4 z( w% _$ `9 K
  2.   ER_IROM1 0x08000000 0x000ff000  {  ; load address = execution address; ^$ {3 x$ v) H% E
  3.    *.o (RESET, +First)
    ; i0 [& M  d  Z+ h+ `# _+ d
  4.    *(InRoot$Sections)* p" K- i, }( V6 Q7 x- M5 y
  5.    .ANY (+RO)
    / b) X9 \8 z! e1 A
  6.   }
    - M8 X! O/ ~* e) l: P, q5 X

  7. / M0 s+ X* R4 p/ f
  8.   cmdreg +0
    7 q! Q; p; C3 n2 D. M# k
  9.   {
    " a6 d" b  E  w! G
  10.         .ANY(cmd)( m6 M2 `' R: m- |: G
  11.   }
    % g/ M: \0 |6 B) z  ^/ S8 b) R# G/ w
  12.   RW_IRAM1 0x20000000 0x00020000  {  ; RW data/ h, ?: ^' l$ {# n' Y( x
  13.    .ANY (+RW +ZI)
    - ]( l; [3 Z2 x8 j5 |: g
  14.   }
    / Y( v% I" ^& t: T$ Y+ N
  15. }
复制代码

" R: C5 i+ a) D0 p: x/ C# B! H
- O9 e0 {9 Y6 _& [. t4 Z( R
中间一段就是增加的
. ^: u/ }& d8 x6 N5 W. @3 A8 X4 g0 ~cmdreg区域名字。2 R( X& A7 t: [# I/ }
+0的意思是紧跟着其他代码段。% f" o7 @% |# _+ d9 o( B: e
.ANY(cmd) 这个比较关键,跟代码中的(section ("cmd"))对应。
也可以指定这个段的起始地址跟长度7 r2 m4 B$ R3 K+ ?8 [& ^
cmdreg 0x080ff000 0x10006 t: E5 v( o9 u2 m) x8 {
{
0 c" B; B* c; V  M.ANY(cmd)
) _4 G  h% o% m, Z}
  • 第三,就是要防止这些变量被优化
    4 G* L) P1 f5 U在option中设置
    8 H9 S1 i1 r' ?# ^# z- o! n) x4 [& Q2 C' \3 d4 u+ \
    看下面,Misc controls中,添加一个宏“--keep=strcmd_*”,意思是所有strcmd_开头的变量跟函数,都不会被优化。
    ( ^4 M3 C; Y2 n& F3 X7 M% ~  q
确认结果
编译后,查看.map文件(通常在工程下的Listings文件夹下)
  1. Execution Region cmdreg (Exec base: 0x08048efc, Load base: 0x08048efc, Size: 0x000000a8, Max: 0xffffffff, ABSOLUTE)1 i& {+ K3 N3 o- F$ F$ x! N

  2. 8 K# R, j; [* y- ~
  3. Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object4 C& W1 E6 H, w8 k+ G

  4. - V& v( n6 w6 R/ l7 D% }
  5. 0x08048efc   0x08048efc   0x0000001c   Data   RO        16605    cmd                 cmd_sys.o/ Y0 W' }( ?9 h: ~+ K/ W
  6. 0x08048f18   0x08048f18   0x0000001c   Data   RO        16606    cmd                 cmd_sys.o7 r4 |+ ~) \+ i: H* j: h1 I: Y' Z0 k
  7. 0x08048f34   0x08048f34   0x0000001c   Data   RO        16607    cmd                 cmd_sys.o
    % E4 L% N2 P/ g( |4 [0 Y# J
  8. 0x08048f50   0x08048f50   0x0000001c   Data   RO        16608    cmd                 cmd_sys.o0 y# [) x5 Q% e7 E; T
  9. 0x08048f6c   0x08048f6c   0x0000001c   Data   RO        16685    cmd                 commnad.o: b0 G9 |7 Q! o& c# `
  10. 0x08048f88   0x08048f88   0x0000001c   Data   RO        16686    cmd                 commnad.o
复制代码
) Z/ n6 }6 u4 j5 u
从中也可以看到我们前面定义的意思# R% Y9 z" _# {' G* {) d
cmdreg是Execution Region名字
4 S" x$ L) Z! aBase: 0x080ff000, Size: 0x000000a8, Max: 0x000010002 ]% S; N+ s1 e0 w! o* b
我们现在只用了0x000000a8字节
" Q$ U' {& f" L; x" H" F/ M) Fcmd 是E Section Name
代码中使用段地址跟长度
好的,前面我们已经定义了一个命令段,那代码中怎么用这个段呢?/ C2 E& w% }6 D6 @7 g
像下面这样使用即可。
  1. extern unsigned char Load$cmdreg$Base[];! H0 S; R, z9 d% m
  2. extern unsigned char Load$cmdreg$Length[];
    : D3 t# X- r! ]! d. D

  3. , q6 v+ q! o2 e- z' ^1 O/ ~
  4. unsigned long add = (unsigned long)Load$cmdreg$Base;
    , h# ~4 u" D0 v
  5. unsigned long len = (unsigned long)Load$cmdreg$Length;8 C5 K6 G0 {" J+ L% g# {" a
  6.   M% G7 v  A0 \) U3 y" h+ X
  7.         uart_printf("cmd addr:%08x, limit:%08x\r\n", add, len);
复制代码
; _2 x  t2 M9 v1 _( _- S
在网上查找如何引用段地址时,找到了这个网页:5 l6 @. t$ }# ?
http://www.cnblogs.com/Dreamxi/p/3507932.html
1 b( s% ^5 v) F0 |7 C: @大家可以参考这个网页的做法。
问题
--keep是在MDK设置中定义,能不能直接在代码中定义?9 Z; k9 T6 I% g; J% ^6 G5 t/ r& l
--keep=cmd_*会有匹问题,如果以后其他模块定义类似的变量或者函数,就同样不会被优化了。
( Q$ b! f0 d# D+ H能不能在代码中直接指定不优化的内容?不使用通配符。- ?0 |4 b- I2 ^9 d2 \2 X6 q! F
不管了,暂时能用先。
通过shell交互
安装Xshell 5软件,配置一个串口链接。& D$ Z. G. _; ?! [; ]( |! ]% K3 t" F

8 F) i  Y+ s. v8 l$ I系统启动后,敲下回车,出现命令行,输入help,查看有多少命令。3 Z8 P' E4 r+ |' h7 ]& D. S: ~3 G
输入命令systeminfo,查看系统信息。
增加命令
可以随意添加命令,按照下面的个是注册命令就可以了,
REGISTER_CMD(    systeminfo,2,1,do_system_info,    "systeminfo",    "\t display system info ");说明
  • 1
    7 l& u6 T" ~( m, E& `本次测试命令行基于freertos。4 {. u' t2 f3 I' J1 L4 m8 a
    因为命令行程序内部是while(1)死循环,如果没有操作系统任务调度,很难实现。2 }+ q$ k% |- L$ |* j
    除非只有命令行功能,并且其他功能全部通过命令行调用或者是中断。
  • 2
    ( j5 X2 ^9 }1 h; Q/ S1 w& d+ o代码托管在github:http://github.com/wujique/stm32f407/tree/sw_arch
    & T% L% n8 e) Z
总结
本文档指说明了移植过在MDK的细节,对于UBOOT命令行的具体实现,有兴趣自行研究。
0 S! t8 W4 u4 J: v, v/ u9 w

移植uboot命令行.rar

下载

470.56 KB, 下载次数: 137

收藏 3 评论3 发布时间:2018-5-15 10:51

举报

3个回答
黑皮男 回答时间:2018-5-15 14:18:30
大神
zero99 回答时间:2018-5-17 16:59:05
学习了
wujique 回答时间:2018-5-29 09:23:50
最新的代码请到github上获取,仓库会持续更新修正BUG优化性能& Q- U7 S. S1 v# O
http://github.com/wujique/stm32f407
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版