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

【源代码】STM32F103C8T6最小板搞定CMSIS-DAP和SWO功能  

[复制链接]
radio2radio 发布时间:2018-5-31 15:47
阅读主题, 点击返回1楼
1 收藏 45 评论418 发布时间:2018-5-31 15:47
418个回答
radio2radio 回答时间:2020-11-23 10:44:07
wth_arm 发表于 2020-11-23 10:000 M0 ]: b& p0 s+ N/ l
再请教一下楼主,我编译时永远都是BLUEPILL,想改成STLINK_V20,#define  STLINK_V20  1,这样定义没成功, ...

: C7 F/ m. c1 `" u7 {; ^7 X7 o( C更换不同的板子,在这个下拉菜单里选择:
- `& i, }& @9 a Boards.jpg / n; D  P" l" o& ]% o# P8 c# ]5 V/ T
! @: v' r0 p( J0 q6 y4 y" r' \
wth_arm 回答时间:2020-11-23 10:51:57
radio2radio 发表于 2020-11-23 10:44
5 X, I7 A5 e4 h8 }更换不同的板子,在这个下拉菜单里选择:

' N* v2 S7 P( |% @, ~- Z3 fOK了,终于搞定,感谢!!!
ljlt 回答时间:2020-12-7 10:03:45
太好了,感谢分享。
ljlt 回答时间:2020-12-7 10:04:09
感谢分享,不错。
冬天ア之釜 回答时间:2021-1-8 14:10:55
看起来真的很不错
huawuqiu 回答时间:2021-1-11 17:04:57
感谢LZ分享~~~
ricklou 回答时间:2021-1-25 10:50:25
除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduino ide),stm32好像有联络信号pa0和pa1,希望做一个,让复位时给一个低电平复位信号。( @: U: s9 B4 M  t$ j1 C: Y
ricklou 回答时间:2021-1-25 10:59:32
网上搜了一下,2011年就有人讨论流控信号的问题了,现在还没有解决
radio2radio 回答时间:2021-1-25 11:31:13
ricklou 发表于 2021-1-25 10:50
: A. k2 E. s  k8 G; A0 V除了mdk和iar能自动复位,其软件他都不行(iar for 8051、keil uv4、keil c166、jltool3、nfc tool、arduin ...
! ~' G* s6 \' y' ]6 U
我这个是有复位信号输出线nRESET的,不过IDE要懂得向DAP发出复位命令。
  r5 A: M& q6 I" ]& c" o% Z
/ C8 o1 x3 R3 t4 x+ z  X软件复位是另外一种情况,需要向目标IC发送复位“密码”,Cortex的IC有这样的密码。 这就不需要连接nRESET线了。
ricklou 回答时间:2021-1-27 23:00:25
可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号
radio2radio 回答时间:2021-1-28 18:01:27
ricklou 发表于 2021-1-27 23:00
1 o+ e$ ~% D& H可以把nreset映射为dtr或rts吗,很多软件走的是com协议,或者告诉我如何触发复位信号 ...
: x5 q9 a9 z. z6 A/ x' e$ ^4 ?# L
nRESET是受使用CMSIS-DAP的IDE的逻辑控制的, 不能随便修改。
" k+ W2 a) F0 u8 A你要的功能应该不是一定需要走nRESET这条线, 随便找一条空闲的GPIO,模拟一下DTR/RTS,很容易的吧。/ }  j+ {" I) ?. w. _- E' o( j4 Z) N
, ?+ k" Y) a6 \
你用的功能好像只是用USB转串口,那么就应该使用USB-VCP的程序来改。
  _' x* T2 a* g( I. U; q0 h或者买一个有DTR/RTS线的USB转UART的小板, 便宜得很, 5~10元一个。/ I2 Z2 O; b- C7 J  V, f
0 A& G' e" L( T) m( g

