测试ST 官网的 FreeRTOS6 z" i5 H O! Z+ d2 W
& N( v6 ~8 B6 T& y3 b" [4 U移植shell
, A5 i: Q( R) e" G* @主要是串口对接, 需要重写两个函数
( c3 d9 a5 v+ K" y6 m! e7 Z1 h+ E
- int fputc(int ch, FILE *f)4 H8 }) g) ^4 E8 l: O% j0 W R
- {
9 I, _+ ^, d5 Y, N9 m. | - /* Place your implementation of fputc here */
6 i& K! D @( a4 v" J - /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
9 k9 \& N5 f0 v9 T - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, UART_TIMEOUT_VALUE);
2 T. o4 a; z/ T, { - return ch;' u( a$ {9 ~6 X2 r( _8 [
- }
, |8 \% x8 a4 P1 ` - // #endif
X) ?# j! e T0 P4 g( B; U8 ~
& Y) ?8 p: L. M' f( h, p: K. m- char shell_buf[RXBUFFERSIZE]={0};
$ ~: m1 c$ H3 Y4 v - char shell_len=0; i& ~0 T( ~+ w5 Q# h+ T7 O
- char *shell_buf_head=NULL;) y1 w1 t% J* g+ o9 }$ H* @7 U
- \ I/ i4 G( {
& \1 A1 d! k' P9 v- int fgetc(FILE *f)+ h, |# U% N* T- N+ V
- {: _9 N! c1 ?7 k/ H- L
- ; b. l7 J- G( n, J1 [9 M
- while (0 == shell_len) {; ^* Y0 g, H; y
- osDelay(1);
9 p# Q- _' p1 `9 S4 T# E# A8 z - }9 w- \: t2 o) O a$ X, [
- char ch = *shell_buf_head;
: \* M7 `: D! R/ D+ @& [8 M P+ l - shell_buf_head ++; G; e+ E. a* L( s' _* Q) `
- shell_len --;
' }) @" e& B- Y- z
- S; `/ \% V; F% J v5 E- return ch;
8 {. T; [: g" S, q, W2 u - }
复制代码 0 ]) Z+ ~+ p3 u2 d8 V
增加了一个回调函数, 收到数据拷贝到shell_buf, 然后重新初始化串口中断接收参数,指针,size,count+ o1 A( p+ w( `/ q7 d: e
9 g( `' M6 ~# [* d# p( X( e& U
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
0 M6 o: x$ w* M# O - {8 \0 L. b* v4 z( }, G$ p( l1 ~$ [
- /* Set transmission flag: transfer complete */
, N9 |5 ^, G" n+ n. N. p3 ^: U - if(UartHandle->Instance == USART1) {: O: D I9 O1 w }+ Q
- // UartReady = SET;
; u2 ^+ H2 k3 ?) L7 }/ R3 y/ [ - shell_len = UartHandle->pRxBuffPtr - aRxBuffer; @( P$ a- s3 A& P
- shell_buf_head = shell_buf;& h @, v8 W; c' ~4 ^6 x+ @* v
- memcpy(shell_buf, aRxBuffer, shell_len);, k, w% B& q- ^6 x8 Z4 J$ t
- - ?1 B$ q& G/ `% |4 q8 O
- UartHandle->pRxBuffPtr = aRxBuffer;$ K. b1 ~0 v- ~
- UartHandle->RxXferSize = RXBUFFERSIZE;
1 u k- U7 @! T+ I% h2 P - UartHandle->RxXferCount = RXBUFFERSIZE;
* Z% @+ Q" U m/ k/ x - }, y/ X, e4 M5 U7 E& \$ k2 n, A
- ) H" \" J/ u8 x. @! r
- }
复制代码
) g$ E- Q n$ t( r遇到的问题, 1. fgetc 不能直接调用HAL_UART_Receive, 否则会死等,导致其他任务无法运行。9 ^+ {8 ]9 A$ T0 r( N. B& L
# Z; S3 R5 G9 L" J% x
解决这个问题的方法是,接收采用中断方式。0 @- G d8 R9 U( w# Y
" z1 U. o& ^2 E# \5 f+ K问题2. STM32CubeMX 生成的代码,串口中断接收是固定长度的方式, 对于shell 不适用。# \2 H$ v, W) g% a# \! k
# M! J8 q6 [3 ]解决这个问题的方法是,修改中断处理程序,如果是调试用的串口,直接处理接收数据1 ? ]/ \5 o/ o7 |# A8 l7 J7 U
+ O! E! m3 ~) D
- static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)' L4 Q0 d8 Y! y+ ^; n) s
- {
1 ]! F7 z" d$ c, Y - uint16_t uhMask = huart->Mask;
. y8 t1 Z) T& C/ i - uint16_t uhdata;
, V, Y: B! @+ }, F) a' n
- K9 t1 b0 s9 R6 x6 s- /* Check that a Rx process is ongoing */7 d' \: |, `* V% ]
- if (huart->RxState == HAL_UART_STATE_BUSY_RX)
! N3 n& x) S7 ?4 x - {8 v! U2 z/ \" }7 u. A3 ]
- uhdata = (uint16_t) READ_REG(huart->Instance->RDR);( n0 [& w& [( ]2 N) X$ W
- *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
7 U) M+ u0 h4 r! j2 f - huart->pRxBuffPtr++;
% |' }( q+ s; W - huart->RxXferCount--;
7 w) ?& y9 b; H+ X& x
! S8 s0 Z; P) G+ z" C3 r* ^- if(USART1 == huart->Instance) {+ Z/ t2 @" G; Z" O
- HAL_UART_RxCpltCallback(huart);$ n% o* ]9 P! c! s. Y+ w) K7 V8 s
- }
$ Q% u& O9 n* V+ {; Q% i - if (huart->RxXferCount == 0U) {
# z; J! ~+ w2 E( w - /* Disable the UART Parity Error Interrupt and RXNE interrupts */- O: Y; w! w7 D+ e' L7 X/ ]
- CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
: ^- V! H# s& X0 V4 J. }# d" j
5 ^% S3 k0 G' K% z5 D' ^7 ^- /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */' }- n1 w* P0 [6 g5 H* m1 t0 A" z
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);9 z+ _! H: K( s* M8 e
) s% B+ R( L$ V; H5 j3 D8 ^+ {3 R- /* Rx process is completed, restore huart->RxState to Ready */
+ h- }4 W# P' \5 c4 s - huart->RxState = HAL_UART_STATE_READY;
& a; L. c/ b+ h8 u
: \- U& w" Q# t- i. \1 }- /* Clear RxISR function pointer */" K) C5 y* a8 X1 G& S" G) B
- huart->RxISR = NULL;9 u4 J' H, J( E4 Y5 @
+ W* j+ ?0 P2 e7 x- #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)* i Q# R! ~& Y9 s1 J3 O
- /*Call registered Rx complete callback*/
- _, h9 ~! G' P0 w - huart->RxCpltCallback(huart);& m4 P0 M2 c4 u, ^! j; ~4 r0 L9 N
- #else' J" Z3 K9 s) ?# k& Y
- /*Call legacy weak Rx complete callback*/
$ c; Z5 l& P- f9 e- i( @ - HAL_UART_RxCpltCallback(huart);" |8 F4 q$ c, f9 S
- #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
4 p- C9 x$ p+ K% i& | - }
1 J" x o, g9 q, q( N" j$ W - }1 ? C$ A5 i! M# Z" }* L$ H
- else
. `$ H+ a8 O* N8 z1 t9 L/ g - {
7 }5 a" [ p8 S- c% ] - /* Clear RXNE interrupt flag */: u4 x% I3 k1 A. F9 q/ W4 U
- __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
/ h: Q$ u" ~+ f v - }: c' L' `8 Y, B* p
- }
复制代码 . q: Y s, h+ R
问题3. shell 放在Mgr task里面,由于内存分配128*4 不够导致死机
* b* n8 a' m# E: M$ z. r- U( M8 ~
解决这个问题的方法是,去掉没有用的shell 指令,限制最多支持64条指令。 任务内存分配加大 256*4' \4 H: Q+ X) c8 U' L$ q
$ p5 {- {: g! w" e) u+ ]
最终效果图/ V" y/ U2 i* @
' X; Z' P# d: x
5 O, G$ r: N7 |/ q( }2 ]
! |7 G4 r$ X3 p4 V" a( G$ Y$ A
; G2 ]' g3 ?) ^9 z |