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

关于μCOS/II v2.85内核OSSemPend()和OSSemPost()函数工作原理

[复制链接]
zero99 发布时间:2016-6-17 00:26
//----------------------------------------------------------------------# I0 ]! Q* b1 C  [' b) e2 o
//1.OSSemPend()函数: g% @2 f) b/ T5 Y$ j0 Y
void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr)" r( u+ V+ g+ ~" N) u) D5 t
{2 p  o- {" o: i; e
    INT8U pend_stat;
. n& m$ m& x" I" F8 ~) N#if OS_CRITICAL_METHOD == 3
) s8 g: N$ f3 }& A! P  |# F    OS_CPU_SR cpu_sr = 0;
) C2 d8 `; r8 l9 |7 C#endif0 K- Y0 ?; x% ~
7 o: W! O7 ?; ?' v8 |
#if OS_ARG_CHK_EN > 0
  c0 p. F* d; L/ w* L+ u, r1 m    if (perr == (INT8U *)0) {
6 J* d) G2 i+ K  S) K( b        return;; [$ a' K. C3 Q
    }* D& B) b2 D) ^: Q; E. P
    if (pevent == (OS_EVENT *)0) {) a+ d- k7 D7 J$ u' {- O3 m
        *perr = OS_ERR_PEVENT_NULL;
9 u8 H$ W& h5 K: {$ x' Q% n# q' i- s        return;
) {2 \+ L3 k5 K    }
" d$ h( z" W, P#endif
4 U% k$ M, ?& w1 `' l( |: P- M  Z6 A    if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {
! ~, C! L8 S+ ]" A. e1 h//确保该event控制块是Sem类型
) G: I9 \! B+ L; p$ \" J* B        *perr = OS_ERR_EVENT_TYPE;5 l$ Z4 G$ t/ s0 k; V, C$ v2 E( L
        return;' ^- _5 G" j* k( @! ?
    }7 z+ Z, z) [* f+ \; n
    if (OSIntNesting > 0) {
! V" A; l$ W$ Z. u//ISR中,不能使用OSSemPend()# H& u* d# s- p& k0 W" x9 @5 Q
        *perr = OS_ERR_PEND_ISR;# E5 y' p" P- F3 e3 A- K
        return;
( T5 r- b* A4 X2 Z8 y' M; B    }
5 X) S( i# g) i* C  `# x    if (OSLockNesting > 0) {
' }; |$ ?& }9 R: Q2 J//μCOS/II v2.85内核已经被强制锁住
. d! T# [' g$ Z* `        *perr = OS_ERR_PEND_LOCKED;
7 p0 ^) }2 c6 o' e+ R4 z7 R        return;/ }2 u& d. @1 [6 J
    }
+ }. z2 Q5 W# p$ e6 X//非法的统统不是,信号正常,所以有必要进一步处理' M3 _; v3 \8 X% T
    OS_ENTER_CRITICAL();) B3 r2 T! l- ~* k! F1 {6 A3 U
    if (pevent->OSEventCnt > 0) {; E6 N( q9 B" F$ ~! E
//程序的其他地方已经触发了事件,异或在初始化时设定了n,如:OSSemCreate(2);" V' ^$ S: @  M* v' d$ f
//所以该task无需悬停,直接获得事件的使用权
5 F) f: F# ^4 L4 `3 Q        pevent->OSEventCnt--;- u5 w$ J4 H1 x/ V, K1 `+ ?  T
        OS_EXIT_CRITICAL();
+ q5 g/ ]  `! s2 f- K" l        *perr = OS_ERR_NONE;
8 E% }! q1 S; q. s# X  f6 H3 |# c        return;  C8 `- b& J7 L2 z6 B
    }8 [2 _+ k) r7 H
