测试ST 官网的 FreeRTOS
" R1 J! c. J1 y5 T( A, v6 P% g/ S5 o/ _/ L
移植shell
n1 m" ]2 C$ M% _: k主要是串口对接, 需要重写两个函数2 t9 n- n2 O6 p8 }7 x" n
^7 ~* P! y& r- J, l- int fputc(int ch, FILE *f)
8 U) j6 e, w4 ~* c, m& E j - {
& m7 O" s9 S/ X& F, U4 t - /* Place your implementation of fputc here */" e2 s: _5 _8 x1 d. `& A
- /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */1 z5 Y# K, U/ K+ L4 n
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, UART_TIMEOUT_VALUE);
* \; X- o' J0 n) J - return ch;
: L6 j) `$ r9 h# W- b& E - }! D9 ]4 @3 Y( G. a; V
- // #endif
' G6 J! G$ J( D6 m. ` - , C" O. J+ B) Z0 G/ ]7 O3 @" `
- char shell_buf[RXBUFFERSIZE]={0};6 @1 @) z2 ]. z1 p
- char shell_len=0;
: W4 a5 O$ Z8 H1 B* t0 K - char *shell_buf_head=NULL;
# M0 s: [( v" k6 K3 c* D% ~) @ - 6 U {5 x: W! ]) S- }# g; b
- 5 t! ~9 K q: G, f5 _4 w) ?
- int fgetc(FILE *f). u: c4 B( q* Y& r
- {
2 ?+ q& Y: y8 b' I H% ?
1 c. ]. {6 b/ h" U5 m5 r- while (0 == shell_len) {! O8 r4 V. E, O) |/ _& y
- osDelay(1);
/ _0 h* J% I' h9 | - }
- h( Q U! Z. ? - char ch = *shell_buf_head;; e: n/ }/ W+ e! g. {( [
- shell_buf_head ++;* }% o# Z, P g# O/ P! ]. ?
- shell_len --;& n! k# O5 @+ W! Y4 P% N
- / A5 f$ e: L# a3 Q' q+ c
- return ch;
* B s8 _9 U J1 A - }
复制代码 . d' C+ O8 D( L- g* s' v O" s/ O
增加了一个回调函数, 收到数据拷贝到shell_buf, 然后重新初始化串口中断接收参数,指针,size,count
. Q7 K& Q/ L; R# U# u8 w0 l, M& h7 B& m# \) x
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
" c: X- B: D, h. N - {
( ], c0 e# W0 ]) | - /* Set transmission flag: transfer complete */# i$ _- f% M6 _9 v% N; J
- if(UartHandle->Instance == USART1) {# _. K$ v5 R3 S2 M% y. g
- // UartReady = SET;, I) A5 A, l \% H0 N( A
- shell_len = UartHandle->pRxBuffPtr - aRxBuffer;7 H, l7 I$ h! I1 u- k( J; F6 Z
- shell_buf_head = shell_buf;
2 f, Z7 e# }/ T. H/ `" J - memcpy(shell_buf, aRxBuffer, shell_len);+ N% V9 C3 {+ i2 B0 l
/ R, e# e& H. x* z0 L- UartHandle->pRxBuffPtr = aRxBuffer;. {: J6 i6 l& x1 `/ v
- UartHandle->RxXferSize = RXBUFFERSIZE;
1 C5 c! U, `, e8 W2 P - UartHandle->RxXferCount = RXBUFFERSIZE;; u3 U8 C) o$ ^4 m y9 s
- }
5 ~8 S; t u" X) O: q
# d' H9 s9 |0 _1 O; J& c" ^- }
复制代码 7 ~5 `8 B; \, y/ }/ ~
遇到的问题, 1. fgetc 不能直接调用HAL_UART_Receive, 否则会死等,导致其他任务无法运行。
# C* J6 @; b0 c7 o+ M$ p* F4 p- r* ]4 A& [! [
解决这个问题的方法是,接收采用中断方式。4 a! c3 n! X7 r6 @' h. @% f
1 |6 @0 ?9 s1 K) l: u( ?5 y- g问题2. STM32CubeMX 生成的代码,串口中断接收是固定长度的方式, 对于shell 不适用。
$ [0 I: M5 p* a" X1 b# [0 k' w, s" k* q9 Y9 x1 S" ?- @" s5 k
解决这个问题的方法是,修改中断处理程序,如果是调试用的串口,直接处理接收数据
, G# e. y; y [8 F8 J
$ g' \/ i" k v8 {& M- static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
& N7 D5 v: G1 T& ~& m - {8 B3 C2 V; e& |2 O. \ M' k
- uint16_t uhMask = huart->Mask;5 {; B- |! L, S1 x# t
- uint16_t uhdata;
. O3 F! h: Y9 Z, T. {, e9 S - 5 j+ N0 t4 I I ^3 y
- /* Check that a Rx process is ongoing */5 T0 T! _* H$ a# A6 H
- if (huart->RxState == HAL_UART_STATE_BUSY_RX)+ L6 d9 [' \' f1 }
- {, l- w- l2 W3 d* T8 q9 ?
- uhdata = (uint16_t) READ_REG(huart->Instance->RDR);/ d) H6 n- G5 C5 S/ Q6 i
- *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);; Z* p$ |# Y5 [: t
- huart->pRxBuffPtr++;
' |" `; H& h* ~! K; `, N$ z - huart->RxXferCount--;
) `5 B6 A' s' c - ' u% W9 _! `; B, S
- if(USART1 == huart->Instance) {) X6 m8 k# T. i8 R( ?: |- C8 `6 t z
- HAL_UART_RxCpltCallback(huart);
- U) T0 R$ @1 ^ - }9 {$ @, C% \" V
- if (huart->RxXferCount == 0U) {- I; \7 d' O" l, o" A) r# V
- /* Disable the UART Parity Error Interrupt and RXNE interrupts */, u5 V' R& M) C
- CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));! g8 H6 u0 s5 q# @
- 3 D$ y! N/ h" r+ l& a9 P
- /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
+ W! k( M0 c2 _+ t3 E8 ` - CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);4 ?$ r- P* A" F, {% Q
0 E1 T. C: X, z; T) {* A* b- /* Rx process is completed, restore huart->RxState to Ready */, N+ ?* h) L( e& S2 y( V
- huart->RxState = HAL_UART_STATE_READY;" v4 a* ^+ F% V8 T5 {' J1 q( C9 Y
! u3 O" V; ~3 ^- _; }- /* Clear RxISR function pointer */
/ Z2 `! ]7 a ^6 P* ]$ m - huart->RxISR = NULL;) C* ?/ f" v4 D4 U# t* g) H( D
0 T+ y0 y7 O J7 K' |4 v* D a- #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
, ]5 D) e; s1 f+ L( a( r" Y - /*Call registered Rx complete callback*/
& y/ u, \6 s4 J6 T$ K - huart->RxCpltCallback(huart);
3 z2 v- p7 j: ]3 O9 F - #else
2 v5 A0 N4 T" D f$ G) r - /*Call legacy weak Rx complete callback*/* [& | L! A J0 X% p5 q
- HAL_UART_RxCpltCallback(huart);! a( R1 w3 ^0 K: Y- A% }
- #endif /* USE_HAL_UART_REGISTER_CALLBACKS */2 T6 F0 `4 h9 N- b; s# m
- }% j+ q: j0 g5 |8 p) o
- } \) O9 ?5 L: [+ _6 u
- else# C9 P4 q5 D- W5 b+ w9 Z# d0 ?6 Z
- {; ?. e p7 I. S) L0 H" r% i
- /* Clear RXNE interrupt flag */& J' j6 }4 N! i* G5 Q- G
- __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
/ Q) y! T4 R6 I/ V5 R - }
?5 V$ p- F% v- j' \ - }
复制代码
0 z' |/ W5 T$ H, _' Q' x. i$ t问题3. shell 放在Mgr task里面,由于内存分配128*4 不够导致死机
6 g( N1 @+ K7 h2 T
* B& `5 K0 J s+ H+ @1 m解决这个问题的方法是,去掉没有用的shell 指令,限制最多支持64条指令。 任务内存分配加大 256*43 C: L- X X+ @5 g
4 i2 ]; f4 H7 [& y% C) K
最终效果图
( ^ V" [0 Y/ u7 P- \" N3 ]1 g7 m
1 w, `; `7 X& t6 ^2 ?2 k; W) @, \" {$ X" y7 c O9 T
/ g9 @+ e8 [$ t' m0 n- I6 X, w |