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

【经验分享】三段式程序架构设计(更新实现方法和STM32F4例子)

[复制链接]
STMCU小助手 发布时间:2022-1-9 20:00
如果你认真看了前面的文档,会发现一个我们的教程跟其他教程的不同点:其他教程都是在教你如何用这个设备,我们说的是,如何给这个设备写驱动。其中,我们一直在强调的一点是,要提供良好的接口给应用使用。
" _/ b4 U5 H6 o& |: l为什么呢?因为,一个复杂项目,底层通常是跟应用分开的。1 M+ `8 L7 Y+ T) a, s; T4 w7 ~( k. T
为了应付复杂的程序,通常需要一个大概的程序架构设计。下面,我们一起学习一种常见的程序架构设计。

5 Y% @8 j8 X) u: D+ }为什么
6 W1 |% q5 ~: x& _( ?3 j
为什么需要架构设计呢?
" F; c* _# V1 b" Z; X: y9 ~1 m
固件更新
6 s- V- J8 y% a0 u' @
到目前为止,下载程序,我们有两种方法:
  • 通过串口下载,在下载过程中,需要控制boot管脚。
  • 通过JTAG(SW)调试口下载。* D8 b6 t% P6 z: g0 B8 o1 ^
在真实产品开发中,调试口只存在于PCB上,预留测试点。没见过有产品外露调试口的。
1 Y8 @  ?. V9 H0 V9 e2 s有外露串口的,也有用牙签顶住一个小洞就能更新固件的,少,很少。( K3 q$ y( V8 k$ Y1 M/ d
产品需要支持其他方式更新固件,例如U盘、USB、无线OTA更新方式。

2 l) V- S5 E, y/ A
怎么做?
当前芯片基本上都支持IAP功能。
6 d$ W1 Q1 H; B6 N. ]* E/ h简单的说,就是,在运行程序时,可以通过程序擦写FLASH,写新的程序到FLASH上。
8 }' C) Y0 C, p9 c( h1 f那么我们可以通过IAP在应用更新固件。
9 Q" R4 h! l  d: Q6 R1 b
应用和驱动分离
2 u" E* l+ o) t8 A' X+ D( G
功能复杂,程序就大,人就多。* e& q0 A' {: T0 D2 d; p4 y' B- g
遇到问题就扯皮。
$ k1 E3 b! i+ I- _: m- ^( t有的公司,会将底层打包为库,丢给应用使用,应用将自己的程序跟底层库一起打包编译。# F; t$ j8 M7 v
这样的方式,并不能解决问题。& u+ R+ j- W7 l! y4 ^# R! s  R
除了扯皮,也有实际问题。
  • 多应用$ s* n9 C; V  G& P9 Q
    有很多行业,一个设备,会卖给不同的客户,不同的客户就有不同的需求,就需要不同的程序。1 `" m9 p6 a$ w; ]: ~# E
    如果底层已一个BUG,需要修改,那么就需要发布N个程序。
  • 升级压力, j4 F& A2 L" g5 o6 [/ B' @
    如果程序比较大,例如驱动有200K,应用有200K,一起400K,那么,OTA就要传输400K。+ R9 D, a) @6 N5 J% p
    如果两者分开,只有一个修改的时候,只需要OTA 200K。
  • 促进发展5 O; H; F% t" l9 N7 A( ~  R* Z. M5 P, y
    如果将底层和APP分离,务必就有一套标准的接口。& b6 R4 T" e+ T
如何做?
' P6 g/ Q8 q2 K7 a; X* J4 u牵涉以下问题:
  • 空间分配: k, z+ F) }( ?5 d0 L  f0 z
    驱动跟应用分离,意思是,驱动一个工程,单独编译。应用是另外一个工程,单独编译。% q: o4 ~" h" G( V- E7 Y1 N, B
    那么FLASH和RAM空间就需要分开,通过分散加载文件实现。
    / j# ^, T( o" s4 N, f; ^RAM,分开的是全局变量空间。临时变量用的是栈,不需要分开。
  • 时间片
    % W. ^% L* v6 L# z6 c; V+ F如果驱动没有时间片需求,那么驱动,就类似一堆库函数。应用只要调用就行了。
    7 x# x, t, |* q3 }& r7 ]! {2 @如果驱动有要轮询的任务呢?, g4 P) k$ j# Y3 f% L3 h. n4 V
  • 可以放在一个低优先级的定时器中轮询。-----不建议
  • 去不放在一个函数中,让应用带着跑--------如果应用是小循环模式,带着跑很不方便。
  • 上RTOS,驱动掌控RTOS,应用做为一个RTOS的一个任务----------强烈建议用这个方法。( D# H; O) y$ e' \- ?
  • 接口
    * {1 D% a$ P* s8 j3 S4 G应用如何调用底层接口呢?
    4 h9 Z. x% G& Y2 O9 xCPU执行一个函数,就是将PC指针指向函数。: w0 H$ N2 [# i" A
    写程序时,我们经常会用函数指针。, \3 ^2 o# j  u
    APP和驱动的沟通,就是通过函数指针来实现。
  • 分离的缺陷# q1 F) w. M4 C) m, K
    驱动和应用都会链接标准库,代码会大一点。7 _( A1 a3 v' x9 }7 J- W( O
常见架构
* V6 N$ `* \6 Q6 i# H
我们常见的架构方式是:3段式框架。
% K2 {2 J, |. i) E如下图:

$ T# p$ \* Y" f; U9 ^9 o1 Zfile:///H:/wujique/%E8%B0%83%E8%AF%95%E4%B8%8E%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95/4.0%20%E7%A8%8B%E5%BA%8F%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1/pic/%E6%A1%86%E6%9E%B6.png
戏称三权分立
  • BOOT
    3 L" n, z! g9 N2 e% y" h最先启动的代码,负责固件更新,并包含最基础的固件下载功能。
    " V' S9 |' d/ e/ E4 N. x) c启动后,跳到CORE运行位置,丢失控制权。
  • CORE! }  `, o9 i) T, ^( o& k" }
    通常包含驱动,测试程序。可能会支持更多的固件下载方式。
    / w0 m& ]* d& y- H/ C) p部分软件模块也放在CORE。例如文件系统等软件模块。: Z( n4 Y# B# d- m1 F8 ~
    所有给应用使用的接口,放在固定位置,以便APP调用。: ~" h, V5 n: a9 X8 `
    如果没有使用RTOS,右边就不是获取,而是跳到APP任务,一单跳过去,CPU控制器就归APP了。
  • 应用程序
    ' W2 c  A$ M) u, h' q1 `3 _! p实现应用逻辑,通过调用底层接口控制硬件设备。
    6 y8 {8 `: A  ^; p1 A) b  f