( Z+ ?$ E! r' v+ y: K
abcd44 回答时间:2021-7-18 22:32:37
楼主好!一年前路过此帖现如今又回来路过了,最近痴迷于无线下载,不知楼主在此方面有没有研究或者相关的建议呢?. T6 ]; p6 q! a# s! [6 s
AYANAMI_S 回答时间:2021-9-23 13:39:40
楼主 为什么我烧录您build文件夹下的hex( F103-DAP-SWO-CDC-BLUEPILL-SWD_PB8PB9.hex) 将核心板与电脑连接会显示未知usb设备呢  keil也识别不出cmsis dap % w2 w# t5 F$ U  G
起点VS 回答时间:2022-8-12 09:23:24
正需要,这是好东西
KEVIN.Z 回答时间:2023-9-7 22:41:22
我也自己用ST官方标准库STM32_USB-FS-Device_Lib_V4.1.0移植了DAP V2.11版本的,即CMSIS 5.9.0里带的DAP,芯片型号用的STM32F103C8T6核心小板子,实际上我还有一块板子装上了APM32F103CBT6的,程序能通用,没跑RTX系统,轮询执行- I( Z( Q/ T5 F* o6 Q
/**
" x( A. i: Z! j6 j: U, N  ******************************************************************************
6 X/ b, g0 \5 ^0 W5 R/ p3 h  * @file    usb_endp.c+ U& ~) W" \; p/ f9 M) B* ]8 g. f
  * @author  MCD Application Team
# }& r% {2 h$ U$ K* F9 Q/ D8 S  * @version V4.1.0
" Y9 H! [4 v) N. C) _) @/ O  * @date    26-May-20175 W6 O( c' m3 o: ?
  * @brief   Endpoint routines
: y! s: o" Z, P, \1 f  ******************************************************************************
6 y9 x( V, E* E  * @attention+ f+ Q3 p: y: I+ N! D7 i4 F. x
  *
9 h$ _0 B; H# O0 n$ m/ E  * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
0 _& R+ G0 ^3 N  *
% V7 q$ C; y( I  * Redistribution and use in source and binary forms, with or without modification,/ ?! U. b  X, ?4 M: H( B
  * are permitted provided that the following conditions are met:; D3 [- n) Y' ?
  *   1. Redistributions of source code must retain the above copyright notice,* L% f" D' K9 a7 `' {0 i
  *      this list of conditions and the following disclaimer.
1 Z7 J0 v' Y" J. M3 C  *   2. Redistributions in binary form must reproduce the above copyright notice,
4 e; L! o9 S, R7 C$ ]) d  *      this list of conditions and the following disclaimer in the documentation
; Z) r& U2 g+ B3 J+ d' b/ W  *      and/or other materials provided with the distribution.0 P. J* _, j: l- X5 [% p# u3 ]
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
% |# ^2 p) ~* A. L5 P7 Y; w6 s, H/ C3 @  *      may be used to endorse or promote products derived from this software4 ^) r$ _0 r& G# F" B' e2 `
  *      without specific prior written permission.
" V% Q$ B1 R0 a% B9 O  *
7 o: F7 H0 Y+ y  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"8 F2 r; ~9 Q! |: v4 f. E$ F
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% T1 _# d# C0 _6 Q* a. r  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE! U3 R4 G8 j( ]/ J% G2 [
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE7 X. B* [$ {2 s( S' b
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL; t7 m1 b: {& x1 @* Y; w$ J  Z
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  o1 c' B9 N9 [' O" T& L3 O1 _  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
3 ]/ ~% p3 e) X2 {  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
" X9 W& Y( D, E) y7 M4 x2 S  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
8 k2 o- y* e5 N  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.( t( D/ Y; b5 x. `4 r0 ]
  *8 }+ l4 p0 X6 J1 A: g
  ******************************************************************************
% e' ?( U: O- Z& V( J7 w! Q  */$ Z" O3 l' W+ n/ u/ }5 }  ?
% ?* T% b* h6 o: I0 }" V/ r

+ g5 ]( X3 f, l2 T1 I/* Includes ------------------------------------------------------------------*/
2 N: l% G! p5 H9 o( N#include "hw_config.h"' l5 V  y- n3 Q8 U- }7 d+ j
#include "usb_lib.h"& v' H0 t7 q+ x8 T
#include "usb_istr.h". [! M* _. C( r# {& h
#include "stepper.h"
4 c: N! n1 E- f6 r' B3 U. F( e! K#include "string.h"
7 n2 Q5 L( A+ ?2 @  n, |3 b$ W5 _+ q. X( |6 t* f
#include "DAP_config.h"0 k% r2 h! \: E5 r! _
#include "DAP.h"4 m* N7 D( m6 g8 [, G: D: S
: M& X9 m$ n2 p1 h
3 ?" j8 ]2 D) V7 N7 x
/* Private typedef -----------------------------------------------------------*/7 f6 D5 b! R% o
/* Private define ------------------------------------------------------------*/; l: I9 T$ e5 W1 \8 {
/* Private macro -------------------------------------------------------------*/
: q1 ~9 o+ u8 h7 E, U/* Private variables ---------------------------------------------------------*/
  F) p/ ~: P# ~5 U9 O' G4 Zstatic volatile uint16_t USB_RequestIndexI;     // Request  Index In- f/ `0 c5 N9 i8 g
static volatile uint16_t USB_RequestIndexO;     // Request  Index Out3 a; ?# h  @# ], B7 d+ z2 t1 s' h2 |' l
static volatile uint16_t USB_RequestCountI;     // Request  Count In
* K( G  w4 O$ ?- Y/ C# k  |static volatile uint16_t USB_RequestCountO;     // Request  Count Out
/ y. }  G5 @% |/ n9 lstatic volatile uint8_t  USB_RequestIdle;       // Request  Idle  Flag. t. Z. m  K6 P

# X- A! p2 [2 B3 i+ p, Pstatic volatile uint16_t USB_ResponseIndexI;    // Response Index In+ G% i$ O! B) U7 H7 x' ^* u" x2 A
static volatile uint16_t USB_ResponseIndexO;    // Response Index Out
, l6 C2 J! [$ O3 ~  Xstatic volatile uint16_t USB_ResponseCountI;    // Response Count In  ~) k' f# B  d# O0 \8 j6 x
static volatile uint16_t USB_ResponseCountO;    // Response Count Out  R# {' g! O' O' Y0 k0 M0 z
static volatile uint8_t  USB_ResponseIdle;      // Response Idle  Flag
* }% y& M+ S5 n) W+ h7 ~6 gstatic volatile uint32_t USB_EventFlags;: Q; ~! A" D8 P3 [" a( M
4 J3 W5 L$ y( B% k( f/ p
static uint8_t  USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Request  Buffer3 b3 C; I& h4 W
static uint8_t  USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO")));  // Response Buffer' c0 z- r. V* a! Z+ F& q! j
static uint16_t USB_RespSize[DAP_PACKET_COUNT];
, Q% s$ m5 v& E# C
0 ?4 j; b1 a! w/* Private function prototypes -----------------------------------------------*/! h9 L! A+ @. a" d
/* Private functions ---------------------------------------------------------*/
6 }# F: E* M% a: P1 R) q/*******************************************************************************9 _( A7 _/ n& V
* Function Name  : EP1_OUT_Callback.
: T9 M: H5 J/ Z7 S* Description    : EP1 OUT Callback Routine.
: E( K" l( |: ~. ]* Input          : None.
, ~2 c5 M6 i9 @) z* Output         : None.& r" Z- |0 N/ J4 @) v( B$ {
* Return         : None.; Z8 f4 l' t+ n$ W( e
*******************************************************************************/
' _2 S4 U9 W  g- E2 Hvoid EP1_OUT_Callback(void), F& _1 N/ M* K5 A; ]1 k- J
{( W* R  X4 z7 t5 ]3 ]
        uint16_t n;
" G0 y3 a: }0 m& k0 z) Z1 ^: i& t( l4 e
        n = GetEPRxCount(ENDP1);1 j0 Y0 O# A0 `) T3 i5 n$ [. ]
        PMAToUserBufferCopy(USB_Request[USB_RequestIndexI], ENDP1_RXADDR, n);
+ i6 \* \, w3 r9 W% S        if(n !=0){
* }. K* s- _; I' y# j# s                if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {8 Y$ w& {5 j0 Z( E$ @, p# a8 u
                        DAP_TransferAbort = 1U;7 r9 s/ {8 ~" U7 I! N" @' o0 v0 W7 q
                } else {* U5 I- x7 ?) u+ w
                        USB_RequestIndexI++;
, N& _* u2 ]3 I* `% W% V+ v' ~      if (USB_RequestIndexI == DAP_PACKET_COUNT) {
6 Y/ F! ~6 B* W$ g                                USB_RequestIndexI = 0U;7 ~( F, a8 ^6 C
      }* `5 B  W) E: K8 B& N" N0 x
      USB_RequestCountI++;& r  v% X2 q" p& q* L
        USB_EventFlags = 0x01;' X- @9 {& x0 C! z
    }5 r# b1 J: J# b
        }        5 O7 }4 u, |. V3 o1 c3 F+ }
        // Start reception of next request packet+ f2 c; L, R7 u% J; w- s
        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {# `) o+ [! S* {9 R2 h3 I$ D
                SetEPRxStatus(ENDP1, EP_RX_VALID);; r0 [9 K% Z' L# s8 n
        } else {
1 f* R, h! w& h/ v. }6 A                USB_RequestIdle = 1U;
, z% v: S, q, L8 \, H5 @& J1 D        }                        " @) p+ l+ V8 [  X3 V0 z5 {& j& i
}
2 U0 ]- n4 I2 {1 q2 t) B9 Q2 _: e
/*******************************************************************************3 E- S+ l  m1 ^+ V# ]; l+ v) `7 i
* Function Name  : EP2_OUT_Callback.; C8 K* ]  l5 b6 v( k
* Description    : EP2 OUT Callback Routine.  u6 v6 @& ]7 e4 }
* Input          : None.
5 U  S+ T% Q; _& o- J5 H* Output         : None.  D: }; P! h) X4 a. H  |
* Return         : None.; j/ I0 G3 n% T$ ~! w
*******************************************************************************// u  ?" M7 k9 J0 X  r* [' ^" v
static volatile uint32_t TX_n;: m$ e8 H% C  t; l8 r3 E- {) C
static uint8_t *pbuf;& n( L5 n* Z  m* J/ t7 D
void EP2_IN_Callback(void)1 {  j9 q! U" j; Z4 @' u
{* T* _  t) G5 s
        uint32_t a;2 H& \( x. [" i' a9 I9 z
        if(TX_n>0){
5 b% J% m" t, z  n+ I/ A                pbuf+=64;7 f' T" z3 U% ]' M1 b4 {
                if(TX_n>64){7 K) d; R9 P2 O) b
                        a=64;5 l' e* W0 d1 u( a
                        TX_n-=64;
2 M& w3 m( g+ N: e, Y( a                        
9 i2 E" n! b9 G                }else{
, W4 ?( e: K& B* `* r+ I8 G( _( y                        a=TX_n;
  D+ V; l: v# I! J                        TX_n=0;- Q* S% p3 ~+ u( k$ k9 g
                }& N1 m. G& t' A% P9 D
               
! t: }3 N7 X( I        UserToPMABufferCopy(pbuf,ENDP2_TXADDR,a);
5 n( _* V$ b' ~/ T) |        SetEPTxCount(ENDP2,a);
. j+ e! }* I" F: q1 _0 h5 D6 w                ' o0 e4 E/ @# Z
        SetEPTxValid(ENDP2);, v0 b# v) L+ R& L7 o
        }else{! T4 H; V+ F" x/ x. {" g
                #if (SWO_STREAM != 0)
- @+ o  f  E! C3 q                SWO_TransferComplete();2 S1 Z0 v1 m- p' J5 }- |8 r
                #endif. E- Z' l+ g2 ~' c7 O+ X/ ]
        }
; B* E8 M! W1 W2 `0 Y& @}, s6 E5 w5 }& H# r+ W0 a! z% L
+ t7 o. j( B0 G! A) N
/*******************************************************************************
: i! l3 E3 S3 i" R: F# {: H* Function Name  : EP1_IN_Callback.
: R  O! b# c5 t( T/ f: Y* Description    : EP1 IN Callback Routine.2 E, X4 c0 D6 N* {
* Input          : None.! c: Z; G6 ]2 x5 T8 p* h9 W# B4 Q
* Output         : None.; @6 n, z" ]$ B& d
* Return         : None.3 ?& u- B( O4 m+ R3 A
*******************************************************************************/; K5 F# r, J6 I9 M% @
void EP1_IN_Callback(void). j% E  s+ a% V3 s- f  z
{8 \/ Z  i; w* ~
    if (USB_ResponseCountI != USB_ResponseCountO) {
# ?: T% o; W6 ^      // Load data from response buffer to be sent back5 I$ y6 r3 d+ T2 I
                        UserToPMABufferCopy(USB_Response[USB_ResponseIndexO],ENDP1_TXADDR,USB_RespSize[USB_ResponseIndexO]);
5 K' U7 J; T- _+ D0 T9 c2 E                        SetEPTxCount(ENDP1,USB_RespSize[USB_ResponseIndexO]);2 }% t. t" b4 n
                        SetEPTxValid(ENDP1);                        1 }0 V5 A4 c9 S$ {
      USB_ResponseIndexO++;6 n. t; f+ k3 [4 I, q+ Q  G# i
      if (USB_ResponseIndexO == DAP_PACKET_COUNT) {% |( [9 J2 ?4 O1 I. ^
        USB_ResponseIndexO = 0U;* s0 x' H; Q  E3 A$ d& P, Y2 V( ~3 u
      }1 _" ^; R1 n2 n* O+ q& t# v
      USB_ResponseCountO++;
# K* m# S+ Q! O  i    } else {
3 `1 E3 `# j7 r# o( P& N3 {- t# E      USB_ResponseIdle = 1U;
& x9 k: }7 ]. V/ c7 `    }  
' a4 Q$ p1 J% E" i# J}
2 a$ ~$ ^: f2 k/ K( |/ ^/ Z) H7 E2 R5 l+ `/ N4 F5 V( V
// Called during USBD_Initialize to initialize the USB HID class instance.7 }; x8 l5 g1 i8 ?2 z+ q; e
void DAP_FIFO_Init(void)
1 N2 T( Z0 a& s1 Y% j6 U4 d" D{
4 L# {5 V3 {. f$ j! v3 A( {/ c+ i* d    // Initialize variables) H' u  ?/ n( b8 n( w3 r# p
    USB_RequestIndexI  = 0U;
; @" u' R8 e. Y5 E4 y4 e    USB_RequestIndexO  = 0U;
; n* j9 Y' L: K) p% ]  ]/ K) _    USB_RequestCountI  = 0U;
' D: X% X8 Z, _+ Q+ T    USB_RequestCountO  = 0U;; a3 y$ i/ m) j% B, j/ E. M2 ~3 X5 w
    USB_ResponseIndexI = 0U;. B1 i! W6 p  U. T0 Z) a
    USB_ResponseIndexO = 0U;
3 w# }) j: Y8 h% @! g* z, \4 g$ U    USB_ResponseCountI = 0U;
& D# k9 O% N, @    USB_ResponseCountO = 0U;
2 r3 d' X0 x' i% }! o9 `2 B5 z    USB_ResponseIdle   = 1U;
/ r- k  L. \+ d( H    USB_EventFlags     = 0U;% T) [: L! S# ]/ G. ?2 m+ r
}
: t1 I) q" y3 c2 p* `* x4 H% b5 [9 R7 a! R/ X. w8 h$ e7 r
uint8_t DAP_Thread (void) {% u* ?* x- e4 {) F# f
  uint32_t flags;
# a( r- q$ s, g, M  uint32_t n;) [4 E7 W* d# _

" [  m7 w. I) Z! K6 C  //for (;;) {
6 h1 ^9 E0 ]& b  //  osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);
4 B% x& d* \4 ~$ O  [, j                if((USB_EventFlags & 0x81) == 0)6 y: g  P2 X$ n9 T2 e9 B% U
                {
$ d0 D0 }+ p% S0 a. {6 R                        return 0;. [, b) Z: s! Z$ `* b; N& P! {
                }
7 E, ^8 g! ]: s+ N! j                USB_EventFlags &= (~0X81);: `' O6 K$ k, Y1 e9 X# F. ~" W1 O
                4 B& Q& i6 P7 D' D1 w) n
                                       
: `8 [  n* j% i9 k    // Process pending requests
6 R) n; f4 o' |5 ~8 E6 b3 J    while (USB_RequestCountI != USB_RequestCountO) {/ c. X3 n( }( o) ?/ S& Q5 C
                //if (USB_RequestCountI != USB_RequestCountO) {- }1 e! j: q: A; K( |( q! E
      // Handle Queue Commands
: A4 ?# M' j; n5 U9 |: y0 W      n = USB_RequestIndexO;
; m' l  i. ^( ]. e! t# O, c      while (USB_Request[n][0] == ID_DAP_QueueCommands) {$ W7 z0 S& o2 W' `- p7 S
                                //if (USB_Request[n][0] == ID_DAP_QueueCommands) {6 b( j: o* P9 u, C( J, f0 p% q
        USB_Request[n][0] = ID_DAP_ExecuteCommands;3 w5 W. {) i* h$ k/ C
        n++;) N- A2 E; I7 S8 l7 P+ h. h- z) Q  l
        if (n == DAP_PACKET_COUNT) {* [: }3 q2 ?/ D; K6 o/ h, r, }' d0 |
          n = 0U;9 K. n0 p2 m* o/ R2 l2 z6 r
        }
. K& G/ A: @/ n. L1 z) u5 R        if (n == USB_RequestIndexI) {. [7 i+ v8 `2 D, N* D
          flags = USB_EventFlags;. I; S2 W4 z1 u' [3 [1 d
          if (flags & 0x80U) {
+ ?1 T4 K$ k2 p$ a            break;
3 j' z- c) O  |- t: Y          }
) W* U5 ]' A- v2 d        }
- K( z" g% }7 N0 k" ]      }/ O8 t# P8 A$ E% i7 L: p' }" [
* @- h. K; Q4 p3 c6 [; y( ~
      // Execute DAP Command (process request and prepare response)
! T. }# r* o3 _3 M$ x1 G. b      USB_RespSize[USB_ResponseIndexI] =
/ s" A* x: ]9 L  h$ L; i* s+ {3 w4 C        (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);* B" z" b; W* O, E1 I) {

1 I6 j4 B# x! Z' l9 V      // Update Request Index and Count
' `6 {* J, p) T& g' |# E      USB_RequestIndexO++;
+ T) g* U" `$ Z7 G! q, i      if (USB_RequestIndexO == DAP_PACKET_COUNT) {* S# _9 U# T2 n- `- C6 b
        USB_RequestIndexO = 0U;
0 u1 k5 k! [9 z      }1 d' H( I# Y# Y; w
      USB_RequestCountO++;
, ?- R5 b! i4 g: d1 t" _# m. v. w% K' T7 X
      if (USB_RequestIdle) {
8 }( B) l7 L. x        if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {3 i: Z9 z: y" w" Q
          USB_RequestIdle = 0U;
1 ^- s* H4 a8 k8 b1 J; I          SetEPRxStatus(ENDP1, EP_RX_VALID);0 S% c8 X  F6 Q+ w' u9 s
        }! |2 N% K( h4 [) H9 e* }& ~$ x
      }
2 Y# H- N/ n& u
5 y; R4 C& W( [! g: R      // Update Response Index and Count
( Z0 a2 {6 u2 g* p. m      USB_ResponseIndexI++;: V* J, q  O  B1 e' _0 R
      if (USB_ResponseIndexI == DAP_PACKET_COUNT) {
$ V9 h: M$ x, z; T! t+ c7 w% e        USB_ResponseIndexI = 0U;! C; r- P8 P' F. {/ _7 q7 G
      }
% R( y% w1 `2 i3 W: B! a1 M4 F      USB_ResponseCountI++;+ |( L0 {2 O  X1 m2 A1 G; y
/ {1 p2 s) c+ b: ?5 i4 D( W# s
      if (USB_ResponseIdle) {) M, n6 l+ N# ?" o: R8 G
        if (USB_ResponseCountI != USB_ResponseCountO) {7 m0 s5 j2 I6 w. h3 m/ P2 J
          // Load data from response buffer to be sent back
( K3 A7 @7 ]- J+ p; ^          n = USB_ResponseIndexO++;
( S- h3 \- y) \8 J" a          if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
$ d5 H4 i$ J* B: ~* n9 D2 j            USB_ResponseIndexO = 0U;
, `+ C- g* e* ]' k+ ^9 T          }
/ w( g1 t- R& I1 `          USB_ResponseCountO++;
  U9 K9 _. t, o2 p! W1 c% [          USB_ResponseIdle = 0U;
7 }% ~% d( T( ?; E/ [          //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);% Y" L' w2 V! Z
                                        UserToPMABufferCopy(USB_Response[n],ENDP1_TXADDR,USB_RespSize[n]);
6 F: ]) @- C$ c4 h                                        SetEPTxCount(ENDP1,USB_RespSize[n]);
6 H0 O/ a+ V) U2 Y5 _2 }; l; s                                        SetEPTxValid(ENDP1);
4 U' P5 \7 G8 d6 f' o  ~# O        }
$ _" w1 @0 g. l* Q      }
3 V; b' y6 E, l, _) }    }
+ |' L! t& W' ~- U        return 0;
2 z6 d, B' y. i" O' D}
  G8 b, ]5 C% L
9 k& L% r. V& D1 m# U// SWO Data Queue Transfer* P; c: U' j. N
//   buf:    pointer to buffer with data( Z$ P* f- I2 y% e# Y' k$ m% q- I
//   num:    number of bytes to transfer& [% F* d+ r1 n) A% L9 A2 P
void SWO_QueueTransfer (uint8_t *buf, uint32_t num) {3 B8 `" A5 N, Z2 l1 {
  //USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);
2 \+ ~7 m; V1 C) {" p        uint32_t a;
+ K. U5 X7 f/ m  s) f) L4 D( Q        
0 ]: ^2 V' q, E! ]7 g+ g- ]8 }% P        if(num>64)
: t7 h; v5 L9 t! e) e. m) ^        {
: [; a9 e& }3 q  j3 T" H7 }                a=64;
) {  @& B# T& s$ \  O- y4 l8 k                TX_n=num-64;
5 G6 X1 S, }6 w6 b0 x$ k                pbuf=buf;2 H9 \* I: Y+ K2 F8 Z0 p% w% U
% L+ J' O' d6 J& P. N0 Z: R7 u# Y
        }else {: J; ~- C" C% f& n& u
                a=num;
# D1 K. d8 i( R: r$ l! {                TX_n=0;& O: L0 ~- A& s+ [$ {( c; n
        }$ ], `. X; \4 U) w0 I* t
        UserToPMABufferCopy(buf,ENDP2_TXADDR,a);& ]0 u8 V4 B% X/ u; C8 I
        SetEPTxCount(ENDP2,a);
, C( L% K" B( l+ z; }        SetEPTxValid(ENDP2);7 e1 S5 _! L# b* k4 ~' a6 V+ I
}- I9 \1 c& Q  \, z' z/ ]3 G

& j# p: V; h& \% O// SWO Data Abort Transfer9 s* X( L. O  S: _
void SWO_AbortTransfer (void) {, ^- \, b) ]3 f
  //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
; [7 o$ r! h- D! {0 _" H5 p, A1 b        //SetEPTxStatus(ENDP2, EP_TX_NAK);4 [( k% i9 M  o( d; C- [8 p
        SetEPTxStatus(ENDP2, EP_TX_DIS);
1 W+ N6 \- X. {" I! D        SetEPTxCount(ENDP2,0);
/ K+ t" b0 E* a        //TX_n=0;
* k+ E$ f: g: t9 J) [' q}
6 H2 T: {  G& I) l- ]7 g/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/. l& T6 f9 Q: v, n8 Q* Y  b  I
- L9 f8 A; }/ X4 u+ C- U3 E* {4 I0 N
移植大概是这样的,利用STM32_USB-FS-Device_Lib_V4.1.0里面的例程Custom_HID修改为自定义USB设备,3个批量端点,OUT,IN,IN,由于批量端点不像HID哪样要使用报告描述符号,但要让WIN识别出驱动,添加了WINUSB相关的描述符号,在端点回调里实现DAP的FIFO处理,然后把DAP_Thread里面的线程调度修改为标志通过,放MAIN主循环里调用,测试SWD下载程序,调试都完全没问题,时钟设置为10M时感觉速度还是可以的,这能体现批量端点的好处
& J1 G6 U# U" \) JDWT部分即TIMESTAMP的时间参考,由于没使用Keil的核心库,得自己对相应的寄存器进行开启,而且3.5库的core_cm3.h里面没声明这个寄存器,只得自己定义一下了* a# q/ X$ k; u+ p4 s
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {' ?3 Q% g$ n; r0 L2 w
  return (DWT->CYCCNT);
. N5 T" F0 O$ K; o3 R}# E, r7 B  q$ C" [$ _

; V+ C4 U& l1 d, U0 t. c, f# |9 Kvoid DWT_Init(void)
2 T" j4 ]+ x3 X{
# E2 a( R3 H5 n+ _) N    /* 使能DWT外设 */
; A7 F; C' \; B- _0 @6 L    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;               
9 N0 {- O, C* |6 h2 m3 W2 k- ~# g
    /* DWT CYCCNT寄存器计数清0 */
% W% j2 j) c* C# L    DWT->CYCCNT = (uint32_t)0u;/ M& @7 t9 V1 Q5 [2 F7 B
/ e7 W3 `+ B3 m7 l( ?* A
    /* 使能Cortex-M DWT CYCCNT寄存器 */
9 d5 X" j% ^4 i1 z2 [; S    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
, L7 g5 N: y8 ]7 f4 |4 k}' W3 ]8 d( l9 t2 o
        
9 f' y- v/ i1 @3 k" k% D4 |1 P! v1 h
然后加入了SWO,SWO有个SWO_STREAM传输方式,在不使用这种方式时,开启了SWO调试后单步调试时能正常打印信息了,但是当点全速运行后感觉像卡住了一样,要等非常长的时间才会在断点处停下,如果程序没有下过断点,点全速后就会出现Keil卡死,也不知道什么原因,看程序代码像是在调用SWO_Data时被阻塞住了一样,而且在等待的时间里操作Keil像是也没法动一样了,非常慢一卡一卡的,进入了断点停下后就没这现象了,此时单步也是正常的,也就是说全速下,SWO有问题了,但在没开启SWO时调试和响应速度哪叫一个爽的啊,SWO部分的串口是直接搬了DAP例子工程里的串口驱动代码进去实现的,不知道是不是这个原因导致SWO被阻塞,或者自己另外写串口驱动提供给SWO,另外串口波特率最高只能2MHZ,超过这频率,SWO打印信息打印不出来的,串口波特率就是在Trace设置页面里看到的SWO 频率+ O# Y4 V! N9 {. x, ?) Q  c) Y7 q4 Z
3 A$ p, ~, n( v$ [
然后改为使用SWO_STREAM传输方式,这种方式是单独使用另一个IN端点进行传输,即DAP的命令调用SWO_Data时只取走了SWO的状态,没取走SWO读到的数据信息,数据信息通过SWO_Thread通过另一个IN端点发送出去,SWO_Thread也是把线程调度修改为标志式让行的方式,对于50毫秒超时处理部分没弄,就这样放到MAIN里的主循环轮询调用,换了这种方式后,SWO单步调试,全速下也能打印信息了,而且全速下不会是卡住了,响应速度就与没开SWO时一样的效果,即没了被阻塞的感觉了,非常爽快,所下的断点,按一个F5马上能停止,非常快的响应速度,但有时候Keil底部状态条会提示Trace:dataOVERFLOW,查了一下这提示说是SWO端口读取太多的数据,导致被截断,具体也弄不明白哪里问题,另外手上使用的自制JLINK V9,开启SWO时,SWO时钟是6.XMHZ时钟频率的,而且连接上芯片后,打印信息啥的都正常的,而且不会有报错等待问题,在想这会不会JLINK的SWO接口是使用SPI做的,毕竟串口这个时钟频率能正常工作吗?DAP里的SWO能否改为SPI接收,因为不使用SWO_STREAM传输时会被阻塞住,很大原因是串口时钟频率太慢了,这估计得研究一个SWO的接收协议才行,个人来说SWO方式还是比较实用的,有人会说会占用一根IO,但要说使用串口进行调试不也是占了一个串口,但又会有人说JLINK的RTT不香么?
+ v/ D" l( S8 E; E) h1 S声明这个变量static volatile uint32_t SWO_EventFlags=0;
9 q: {9 B5 M/ k- ^; }在SWO里每一处调用osThreadFlagsSet的地方都改为如:7 O4 O# q7 M! r$ j3 i& K, Z
//osThreadFlagsSet(SWO_ThreadId, 1U);2 n  U6 }6 r! ~- k3 I
SWO_EventFlags = 1U;
! n/ o, O9 V1 M0 `1 T% H) x
3 E/ e- n+ s3 w* D8 H" L6 K' x8 U+ _% Y) \. I$ F3 ^# J9 p( c
// SWO Thread
* j# Y# _  l6 x3 d( Z$ A5 b/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {: l; z( i& q$ R9 m
  //uint32_t timeout;7 z3 }% A( b3 P7 {( n5 z
  uint32_t flags;' {9 R9 H. r; v+ Q# S- x5 ?
  uint32_t count;
& {  O' d7 r2 {: R  uint32_t index;8 g! \- G& Y8 I4 J9 K9 ~
  uint32_t i, n;
, i$ J: Y( r( H8 j7 x3 H  //(void)   argument;
# ]) e- L0 |' d+ t) k- \6 U+ a9 j/ J" \$ ~/ F9 V/ D  B0 u+ Z- n8 y
  //timeout = osWaitForever;
- S# J6 _3 x! G
8 z2 ^( B& O& ?4 i  //for (;;) {
" t1 ^' J2 t* M7 O1 n* t    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
" ?  K( V3 R. y5 X% J6 f4 |                if((SWO_EventFlags & 0x01)==0)return 0;
8 F$ g( F" V7 U+ u" C! d# D7 P) @         
1 o& R# p2 u, H% z& S. o; C. m( }                flags = SWO_EventFlags;$ u& @! e/ d3 H
                SWO_EventFlags = 0U;
, R1 ^+ S8 d, A    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
3 d! l6 w2 ]! ?      //timeout = SWO_STREAM_TIMEOUT; 这里是对于进入了SWO_CAPTURE_ACTIVE状态时就把线程超时设置为50毫秒,大概意思应该是osThreadFlagsWait到达这个超时时间后,不管标志是否切换为1U,都放行SWO_Thread调用一次,timeout = osWaitForever时相当于无限长的超时等待1U标志,对RTX不熟悉,不知道是不是这样子
. X  F) a; D/ o% i  o                        ;4 p! ]+ ^7 F3 _6 j8 X4 l$ s- n4 }/ P( q; ^
    } else {% X0 Z5 ~6 h' y; p$ c
      //timeout = osWaitForever;
3 Y* b( q) }" z5 o/ T      flags   = osFlagsErrorTimeout;
" M0 @- ]1 [# K* L    }9 H5 j9 {+ W8 D  Q. l
    if (TransferBusy == 0U) {
) W6 F, I7 m; m& y- k4 T- n$ d* B      count = GetTraceCount();
# C9 M( F# g: x" s1 {  o* I6 m      if (count != 0U) {& i: N$ T5 ]: u( M7 k$ p; r
        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);; r; O: X7 U$ K$ I; f
        n = SWO_BUFFER_SIZE - index;
  I9 g/ N. n2 |0 G& i2 b$ C        if (count > n) {
8 B; @. M5 {  t7 \5 u; a5 M          count = n;3 I8 e1 {0 B3 F! ~& b0 w' X
                                       
+ h1 K0 o: N  a4 {        }% F2 i" o4 G% Z7 n# q% ]: U
                                if(count>USB_BLOCK_SIZE)9 N" |: G1 m! g! v
                                        count=USB_BLOCK_SIZE;3 j3 A/ d2 d/ s; r; A8 U2 \2 N- v
        if (flags != osFlagsErrorTimeout) {2 g' {/ j2 O; R; t5 a
          i = index & (USB_BLOCK_SIZE - 1U);5 B+ |/ n5 c5 N3 w
          if (i == 0U) {1 n4 _, ?* [' v! C7 ?$ X! p9 G
            count &= ~(USB_BLOCK_SIZE - 1U);2 C2 W  Y1 g) A, @7 M4 m: B
          } else {0 P$ O! {* z5 i( s3 W
            n = USB_BLOCK_SIZE - i;( ~( z( p+ Z8 r9 ]0 \. ^
            if (count >= n) {
8 }9 h0 g. @0 Z1 J              count = n;& K% c  A3 A1 P) h) c2 \
            } else {
" V' I9 `7 _8 e* W9 \7 u5 c              count = 0U;8 j- u* f, p- S* P
            }1 b" E( R: v4 g. J! [* {
          }4 l0 K8 p3 I" O- f8 u
        }/ O/ _- ]+ G; R1 E
        if (count != 0U) {
, O# a. E" B6 }: z  r( g  E          TransferSize = count;9 ^9 o& G$ c: V
          TransferBusy = 1U;
; U" N9 i3 x! d  @. {          SWO_QueueTransfer(&TraceBuf[index], count);
( N7 o6 i. k5 u& a        }
9 B# K/ t$ [5 L* t      }& v, P% Q( C$ Y' A3 T" ?
    }, {6 a6 q7 }. R; d0 L) l
  //}
* k) u# D7 X& |# p) r) q                return 0;. J5 Q9 U6 @8 v
}
' V, l) |9 S) Y5 e  A  L利用DWT增加超时等待,先声明变量timeout也在外面声明#define osWaitForever         0xFFFFFFFFU ///< Wait forever timeout value./ C& _1 F5 E! F0 W: ~
#define osFlagsErrorTimeout   0xFFFFFFFEU ///< osErrorTimeout (-2).
" [: i  g2 y- ^3 dstatic volatile uint32_t SWO_EventFlags=0;
/ O' v8 f% X3 Q8 cstatic volatile uint32_t timeout=osWaitForever;
  a# i' |$ X* k4 a2 r# tstatic volatile uint32_t timeWait;
