& f5 ?) t8 P3 w9 y7 W6 v9 ?# `$ q6 b
/ Z5 ]9 j& A8 D8 j7 x0 @描述:
' x: Q0 d5 Q; R我意识到我是垂死的人群中的一员,他们只使用emacs作为IDE。我决定和SystemWorkbench一起生活一段时间。很多事情需要处理,我的笔记可能会帮助你。
?% p: Q. P$ v/ K/ {: w, {
9 S7 }! [( N& `. m+ D( G3 z! k1 b* P6 ~9 t- m: G! S
/ P+ A9 D1 }. }2 q/ M3 F5 C
细节:
) h, q% g8 l" P1 U- E2 V基于http://hackaday.com/2017/03/30/t ... uino-with-debugging上的评论,我决定让SystemWorkbench试试。
! ?$ Z; L7 b( C: K" g9 I0 }1 r! w$ N7 J
, T# N/ H# W; I+ V! O4 D
项目日志:
- u! A; w3 B4 _: e; K4 X+ ]6 H使用CDC USB串行接口的提示:0 s3 v5 C& b: e% R. m/ t- E. i
当你把USBCDC序列添加到你的项目中时,对于下一步该做什么你得不到太多帮助。CDC发送fs的呼叫很明显。给它一条消息和一个长度,它就会发送它。够公平的。
3 l7 W2 e" e& R" M* z8 R. \
2 m( J$ C; \# f; A但是,接收是通过一个名为cdc_receive_fs的回调进行的。你不叫这个。框架为您调用它。
. E D' Q. f& a+ f4 D/ N8 E0 S( N5 q6 g! \! L! q$ p6 ~
这是我的版本:& _/ p! s, i6 D
3 i' u9 Z8 @9 U1 V3 M/ L- static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)% a- q3 g8 ^0 a0 U8 T' Z) k
, w: G1 v0 A. z u" j( V- {2 ^3 K4 D D' C
- 0 F. q8 f$ N/ O/ W2 N: A2 K" \6 {
- /* USER CODE BEGIN 6 */" u: P" }3 A0 w) x2 S
- uint32_t len=*Len;* D! C4 |1 G) c9 @4 U, ^" i
- if (hUsbDeviceFS.dev_state != USBD_STATE_CONFIGURED)
. a! p3 e8 d: F5 ? - {
; x+ X/ i' k6 C1 `4 B* V! U - return USBD_FAIL;6 x0 _/ ?5 m. m' n4 t0 ~
- }
4 I) o' A- o, i% l
* [* U7 b7 b/ Z8 m- if (((Buf == NULL) || (Len == NULL)) || (*Len <= 0))
5 b' O; i8 i, h' N' j1 ?+ ` - {$ o$ ?3 d6 _4 I
- return USBD_FAIL;2 r- ?3 G8 |8 t0 m
- }
9 k8 q9 W4 o" h; f! j. `) M - 5 m9 N9 y; [5 |+ g
- /* Get data */
' n9 X% m8 w. d5 b3 o - uint8_t result = USBD_OK;
7 U" y( e: B( V# j8 i& M - do" A8 [/ F: b5 M5 e6 V% k
- {# T4 Z" k) |! D E( v' ~) n/ L( W
- result = USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
, `9 r' r- U b( ~! d: p& M& c - }; C, d+ r9 X9 i. |* h7 g
- while(result != USBD_OK);
: W% P; O; r0 |" G7 U4 w9 U2 P% W
& ?6 C6 ]( b" O% a1 m( z! d- do
. ?6 J9 R5 Z9 r- V - {5 m3 ^/ P) k t, ~$ X, H
- result = USBD_CDC_ReceivePacket(&hUsbDeviceFS); z4 A. h7 Y( @- Z) T
- }
( T. [5 H' K+ B1 \( b+ R - while(result != USBD_OK);* Y. G& o. `$ B- ?
- ; F1 b( R$ ^# l6 y1 ?; e# o
- // add data to FIFO( L' A4 l2 u- R! G6 z+ g% R
- while (len--)
8 k7 Z- m8 {. z: Z0 v+ M - if (FIFO_INCR(RX_FIFO.head)==RX_FIFO.tail)& V, d+ g- U2 O* P/ I/ _
- return USBD_FAIL; // overrun& O) H6 w1 H9 C4 i9 z
- else; y5 q, y1 ]6 K1 i$ w
- {
& H7 D- `; g! ]! d - RX_FIFO.data[RX_FIFO.head]=*Buf++;. e' F6 B0 b$ t5 { j! [
- RX_FIFO.head=FIFO_INCR(RX_FIFO.head);
+ J0 o, A( m5 T - }
/ i9 P% c/ O2 V7 ~5 m2 i - return (USBD_OK);
9 ^+ H3 R, c: o+ T3 d7 X
( \& W1 t5 ?: @! U3 M- /* USER CODE END 6 */ ! o. R9 O" Q$ H6 B0 v# ^
7 d2 G+ O- g: ~; S$ M- }
复制代码 在其中一个标题中:
% |8 o/ z. }2 u" @1 Z7 c9 c/ k4 X- #define FIFO_SIZE 32 // must be 2^N3 @- w! w r J8 q5 c
- # t: H$ `5 X: ^/ o3 I+ S+ _
- #define FIFO_INCR(x) (((x)+1)&((FIFO_SIZE)-1)), \8 f. x* r2 M0 k
8 y+ H& E' Y% o# F- O' H- @- /* Structure of FIFO*/2 u9 C, d# y7 I0 r
5 @$ F3 s2 c: h- typedef struct FIFO/ Z$ q1 i: [6 D+ Y. ]& U
- + }, Z |; I; ~+ P! v5 f$ y# ~
- {
1 F9 R/ u( ~4 V% G% C( Z - uint32_t head;* F1 p2 v5 j1 _4 c
- uint32_t tail;9 a) ?2 r: ^5 ?$ l6 w3 j. T( o
- uint8_t data[FIFO_SIZE];8 M& z8 t" V# a2 X* N! x. D6 }
- } FIFO;" |4 N/ t0 d2 S6 [* v
- 6 R2 _1 g9 x/ Z$ u8 H- o: p
- extern FIFO RX_FIFO;
复制代码 那你也需要一种方法来读出来。9 V9 Z6 C; F1 h: E# U, |% q2 P# u6 S
- /* Create FIFO*/
, p, c0 X4 Q- V# b, `+ A$ m. e - FIFO RX_FIFO = {.head=0, .tail=0};6 V5 g9 P6 |* \" K5 g
- 4 ]7 j0 R% b: Q
- // returns bytes read (could be zero)
r* J$ ]! M0 Y# b. e - // would be easy to make it end early on a stop char (e.g., \r or \n)% C: R/ {8 c, P# Q7 ]
- uint8_t VCP_read(uint8_t* Buf, uint32_t Len)
5 i/ V* y8 A0 B! ^$ D - {7 B" S( w( d. \3 ^' t
- uint32_t count=0;3 z( K6 l5 l/ ?, q( L
- /* Check inputs */; V& P9 F: K$ l9 V9 V
- if ((Buf == NULL) || (Len == 0))
4 D/ }/ g+ k# C' k- P- x - {* I6 w! ~5 _9 ^/ U* r9 Y1 G
- return 0;/ K0 p% J6 \1 a0 t! H. i
- }
9 V6 l6 P# e' k, ^& x
. z0 a( i- A; ~& N4 t/ C- while (Len--), q x: [8 P8 u6 z' H
- {
" f1 T, Z' g6 R6 I' b- E, \2 V6 t - if (RX_FIFO.head==RX_FIFO.tail) return count;, m8 c# d6 K8 P4 I( K+ D8 x3 t* ^
- count++;
% @$ E: X4 R- c* P - *Buf++=RX_FIFO.data[RX_FIFO.tail];6 C* N, Z& h' m! p3 J9 d" w
- RX_FIFO.tail=FIFO_INCR(RX_FIFO.tail);
7 [8 B4 M' f ~% ]) ?$ t% a - }
1 m. c9 b5 l: L. v# d" f/ q% D
% o3 R5 P$ U& {8 K j3 o- return count;3 U9 J C! Q3 o, s9 ?& H
- }
复制代码
/ E9 \% V, ?( r! K5 a0 a/ p启用半宿主printf
3 {; t, z, p% l- B/ O0 T如果您不希望printf转到串行端口,那么您可能希望它重定向到gdb控制台(Eclipse内部)。
/ j% M4 L3 l- J/ t& `* e& R
9 S# \) _ T6 u& I1。添加到链接器选项:
, p9 m- N1 J, m0 P0 R w& P% b" o& V* Y6 {
- -specs=rdimon.specs -lrdimon
复制代码 2。在调试配置中,找到运行命令并添加:7 i2 a3 i: p1 A% z% j% T3 Z2 T
- monitor arm semihosting enable
复制代码 3.在main()中,提前进行此调用(在调用printf之前):6 d+ y1 Y+ |5 Z' S( ~5 F [
- initialise_monitor_handles();
复制代码 就是这样。现在,printf将转到您的控制台。( ~1 c. r5 ]& W# |. Z3 i7 H
3 D5 N' ~8 T3 O* e; Y& H) C% Y# M# g. d
& ~, W0 g' x/ m! F9 ? G+ `0 F6 H将printf和朋友重新定位到UART6 Q5 X% C# J1 W- n
- 确保您有足够的堆栈!如果您没有在项目生成时设置它,请在.ld文件中修复它(并确保在cubemx项目中修复它,以防重新生成。
- 另外,用IDE而不是cubemx创建一个虚拟项目。从该项目中窃取syscalls.c文件并将其放入项目中。
- 显然,你需要在cubemx设置UART。
- 添加:( P% y5 P1 B/ @" r2 I x+ V
- int __io_putchar(int ch)
! y# C3 i3 {8 f8 @" C( f! `
1 J7 [4 E1 y( x; ]; l& y/ f2 n9 Z- {' y+ b8 n! n; l3 u$ h
- 6 F4 h( ^3 `: g" W# p8 [
- uint8_t ch8=ch;
# n% a6 \ i7 \
+ a' h+ W1 p \- L* n- HAL_UART_Transmit(&huart1,(uint8_t *)&ch8,1,HAL_MAX_DELAY);& f6 k7 r k. E3 {% j5 g4 k
5 t. Z! C% e- y7 Z8 ~, t$ T: {- return ch;
! B/ S" z6 |/ T- _" e
, t# ]3 e' v. U# s/ g+ s* ?- }
' U3 Z }- l, Q- l2 V V/ k
/ E1 f$ t1 U7 Y7 p: |9 ~) r9 r/ z- int __io_getchar()
& d5 |% C0 `- A- r* [' a - S6 `! W' g1 }' } q, U
- { F5 b" b7 s- H1 Q' L/ C3 F- m
- ( O! Q$ A4 [7 u* r1 W9 v
- uint8_t ch8;
- Z8 t# ^# C$ q8 ]0 `: S - + {5 o4 l0 R0 S7 j
- HAL_UART_Receive(&huart1,&ch8,1,HAL_MAX_DELAY);4 t2 U5 f; B9 }0 s
- & P. l, D; A! [- C& b
- return 0;7 x0 p; U* F' d' a8 Z$ t
; @+ N: D7 M. l! J9 R5 L _- }
复制代码 完成!神秘的崩溃意味着你的堆栈太小,或者你让启动跳线设置得很有趣,而SP没有设置成你认为的那样。
0 |, U) D1 j) v
# Z8 ?3 Z% X9 P) B$ J; ~笔记1 I! e/ z; i4 Z, b3 S/ t% W
- http://www.opensmt32.org/system+workbench+for+stm32
- 将cubemx从ST网站安装到Eclipse中。http://www.st.com/en/development-tools/stsw-stm32095.html
- 您必须具有用于此板的ST链接2或2-1。似乎不适用于ST链接1,即使其他工具可以处理。
- 如果你用PLL时钟的话,库贝姆有一个错误。在SystemClock_配置中,行应该如下所示:rcc_oscinitstruct.sociatortype=rcc_sociatortype_hse;
- 创建配置时,openocd的设置硬连接到项目目录中的.custom.cfg中。所以,如果你改变了任何东西,看起来你必须修改或编辑这个文件。
- 重要提示:除非您将openocd配置更改为仅使用:reset_config trst_,否则调试器将无法工作。默认值将不起作用。
- 如果将引导跳线设置为引导加载,则调试似乎可以工作。但是,您将得到引导装载程序stackpointer,它是一个非常小的堆栈,可能会覆盖您的C库数据。这将导致奇怪和不可预测的行为。
- 如果安装eGit,就可以获得Git集成。
- 如果安装tm终端,则可以在IDE中安装终端。据说它支持串行,但在Ubuntu上,RXTX配置是主机化的。我运行一个shell终端,在里面运行picocom,而不是修复它。工作良好。; Y; V, v# x. L! Q1 C
; L3 V; Y. b. {. V3 y4 L原创:Al Williams3 \ \6 g; V) E! O+ W$ j
出处:http://hackaday.io/project/20879/logs
" R x* a& ~% h1 c' \6 {' m4 k% n- o5 p6 f8 X: p0 F* @
3 c4 k; \. y( m! y1 v. s" D4 ~) H' Y
9 ?) v2 j3 J. o' ]( j7 T
/ R* w2 I. P3 d& X1 {7 y% P" J$ o: r
. S5 t4 x! k" `! E1 t" Z |