* d  x' D& l& F( e关键流程

8 Z- Q8 Q5 C; ?. ]: [3 {6 }0 R
BOOT启动,校验固件,跳转还是更新。8 d- ~9 R0 U- |% h  Y
CORE运行,环境初始化,驱动APP任务。
' D# m, V8 T3 c) t# m2 S) `APP,其实就是一个函数。

+ @: n, g, o1 K+ l2 D
实现
: j( H5 F/ S4 V9 Z8 A6 @/ i( ~* \1 e
只讨论基于RTOS的情况。
7 W( C. o9 C+ d6 j3 A; g3 I硬件基于STM32F407。
) R$ B  L$ K5 @  o0 c8 E9 W* \只讨论关键技术。

2 n% f/ M! ~" l6 n
分散加载文件划分: P# w4 j/ q9 {- q& s! Y8 ^

- H- }9 o( U0 T) }1 {9 oBOOT跳到CORE
& t- S4 y4 A' ^# s; O: x: V
. N/ ]- b* N$ ?+ ICORE启动APP任务3 i) ]/ H+ \0 B7 F; C0 G3 T
% t. E2 d6 b- j7 o& B
驱动接口的定义, l7 L, e3 @" s# [

7 C& b  d6 x) H5 V$ Z3 sIAP
/ i$ @$ g/ \0 |! D+ @
收藏 评论1 发布时间:2022-1-9 20:00

举报

1个回答
朱贵和 回答时间:2022-1-9 21:50:42

谢谢,学习了。

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版