//当前还没有任何事件发生,所以本task需要悬停,让出cpu[gliethttp]/ c# D- f0 Y) A: G+ s2 }
    OSTCBCur->OSTCBStat |= OS_STAT_SEM;//是sem事件让本task进入悬停等待的" U; [- }. j, i. Q/ N3 y% D9 c
    OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;//假定不是超时,为正常收到信号
  p2 E% v& t7 i  [: m//超时,如果timeout=0,那么,本task将一直悬停,仅仅当收到事件触发信号后才重新进入调度队列3 g5 T6 }4 E4 {: X( w! w9 D
    OSTCBCur->OSTCBDly = timeout;! y) d( |! B2 j- U
//OS_EventTaskWait()函数实现的功能:4 P& ], k+ b- o  G, x
//把本task从就绪控制矩阵中摘下,放到pevent事件专有的进程事件控制矩阵表中./ X- @1 Z; G. a0 |3 u2 U  |
    OS_EventTaskWait(pevent);
" `9 u( @# f% X- L* f    OS_EXIT_CRITICAL();
1 h) f$ p( P% U: U: S//因为本task正在运行,所以本task现在的优先级最高,现在本task已经将自己从就绪控制矩阵--调度器(x,y)矩形阵列中  i1 s9 w# ?/ M$ d
//把自己摘掉,所以调度函数OS_Sched()一定会切换到另一个task中执行新task的代码[gliethttp]
6 B7 p! M* @2 s# G& W6 j9 h/ n    OS_Sched();//具体参见《浅析μC/OS-II v2.85内核调度函数》/ R' _: o! ~; s( @
//2007-09-09 gliethttp/ c, W8 B2 u: `$ e. e# T
//可能因为OSSemPend()中指定的timeout已经超时
3 ^" O+ b( w( N" L1 G//[由OSTimeTick()函数把本task重新置入了就绪控制矩阵,具体参考《浅析μC/OS-II v2.85内核OSTimeDly()函数工作原理》],( a8 l. b* N# p0 e
//又或者确实在应用程序的某个地方调用了OSSemPost(),以下代码将具体解析是有什么引起的:1.超时,2.收到正常信号
- P3 M3 o' z. Q; g' c    OS_ENTER_CRITICAL();3 a. y. g7 j2 H% t" F7 a! t
    if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) {, f5 G; i9 c; a: p  c
//是因为timeout超时,使得本task获得重新执行的机会
2 s; m2 h) P$ U# o: R  F        pend_stat = OSTCBCur->OSTCBStatPend;; w2 X0 c8 d2 `0 f( W' o- `$ |
//清除event事件块上本task的标志) f/ l, A0 e. t3 H8 s' r- m! L
        OS_EventTOAbort(pevent);
# h2 w$ R% p. J# m8 i' d        OS_EXIT_CRITICAL();
4 k. r/ v/ L1 F& Q7 a$ _/ x# ~3 o$ W        switch (pend_stat) {
+ p) b  a% R/ |, c/ g1 O            case OS_STAT_PEND_TO:* C, V7 ]6 G% K0 l0 n% @2 }$ G
            default:! j9 T$ Z! e, L$ l4 L* B5 O
                 *perr = OS_ERR_TIMEOUT;5 @$ U# `! M, y" p: I% I/ R
                 break;
/ I: g7 F: H8 W6 l) n7 j            case OS_STAT_PEND_ABORT:) n$ h0 `. F9 r  I5 u( W
                 *perr = OS_ERR_PEND_ABORT;
/ @' @' i( F# {                 break;* M6 v6 j+ N. u% E5 }- l
        }% i' I7 d/ |* L
        return;
* p; r( T" x5 P    }
* c5 G* c2 n" p- v& m2 b: G//由OSSemPost()抛出正常事件,唤醒了本task,因为在OSSemPost()时,8 l: m7 o. M* U/ ]5 ^; x: `* P
//已经将本task在event事件控制矩阵上的对应位清除掉,并且把本task放入了就绪控制矩阵中,4 \5 s+ b3 b! R. [
//否则本task也不会执行至此.
8 q# s$ P2 l# U8 P& O    OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;//现在本task不悬停在任何event事件上
, J2 J& K, ]/ J. w. D9 D; U0 x. \    OS_EXIT_CRITICAL();
" }0 o1 @3 r. [    *perr = OS_ERR_NONE;9 Q* G1 y; c; n- n* ]
}6 H' x" U* \; Z( Z( ^3 Z" h4 [
//----------------------------------------------------------------------: P; ^& y; {6 Y1 i1 a+ F
//2.OS_EventTaskWait()函数* _( `4 u1 |1 r& }6 O) B
void OS_EventTaskWait (OS_EVENT *pevent)
; f2 Q9 `% k  o' b3 A{0 K# T0 E5 g; A5 a  M' T
    INT8U y;
( o% ~8 E$ D* X% b6 n7 l) ^//2007-09-09 gliethttp
* x! R6 d1 e& [4 H7 K3 a  A& R//pevent为此次task挂起的EventPtr单元3 `& T' R3 n; y  p: x
    OSTCBCur->OSTCBEventPtr = pevent;
