本帖最后由 丿灬幸灬 于 2018-11-5 10:24 编辑
! @0 C+ O; t' m
/ ~. o# j" I# l# ?
- @ i9 d1 r0 _& k. {7 |* y描述% {; k* B1 [5 Z2 ?
我意识到我只是将emacs作为IDE使用的人群中的一员。我决定用SystemWorkbench一段时间。有很多事情需要处理,我的笔记可能会对你有所帮助。9 d, {. Q' F) J0 H& d0 _
6 M$ O( W; `1 m1 S8 {6 I4 B* d细节. _% q6 o& x6 ]; n$ f! B1 v @+ z
基于对之前的评论,我决定使用SystemWorkbench。 I# }% J8 w; J- M8 m/ N# f; f
7 E4 I: m8 [( i
6 Q$ g0 Y2 b' |0 B, e1 j0 P9 g
0 t# E- q/ U/ p& N使用CDC USB串行口的提示
: O4 }7 ^4 P( A. s0 Q) Z( e! k7 J) C1 I& U ~0 A$ b
当您将USB CDC串行总线添加到您的项目中,您不会得到关于下一步做什么的帮助。CDC_Transmit_FS调用非常明显。给它一个消息和一个长度,它就会发送它。很好。4 V2 \, K/ g8 G: I% K
7 f+ \4 l5 t. m) N; L
不过是通过名为CDC_Receive_FS的回调函数接收。你不会把它叫做。框架为您调用它。. C5 Y. d+ F& J4 ^+ A8 B
. j) Z3 J" {4 n+ x: j
这是我的版本:. Y; B- J' \$ ]+ a5 [
- static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
# C2 r" \1 ~; q d6 V - , F' B1 @* A4 u1 Q$ t' B
- {+ i* \% |. B6 r! Z; C( P; }
8 X7 V" G# X; G! h9 S# M- /* USER CODE BEGIN 6 */% z& ]* E- N7 A
- uint32_t len=*Len;) Y6 g" S( Z& a- W
- if (hUsbDeviceFS.dev_state != USBD_STATE_CONFIGURED)) j7 B- |3 N! B* T+ c* e
- {. Z$ c, N8 s' `: [
- return USBD_FAIL;1 g4 u5 h. y* l1 o1 M P* K1 ~
- }
+ M- T( O+ w' b- g - ) b2 q$ G0 p- b' m
- if (((Buf == NULL) || (Len == NULL)) || (*Len <= 0))
/ s$ c" H+ `+ o' r9 Q - {
! ?: I# F: p5 @) F6 H - return USBD_FAIL;# a4 P% ?" h+ I. m- B
- }2 V8 Q" m9 Y: ~, \% O! k# j
7 n" O" Q" L$ N7 U& x& J7 F- /* Get data */$ W f2 i3 Y% }/ f( k) p$ x
- uint8_t result = USBD_OK;& C. i# D" i) ^) H" B: I8 b
- do% {* u6 f/ r; s; E5 g1 A" v% u
- {
- H, G8 D4 H, i- C# V, q - result = USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
* H3 `+ e( g2 } ?1 p. S1 p - }
4 |7 }7 c9 ?9 D x' E u$ { - while(result != USBD_OK);8 A0 O3 U4 n$ ?0 X; @# |3 r
- & O9 e* u( |" u9 [7 A" z
- do
: U3 W4 u: o% n I/ }- a - {
( F2 m1 S: O6 a: R3 t - result = USBD_CDC_ReceivePacket(&hUsbDeviceFS);
0 w: r1 r! f! s7 y7 }7 S7 q - }5 o3 E( f5 K" _+ C( E: _
- while(result != USBD_OK);" D! T4 P3 y. { v0 u
3 f3 M- ]$ ?, j$ V9 T, `- // add data to FIFO
; J6 t: u# B/ T7 V; x+ J - while (len--)( x& V% M9 R6 f$ j6 c
- if (FIFO_INCR(RX_FIFO.head)==RX_FIFO.tail)
8 T% U/ g% m" g' @; n0 f - return USBD_FAIL; // overrun" e- t1 [5 @- B7 c$ u
- else
# X& K' Y4 g/ e8 g - { c8 P3 } [# H3 G% }3 c
- RX_FIFO.data[RX_FIFO.head]=*Buf++;0 j; N5 l# C- Q9 _' S1 v
- RX_FIFO.head=FIFO_INCR(RX_FIFO.head);" H0 E1 \+ S6 \/ Z5 @
- }7 G( A9 \4 L2 p4 w. O- S9 F/ L
- return (USBD_OK);5 h5 x* p- A, o3 l4 a
- 1 |# o. }6 A- O0 Q( n
- /* USER CODE END 6 */ " y( @: D B6 B% H/ {' f
- L( Z. N) D8 n$ c: e: x- }
复制代码
" [2 E' k3 V& Q. i7 [这是其中一个头文件:
- d; W3 z2 o* `' \ o1 a9 @8 y
6 S/ m/ N$ N& t& X' _- #define FIFO_SIZE 32 // must be 2^N
" d1 A# \2 @( e7 g - ( {" a6 k* o9 T( O7 M7 ?) x2 s6 N% U
- #define FIFO_INCR(x) (((x)+1)&((FIFO_SIZE)-1))$ Z( f k' F, l( F# U! R0 \
- 9 P1 r" h/ l9 @# S: ]
- /* Structure of FIFO*/
; F* k" g8 X1 o% x7 B
# i7 f8 P P6 T: j! K$ [0 g- typedef struct FIFO
( A* r3 h, |5 ~5 B7 O9 V0 r" f( z4 X - , o5 t1 E; }1 X' V
- {
- r9 [4 c7 t' _ - uint32_t head;
0 F/ F( x: e1 _! p+ [( P - uint32_t tail;
% b: L ?" Z2 h$ l. b( L - uint8_t data[FIFO_SIZE];
1 _$ _- J/ d* H5 V" ?% w. [1 D7 L - } FIFO;
! n/ g) p# s/ A3 A- S3 a
! m# B, C' C: A# G5 \" m) [+ k- extern FIFO RX_FIFO;
复制代码
* b) M' Y7 m: |# P# R然后你也需要一种方法把它读出来
+ y2 {- \& E3 t% M- /* Create FIFO*/
( S" K# b; f. S/ d- h2 i! @ - FIFO RX_FIFO = {.head=0, .tail=0};
- @0 g: b: i- P) R8 z2 ]
( A2 _- Y: r/ C, \; b+ l# u+ H8 k- // returns bytes read (could be zero)
, N, `" N* ]$ G7 ^- U# X; ?1 H. x) t/ S - // would be easy to make it end early on a stop char (e.g., \r or \n)( p, \" l, c7 T1 h4 q
- uint8_t VCP_read(uint8_t* Buf, uint32_t Len)
- j) v. r( \( o% i& [% C! [2 A - {
: A$ j: y- _4 K/ t; Z8 _ ] - uint32_t count=0;
6 H1 m; t' x' u- t* ~7 b7 [ w - /* Check inputs */
" I+ E5 S7 n |: s3 | - if ((Buf == NULL) || (Len == 0))/ W2 s7 ?1 c" W, h
- {0 ]6 A# c3 n6 b0 N! t3 |7 O
- return 0;) b: t& o$ F' Z; y/ w
- }1 P- t2 e/ i3 K
- 0 k% f9 z5 ?. H4 q% D3 V1 v3 t
- while (Len--)
! r3 [$ ?! s$ f5 U& N7 } - {4 y5 m- G' J) q$ V' q: H* j
- if (RX_FIFO.head==RX_FIFO.tail) return count;
( G5 L* q: m0 b' ~0 ^! ?3 G! |! M) c9 o# r - count++;
/ I! r O! a5 d; u( j9 d' t) Z; ]8 ^ - *Buf++=RX_FIFO.data[RX_FIFO.tail];
) ~: b8 u# i+ H) U R) `1 d5 L4 ^ - RX_FIFO.tail=FIFO_INCR(RX_FIFO.tail);! U1 X* T _ l% M- [
- }. y$ n5 b( s& E
3 J/ W8 ]3 t) }) D- return count;; G+ ]1 j/ i- m$ H1 t3 ?7 y
- }$ f+ w7 g6 f, h! h. j. d% s) i
6 f M& s+ d( _+ U' Y: D" H
复制代码 0 k* F3 P7 [0 i. L% U
使Semihosted Printf
& b U- M7 k* g( _/ Y6 s7 _% J7 e5 ~: A& N4 J4 W' n4 I9 n, Z! c* I
如果您不希望printf转到串行端口,那么您可能希望将它重定向到gdb控制台(在Eclipse内部)。
; H/ Q4 w: z" E4 X9 \
4 e6 p9 E' [3 j" u1、添加到链接器选项:
( ?2 e# N! U) Y% H$ A- -specs=rdimon.specs -lrdimon
复制代码
9 @8 k5 G; E9 }2、在调试配置中,找到运行命令并添加:* b' Q; U2 ~# X
- monitor arm semihosting enable
复制代码
1 s2 l, ?4 w5 ~3、在你的main()中,提前(在调用printf之前)进行此调用:0 o4 T1 O9 J( {5 t: e/ N8 `7 [
- initialise_monitor_handles();
复制代码 就是这样。现在printf将转到控制台。% ~5 \& q6 j9 q& T4 e4 i7 ^
4 p. w8 W4 x7 b# K% I$ U X. d( N重新目标Printf到UART
! P- n5 e$ V1 g3 o1 \9 v
! ^4 H& J$ ]- n7 R! L5 X5 K1 D4 }& T1、确保你有足够的堆栈!如果您没有在项目生成时设置它,请将其修复到.ld文件中(并确保也将其修复到CubeMX项目中,以防重新生成。& u6 J. }/ L; a. o& l! }
8 p+ v- l* z5 W. e
2、另外,使用IDE而不是CubeMX创建一个虚拟项目。偷的系统调用。c文件从那个项目,并把它放在你的项目。; e; O+ ^) P" z2 J
" ^5 c, a2 U& W" R6 O4 X: r3、显然,您需要在CubeMX中设置UART。
& X1 T& t. I5 j. o0 W, `$ N% t9 D, Y* W( Q9 R$ b6 V
4、添加: {3 o( v: b3 G
0 m0 n0 k W9 W- int __io_putchar(int ch)
% J7 ]& a8 ^7 E - " v, Y# P3 ]7 n8 |. P; Q; {
- {* p: s% Y; ^3 z0 B |
- 9 _- J5 t! L" G
- uint8_t ch8=ch;
" M0 U, h( ^" C3 e* Q2 B
! a+ v* Y9 a6 n9 y- HAL_UART_Transmit(&huart1,(uint8_t *)&ch8,1,HAL_MAX_DELAY); |( W7 ^1 J6 O
- 7 Y7 P- Z7 M( ^2 ]# v+ W
- return ch;
7 q0 S4 I: ?1 ]2 l
% i' |# k* B+ R q% w# {5 w- }
9 w/ J, u0 k u$ W+ j& @5 @: y( f - - M1 E* H0 A5 p6 Z" x9 `
- int __io_getchar()
0 c/ j& |/ B9 [( d - }$ n: _0 _* o r$ j
- {
; i1 x; L7 |- M! a2 ~) B% T - ( F3 L3 [- i; t9 O: x, _
- uint8_t ch8; [$ `7 y9 {! `
( l8 N4 n) N1 I3 m- HAL_UART_Receive(&huart1,&ch8,1,HAL_MAX_DELAY);0 g E9 |9 u9 \0 T
- " F! @( M. b9 r! }1 T
- return 0;
; t9 t/ i0 d8 N& ?7 L: P - : b0 d, g+ M" b( j5 W0 ? H$ Y- B
- }
复制代码 完成了!神秘的崩溃意味着你的堆栈太小,或者你的启动跳投设置有问题,SP没有设置成你认为的那样。
( R3 K+ ?2 G4 v2 d& H
& E8 T6 a. w( V- t9 |; d" c笔记5 _- \1 G1 L) g$ P. o0 P2 v3 F
, ?3 @/ Y- X1 V$ ?. d1、STM32系统工作台* G# j! _3 v- M) Y' h( P
1 I, |/ n2 J( ~5 p$ c1 v7 S# ^0 k2、从ST网站安装CubeMX到Eclipse。) L4 n# {: j( G; _8 G) }+ W
: S: Q3 l3 K' P3 T# i3 S# X
3、这块黑板必须有ST-Link 2或2-1。尽管其他工具可以处理,但ST-Link 1似乎无法工作。# E' S' k4 `+ S7 P, U8 r5 d% [* E
: z' s* I- E- t: K3 s9 W5 Q& Q( U) n
4、如果使用PLL时钟,CubeMX有一个错误。在SystemClock_Config中,代码行应该是这样的:RCC_OscInitStruct。OscillatorType = RCC_OSCILLATORTYPE_HSE;: n" E8 K4 J/ ]. e, @
- M# J U c) c4 e7 u0 O5、OpenOCD的设置是硬连接到.custom中的。当您创建配置时,cfg在您的项目目录中。所以如果你改变了什么,看起来你必须删除或编辑那个文件。9 j6 T' C; J( }+ W& r% _7 q+ ^, {' ?
2 X0 Y3 n5 g4 O0 G4 M
6、重要提示:除非您更改openOCD配置以使用:reset_config trst_only,否则调试器将无法工作。默认值不会工作。
8 t6 V' M' n& K ^% m+ @
9 j8 B' `' y5 ~9 S E7、如果为引导加载设置了引导跳线,调试就会正常工作。但是,您将得到引导装载程序堆栈指针,它是一个非常小的堆栈,可能会覆盖您的C库数据。这会导致奇怪和不可预知的行为。4 b6 x) r+ B% ]0 }8 ^5 u9 }- W
7 N3 |" O, @% Y
8、如果您安装了eGit,就会得到Git集成。
- o) U3 I1 Q% m
& L. i3 h/ W; M1 X9、如果您安装了TM终端,您可以在IDE中有一个终端。它应该支持串行,但在Ubuntu上,RXTX配置被处理。我没有修复它,而是运行一个shell终端并在其中运行picocom。工作很好。
3 q1 ~( D0 c) d: X* U7 x6 H$ l( I: f1 g
原文请见hackaday p8 l5 b: X# ~ v4 ]2 o
2 e" y3 y5 p+ {2 C |
能不能麻烦您不要发布不带来源链接的机器翻译文章了?这既是对读者的不尊重,也是对作者著作权的侵犯。版主是不是可以警告此人?