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

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

[复制链接]
wujique 发布时间:2018-5-15 10:51
本帖最后由 huangxuejia-29212 于 2018-5-15 11:02 编辑
7 S& _% H9 v( m
2 s$ m! A- G' Q, a* w
够用的硬件5 }$ M" e0 j9 t  y( A
能用的代码
" v' k9 E7 `9 s# d) C, Z: E' v. H实用的教程; S: N( [* f! X+ L9 R
屋脊雀工作室编撰 -20180418# H$ d: A6 }, l$ t5 d2 r
官网:www.wujique.com$ ?/ f2 l. q9 ~$ r* U$ O
github:http://github.com/wujique/stm32f407/ W/ J; M4 X0 P- W8 o
资料下载:https://pan.baidu.com/s/1pQrKr2_Jufd-cEYV4ZYAFw1 M* _& p- z0 y. m1 ?" q$ _
本文章资料在stm32f407\4 教程--其他系统模块\移植uboot命令行目录

今天开始移植uboot中的命令行功能到STM32上,使用的是MDK(KEIL)编译器。: ?6 n& W$ |, j! ^; Z
其实以前移植过一次,平台是K21+IAR。由于代码中有部分与编译器有关,折腾了半天才实现。特地记录。
UBOOT CMD
UBOOT CMD的代码中,有一个比较特殊的定义。2 P) A& \; z1 P! r; m4 C, P) b
命令的定义通过一个宏声明一个结构体,这个结构体如下
  1. #define REGISTER_CMD(name,maxargs,rep,cmd,usage,help) \      __root  const cmd_tbl_t strcmd_##name @ ".cmd" =  {#name, maxargs, rep, cmd, usage,help}
复制代码

0 ~1 E, M/ K4 a7 t4 p
我们先分析这个宏的功能
2 f" {1 v% g; k+ Q# `( J3 t# e2 u- __root:
! w  T3 t" C. O1 R5 I被修饰的变量或者函数在用户程序里面没有显式调用情况下,也不会被优化掉。
# \4 m7 a6 `/ N- @1 x  L7 W# |- const:
1 e' A+ y: K7 `  D: f1 M+ ]$ U& S* s这个大家应该常用,就是将变量定义为常量,保存在FLASH,不占用RAM。
3 K% `$ p! t% a7 b- cmd_tbl_t:: ]- N8 A" D3 ?! n
结构体定义
. X. `7 k5 b2 J: M- strcmd_##name:
! Q  K4 q. _6 I. S7 M+ e宏名字,例如宏第一个参数是test,编译后得结构体名字就是strcmd__test
4 T0 K' P# s. {# D1 W" e' m8 r- @ ".cmd":: {- c- j* j% R8 h
定义的结构体保存在.cmd段,这个段是在IAR工程的.icf文件中定义。
剩下的就是赋值给结构体了。
这样定义的结果就是:
定义了一个放在.cmd段的结构体,就算这个结构体没有显式调用,也不会被程序优化。
MDK(KEIL)定义
那么在MDK下要怎么定义呢?
3 J& D2 I8 L$ n" i9 o, Y% L/ k- 首先是如下,通过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}
复制代码
: j& P/ I% \/ @( J" O8 w
  • 第二,就是要使用自定义的分散加载文件3 L* ]6 z6 A4 }6 m0 b

    / ]% e# c0 _. r) l" [把左上角的use memory layout from target Dialog前面的勾去掉。( {2 d) _  q& O
    然后点击右边中间的Edit按钮,关掉窗口,就可以编辑.sct文件了。8 E" h& k( @( K9 H' W

# }1 a% ]( M- T6 p+ Y
  1. LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
    - T/ z9 J: m* h0 F
  2.   ER_IROM1 0x08000000 0x000ff000  {  ; load address = execution address
    : t& H' E1 q; B
  3.    *.o (RESET, +First)  w+ l6 W0 p( a/ f/ [* ]/ s% i
  4.    *(InRoot$Sections)
    6 v9 ?% k+ E4 b, ]) M7 u9 {
  5.    .ANY (+RO)+ O0 p! o: l! X9 u/ W/ b/ |5 }
  6.   }
    0 ]# K! c0 ~' j' {: l5 C

  7. ! p! L$ k$ p% z6 P! R- a
  8.   cmdreg +0" H2 w4 Z* f; _/ S* y
  9.   {
    # [6 D2 ^" l( z- L$ d# z
  10.         .ANY(cmd)
    & n- x: h4 P' I$ Z
  11.   }# n5 D1 |" |! b: X2 _" t" h
  12.   RW_IRAM1 0x20000000 0x00020000  {  ; RW data
    / n# L* {) }, V' o% Y+ t! j
  13.    .ANY (+RW +ZI)
    . f% j" B3 h9 ]& p
  14.   }( z# \3 n8 \" \3 Y, p  x
  15. }