! x# Q* U( U" |* U//清除调度器中该task对应的标志位3 R4 u4 w, }- }  t9 D  Z
    y = OSTCBCur->OSTCBY;
: |$ t# w4 R- F, i    OSRdyTbl[y &= ~OSTCBCur->OSTCBBitX;- l! D% O0 z5 G4 k
    if (OSRdyTbl[y == 0) {/ ]; q& @" H1 F- q& V& }
//当前y行对应的8个或16个task都已经悬停,那么当前y行也清除.
$ l5 F9 J: Q! u5 }$ _6 T# H        OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
2 F* i1 `% ^* w$ w    }
( _2 B/ T( Q0 R  K( j7 K8 ]//2007-09-09 gliethttp% Y+ q, X: A9 B4 ^! U9 X3 F
//将该task的prio添加到pevent事件控制矩阵中,这个矩阵的功能和OSRdyGrp、OSRdyTbl没有区别2 M, r* j* a* j, x" ]' p2 r$ c
//都是用来计算出已经就绪tasks中的优先级最高的那个
* S/ A; m7 f2 G4 l/ T6 P    pevent->OSEventTbl[OSTCBCur->OSTCBY |= OSTCBCur->OSTCBBitX;
! p* b; i6 r- O3 \4 E    pevent->OSEventGrp |= OSTCBCur->OSTCBBitY;
6 a) |' V0 Y  J! c/ T7 S}+ ~9 @/ r$ R/ E8 b& x( x3 B
//----------------------------------------------------------------------: j. }$ C3 l( e0 b* n0 F3 |* m( U
//3.OS_EventTOAbort()函数
8 V6 Y! ~# H9 b% W% ]1 Dvoid OS_EventTOAbort (OS_EVENT *pevent)
1 v5 S2 x) r7 s% W{
3 ^6 ]( A, `& m6 l, b6 T# M    INT8U y;0 D: T/ B. O% U
//清除event事件控制矩阵上本task的标志,因为OSTimeTick()函数未清除该单元. o6 a- R: Z& j3 i' f! K) P7 W
//它仅仅把本task放入就绪控制矩阵中,使得本task重新获得被OS调度的机会而已+ D. d! l2 Y8 l
//具体的清除工作还要自己完成0 @% e. ?) z7 H" Z2 a" _
//具体参考《浅析μC/OS-II v2.85内核OSTimeDly()函数工作原理》
  _3 R1 I, i. C    y = OSTCBCur->OSTCBY;$ h! h8 W) C5 |8 ?, u
    pevent->OSEventTbl[y &= ~OSTCBCur->OSTCBBitX;
& k' `3 g% O0 B  X: e    if (pevent->OSEventTbl[y == 0x00) {. _* s' N& l. }7 h
        pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY;9 W. f  n. L- o6 J- }
    }