' a  O, {/ Z3 K' u( t函数改为这样
. D" J0 I, B2 w  l2 @/*__NO_RETURN void*/uint8_t SWO_Thread (void ) {5 M- ?3 |! I! O# Y
  //uint32_t timeout;1 J7 L$ Z5 p- p
  uint32_t flags;
! c3 Q5 G9 v7 T, Q  O  uint32_t count;
+ ^. G" Z4 M4 U$ [  J. C/ b4 r, O  uint32_t index;
+ l1 w7 G- K' G, n1 m$ s+ r) O1 \8 i% O  uint32_t i, n;
( ?% b7 Z* t3 J! |  //(void)   argument;1 x( V( _/ B# u7 g
* y/ C- g/ n4 Y% Y4 o1 z- R& |, C
  //timeout = osWaitForever;
" @9 w& @, M/ V" K4 u
. o: B5 G8 T) c; R, N  //for (;;) {% o. M6 G7 R9 B. E. k
    //flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
, ^! _, [" ?: H& N7 m, f                if((SWO_EventFlags & 0x01)==0)
6 X# P$ @1 V2 w# O7 F                {
0 K  R7 o( q# T2 E( {& y                        if((timeWait-=DWT->CYCCNT)/72000 < timeout)  //少于timeout时间值直接返回,DWT->CYCCNT由于这计数值是按72M时钟计数的,所以72000就为1毫秒,0.001*72000000=72000,由于是与DAP处理是顺序执行,这个时间无法准确在50毫秒,但总来说与跑RTX系统 的超时等待差不多原理了
, B  {+ a6 O6 h0 N5 n                        return 0;: x, U* l) j4 q7 t
                        
5 g# b! c* A) Z, C  j( k                }
. a+ K/ S$ F! A: y! l4 o3 I         
3 D  y% v. N- D) I% o6 K                flags = SWO_EventFlags;
# ~4 }% Q  F. h: x, D                SWO_EventFlags = 0U; & _2 ^% i/ m# i- w  ?1 w
    if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
7 G+ N8 Y$ x3 k  x: h  `      timeout = SWO_STREAM_TIMEOUT;
, v4 Q3 r, B# s. m3 h      timeWait=DWT->CYCCNT;
. ~" D! R  F/ o3 D+ y0 Y8 Y& |    } else {& t! F% J6 k1 ]% K6 o  m( p* j
      timeout = osWaitForever;: m( i) r5 w+ S& T; [/ p: Z
      flags   = osFlagsErrorTimeout;
* E; Z7 H+ U# {/ \7 h    }
) a5 l) D- W" c$ A; a* Z    if (TransferBusy == 0U) {7 J  k$ c$ U; k; i8 g0 c. x
      count = GetTraceCount();+ Y4 l* O$ k( _& y/ p
      if (count != 0U) {
" q5 ]* f% c6 x: Y% M9 x9 B/ P        index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);8 f' X/ S- T+ r: J5 n! W& C
        n = SWO_BUFFER_SIZE - index;
$ o" L, R4 F. c3 ]& M$ \! m        if (count > n) {' `" N5 w/ g9 ?1 y: P8 e
          count = n;1 a! D$ R3 z! Y
                                       
$ H: X" f1 g5 u- K( Y* G( ^# ?        }
$ Q0 K, o* Y8 M" D4 |/ ?                                if(count>USB_BLOCK_SIZE)
" P/ z8 V) U0 N: _5 i                                        count=USB_BLOCK_SIZE;" c* z8 `2 G( l  ~. D3 f6 I
        if (flags != osFlagsErrorTimeout) {
. I5 A4 i, p9 x2 {/ W9 s          i = index & (USB_BLOCK_SIZE - 1U);/ X9 f) a7 q. ], c+ K* S) `9 B% h: S
          if (i == 0U) {# w# ?3 U7 d# K2 _: V
            count &= ~(USB_BLOCK_SIZE - 1U);
& s* z! n' V7 \+ Y/ C2 U          } else {
& ]9 l0 ?9 _% W. c7 }! j5 [8 q3 C, u            n = USB_BLOCK_SIZE - i;" I$ r8 q9 i# e5 e. k% p/ V
            if (count >= n) {
  `/ j# u% m& a# V, T& ?' f              count = n;6 J7 T) D! ~; s$ n
            } else {, H6 r+ B; q: u1 e# R. r
              count = 0U;
- D: g8 ?0 u9 ^$ q  m. w+ U            }( O% W* L" ]9 G7 u+ h) |
          }
3 n1 j# C( R; e( i# f1 l" }1 A2 X( ~$ v        }" I4 @& A: \$ Z7 {6 w8 n5 L* T
        if (count != 0U) {$ L2 d2 n. R+ I: E0 {' x
          TransferSize = count;
9 |9 J0 w2 m+ V          TransferBusy = 1U;7 Y+ ?+ j0 b. B! I- r' F& e
          SWO_QueueTransfer(&TraceBuf[index], count);* H& \" |4 I. _5 t% M
        }; L: s- Z/ H% v! s
      }
3 N6 A$ \/ i( P( S. C$ J1 T- N* j    }2 S4 R7 d1 G+ t( _9 H1 u0 }; g- _6 l
  //}
% ?8 k4 X8 J4 R2 u& X' @# f                return 0;
$ q- r% H  p* \- O}这样修改后也不知道能否解决Trace:dataOVERFLOW,也是刚想到的,试了才能知道了,另外还要说明一下,USB_BLOCK_SIZE是声明为512字节的,即SWO_QueueTransfer(&TraceBuf[index], count);时,如果count超过64字节后就得要分包发送了,这个USB库发送部分得自己分包发送,上面的SWO_QueueTransfer发送代码和端点回调处EP2_IN_Callback已经加入发分发送了4 x( Q3 o) u4 G
) e& e) r6 R# S) b! |5 E
CDC部分暂时还没加入,SWD现在是非常稳定的,而且速度感觉也是不差,就是SWO的问题不知道如何弄,另外看到其它人弄DAP,把SWD读写部分改为SPI,看了一些SWD读写协议,它好像有一个8位一组和32位一组的部分,如果换为SPI是不是就可以更快的速度读写了,另外DAP与USB之间的FIFO部分它有一个队列等待,看意思就是当有标志着队列的包时,就等待接收更多的包缓存后再执行处理,对于批量端点,连续的传输大量数据确实是批量端点的长处,因为批量数据时,端点接收完一包后不会NAK,端点会接着接收下一包,少了一些中间商的处理,也尝试过这个队列等待修改为不等待,即接收一个包,执行一次DAP处理,它同样是能正常运行的,对于批量传输来来说,感觉应该队列等待会提高USB传输的速度,比如下载程序时,Keil 一次性下发多个命令包,比如达到1K或者2K字节或者更多,DAP先全部利用批量端点的优势一次性接收下来缓存,然后DAP才执行一个个命令包的响应处理,对于读写部分构成字节为一组的就使用SPI读写数据,零散的位部分像ACK,SWD复位等待部分用IO模拟来处理,SWO部分感觉如果能修改为SPI接收估计时钟频率可以更高,这样响应速度更快,另外STM32_USB-FS-Device_Lib_V4.1.0固件库的USB端点没有FIFO,不像OTG USB FS 库哪样端点都带有FIFO,但是提供双缓存端点,准备把端点修改为双缓存的,这样当连续多包传输时,端点就不会NAK,少了这个等待时间,能增加端点的传输速率) U& \% g6 v1 k& ^5 Z

9 q3 Y1 D4 ^* A( f6 L; P* K/ o1 v' H7 o# W
int main(void)
/ y3 l5 R" w- v8 j{
( G& n) s2 e& N3 q" z  DWT_Init();$ {4 F+ P) ~1 l8 b/ e( x6 f
        DAP_Setup();
8 T( |; j9 g! v/ P+ h2 j  USB_Interrupts_Config();
! E! [$ [% o; D+ y) p" C2 u$ Q  Set_USBClock();, M# m+ W  N+ y0 p% _4 K! {$ X
  USB_Init();
+ O9 @$ |% r% h        //TIM3_Init(35999,0);; ]8 K1 [, [3 `8 R1 a3 p
        //TIM_Cmd(TIM3,ENABLE);
6 Z. u+ j0 v9 R3 V# \3 ^        
5 h  V" `0 ~: y8 h        " |) w6 n+ D* x" ?, S3 V- T. y
  while (1)
$ M; I4 {. |& d  a4 l! C( R) c  {
! ~, x' B' |1 g                DAP_Thread();
" M% M) |8 P: T  l% V* |2 J                #if (SWO_STREAM != 0)
: Q% T' o  L% n3 Y- T                SWO_Thread();6 t+ q+ `) a: R2 `- J* h
                #endif) g: J' ?; \/ X! M7 Q6 w  d" O+ g
  }  Y2 G; m' E/ C3 G5 S. [
}8 H$ w+ `# @  T' L5 N2 y# h# m

2 o1 q6 j) X0 ~对于DAP_config.h的IO配置我是这样弄的
$ }0 x: c* \7 M  x///@}, [& n, S3 k) d
// Debug Port I/O Pins
- C5 C5 E0 T7 u7 W
& w; Q( O0 j# m- j7 R// SWCLK/TCK Pin                GPIOA[6]# B! j& e! W7 T4 e4 _5 U* \5 _
#define SWCLK_TCK_OUT                       *( uint32_t*)0x42210198
2 M, ^# g% g  c0 Y- @3 x6 H#define SWCLK_TCK_IN                               *( uint32_t*)0x422101185 w; M/ L7 f4 }( G6 W
3 N1 q# F4 W5 P6 m3 ?! `( S5 B
// SWDIO/TMS Pin                GPIOA[7]
+ D* Y4 e) y6 v* M, G, ?8 s#define SWDIO_TMS_OUT                              *( uint32_t*)0x4221019C6 Z7 C$ N; D9 G4 M; X
#define SWDIO_TMS_IN                               *( uint32_t*)0x4221011C" i0 U+ L6 o; ?. f3 d
# i. {* C! f( H+ H4 g; @
// SWDIO Output Enable Pin      GPIOA[7]/ G. J+ [  E/ h" ?0 ?# g( H
#define SWDIO_Output()         {*(uint32_t*)0x4221021C = 1; \
$ q5 V; Q6 ^0 c% P- B                                                                                                                                *(uint32_t*)0x42210070 = 1; \
  k: j6 ^8 r2 ]2 R                                                                                                                                *(uint32_t*)0x42210074 = 1; \
2 {* n5 t8 q& x- e2 e3 K. T& X1 ]                                                                                                                                *(uint32_t*)0x42210078 = 0; \
+ s3 Y6 ]$ M* v0 `' w& I5 D                                                                                                                                *(uint32_t*)0x4221007C = 0;}
6 O( I2 v9 b* y- }0 k
6 {6 l$ z+ @) J4 H1 u" `#define SWDIO_Input()                 {*(uint32_t*)0x4221021C = 1; \* B* I, d7 v) @% V7 N, O
                                                                                                                                *(uint32_t*)0x42210070 = 0; \
