電子產(chǎn)業(yè)一站式賦能平臺

PCB聯(lián)盟網(wǎng)

搜索
查看: 109|回復(fù): 0
收起左側(cè)

嵌入式架構(gòu)設(shè)計(jì),淺談"驅(qū)動分離式"設(shè)計(jì)思想。

[復(fù)制鏈接]

485

主題

485

帖子

1623

積分

三級會員

Rank: 3Rank: 3

積分
1623
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2024-10-29 17:50:00 | 只看該作者 |只看大圖 回帖獎勵 |倒序?yàn)g覽 |閱讀模式
我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師
1 D3 B, E$ S9 {& s" _- d: [關(guān)注我,一起變得更加優(yōu)秀!今天跟大家找了一種常見的應(yīng)用與驅(qū)動分離設(shè)計(jì)的方式,對于目前一些高性能MCU還是值得使用一下的,不過對于原本主頻不夠高、性能不太強(qiáng)的MCU不建議使用,畢竟這樣的設(shè)計(jì)還是犧牲了一定的性能。在正規(guī)的項(xiàng)目開發(fā)中,項(xiàng)目往往是并行開發(fā)的,也就是說硬件設(shè)計(jì)、底層軟件設(shè)計(jì)、應(yīng)用軟件設(shè)計(jì)等是同步進(jìn)行的。比如說在開發(fā)板上調(diào)試模塊驅(qū)動,在其他平臺上調(diào)試應(yīng)用程序再移植到目前這個平臺等。5 W) i5 C3 e( ^" Z
1
8 d) |$ b' k) l: C為何不見嵌入式軟件架構(gòu)師職位?
$ c1 A% }6 |& S% J在招聘網(wǎng)站搜索架構(gòu)師,會出現(xiàn)各種系統(tǒng)架構(gòu)師:web架構(gòu)師,后臺服務(wù)端架構(gòu)師等等,但是唯獨(dú)很難看到嵌入式軟件架構(gòu)師。嵌入式軟件不需要架構(gòu)嗎,驅(qū)動不需要架構(gòu)嗎?
. M8 l* A3 s8 X2 _: I答案當(dāng)然是需要,不過為什么沒有這方面的職位?
+ ?, p+ m- @" M# P/ l; a一般的人會說,小項(xiàng)目才用單片機(jī),實(shí)現(xiàn)功能簡單,無需太多人參與,所以無需注重軟件設(shè)計(jì)。其實(shí)是很幼稚的觀點(diǎn)(剛畢業(yè)時我也是這樣認(rèn)為的)。: Z/ N. [; B/ i& }# W; t4 L; f
目前國內(nèi)的嵌入式開發(fā)主要分為嵌入式底層開發(fā)和嵌入式應(yīng)用開發(fā),嵌入式的底層開發(fā)一般叫做驅(qū)動開發(fā),或者bsp開發(fā),有時也有稱之為linux內(nèi)核開發(fā),名字聽著都很高大上的感覺。
. p3 w5 O3 M3 _2 z  T9 `; X而嵌入式上的應(yīng)用開發(fā),一般業(yè)務(wù)邏輯比較簡單,被很多人忽略,所以招聘方也會感覺沒必要招架構(gòu)師級別的了。2 A( v* r9 J7 K6 y1 R+ g
8 K+ m9 N' R  r: }& f* w; |# N
2* y: _( ?* n& o8 v" b% r, a+ j! j
嵌入式軟件架構(gòu)的好處
. L, e/ a& A9 ]0 x& j為什么有人覺得沒必要有嵌入式軟件架構(gòu)設(shè)計(jì),那可能你做的項(xiàng)目只是流水燈級別吧。1 W: k5 H4 v' q# m, c0 N
當(dāng)然,不能說完全需要,至少對于大多數(shù)項(xiàng)目而言,都需要有一個軟件架構(gòu)設(shè)計(jì),好處也是有很多,這里羅列一些:
9 D/ m# V) ^$ d7 }1、應(yīng)用的代碼邏輯清晰,且避免重復(fù)的造輪子。* e$ r1 B$ ^8 T3 I0 y7 ^. V. p
2、如果沒有好的架構(gòu),移植將會是一件很痛苦的事情。
4 N2 d9 ]3 T, T6 w+ U6 M# X3、方便后期維護(hù)和升級。
* K* g8 P; i( Q- f4、最大限度的復(fù)用。
8 q  i9 G' y, \% `% n, H& w* U5、高內(nèi)聚低耦合。 - f$ V, l" ~4 T
30 |: h6 E7 P& ^" I8 |% ^( B
嵌入式軟件架構(gòu)之驅(qū)動分離8 L- J/ ^3 x; e
經(jīng)典的linux+arm配置屬于資源比較豐富,高配的嵌入式系統(tǒng),其操作系統(tǒng)本身就很強(qiáng)大,軟件設(shè)計(jì)也變得水到渠成。本文所要提到的嵌入式,其實(shí)更偏向于單片機(jī),結(jié)合一個案例給大家講講分層設(shè)計(jì)。以MCU + IAR為例,講講把底層軟件和應(yīng)用軟件分開。第一種方式:把底層軟件生成一個靜態(tài)庫提供給應(yīng)用。但是這樣就會有一個問題,如果靜態(tài)庫改變了,得重新編譯,然后提供給應(yīng)用,應(yīng)用程序也得重新編譯一下,這顯然是很麻煩的一種處理方式。另外一種方式:底層軟件和應(yīng)用軟件是兩個獨(dú)立的bin文件,姑且叫l(wèi)ibdev.bin和app.bin。非操作系統(tǒng)的嵌入式是沒有動態(tài)庫.so這樣一說的,不過底層軟件這個可執(zhí)行文件姑且就認(rèn)為是app的.so吧。這兩個bin文件通過配置icf,映射到不同的flash空間以及分配不同的RAM空間。顯然,這兩個bin文件的關(guān)系是app.bin會調(diào)用libdev.bin的實(shí)現(xiàn)。但是他們是獨(dú)立的bin文件,如何關(guān)聯(lián)起來呢。這事就需要一個函數(shù)表告訴app.bin到哪里去調(diào)用libdev.bin里面的函數(shù)實(shí)現(xiàn)。要實(shí)現(xiàn)這個函數(shù)表,就需要有統(tǒng)一的函數(shù)接口才方便管理。這個函數(shù)表可用靜態(tài)庫.a實(shí)現(xiàn)(libdev.a)。libdev.a的功能就是要映射所有l(wèi)ibdev的接口函數(shù),使app調(diào)用某一接口函數(shù)時,可以跳轉(zhuǎn)到libdev.bin里面執(zhí)行。具體設(shè)計(jì)思路:1.函數(shù)表用結(jié)構(gòu)體的方式實(shí)現(xiàn),結(jié)構(gòu)體元素為函數(shù)指針。1struct libdev_ops{3 P" j1 ?$ @/ Q- k- ^8 w: P
2    int (*dev_PortOpen)(int PortNum, char *PortParm);
5 [' I/ M, l0 t( o' F6 m! z3};
" i9 u  m6 _8 Y8 l$ |2.在libdev.bin里面,對結(jié)構(gòu)體里面的函數(shù)指針賦值。) {& ?: ~5 ]9 C$ n- B5 f9 x; ^+ i8 f
1void libdev_ops_init(struct libdev_ops *ops){
, {7 b& T( J/ S7 c6 u+ v+ W2    ops->dev_PortOpen = dev_PortOpen;//把函數(shù)地址賦給對應(yīng)的函數(shù)指針
, s0 W8 Y9 w; D( g7 a, P# G3}
+ o5 ]2 @8 ~; _) \5 |3 }, o% J3.程序啟動時,先進(jìn)入libdev.bin,然后再跳轉(zhuǎn)到app.bin。在此需要一個地址跳轉(zhuǎn)函數(shù)(在libdev.a里面)。1struct libdev_ops ops;
1 @9 \0 _8 t4 F+ `2void call_app(int addr)
$ W8 R/ @! g* Y8 J3{
* Z) g+ `( L# S( K4    int (*startup)(struct libdev_ops *ops);
: A: v  r5 l5 B4 ]# O4 q5    startup = (int(*)(struct libdev_ops *))(addr);
) b9 p( W# C4 s: u8 @6    libdev_ops_init(&ops);
' A6 o" N, I4 V* }8 C: x# y7    startup(&ops);
8 K) @! K4 X6 i8}
5 `# W) |% \& Q4.重新封裝所有函數(shù),如下:  O, k2 Z. S( o5 \+ K
1int dev_PortOpen(int PortNum, char *PortPara)
* O* P6 v; _) y1 ^8 n2{6 _  \0 L3 z/ T
3    return ops->dev_PortOpen(PortNum,PortPara);9 ]# w* U9 c' u2 a5 k& M, S
4}  w* q/ E. N4 o6 t8 l) q0 k( P
5.實(shí)現(xiàn)libdev.bin需要跳轉(zhuǎn)地址的函數(shù)(在app.bin)。
+ O0 w7 B1 U7 V1 k8 e1void common_startup(struct libdev_ops *libdev_ops)# I) k0 l1 @. T, G3 X, ?1 s3 Q/ i
2{
3 V4 |! Q; c# r1 y& K8 v3    ......- k- N7 E9 M, s; r4 H( p6 w0 F
4    ops = libdev_ops;% \9 {& D  `1 i0 G) C, b% @4 a! f2 p/ Y
5    dev_printf = ops->printf;//printf為不定參函數(shù),不能在步驟2中進(jìn)行賦值,所以在靜態(tài)庫里進(jìn)行初始化賦值。
1 p9 `3 _# r" O; q! O! C6    main();//跳到app的main中
. a' n* M+ x( ~- j) o4 q7}/ A1 m2 l/ R( n5 r: l
6.app.bin程序的啟動地址修改,修改 IAR配置
! v) w2 i# n& r" [+ k" o# e進(jìn)入options--linker--library--勾選override default program entry,在Entry symbol 后面輸入common_startup。! q8 W7 s" A) Q) _6 L' p
7.因?yàn)橛袃蓚.bin程序。所以就需要配置icf文件,并且call_app(addr)這個addr為app.bin里面common_startup函數(shù)的地址。因此需要編譯app.bin后在output文件里面的app.map里面查看common_startup的地址是多少(由于這個函數(shù)是程序最先執(zhí)行的函數(shù),所以其地址為icf配置的起始地址)。; C; P) e& h" O% j& l
8.然后你在應(yīng)用里面包含了dev_PortOpen函數(shù)的頭文件就可以正常調(diào)用這個函數(shù)了。
) j9 R& S( R, f' S因?yàn)閘ibdev.bin和app.bin是同時運(yùn)行的(app.bin調(diào)用的libdev函數(shù)的實(shí)現(xiàn)在libdev.bin里面),因此必須把RAM和ROM分成兩份,不得重疊。: J& c$ R. t) H3 Q
素材來源:https://blog.51cto.com/kenotu/1614390
9 k3 [" P' Y9 q9 K5 W4 n, q9 s1 u6 ]% ]-END-- R+ `+ I4 ^' ?% q0 u) a
往期推薦:點(diǎn)擊圖片即可跳轉(zhuǎn)閱讀
' h; _- }; ^% y9 c0 C- M* g                                                        8 o, l0 i6 a4 F, j
                                                                ) ]1 ]8 C* @3 ~' K/ C& Z7 w4 ]& N
                                                                        ; Q3 I! w8 v% h" d+ P0 K
                                                                                6 ^1 L% F% {. U4 m# ~! c2 q
6 F1 [! Y3 {& u8 _
                                                                                - K; n" o# j  [3 @
                                                                                        分享一個跨平臺通用的 GUI 框架!
( E+ F9 L, r' J/ Z                                                       
2 M! h: a5 Q/ |                                                               
9 Z+ ^0 M0 }8 n2 p' U                                                                       
2 U4 D0 {! V9 f' a+ P: [                                                                                4 m5 ~( H6 W$ m, z1 |
! N& ?5 K- }1 s% P, m
                                                                                / h3 v+ y- z$ w( D
                                                                                        嵌入式 Linux 對接星閃,用 C++ 設(shè)計(jì)一個通用的 AT 指令解析器。4 T4 {: W2 V9 |$ p( `
                                                               
9 K" F. E/ ?, u' L* O2 S  L                                                                       
; G2 i* g# G0 z: C  k0 q                                                                                8 k! n% J: `. O( @* [

8 {, H. i. i6 n: X, ^7 x& Y                                                                                  u" R3 L( r+ X# s
                                                                                        嵌入式大佬分享,簡單易用的開發(fā)工具及解決方案!
& c, m' A" L. ~5 F                                                                               
, x! w' n3 f2 x2 N/ o                                                                       
* J) }8 i$ |) X0 @; K  O! l                                                               
! v) L: k" M5 P6 s( a5 c                                                        我是老溫,一名熱愛學(xué)習(xí)的嵌入式工程師
5 M! e2 c! m# m9 D. g3 w( o. g關(guān)注我,一起變得更加優(yōu)秀!

發(fā)表回復(fù)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則


聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表