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

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

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

如何實(shí)現(xiàn)嵌入式軟硬件分層處理接口?

[復(fù)制鏈接]

437

主題

437

帖子

96

積分

一級(jí)會(huì)員

Rank: 1

積分
96
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2024-8-12 17:50:00 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
我是老溫,一名熱愛(ài)學(xué)習(xí)的嵌入式工程師
4 c. R2 L) T) r8 D0 w關(guān)注我,一起變得更加優(yōu)秀!一、前言以STM32為例,打開(kāi)網(wǎng)絡(luò)上下載的例程或者是購(gòu)買(mǎi)開(kāi)發(fā)板自帶的例程,都會(huì)發(fā)現(xiàn)應(yīng)用層中會(huì)有stm32f10x.h或者stm32f10x_gpio.h,這些文件嚴(yán)格來(lái)時(shí)屬于硬件層的,如果軟件層出現(xiàn)這些文件會(huì)顯得很亂。$ p) @$ q1 [  ^/ c) W$ d
使用過(guò)Linux的童鞋們肯定知道linux系統(tǒng)無(wú)法直接操作硬件層,打開(kāi)linux或者rt_thread代碼會(huì)發(fā)現(xiàn)代碼中都會(huì)有device的源文件,沒(méi)錯(cuò),這就是驅(qū)動(dòng)層。6 E9 N7 h; R, |( L3 r

( f3 Z, f' D$ u; j' F! M6 |二、實(shí)現(xiàn)原理原理就是將硬件操作的接口全都放到驅(qū)動(dòng)鏈表上,在驅(qū)動(dòng)層實(shí)現(xiàn)device的open、read、write等操作。當(dāng)然這樣做也有弊端,就是驅(qū)動(dòng)find的時(shí)候需要遍歷一遍驅(qū)動(dòng)鏈表,這樣會(huì)增加代碼運(yùn)行時(shí)間。
  L9 }( `3 R5 B% u" R三、代碼實(shí)現(xiàn)國(guó)際慣例,寫(xiě)代碼先寫(xiě)頭文件。rt_thread中使用的是雙向鏈表,為了簡(jiǎn)單在這我只用單向鏈表。有興趣的可以自行研究rt_thread* T, ?. c( [1 `8 D. c: |$ V8 i% n' L
頭文件接口:
' m+ i  O& e1 F( K本次只實(shí)現(xiàn)如下接口,device_open 和device_close等剩下的接口可以自行研究。這樣就可以在應(yīng)用層中只調(diào)用如下接口可實(shí)現(xiàn):, B3 T. }5 A; ~( ?7 ?8 B" Q8 @( r
/*: F- J) K- p% N, [
    驅(qū)動(dòng)注冊(cè)
0 h8 N0 l; Z, I( E* w, p*/0 X2 F# A% S: ^0 f; i
int cola_device_register(cola_device_t *dev);
1 ~6 F' O% S- r& S. @/*% ?1 i$ G& U" G3 D
    驅(qū)動(dòng)查找
6 e+ U  b2 g! i. Q! D2 d  E, ~*/
% g" Z- p7 V( x0 Vcola_device_t *cola_device_find(const char *name);, Q$ b0 q0 y, n& k/ z3 J
/*4 W* F' j$ t$ C9 ]0 E
    驅(qū)動(dòng)讀. V" n% i" |1 x* g) \" o& L
*/1 ?% `4 o2 _- z  ]5 M7 S8 M
int cola_device_read(cola_device_t *dev,  int pos, void *buffer, int size);
. O+ F. [4 {8 d/ Y. ]/*  c( ?8 H$ U# J
    驅(qū)動(dòng)寫(xiě)
% z7 B2 e2 I. e*/+ T3 v4 @# ]8 z0 U( U
int cola_device_write(cola_device_t *dev, int pos, const void *buffer, int size);* V  X0 x. F, i2 U) ]& r, ~# S! c
/*
+ C) z! g9 e& ]- I" I    驅(qū)動(dòng)控制$ W5 ~) V9 w; N2 ?& y  J3 H& @
*/
  F. }, M% M! d2 K9 t/ `int cola_device_ctrl(cola_device_t *dev,  int cmd, void *arg);;頭文件cola_device.h:
* e6 n+ Z' K9 h% [  \#ifndef _COLA_DEVICE_H_
. L1 [( K' r: U  v' J, w" ~3 e5 J#define _COLA_DEVICE_H_4 W0 z6 {  r# e/ Q
enum LED_state% |8 i  Y+ A8 b$ N5 K7 `
{
5 N0 ^6 _# T9 _8 ?( Z/ a    LED_OFF,
$ C7 G; s. l) V! t$ \    LED_ON,
$ R1 {- c  z( e    LED_TOGGLE,
& a/ k6 i2 i9 z" f) g" l};) d9 D5 Y/ C" p' p% i
typedef struct cola_device  cola_device_t;6 F% d9 `# q3 n
struct cola_device_ops* B& m; K* D" z6 Z1 @& `
{
) ?: I" ?  P6 z; }2 p( J: W    int(*init)(cola_device_t*dev);( _5 ]9 K/ M- o9 K1 x/ x; M" t
    int(*open)(cola_device_t*dev,int oflag);) E% O- Q3 l3 h+ l" s' Y
    int(*close)(cola_device_t*dev);
; {" {$ y2 t8 h. O2 Z4 m    int(*read)(cola_device_t*dev,int pos,void*buffer,int size);4 X7 t9 R) k6 ^. m2 ^/ [
    int(*write)(cola_device_t*dev,int pos,constvoid*buffer,int size);" S# D# ^0 m. J5 V. E
    int(*control)(cola_device_t*dev,int cmd,void*args);
6 r6 K7 s6 e7 a7 y};/ q5 i: H- W4 G0 {* m
struct cola_device
# l+ c$ s; x, J3 Q( m8 W{
* J9 ~. X5 Z1 E1 A4 A- z5 D    const char* name;
  @4 e) Y( V, R' u    struct cola_device_ops *dops;
7 @7 ?4 j5 Y; e    struct cola_device *next;9 r, B& u. i- q  ]
};
7 @, e9 y! g7 M/ {. ?8 t1 F+ w+ d/*, K6 j& R% r; v8 ~3 T
    驅(qū)動(dòng)注冊(cè)
$ F! U3 r% z6 B7 f2 |*/& ]6 U" W9 F0 [: P- f
int cola_device_register(cola_device_t *dev);; ^4 o/ U6 Q5 q  I% [$ I
/*
) {7 O9 Q( z5 I& ]) `1 t% A' p    驅(qū)動(dòng)查找
/ L4 U- w1 O0 R; v*/- L4 j4 Z" F7 b$ c$ r; K, c
cola_device_t *cola_device_find(const char *name);  y( k& R5 f) S' b& G' w& R7 P; n
/*
% A& h  W2 m: e+ h* T$ s3 Z! F    驅(qū)動(dòng)讀
* r7 s/ d. o5 Z7 Z9 D! E*/% o  l9 L% b4 G$ r1 l+ A
int cola_device_read(cola_device_t *dev,  int pos, void *buffer, int size);
5 W: G% ^+ }1 r% c/*
# c! Q( D( h1 v; N& T& Z3 [    驅(qū)動(dòng)寫(xiě)
3 T2 d$ \; d3 a2 O3 k*/
  E# h% n2 D" K0 y2 L* n" tint cola_device_write(cola_device_t *dev, int pos, const void *buffer, int size);
& k' d1 }4 C% L( |/*. t8 A# l, C* ~4 i) z
    驅(qū)動(dòng)控制+ q5 a1 t2 }/ w2 R( E  O0 D* M' {
*/# w* T. N/ v6 A4 B4 t. a, D3 L
int cola_device_ctrl(cola_device_t *dev,  int cmd, void *arg);. N4 z7 d- P$ C
#endif 源文件cola_device.c:
* |/ J% f6 K) U0 V) j#include "cola_device.h"
2 Z, h% X0 q6 G# }) ?$ z#include
+ `  J4 F$ @3 U4 Z; E0 A#include
; T; |) \% s3 }% E) Bstruct cola_device *device_list = NULL;
6 w% X8 V0 d: U2 }" V* h" e/*
: Q5 m; p/ r( C9 i( L4 y$ M8 m    查找任務(wù)是否存在9 e. s( B% ?8 ~2 l
*/
- v$ b, Q0 w$ D. ]: _static bool cola_device_is_exists( cola_device_t *dev )
, v8 R4 u1 e8 z. t{
5 u! Y; w& x1 z, G. @8 _1 o    cola_device_t* cur = device_list;
) t$ y7 ^5 i1 ~. z    while( cur !=NULL): J5 G: g) h, Y  Z& f* O
    {
% _  O4 G3 p, B# \1 w3 W        if(strcmp(cur->name,dev->name)==0)* \  Z" ]% t: R
        {
* ~7 v9 q+ Z: P2 S9 U            return true;
  @' k( a( l! y& n        }
% r5 T: f  I: @  {        cur = cur->next;( i; m$ d) L  X! p; k
    }7 y8 t7 c8 P3 r) f+ Z3 t
    return false;3 I( }$ Y; Q; H9 h1 @+ O! g1 R7 K: m6 B
}
+ f1 Z& `! Q4 l; G6 \9 ]static int device_list_inster(cola_device_t *dev)
6 y4 P3 R' \8 x: k2 `{( v( o3 i( S6 W$ t  L* c" V+ A
    cola_device_t *cur = device_list;
