测试ST 官网的 FreeRTOS# ]6 Q) Z& k; _4 L9 c
3 ]$ w' P# `3 _. a' }
移植shell
: ^4 i9 j: y) w2 O& E) r0 s7 V主要是串口对接, 需要重写两个函数
6 o; w# d2 L, ^' s3 X. V( J3 s ]# @, D4 m6 g2 p8 J7 G& }
- int fputc(int ch, FILE *f). J: k/ ?: L! [& U. ]2 b, C
- {
; v$ c- z, R4 W" V - /* Place your implementation of fputc here */
! w4 z; g* |8 U2 I - /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */. M/ ]3 `8 C1 }0 e0 b
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, UART_TIMEOUT_VALUE);
4 z) z0 C1 x N% e) m& X - return ch;
8 d _3 K; C# H) e8 [& ` - }: c/ q9 v& S' W$ X3 m$ j, H, u
- // #endif, t" w |/ U+ R7 e2 N
- 2 ~ Z- e9 V0 ?3 n; C- t! T
- char shell_buf[RXBUFFERSIZE]={0};
- ?" L6 Z7 t! v - char shell_len=0;
9 W( z9 I4 b% f# S - char *shell_buf_head=NULL;
, |6 W7 I; I# I0 d
! I+ [: i& o! X: w+ S
1 {7 B2 A+ V, h: _- int fgetc(FILE *f)5 r/ Z) d6 p2 N9 @5 r0 t
- {8 p; K' t( C1 {
x, S: |. X& l8 {3 Y% e5 b5 a- while (0 == shell_len) {
2 [/ l9 e0 T( x4 b" r- E }( _/ c+ Q - osDelay(1);
) R+ e% n* L2 p* R3 } - }3 t& q3 ^0 X% u
- char ch = *shell_buf_head;
% c( _+ c" c3 U# F. ~! ~. L - shell_buf_head ++;
' d4 j3 l/ t! v - shell_len --;
- q. O r) Z9 R, Q2 `- k
" c% ]9 G" f8 t1 R" ~+ ^, R- return ch;8 N- H: X# N# C4 c$ I$ C. Q
- }
复制代码
/ I8 O; x) F, Q: n0 x增加了一个回调函数, 收到数据拷贝到shell_buf, 然后重新初始化串口中断接收参数,指针,size,count
; ~/ O# J, Q5 q3 G" P3 h# ]3 \$ L% a
- H1 r$ ~2 a+ I- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
6 g$ \7 `# f! D. A& e - {, V8 b; c! F) v
- /* Set transmission flag: transfer complete */
" G5 o* n5 Q* W - if(UartHandle->Instance == USART1) {9 Y i& b1 ^8 m
- // UartReady = SET;
( n% y6 E" _8 L$ B* Q5 n. j - shell_len = UartHandle->pRxBuffPtr - aRxBuffer;
$ Z$ q8 V) ?! @. z( B8 z& Y# @ - shell_buf_head = shell_buf;
( P! T9 a/ N0 l" A - memcpy(shell_buf, aRxBuffer, shell_len);
5 _ d, i" r* l. Z
" O; N0 X5 f; @! f9 i% `/ t- UartHandle->pRxBuffPtr = aRxBuffer;" X& P/ I7 u% n
- UartHandle->RxXferSize = RXBUFFERSIZE;: @0 K( e* }0 L9 n& @" `2 R
- UartHandle->RxXferCount = RXBUFFERSIZE;
; s! ^2 s) ?& |" L$ \ - }
! o0 N' V; g( j) a8 x8 j; t, n- K
5 ]" g0 b$ B1 q3 s" |, U- }
复制代码
0 c9 X- J, I4 u遇到的问题, 1. fgetc 不能直接调用HAL_UART_Receive, 否则会死等,导致其他任务无法运行。
$ [$ o. D T2 M+ ~) `$ h5 w0 o. C
8 ?! h6 J, H9 N. [. q& Z8 ^4 W解决这个问题的方法是,接收采用中断方式。
) `+ [% ?! O, @* m- Z _' R& {/ Z, y9 Z
问题2. STM32CubeMX 生成的代码,串口中断接收是固定长度的方式, 对于shell 不适用。
. Z- b- D$ F- K. r; A. o. ^; I9 b6 t+ m
解决这个问题的方法是,修改中断处理程序,如果是调试用的串口,直接处理接收数据
+ B3 Y3 D* Q) ?" Q2 q4 h. `
x y" X! |1 t/ L! C5 l% x9 M+ b- static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)# e3 `7 U0 L( Y9 Q; _5 C) l& ^2 f
- {( O+ m* a+ p) v1 ^6 O9 w6 u
- uint16_t uhMask = huart->Mask;
$ Z2 H) a: m- N) h) v - uint16_t uhdata;
& U4 s" U1 q/ c# Y: s - $ E5 M. H( u' L4 a3 K6 r* O8 j
- /* Check that a Rx process is ongoing */
" _3 V0 c5 k" T) n4 ~ - if (huart->RxState == HAL_UART_STATE_BUSY_RX). y- R( N) ^8 ~/ q3 t, i( s$ H, z
- {% T* m, a7 k x+ o n
- uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
2 x Y! k6 R+ Y! w) |; ^ - *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);2 T0 g, p; _4 V- P" [1 f% _$ y9 K$ {
- huart->pRxBuffPtr++;6 b3 P% Q' Y1 G) b/ K6 k: P% B
- huart->RxXferCount--;
8 o1 x3 U! k( _& h B - ; K9 ?' x5 a" C& S* N: n
- if(USART1 == huart->Instance) {4 X, k' J# ^! M; f) v- o
- HAL_UART_RxCpltCallback(huart);
3 y( ?" a s) P% s5 \+ S, g) x - }: G* g( u; f8 T2 ?9 m
- if (huart->RxXferCount == 0U) {: p+ U( U% z2 i* A
- /* Disable the UART Parity Error Interrupt and RXNE interrupts */
+ p( i8 [) v' D- X6 S! K - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));. C2 K- c% ~0 M: L
- + V2 Q. Z, Z% F6 z5 }
- /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ n8 D, K- F r2 f# m - CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
7 f0 t5 a8 B* y, k/ w6 W
( T! H+ t N8 s' q- K4 m$ l- /* Rx process is completed, restore huart->RxState to Ready */
2 G' @$ H1 V& n, s: M5 r - huart->RxState = HAL_UART_STATE_READY;
% k) @$ }9 Q1 Q" u- E5 z' o - 8 V6 [6 h# U: ]5 ], y
- /* Clear RxISR function pointer */7 U! o: t2 o# i* a/ `3 P
- huart->RxISR = NULL;
1 @, @* r) a0 J; I - 1 z& q$ G% y/ h3 j8 @4 k6 s5 T# ]
- #if (USE_HAL_UART_REGISTER_CALLBACKS == 1), @+ x' y$ l4 C, a
- /*Call registered Rx complete callback*/
M/ m' v6 q' X. k: G; d& ]& } - huart->RxCpltCallback(huart);
w& Q* N) Z8 q9 B' y1 \ - #else3 g* T3 I- C" A5 a% o* o ?7 F7 W
- /*Call legacy weak Rx complete callback*/
5 @: F) ?3 N& n+ J; T( x - HAL_UART_RxCpltCallback(huart);" ^! x" T0 B; }: `
- #endif /* USE_HAL_UART_REGISTER_CALLBACKS */9 `4 N6 V! m( i D- |3 P) c
- }
8 X4 p6 r5 O, E- P' w - }5 F! } X' ^. A
- else
. z3 d$ L* I% Y2 m( _3 h - {
% [0 Q% ~; s8 i - /* Clear RXNE interrupt flag */! L A# S+ u* [, x3 U
- __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);% B5 h V. H9 S) N2 K3 i
- }9 w& l) q7 g G2 s% d! L* U
- }
复制代码 & [9 X5 u ~& @- N) n9 K
问题3. shell 放在Mgr task里面,由于内存分配128*4 不够导致死机3 t7 V# w' h g: ?) g
A) B/ {- u* e" i, \7 {' u
解决这个问题的方法是,去掉没有用的shell 指令,限制最多支持64条指令。 任务内存分配加大 256*4: `, r+ H6 i3 T0 C6 a
" b1 @; L& f; l7 T0 V& S, J* ?最终效果图4 V4 l! H/ s; z, l6 {
* a8 B/ Y9 L" i9 C. a' |
* {% @( L5 A* P% B
$ R5 j x" F# Z6 o3 P
% X4 H% o! @, F; T1 w$ o4 w |