4 g. h( W" O0 U9 s, n2 i                                                                                                                                *(uint32_t*)0x42210074 = 0; \
0 s4 y. }+ D: S' M+ Z1 x6 z6 ~8 c                                                                                                                                *(uint32_t*)0x42210078 = 0; \6 n& r. R6 ?  |% l' ^5 t
                                                                                                                                *(uint32_t*)0x4221007C = 1; }
; [- {, m* \: E1 ]1 E
9 B" f$ u+ I6 G3 R9 e// TDI Pin                      GPIOA[8]5 Z- S5 v0 a3 h1 r8 B5 n6 L
#define TDI_OUT                                    *(volatile uint32_t*)0x422101A0& E& `2 }2 {( w( f+ N" K- P
#define TDI_IN                                     *(volatile uint32_t*)0x42210120
/ s, o- b! P) U) h
. ^- f3 m' |8 g// TDO Pin                      GPIOA[10]
! T8 d6 p& b. n- r. B& B#define TDO_OUT                                    *(volatile uint32_t*)0x422101A8) _9 ]3 W( w0 ^
#define TDO_IN                                     *(volatile uint32_t*)0x42210128
7 `% d- G0 X: P6 L# Y, a! T2 u9 m" Y7 h% T/ A2 h% j/ |9 o4 Q, [
// nTRST Pin                    GPIOB[3]
- a% d, Q8 U0 Q" r#define nTRST_OUT                                                                *(volatile uint32_t*)0x4221818C
4 x4 m; g, l& p6 c. Q2 N#define nTRST_IN                                                                *(volatile uint32_t*)0x4221010C: S' i! D* T" [% K* [" D" w; j) X
) @0 p- A2 M: l
// nRESET Pin                   GPIOB[4]; `$ [9 U: g  v
#define nRESET_OUT                                 *(volatile uint32_t*)0x42218190
* x, V7 }4 k6 g* r#define nRESET_IN                                  *(volatile uint32_t*)0x42218110
, J+ W. O4 O& `  k) _0 F1 m' w
+ l3 l8 k7 u0 F  ]7 Q  N// nRESET Output Enable Pin     GPIOB[4]
* K8 \9 Y5 M6 L#define nRESET_Output()               {*(uint32_t*)0x42218210 = 1; \1 c* N/ b+ o0 G$ X6 d* `
                                                                                                                                *(uint32_t*)0x42218040 = 1; \  }8 O. Z" u7 ?
                                                                                                                                *(uint32_t*)0x42218044 = 1; \