* X! T: N0 [, v# y    if(NULL== device_list)5 Z$ @4 {# s" H" u8 m4 y( q( Y
    {
; P* G0 r( M' y* c: C; @2 t! p        device_list = dev;5 s' C! o. C& w! R; }$ V" e1 h
        dev->next   = NULL;. k6 x$ H, v& R- W7 w9 X% A1 @
    }
0 E( l% i2 d" \5 ~. K) }    else
$ N  j2 M0 F" i# M6 j    {4 G/ T5 e. r+ y5 {9 x
        while(NULL!= cur->next)1 K% c/ Z2 u6 _: r& v; o+ \
        {
! c5 e: l! v8 q& q            cur = cur->next;
. O! L# J, E) L' _6 s$ z        }
6 k/ s& t( Z/ U# A        cur->next = dev;
: i/ {3 r% \  {# S# Q% A0 M        dev->next = NULL;
  M6 G6 j" e# E6 m    }4 W* Z* f6 x3 a7 W; d4 W% A
    return 1;
" ^% O% k' ?0 c$ b! P- U/ J4 ]}
0 D; {% _' U3 g. f) N! D0 [/*
. G. C3 ^+ _9 S+ O4 K, q    驅(qū)動(dòng)注冊(cè)
, b' n6 F# N! s% M*/" f3 j/ f3 X9 l( H; {# y+ h4 O
int cola_device_register(cola_device_t *dev)
$ z2 L9 P) X1 S  f  f{. j, \3 h( ~6 y( `, P; B  F
    if((NULL== dev)||(cola_device_is_exists(dev)))
( x% C5 d. N  c& e: e/ v$ ]; A$ H    {- Z% P: }% m# ?/ ^
        return 0;
4 Y5 v( R* e7 m5 w    }
8 d. e' c" w1 m" k2 `    if((NULL== dev->name)||(NULL== dev->dops))- K8 ^& N4 t+ w
    {+ q0 C6 R( _5 ]& C& R& u
        return 0;: ~, Z5 g2 e) q; V! ?/ p( i: C
    }7 H: Q1 a  w0 b- Y2 T9 u  X
    return device_list_inster(dev);0 |' X) F* {) h6 B% D
}4 _; l3 ~; g( S. i3 s( Q
/*5 `" f- k3 E6 l5 E( e
    驅(qū)動(dòng)查找& v4 R: W$ V4 w: p4 l
*/. x  i) f2 t9 |
cola_device_t *cola_device_find(const char *name)& y( c5 D6 a& N7 H% `5 N5 U
{) g3 k% g9 q) A. b3 f5 z+ \
    cola_device_t* cur = device_list;: _) \! ]5 Y2 g" N% O% |  \: {
    while( cur !=NULL)
: @( r/ V" @! v( J! G    {
7 H  U* {' ]% C9 k; P        if(strcmp(cur->name,name)==0)
& l, [' U; ]  @5 G        {
! s6 e) `9 ?( |: k            return cur;8 S( `+ w, y. a: d4 ~2 C
        }
" n! l" w, L( ]% L0 c        cur = cur->next;' w. [" R) [: p, S3 y
    }& w% S# ?, N  k2 ~( e
    return NULL;
9 ]9 T3 X" J) V9 f" u: ]4 n}' T  K. U9 s. G$ c0 _" P) Y/ C8 H
/*
, v# y- G, S" a0 K! G: o. D; d1 s! d    驅(qū)動(dòng)讀/ h: ]! X+ R6 u$ ~7 }, Z
*/: b8 }; Y/ ^- p% k/ Y
int cola_device_read(cola_device_t *dev,  int pos, void *buffer, int size)8 ~2 s# z. M- M% f7 D" _$ g
{
) }+ k" l9 A9 f0 Z# V0 f" f9 w! a! U    if(dev)
" |/ b& q" E: h0 i    {
; E9 C/ S1 i9 e) A* W        if(dev->dops->read)
9 U" t/ }) w% N8 o        {
/ P2 v" T9 Z" y/ c8 `0 _, _            return dev->dops->read(dev, pos, buffer, size);# H. k) Q4 ~; ]1 t- T
        }
: Y- b: i$ `* w! I: r! M" B; s    }# ~; D; Z1 o5 k
    return 0;
" T7 A4 Q% N& N$ l}
6 L6 b. J, i& I4 \, B' `/*- a9 {" k5 \. ~6 \! a- }8 p
    驅(qū)動(dòng)寫(xiě)
6 f7 B6 f# e, b, K) `& h# g0 Z*/; c4 _+ V! `9 h9 d) J
int cola_device_write(cola_device_t *dev, int pos, const void *buffer, int size)0 k4 H1 f3 w1 [. m! V: Y
{1 U( o; J5 [# Q$ n5 g
    if(dev), D" X' @/ n. Z7 d% u+ }1 k1 V% m
    {
9 o8 o; X, {$ t) F. E        if(dev->dops->write)
# a8 I. m- U& I/ c% r' n( P. C        {
8 w2 i3 v1 O* y0 w# Q! W9 Y4 w( h            return dev->dops->write(dev, pos, buffer, size);7 l/ R+ W+ L7 F$ o' d$ h
        }
2 z% w" W! t: Z3 C    }
/ H7 U. l! @" k9 [    return 0;
' {0 ~# n! o5 x}
- S! T: @& \0 W8 k( o5 I/*
' ?4 W8 I9 r8 a( i    驅(qū)動(dòng)控制* L! o8 x8 f& X+ F8 }4 q
*/
3 D5 F6 J9 W) gint cola_device_ctrl(cola_device_t *dev,  int cmd, void *arg)- f6 X, ]( v; _) B8 h/ L
{+ _% r1 U* c2 k% m; k
    if(dev)$ A' G; Z, a0 S3 a
    {% _9 X8 T! J& q/ j' m
        if(dev->dops->control)
. v* }+ k" k& Y! {* s4 y& c9 D        {/ @" y0 b) r0 u# v" N* l; e
            return dev->dops->control(dev, cmd, arg);
2 M( e& g+ y, x  D        }8 F6 W% l9 P: _1 X9 V& Y6 e
    }
5 H. ^; [0 M/ s+ T$ A" U" r/ V    return 0;
* w! ?. [& {, P& u0 H0 o( f. a}硬件注冊(cè)方式:以LED為例,初始化接口void led_register(void),需要在初始化中調(diào)用。
9 e1 G0 z4 O1 X, L% J#include "stm32f0xx.h"
* _4 L' |* [8 F#include "led.h"! L+ L; ^. j* b( f
#include "cola_device.h"
% z9 i$ `$ _) S' V#define PORT_GREEN_LED                 GPIOC                  
/ M( X. X& h" n, Z0 {#define PIN_GREENLED                   GPIO_Pin_13              ! Z- |3 g5 `3 ~5 a/ C) `* b
/* LED亮、滅、變化 */8 m! c+ p# A; V3 z0 _/ _
#define LED_GREEN_OFF                  (PORT_GREEN_LED->BSRR = PIN_GREENLED)3 b) X- ^" E  i- y- J  e
#define LED_GREEN_ON                   (PORT_GREEN_LED->BRR  = PIN_GREENLED)3 o/ T( r. [* W+ @/ c6 {
#define LED_GREEN_TOGGLE               (PORT_GREEN_LED->ODR ^= PIN_GREENLED)8 ?% X9 C- c7 q5 }9 q9 `, l
static cola_device_t led_dev;
( _, L: H2 X9 a/ e3 e  Sstatic void led_gpio_init(void)
& X1 Y. G2 a' k% C+ F8 O{
. x  D2 f. u/ c    GPIO_InitTypeDef GPIO_InitStructure;& Q. M7 t& M' ~* M9 i; Z1 c3 z1 J
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
5 v- \$ ~9 k  C    GPIO_InitStructure.GPIO_Pin = PIN_GREENLED;+ g1 n# n) L2 q' u; ?+ ~5 C( p& a% q- ]
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;& h+ o" v& f+ v6 V) A
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
4 \/ g: @) S' M6 m    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;, R  m: O4 u6 }1 f
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
# Q3 {2 o  F3 L  K$ w3 [    GPIO_Init(PORT_GREEN_LED,&GPIO_InitStructure);
3 @& {9 B" V" S& ]0 [" Z    LED_GREEN_OFF;5 s2 R% K  t0 {& c( C" O% p
}; V. h3 r* N  r! \4 [

% N! j- [& {( `3 x) y8 `% T9 kstatic int led_ctrl(cola_device_t *dev, int cmd, void *args)
3 y- S# U/ _! W2 V  m, s  P{
6 ~3 u) ]; P* {# t4 w    if(LED_TOGGLE == cmd)
& v& U; p# n4 t    {) f" c% Q+ c* ^2 D" G$ S
        LED_GREEN_TOGGLE;
1 S( S! `7 P1 K  q" ?# G3 t    }
$ e5 k% ^9 F& a7 Z  _( e    else
! v  A* f9 Z) {$ R' `    {  _, I9 c  I5 \* a) M) ~& P
    }! [. w) s) p! j6 N2 c- N
    return 1;9 u  ~. d7 Q7 v
}
2 H/ D' k' Z- Z4 H. i. ?! f( o! }* Rstatic struct cola_device_ops ops =
# u8 Q% f' h1 o5 O( j% H. c{
' Y7 P7 X- T7 k! ^  h .control = led_ctrl,; r& y6 U4 u: K6 z* O
};/ ]2 Q, Q8 V4 Z% c  E! ^% h
void led_register(void)/ ?; v; a5 @* y& A' h
{
9 d) B0 i; T2 A- P. z" k3 Z    led_gpio_init();7 r5 t. v" }. ?4 l- |7 V
    led_dev.dops =&ops;9 L/ \8 T( w' e( g+ Q
    led_dev.name ="led";
5 D0 v6 a# U( `9 f2 v    cola_device_register(&led_dev);
; M! B* B- O( l8 G6 x4 M) y}應(yīng)用層app代碼:% z4 J* e2 j, n* [
#include 7 ]" N( A% |3 I6 ~5 ?6 ~9 H
#include "app.h"
" Y5 Q1 k9 C! `#include "config.h"1 v4 e# r- F) F  _
#include "cola_device.h", X" }/ I& j4 x
#include "cola_os.h"6 q' N  [; C& Q
static task_t timer_500ms;* o6 z& f; b8 I! {- ~, n
static cola_device_t*app_led_dev;
. m( \4 V3 Q$ w  b7 Y//led每500ms狀態(tài)改變一次
: a3 N  J/ n2 b  ?) H+ t4 \static void timer_500ms_cb(uint32_t event)! d2 F" r& H5 u: z
{
9 D( m. h9 y6 P) S3 G$ g    cola_device_ctrl(app_led_dev,LED_TOGGLE,0);
! g. f; x) k4 b}
9 U& o: u/ F% S+ [# Q, ?: i5 tvoid app_init(void)2 `8 h6 ?- V8 e9 P9 ^4 s. w
{
9 k, |% f0 e3 X$ l9 w    app_led_dev = cola_device_find("led");7 K, |4 B2 u3 v: O/ o
    assert(app_led_dev);" e' e! v* f0 O. [( h/ I4 E6 Y' k
    cola_timer_create(&timer_500ms,timer_500ms_cb);2 j1 f4 h$ T5 {9 E- o
    cola_timer_start(&timer_500ms,TIMER_ALWAYS,500);; N# \- Q; p$ r. |
}這樣app.c文件中就不需要調(diào)用led.h頭文件了,rtt就是這樣實(shí)現(xiàn)的。
2 A0 U; h4 x& x) A) [" }四、代碼下載鏈接https://gitee.com/schuck/cola_os
3 T1 |5 I. R- \  t5 d
原文鏈接:https://blog.csdn.net/ziqi5543/article/details/101512722: b0 v( ^$ S5 z. [$ h
-END-- N; O+ U: g( `2 H% E
往期推薦:點(diǎn)擊圖片即可跳轉(zhuǎn)閱讀! @+ @; G4 Q) V; J& ?- X
                                                        8 @5 U( d/ \1 y7 t( ?& e: `
                                                               
+ f" P: J' k8 J# m7 w& A, k                                                                        ! w& |$ s: R8 w# S$ f
                                                                               
( S6 f: q! d4 _% }- f * p, _4 W5 j9 S8 C* ^" N* I
                                                                               
5 Y! f" _  n7 V6 n0 u( `- Y! v                                                                                        嵌入式 C 語(yǔ)言的自我修養(yǎng)# ^: l/ h  J; z4 Y" D
                                                        " y+ E, u$ A" `7 `# T! A6 ?
                                                                0 D5 K0 u( v3 S+ a0 g! h. y
                                                                       
9 P4 I4 `: v! K! H( c* T                                                                               
1 y9 D  m2 Z+ K" g
% ~# z6 H. [# X! `                                                                               
# t( ^& L; L/ _; D                                                                                        被 char 類(lèi)型的變量坑慘了!
% H( I/ U1 x# Z* e: }* Y, ]                                                                5 B4 Y$ A6 h9 h# R/ A2 u7 ~. I
                                                                       
& P, g1 c- y. e3 b) s/ r# E                                                                                ' _6 l5 K8 w! b' m  Z4 e' n
  W) I6 Q* ?: ^3 ?1 Z# X" q0 H
                                                                                * s/ O; C* ~, R
                                                                                        嵌入式 C 語(yǔ)言知識(shí)點(diǎn),動(dòng)態(tài)變長(zhǎng)數(shù)組+ Z% s2 t% w- X. u3 ]
                                                                               
; ?8 Z2 K" I! m" X. L/ U; g                                                                        $ v* ?7 w% D* W
                                                                1 m7 }1 Y, w' q; q4 f5 o
                                                        我是老溫,一名熱愛(ài)學(xué)習(xí)的嵌入式工程師
$ H3 g) p5 K. j7 I關(guān)注我,一起變得更加優(yōu)秀!

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

本版積分規(guī)則


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