测试ST 官网的 FreeRTOS
' h0 A) h$ Y; M& @" F; e. ~, V9 D3 Y2 K! t! y5 B
移植shell6 v+ Q7 G: c( }3 \4 Z
主要是串口对接, 需要重写两个函数
5 q4 U/ P0 S. P: u9 Q
& e3 F" }% I) \1 L2 H- int fputc(int ch, FILE *f)
5 V& D/ n+ k- v6 y6 x8 D( E- v( m7 k7 z - {
. n6 O1 l$ _: z g/ y- }- O: C - /* Place your implementation of fputc here */
5 c5 S3 Z' K, m - /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
% I, Q, ?" u7 C& p8 ~* K( X+ a - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, UART_TIMEOUT_VALUE);
6 C6 u# g/ A) Y1 a( q9 ^ - return ch;# h8 R. d, u3 w) ~8 R9 d! R7 i
- }, }5 ^ `, z: G# Y1 d' h
- // #endif0 V. M0 X" O' w3 L" M% }8 K
% S" I# @3 P# Z( N- char shell_buf[RXBUFFERSIZE]={0};/ `/ E; x% i- U2 Y) n
- char shell_len=0;
0 u4 K- H+ ]1 a - char *shell_buf_head=NULL;+ h+ r, W! B4 y1 m
- ) g! v6 d& q4 J3 D8 q
- 8 J. m* R G- i: `
- int fgetc(FILE *f)1 [3 P0 V5 \' G9 F9 d
- {1 H `! M8 C* ^
- * v6 D7 O" U- _* h8 e `
- while (0 == shell_len) {1 Y" X6 b! b2 g: j) w
- osDelay(1);
1 ^0 |7 j; w2 O3 [5 p$ X - }
0 N: A2 N" h* Y0 u - char ch = *shell_buf_head;
& a3 Z. W) s5 A" D7 y; J - shell_buf_head ++;
6 ~8 O6 ^/ C# P9 J2 J; \, I - shell_len --;
( v/ c+ f- i, L/ l' `8 ~2 | - 6 d; S7 }8 g7 S' X/ e2 k- Q
- return ch;
/ K, c, N" E* o2 m/ M" C; x9 F- r - }
复制代码
- e: P% W3 }, I& V9 F4 ?增加了一个回调函数, 收到数据拷贝到shell_buf, 然后重新初始化串口中断接收参数,指针,size,count
: r" b. ?; k( X# e7 b) \( ^$ J2 f
; q! f2 a( d2 c# o C) u- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
7 M& I7 R _# l) _ - {
/ Y8 e, r/ |$ m: [( ?+ E7 f1 w# D - /* Set transmission flag: transfer complete */; T3 V4 X- M( {" r2 A6 K$ P+ i! }
- if(UartHandle->Instance == USART1) {
9 ^4 _1 r$ u* @6 u4 ]. E) ^ - // UartReady = SET;
, h }9 |: u+ }2 u - shell_len = UartHandle->pRxBuffPtr - aRxBuffer;
- v' G! m/ `7 c - shell_buf_head = shell_buf;2 s8 Y# u2 p! m, y. l% h. P
- memcpy(shell_buf, aRxBuffer, shell_len);
# F' w8 `( D/ k2 X1 a+ P* I; U# D - " q# J3 X+ u5 S$ E* g, a
- UartHandle->pRxBuffPtr = aRxBuffer;) E. l$ M! a% ~1 n' b: j/ q
- UartHandle->RxXferSize = RXBUFFERSIZE;
' x1 Q; [& L0 R1 B0 i* ]' F8 G( Q - UartHandle->RxXferCount = RXBUFFERSIZE;: D1 C. W u' D( H$ Q4 B% J
- }
. \2 h9 j: M7 [0 t. A" G - $ }* f: n( k0 |5 n2 W$ Q
- }
复制代码 / r; q9 R- K, s f/ r
遇到的问题, 1. fgetc 不能直接调用HAL_UART_Receive, 否则会死等,导致其他任务无法运行。; | i7 A" s4 e F, B( f
5 l. x1 V7 e7 w
解决这个问题的方法是,接收采用中断方式。3 O# x8 ^8 O) S4 R
3 t# e1 D! h$ n D+ ?! A. |" L问题2. STM32CubeMX 生成的代码,串口中断接收是固定长度的方式, 对于shell 不适用。
/ j4 Y, [% M7 ^' F7 I/ O0 A n5 S$ N: ]5 a! `+ V1 n
解决这个问题的方法是,修改中断处理程序,如果是调试用的串口,直接处理接收数据
0 l8 P, e. G' H+ A+ f8 L
. w4 m. T" l# X ~8 S6 W5 A2 @5 X- static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
. |. i# v2 x* U0 ` - {
. x3 J$ s$ x( O- Y3 { - uint16_t uhMask = huart->Mask;
# \/ b8 H' b0 p* g* [. n - uint16_t uhdata;: L3 U- W( v0 E+ b3 H% i
: ~2 Z+ ?7 S9 l+ b0 o) a/ f& U- /* Check that a Rx process is ongoing */% |5 M* Z) T/ q" [" R
- if (huart->RxState == HAL_UART_STATE_BUSY_RX)
# v- Z; ]8 c9 \# X2 v, Y - {7 U$ s( d# \* `. O4 N" ^( Z. }) Z$ X
- uhdata = (uint16_t) READ_REG(huart->Instance->RDR);" _9 S2 U4 S: z0 T
- *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
. M; n7 N% g+ q" ]( c% H( e1 t - huart->pRxBuffPtr++;9 B; ?# h* P( r- Z; B
- huart->RxXferCount--;% `2 F9 @" l+ p" d$ _1 X
( r p: n6 n3 p: W+ x% }- if(USART1 == huart->Instance) {0 u, Y6 h! Q5 T
- HAL_UART_RxCpltCallback(huart);) }) d# o D0 L. U& E: ~2 {/ J
- }
+ l4 `$ ~7 \: T2 J+ S - if (huart->RxXferCount == 0U) {
6 o; J, y' ~9 Z2 I0 s9 @ - /* Disable the UART Parity Error Interrupt and RXNE interrupts */
' [# |' D9 _: t9 I# i7 ?7 L - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
% V- i2 u$ V" o# b" r: f. i8 _
M0 h- _ R) |( e3 x! f- /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */+ m% q# h7 n- e& q
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);& ]2 d( `) e" ?
4 ~# l3 N$ p) q6 v& q8 f# u3 k5 `- /* Rx process is completed, restore huart->RxState to Ready */( w6 f4 I' [9 H1 }1 d0 I. a! _
- huart->RxState = HAL_UART_STATE_READY;
" d# Z' u! P0 i1 W9 Y) G
% c y* B9 H, ~" Y/ ^- /* Clear RxISR function pointer */
8 [3 r# k8 P) Z' M% I! f/ Y - huart->RxISR = NULL;8 J7 Q7 z9 T5 ~8 Q# a {" w9 A* _8 L
0 \( s* l$ g7 P( B& J" S- #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)4 q* x( C7 h: M5 H6 p! p, J
- /*Call registered Rx complete callback*/$ D# V% S' @! D( o4 T# Z
- huart->RxCpltCallback(huart);
9 v2 q5 j ?% y - #else0 i9 } Z& l5 K' Y
- /*Call legacy weak Rx complete callback*/' R9 J) x* Q; t$ Z
- HAL_UART_RxCpltCallback(huart);
, j7 {- H. \8 Z% [ - #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
5 S z# s5 r& E; Z/ V - }
; `) r6 _4 Q6 Q+ C% e6 Q - }
- f( _8 N0 z1 {0 u9 H. [ - else
, _1 G; h0 A, J, G2 J$ A; E - {8 S" j% O5 w: a8 K: u
- /* Clear RXNE interrupt flag */
1 d; U/ b) `1 q" b" C2 p' t - __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);* W) F' l: I9 u
- }3 K1 `1 S" i% x* v
- }
复制代码 5 @2 A( ]0 M% w2 }( B* w, b' e
问题3. shell 放在Mgr task里面,由于内存分配128*4 不够导致死机# R- A& k S, |4 O
9 [ w9 m* Q. Z解决这个问题的方法是,去掉没有用的shell 指令,限制最多支持64条指令。 任务内存分配加大 256*4
( C, a$ {. o- ? }; [4 N/ n X
7 E* V* R* Q% v4 [4 U最终效果图
9 Z0 ^9 b! O) _ j8 _; i7 _/ P) G# g/ x+ S9 p# x8 ?- g# v, p) x. a
% u. D2 U4 ?, c0 z' x
3 U5 m, r1 x K8 m
( }2 `* I# w( O+ C |