复制代码
$ q+ ^* C9 n5 f; e. s
: v7 W& v. N. D$ _( l# v4 m& _
中间一段就是增加的
, p9 Z. j: L$ g1 Kcmdreg区域名字。( q. @/ r3 x+ V8 d1 N- _3 t. ^, m( ~
+0的意思是紧跟着其他代码段。
# g# A, A- h; m! H* m" h.ANY(cmd) 这个比较关键,跟代码中的(section ("cmd"))对应。
也可以指定这个段的起始地址跟长度. b, A8 G8 e; Y0 z4 n5 E; G
cmdreg 0x080ff000 0x1000
4 Y9 q9 l4 o( ^- D  z0 g6 a: r{4 Z* j/ b7 U* }" x
.ANY(cmd)9 K( K: C- P3 K
}
  • 第三,就是要防止这些变量被优化
    & D: t: C) |0 s; }8 ^, _# a% F在option中设置0 n8 n/ o% a0 _; ]" |

    ; P1 D# W, @; O0 {4 H( J看下面,Misc controls中,添加一个宏“--keep=strcmd_*”,意思是所有strcmd_开头的变量跟函数,都不会被优化。7 D  j* c1 J3 M( W
确认结果
编译后,查看.map文件(通常在工程下的Listings文件夹下)
  1. Execution Region cmdreg (Exec base: 0x08048efc, Load base: 0x08048efc, Size: 0x000000a8, Max: 0xffffffff, ABSOLUTE)
    . v' D& Y9 P; S4 J+ v4 a6 y5 B8 l

  2. # h! r: X8 n6 ]% [  p+ H3 r$ F
  3. Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object
    - C9 A% H9 O$ K. W' S2 s; q, ]

  4. 0 c4 H0 P' q+ |$ r+ A+ K
  5. 0x08048efc   0x08048efc   0x0000001c   Data   RO        16605    cmd                 cmd_sys.o0 Z  o. r! s  d* e5 J2 z
  6. 0x08048f18   0x08048f18   0x0000001c   Data   RO        16606    cmd                 cmd_sys.o- i" U1 u9 W& h# q8 `0 v& S
  7. 0x08048f34   0x08048f34   0x0000001c   Data   RO        16607    cmd                 cmd_sys.o
    ' b8 c& H- W, s8 f
  8. 0x08048f50   0x08048f50   0x0000001c   Data   RO        16608    cmd                 cmd_sys.o% C/ Y& ?: c0 B) {% r
  9. 0x08048f6c   0x08048f6c   0x0000001c   Data   RO        16685    cmd                 commnad.o
    - l, h8 t1 \8 |/ i0 Y2 O# l
  10. 0x08048f88   0x08048f88   0x0000001c   Data   RO        16686    cmd                 commnad.o
复制代码
# t7 Q; C7 B! W
从中也可以看到我们前面定义的意思+ G: @6 A8 F5 Q! [+ t
cmdreg是Execution Region名字2 B0 K8 m  w% M& M" Q
Base: 0x080ff000, Size: 0x000000a8, Max: 0x00001000+ N  F4 _/ O0 _5 P, u: s
我们现在只用了0x000000a8字节/ f1 G7 ^2 W/ ~  F0 y8 f
cmd 是E Section Name
代码中使用段地址跟长度
好的,前面我们已经定义了一个命令段,那代码中怎么用这个段呢?
% a2 A# ?/ N: |, i像下面这样使用即可。
  1. extern unsigned char Load$cmdreg$Base[];) r( @( e7 _  }8 n4 u) y
  2. extern unsigned char Load$cmdreg$Length[];
    ) J0 a: u6 J0 t3 y5 K

  3. / A. Q# z2 Z2 k# n4 i
  4. unsigned long add = (unsigned long)Load$cmdreg$Base;
    / i3 J; `( m2 I  Y& p  m) p9 W. u
  5. unsigned long len = (unsigned long)Load$cmdreg$Length;% b+ c4 L' j" R3 A5 P

  6. . U4 H5 P( C; a, W9 r8 p2 h; ?
  7.         uart_printf("cmd addr:%08x, limit:%08x\r\n", add, len);
复制代码
9 ~$ i8 P4 c4 Q! p1 |) d. b
在网上查找如何引用段地址时,找到了这个网页:6 b5 g+ A6 Q* S3 z8 ~4 j
http://www.cnblogs.com/Dreamxi/p/3507932.html# J* K1 M' x* z: F6 j) Q
大家可以参考这个网页的做法。
问题
--keep是在MDK设置中定义,能不能直接在代码中定义?" I& n) I0 \" X5 X, e, F
--keep=cmd_*会有匹问题,如果以后其他模块定义类似的变量或者函数,就同样不会被优化了。
2 E. e1 v( r& E# Y* @能不能在代码中直接指定不优化的内容?不使用通配符。: }% y2 U2 y0 C- D/ s6 O# g0 P
不管了,暂时能用先。
通过shell交互
安装Xshell 5软件,配置一个串口链接。8 P: c$ i( Y% E# G, S. j
# W7 P! h4 Y% c  C* ]& }; G6 A
系统启动后,敲下回车,出现命令行,输入help,查看有多少命令。
0 o% h* H2 N/ `: P! M( }5 `输入命令systeminfo,查看系统信息。
增加命令
可以随意添加命令,按照下面的个是注册命令就可以了,
REGISTER_CMD(    systeminfo,2,1,do_system_info,    "systeminfo",    "\t display system info ");说明
  • 1- ~$ \  t  P! e0 j
    本次测试命令行基于freertos。
    0 l7 B% U$ q# H$ H+ j# y; o  A- K因为命令行程序内部是while(1)死循环,如果没有操作系统任务调度,很难实现。
    $ N, G3 \0 }0 ]除非只有命令行功能,并且其他功能全部通过命令行调用或者是中断。
  • 24 |' r7 ]; |( U& `+ w- C6 o) m: n% D9 p
    代码托管在github:http://github.com/wujique/stm32f407/tree/sw_arch" D9 A& n' _$ s5 Q
总结
本文档指说明了移植过在MDK的细节,对于UBOOT命令行的具体实现,有兴趣自行研究。

& y# i8 G6 ]2 F8 a

移植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优化性能$ e# N5 y8 k$ j. ^
http://github.com/wujique/stm32f407
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版