& u7 @) t: l0 ?! g: k! e% W# j% W                                                                                                                                *(uint32_t*)0x42218048 = 0; \1 ]9 d& ~/ Y% m6 q' _" |
                                                                                                                                *(uint32_t*)0x4221804C = 0; } ( C2 I) V8 v/ X* }+ k& r' q$ L

/ j# p3 U, i* e2 Z, P3 o% a#define nRESET_Intput()        {*(uint32_t*)0x42218210 = 1; \2 k5 G$ o: [1 e0 R7 ~* z1 {
                                                                                                                                *(uint32_t*)0x42218040 = 0; \, T- Y2 U6 s& r8 y# P2 v' K
                                                                                                                                *(uint32_t*)0x42218044 = 0; \& v! D! y' w4 }. j/ W0 V# J
                                                                                                                                *(uint32_t*)0x42218048 = 0;\% H* w9 x1 `! T  w
                                                                                                                                *(uint32_t*)0x4221804C = 1; }6 ^1 v' x# S% s& ?

8 N/ X( v8 [0 |
& l) {2 V# g8 X// Debug Unit LEDs
* T( ]" U. ~: A7 f, `& f+ S" a+ o5 E1 y% C! q3 c
// Connected LED                GPIOC[13]
' k* T7 |8 R7 J# A5 T' ]5 m. X# I3 n$ l#define LED_OUT                                                      *(volatile uint32_t*)0x422201B44 T: J  Z; p' W
#define LED_IN                                                       *(volatile uint32_t*)0x42220134
% w/ J& L4 \# y& E  i% p( I/ E/ p% l% s* x" n2 s4 n* ]# [- V( v
#define LED_Intput()                        {*(uint32_t*)0x42220234 = 1; \
$ o, }' Y8 B- D$ J" F9 @+ P7 _$ O                                                                                                                                *(uint32_t*)0x422200D0 = 0; \
, G7 p6 m/ `% r6 H( @# L* P                                                                                                                                *(uint32_t*)0x422200D4 = 0; \: X$ w, n/ b, D
                                                                                                                                *(uint32_t*)0x422200D8 = 0; \6 c& {# `7 F: q: l; v1 X* p6 i% g
                                                                                                                                *(uint32_t*)0x422200DC = 1; }/ J% ?" J( W2 N+ u# Y, v