8 u! C. i9 D7 ]" d    OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;
' n2 e, C' t3 M* H* M! O; M3 A    OSTCBCur->OSTCBStat = OS_STAT_RDY;
0 k( |3 o5 y; ^/ {8 L0 E    OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;//现在本task不悬停在任何event事件上
4 G% f6 A7 Z( n7 J! o6 T}3 c" m, g9 ]. c1 i
//----------------------------------------------------------------------
4 Q% E3 E" _+ T$ w2 l//4.OSSemPost()函数
- ?: S) e4 e5 h+ B9 {INT8U OSSemPost (OS_EVENT *pevent)
; g% M6 \7 J9 ~8 w9 }& N+ G{
  [( O7 L) o" t( {#if OS_CRITICAL_METHOD == 3* v/ N7 C: m6 `! A: G& T; [
    OS_CPU_SR cpu_sr = 0;//方式3将把cpsr状态寄存器推入临时堆栈cpu_sr中,可以安全返回之前的中断状态' I" `/ c8 A, D( j: W2 {+ X5 m
#endif
! W' m; s# l( h/ e  u' D, v1 z) ^* U  [9 i
#if OS_ARG_CHK_EN > 0" G3 H) {4 M) ]. {9 {: K' r
    if (pevent == (OS_EVENT *)0) {
5 w3 N' r4 t5 @* ]& `; w. a/ b8 \( N+ N        return (OS_ERR_PEVENT_NULL);
8 o" ?7 y5 n) f6 T; z    }
1 `& N; H0 Y1 F0 z% S& d#endif9 R2 }* p8 ?+ n$ S: ?
    if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {% w5 Y- ?! n( N
        return (OS_ERR_EVENT_TYPE);
$ S9 r" b5 b+ q& J5 f7 R    }
7 q# m0 A) c( `/ W- X    OS_ENTER_CRITICAL();2 O4 v, C7 Y5 g; M4 w/ Q) @. Y0 r0 E
    if (pevent->OSEventGrp != 0) {
0 y$ Q* W" r0 Q7 L& V& z) q    //2007-09-09 gliethttp
7 y" E( h4 q) u( v- c    //OS_EventTaskRdy()函数将摘掉等待在pevent事件控制矩阵上的task中优先级最高的task
: k* ~) O0 T( O* a+ W/ O    //如果该task仅仅等待该pevent事件,那么将该task添加到就绪控制矩阵中8 i  g$ r4 {% L
    //OSRdyGrp |= bity;
% Y1 s" A- w  v    //OSRdyTbl[y] |= bitx;这样调度程序就会根据情况调度OS_Sched()该task了, s+ a' c+ h0 P$ R. k1 w6 ]9 n; b, ^+ B
        (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM, OS_STAT_PEND_OK);
4 Z% `* Q) |& r! y. H4 \- F# u/ A+ w        OS_EXIT_CRITICAL();1 F9 h: g" |% o% H* }
   
//可能刚刚放到就绪控制矩阵上的被唤醒的task的优先级比调用OSSemPost()函数的进程B优先级高
8 U2 x  U+ j$ |+ }   
//所以需要调用shedule函数,
/ A8 E* B- D* V7 Y, y  |& e   
//如果真的高,那么调用OSSemPost()函数的进程B就要被抢占,os将会切换到新的task去执行[gliethttp]
( V+ q) w7 U8 T  G4 I# f   
//如果没有调用OSSemPost()函数的进程B优先级高,那么os不会切换,仍然继续执行进程B,OSSemPost()正常返回4 e3 C% G0 w9 r- k! N
        OS_Sched();
& z5 K8 y9 N4 Q+ `+ `8 v  n7 W$ {9 Z2 m        return (OS_ERR_NONE);
2 R  A8 I( D" [/ S% G    }  E: {& ]) U, L0 d2 B
   
//没有任何一个task悬停在本event事件控制矩阵上,
2 E% l8 o2 s2 Y# ^* u+ p0 W, |   
//那么单纯的对pevent->OSEventCnt++加操作.. t4 N. H- k9 h4 {( j: {
    if (pevent->OSEventCnt < 65535u) {8 d" W. U+ L7 N5 D! P  v
        pevent->OSEventCnt++;/ ^. K' A2 M' k1 o8 x/ c- P
        OS_EXIT_CRITICAL();) ~# Z; k; ^4 f# G/ R6 l
        return (OS_ERR_NONE);1 t! u8 m; a" x' l1 f1 R) l
    }
3 }& t% }* M$ c* {  E: m   
//已经堆积了0xffff次,溢出
3 M$ D# D4 Q& n+ n& S    OS_EXIT_CRITICAL();4 C, c. [3 `/ t3 l3 p! N. M; }
    return (OS_ERR_SEM_OVF);7 s- c3 Q6 P( e2 `& S& V) m
}
( z5 P# f' ~& {! Y8 B3 C
//----------------------------------------------------------------------
" J/ r% f+ {6 ]& f* Z
//5.OS_EventTaskRdy()函数4 E7 H7 s5 F, x4 S: Z4 G% ]
INT8U OS_EventTaskRdy (OS_EVENT *pevent, void *pmsg, INT8U msk, INT8U pend_stat)
* V$ p3 H5 l7 D0 \{
& ?, X, O% X$ T) B- \; s& l4 a    OS_TCB *ptcb;
) u; H2 `. T7 k: h& _    INT8U x;2 L) B& m& ~& E, D" e
    INT8U y;
  x+ [: d" B+ _& }3 n    INT8U prio;" {( z( p+ [8 l2 j
#if OS_LOWEST_PRIO <= 63* W5 r8 z7 r0 p7 x9 j" p
    INT8U bitx;
" @& ]6 ~  R) N& B6 x( s( a! ^9 t    INT8U bity;4 n' {2 S9 M3 W
#else, k% t, [0 ^, f5 U/ u5 E) _3 _
    INT16U bitx;
: X, b' D7 s6 H' ~5 ~5 U; N, j    INT16U bity;
: Q* V7 d! f( D6 M0 e( O' W6 y' v    INT16U *ptbl;8 }2 {; u" ~6 `6 k8 W/ |' Q
#endif: ^8 T3 s, U9 S

7 i& M+ E$ k: B2 ]  I2 K#if OS_LOWEST_PRIO <= 63# R; t% z% a3 c: y
//小于64个task时,快速计算; W5 T/ d4 `. I" t! O$ w
//最有优先权的task位于事件控制矩阵中的第y行的第x列0 ]8 J/ W9 o* I; z! r
    y = OSUnMapTbl[pevent->OSEventGrp;2 C7 X+ z& ]8 c' ?+ M  Q
    bity = (INT8U)(1 << y);; w5 g7 I3 q9 T% T) g. L( J& z
    x = OSUnMapTbl[pevent->OSEventTbl[y;
. J1 Y; m2 `/ d' E$ Q) G- z    bitx = (INT8U)(1 << x);
6 r3 y6 Y% ?# `    prio = (INT8U)((y << 3) + x);
! V( N: e; D- t2 s. I) F#else
$ D& T7 j5 s+ }
//对于256个task, x% |# k: I3 x4 [- A
//最有优先权的task位于事件控制矩阵中的第y行的第x列1 E3 g( F' [2 C- k4 ?8 \
//以下的操作原理具体参见《浅析μC/OS-II v2.85内核调度函数》
  i" q1 ?( j2 E" W    if ((pevent->OSEventGrp & 0xFF) != 0) {
- J. B& ]7 ?/ X, t8 E  h* {: O+ W        y = OSUnMapTbl[pevent->OSEventGrp & 0xFF;+ l$ z" n8 \' N4 J+ |: @; q$ @
    } else {
1 \( Z; x- X4 R* \! y  a        y = OSUnMapTbl[(pevent->OSEventGrp >> 8) & 0xFF + 8;$ C) T3 j; b: Y' R+ `  H
    }
  I  k; S( Y, w+ Y    bity = (INT16U)(1 << y);
8 O( `) f# q; [6 q    ptbl = &pevent->OSEventTbl[y;& g) e9 }* Z+ n4 G. z5 {% W6 D. M5 J
    if ((*ptbl & 0xFF) != 0) {% J1 e, @! Z$ T4 ?3 L
        x = OSUnMapTbl[*ptbl & 0xFF;1 _, P5 ~5 v7 w
    } else {
& A0 y) l3 }3 }( H1 ~        x = OSUnMapTbl[(*ptbl >> 8) & 0xFF + 8;3 x& B. t7 E3 t
    }
3 Y2 D0 G- y4 g8 c4 t' k+ @    bitx = (INT16U)(1 << x);9 y( q, ^0 z: q7 l' w# y' X
    prio = (INT8U)((y << 4) + x);
//该task对应的prio优先级值
" e5 s8 f% C1 L3 D, X7 j4 _
//ok,等待在event事件上的所有task中,只有在事件控制矩阵中的第y行的第x列task. V  x6 l5 `' T/ F' c0 k/ d
//优先级最高、最值的成为此次事件的唤醒对象[gliethttp], x( T9 b1 n1 I2 j3 u% i7 r
#endif
, K/ y; O0 E: A- {, A8 X4 Q
//清除此task在event事件控制矩阵中的bit位
- l6 p, Z9 v5 p6 H    pevent->OSEventTbl[y &= ~bitx;# \+ t; c, u. t# ^6 b/ _/ [
    if (pevent->OSEventTbl[y == 0) {0 E4 u  M9 I* q' P! ~
        pevent->OSEventGrp &= ~bity;
- A3 \7 f, ?9 v( r4 A, |% T    }
* [7 N3 x; A- P, A3 H" p5 f9 i) f2 Q" T
//通过prio优先级找到该prio唯一对应的task对应的ptcb进程上下文控制块2 F; J9 S& \1 C  V7 y0 O
    ptcb = OSTCBPrioTbl[prio;1 \  s9 n3 d8 S$ n
    ptcb->OSTCBDly = 0;
//复原为正常9 R. o9 f, c. `" F% T1 ]0 B( G! U
    ptcb->OSTCBEventPtr = (OS_EVENT *)0;
//现在本task不悬停在任何event事件上
: N; E0 r( O6 O) M# q0 ?+ k#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0)
' x$ I, t  E- o" c    ptcb->OSTCBMsg = pmsg;//传递消息指针
" R& l/ P1 z: g# p; q) O+ m+ B( ^#else
( |/ t4 n, w9 v! D5 d3 h    pmsg = pmsg;
3 B* y- p, P, d' J, _& c- E) w#endif$ \2 R( m7 G; A) j% e/ Q! ]
    ptcb->OSTCBStatPend = pend_stat;
//悬停状态值
6 }/ D9 x$ o; j5 ]3 Y    ptcb->OSTCBStat &= ~msk;
//该msk事件已经发生,清除task上下文控制块上的msk位,如:OS_STAT_SEM! Y/ g5 e) g, D# ~! q6 @
    if (ptcb->OSTCBStat == OS_STAT_RDY) {- n' S0 r, s& z' s. X" l
    //如果当前task只是等待该事件,那么把该task放到就绪控制矩阵中,允许内核调度本task6 t$ W: |. Z& U; L' k/ P* ^# T8 S. X
        OSRdyGrp |= bity;
6 `8 E' P$ w3 H        OSRdyTbl[y |= bitx;5 b3 F! K9 [4 f8 R9 {
    }
8 P2 L+ p0 `" @1 @0 r. R* @    return (prio);//返回本task对应的优先级值
& ^4 o. B4 C, F) o, q}
" O  e8 d3 d6 J# }# u! m. H//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
$ X: f( Q" L% ~PS:"所以从这里来看,os中的各个功能单元管理着自己的事情,就像面向对象的封装一样,"% w' b+ {, R' `8 [& Z) N* y
   "事件控制矩阵和就绪控制矩阵是各个对象独立自治的关键因素"3 v- j# D5 G+ t" G) ~. b
   "其他对象,都努力说服自己相信别的对象是独立的、可信任的、安全的"[gliethttp# b1 k9 w! u5 n& a6 |# U2 w  K. t
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

( c2 ~) W" o! P) J
收藏 评论1 发布时间:2016-6-17 00:26

举报

1个回答
yuxin-366840 回答时间:2016-6-21 16:16:43
看看

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版