// Target Running LED           Not available1 Y( ]4 u- Z: A6 |8 D2 p
$ K* T6 |! I+ I" R& ^5 p
// SWCLK/TCK I/O pin -------------------------------------6 q6 f: t. k$ o
- Y6 p9 b4 z5 p
/** SWCLK/TCK I/O pin: Get Input.% ^9 l2 I7 J( a- m  l0 o" O
\return Current status of the SWCLK/TCK DAP hardware I/O pin.
  m* g, a, j+ y3 f*/
! q! y- R' j% y# g__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN  (void) {
" W+ K% u( Y$ ?$ \& j) ]  return (SWCLK_TCK_IN);7 |9 G( r$ X- r: X$ i
}
# h. j$ I  f! l0 ?  h+ |" d- y1 y: R# Z( ]' @
/** SWCLK/TCK I/O pin: Set Output to High.
7 ]1 k. ?, V2 k: c4 SSet the SWCLK/TCK DAP hardware I/O pin to high level.
+ a  _7 o' s2 ?) X0 W9 G' p9 k0 q  H*/+ o# Q3 O: d$ O0 v/ v) v  h
__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_SET (void) {
  q2 O$ L8 N, ~# @  SWCLK_TCK_OUT = 1;. s* ~. u$ J6 x3 g
}
, ^; H' F0 o( q4 z; x( @
- c% B  d+ _9 ~7 u: C4 \0 N/** SWCLK/TCK I/O pin: Set Output to Low.
' M$ V  y8 c$ C) [5 TSet the SWCLK/TCK DAP hardware I/O pin to low level.
) k* R! k: x- ]# Q*/
+ D( @, K5 \( w+ Q__STATIC_FORCEINLINE void     PIN_SWCLK_TCK_CLR (void) {
0 ^# q; c; ^5 K. U. m' A5 O  SWCLK_TCK_OUT = 0;& ^7 C$ E1 D0 C2 J# @5 E0 l
}8 f+ W* O+ _+ ]: _5 @) ?
+ n: Y/ @! E' m
* N0 G, j0 L0 p
// SWDIO/TMS Pin I/O --------------------------------------
2 d0 _" \8 a+ {# I0 N
& |# R! t; T# _+ {/ {$ U/ {/** SWDIO/TMS I/O pin: Get Input., l" s0 f: Y5 w
\return Current status of the SWDIO/TMS DAP hardware I/O pin.
5 L. A* G. f7 b6 z! {2 M*/
: r1 Q6 R% \; [; F6 f__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN  (void) {
, Q& ~  R, A2 W  return (SWDIO_TMS_IN);
6 j9 i: H' N* |9 z" {5 r3 V}
# R9 x4 x4 L' D* r4 c' B% v
3 P& ?* d; {! j. x9 C, Q8 H/** SWDIO/TMS I/O pin: Set Output to High.
4 n& w% Y5 p4 A6 Y; @Set the SWDIO/TMS DAP hardware I/O pin to high level.. a3 T! A' \; A  I( _( E
*/
, V( J+ b& e8 r# z, ~; ^* n6 x- C& k__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_SET (void) {
, h6 z$ M+ d3 b) }( U% B  k  l  SWDIO_TMS_OUT = 1;  x- c* A: |6 Z7 ]/ X) a
}
4 K; C( M0 M2 I& r% }2 ]
3 s+ z( c# l, Y% D. A' f/** SWDIO/TMS I/O pin: Set Output to Low.) z' ^% e2 Y/ ^
Set the SWDIO/TMS DAP hardware I/O pin to low level.9 C2 x/ u- V7 V9 j4 k9 ~' @
*/+ B0 G6 K! {" ?- U- A3 g9 t
__STATIC_FORCEINLINE void     PIN_SWDIO_TMS_CLR (void) {6 \% _0 u; O' ^& G( v
  SWDIO_TMS_OUT = 0;0 y1 Y' @5 X- Y) O/ b& d
}  G* b5 ?8 w9 b* T
& X( R9 G( F0 V8 P6 {
/** SWDIO I/O pin: Get Input (used in SWD mode only).
+ m$ }( [- A5 i( O/ Z\return Current status of the SWDIO DAP hardware I/O pin.1 K  f. M- S8 t( m! Y8 r
*/5 w& n; O" r) F' ?3 i+ ]& a
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN      (void) {
; c- x; g% F  E3 \% d! b6 ~  return (SWDIO_TMS_IN);
7 U2 T8 F7 M/ k5 O; p}( |, M2 \9 Y: {& v. t6 [

5 w* k/ R9 \; j$ z7 h3 L" @0 }4 E/** SWDIO I/O pin: Set Output (used in SWD mode only).
/ A0 X- ~, T" Z\param bit Output value for the SWDIO DAP hardware I/O pin.) c# u, E7 _! O1 s1 i* t; d5 k/ g
*/1 ^3 m4 T9 j+ J
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT     (uint32_t bit) {
" a5 F! Q$ x! Z4 k( M  SWDIO_TMS_OUT = bit;
* h6 x8 |5 M3 m: K}( B1 C5 e( P# Z' ~! q6 r

, B! \/ ~7 i! x/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).4 [: x1 s- R1 Y7 K$ h0 {
Configure the SWDIO DAP hardware I/O pin to output mode. This function is9 `" s3 c% g9 x' r# t. c
called prior \ref PIN_SWDIO_OUT function calls.
) n& N! n2 ^: k+ z; e*/, W* G8 @0 N2 H1 g1 v1 A
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_ENABLE  (void) {- x* Q$ r7 x% w1 l5 |+ m' v
  SWDIO_Output();4 [& f, c# x  c5 W, Z
}
% p! _" r: L( ~8 w* x
8 w# n$ i9 d5 m' V3 q/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).8 I6 k$ z1 r1 |7 Y: u( R# H* S
Configure the SWDIO DAP hardware I/O pin to input mode. This function is
3 j% A5 S4 |3 U) N9 t5 e# Wcalled prior \ref PIN_SWDIO_IN function calls.
0 c8 U' }7 f1 s% k*/6 R1 f, M9 E6 Y
__STATIC_FORCEINLINE void     PIN_SWDIO_OUT_DISABLE (void) {
; r. z4 F; z, L% {2 Q8 d  SWDIO_Input();
! @5 L( K+ ~& `) M& s}
, m4 s+ e* {6 ^9 d! T/ Q0 q2 Q" P' N
楼上有的说弄无线,其实无线也就是PC<->USB<->无线模块A<->无线模块B-DAP,数据传输的速率主要是无线模块之间的速率限制了,也是非常简单的, H- N' l. n. f9 C6 ]  N- y
即单片机先做好USB接口部分,OUT端点收到的数据发送到无线模块A,无线模块B接收到数据后,推给DAP处理,DAP响应的数据再让无线模块B发送回无线模块A,再通过USB发送回PC,也就是说USB与DAP之间也就多了两个无线模块作为数据的交换,要是会写USB驱动,写个虚拟WINUSB设备的驱动,让Keil的DAP驱动能识别到这个虚拟USB设备,通过ESP32利用WIFI通信应该比使用这种无线模块更快,而且ESP32主频更高,即使IO模拟 SWD接口,都会更快,会写USB驱动的大佬可以尝试一下; |4 j8 K8 l4 P; b. P

所属标签

相似分享

官网相关资源

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