测试ST 官网的 FreeRTOS
+ K+ P& m/ j8 Y2 Y4 F$ Y
% @3 c3 I2 a1 Y移植shell
' w/ e# j( n3 K* O主要是串口对接, 需要重写两个函数 O7 r( }- S U3 q3 Z9 `- r" d O
! W' X0 |; K! f
- int fputc(int ch, FILE *f)2 [$ g& u- l4 F5 R7 V2 F' i
- {
$ ^1 v4 V7 W6 V - /* Place your implementation of fputc here */) U7 Q; C( x& X- m& y
- /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
- B$ M0 b' Z' B. @8 W - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, UART_TIMEOUT_VALUE);
9 y7 |4 N+ I2 K2 e, c# C. P" b - return ch;0 }6 i6 L( l3 _* @) O+ e, }4 `7 ]
- }! l7 g3 c1 u# `. e4 }, ~- l6 M
- // #endif
' k5 M( V: N2 A
3 D) P7 I# M0 Y4 Q1 s3 e3 }- char shell_buf[RXBUFFERSIZE]={0};/ u( x: ?: C; Q9 D& D
- char shell_len=0;* x5 n3 s) o" l* W
- char *shell_buf_head=NULL;) L8 ?, {+ I0 W/ n1 t* t" y0 i0 M
- 5 X. L7 U3 w, h6 i: G- P8 Y! v7 |$ `
o* N8 H; i' G+ p- int fgetc(FILE *f)
+ F/ i0 r3 J+ j3 @' }! V4 N - {
3 o. e: ?% K. Y$ Q, w$ c1 P
! k) k7 N ~, r( T3 G( r: x- while (0 == shell_len) {
3 v+ j# G- e; e, R: s - osDelay(1);$ H% g: S J: w, e& K! ~
- }$ @5 ]* n* v5 V
- char ch = *shell_buf_head;6 b% N* b% N0 R/ i$ D0 ^7 Y$ o
- shell_buf_head ++;
# F7 a6 I( J" Y4 S2 V - shell_len --;
5 W4 T9 v+ V1 r1 n1 q2 \ - ( f! A; e0 g. o) p; }5 B
- return ch;
7 {) B, q; J0 F& Z& r- W - }
复制代码 6 {$ J: R5 L0 q1 R8 c- I9 G
增加了一个回调函数, 收到数据拷贝到shell_buf, 然后重新初始化串口中断接收参数,指针,size,count( [/ |, I) G0 D- h6 a, ^0 C
' I7 H7 ^. V2 d b8 O- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)6 k" S" F. G; r
- {
' |4 g, G7 l7 j' W; k( |. h - /* Set transmission flag: transfer complete */+ i3 u1 t% |0 L5 ]+ i$ _
- if(UartHandle->Instance == USART1) {$ r2 [3 c1 D! p7 l G7 U
- // UartReady = SET;
: |0 b5 o2 V. f7 ^ - shell_len = UartHandle->pRxBuffPtr - aRxBuffer;/ T2 w( @6 y& Q. b& r& O
- shell_buf_head = shell_buf;
8 ?0 n; E& V$ I9 r6 T) } - memcpy(shell_buf, aRxBuffer, shell_len);
2 ~& W) ]+ s& G" w$ m3 F [ - @9 d' ~7 i! b, |+ c; n4 h
- UartHandle->pRxBuffPtr = aRxBuffer;
6 O& e U6 r$ [% G( h+ P0 J - UartHandle->RxXferSize = RXBUFFERSIZE;0 z- j9 P0 ]( h/ ?! n! z
- UartHandle->RxXferCount = RXBUFFERSIZE;
# b7 L+ L& O# y9 S5 |- |9 x# h' ] - }- Y3 z$ k& ~3 S' Z
- ( N/ V8 q9 L" x5 x. B) o" _; s- m% x0 d
- }
复制代码 & G$ U$ X8 \1 B- f) d- m0 J. X
遇到的问题, 1. fgetc 不能直接调用HAL_UART_Receive, 否则会死等,导致其他任务无法运行。) S: J; W- U* v! A
' y c' m; @" }& P" D) z0 D6 q解决这个问题的方法是,接收采用中断方式。
1 Y; V/ f. D& V' u6 p% g) F
0 q) ?2 X% j& J& p6 L% w问题2. STM32CubeMX 生成的代码,串口中断接收是固定长度的方式, 对于shell 不适用。% X. B9 K2 n. |" e/ ]
' M' K# g. d+ K解决这个问题的方法是,修改中断处理程序,如果是调试用的串口,直接处理接收数据
( U4 o% B9 K! [
( b7 w5 F% r+ z9 X- static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)9 N0 g* g! y; B6 r' Z9 U1 C9 W
- {
9 @6 f3 u" `7 M$ h - uint16_t uhMask = huart->Mask;
/ U% A1 `! j) I( o6 S - uint16_t uhdata;" G" s8 D% `5 u4 u& E' d
- 1 u! b. N: c% b! ^; | x
- /* Check that a Rx process is ongoing */( |/ Z' P9 n; ]. ]; y" b' |
- if (huart->RxState == HAL_UART_STATE_BUSY_RX)8 ` {$ e6 e# @9 D( s, K, Q2 N
- {
5 u1 q9 Q) Y2 s7 A! T4 S - uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
7 m4 }3 n$ J4 G" S - *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);6 S: h8 q) T; O( V4 o2 l7 O! h
- huart->pRxBuffPtr++;
4 ?$ Z! _- B3 d+ l" X# n) ?/ j - huart->RxXferCount--;0 A! ?; T Q6 j& m% A
- - @- f3 N8 \: E6 c# M
- if(USART1 == huart->Instance) {
5 e6 j* j9 X" ?$ Y/ ^9 F - HAL_UART_RxCpltCallback(huart);
5 r- Z6 L! ]1 I1 b- {8 ?# u$ E - }
8 n- w) y6 q' `' _ - if (huart->RxXferCount == 0U) {% @. h" J5 L7 h9 J
- /* Disable the UART Parity Error Interrupt and RXNE interrupts */& `9 r/ z6 m! v& P: e# n+ |; J! ^
- CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));/ H, x! A5 W! ^. a* D
( j0 k8 d( @( T$ r% F- /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */' F) D) L0 `9 z1 w9 ]% L( z) U
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
' ]1 a7 z" V# L0 S% I - 2 X+ {2 f5 b% W5 z; {
- /* Rx process is completed, restore huart->RxState to Ready */
: f6 V7 E1 F! L6 ^: O - huart->RxState = HAL_UART_STATE_READY;
L( r! o5 {8 p( O, s5 S7 t& `
' N% @( s* o- z- P0 h3 g$ B- /* Clear RxISR function pointer */
; V; X' {) S" {8 r, h* b: r - huart->RxISR = NULL;9 |. l$ l6 n- W
- * k6 X& z! T+ h" N* {$ b
- #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
+ X/ O R* S! \# m$ W( L; H$ V - /*Call registered Rx complete callback*/; A0 X& N y K( p( ?
- huart->RxCpltCallback(huart);' I" F6 {( b6 b/ X1 J- ~/ A/ E
- #else# U0 K) ?: U9 f* v; h% y
- /*Call legacy weak Rx complete callback*/
1 f- |; G0 [$ j: r0 o H - HAL_UART_RxCpltCallback(huart);
: l$ {4 f( d- H9 |* q2 x5 @; r4 e - #endif /* USE_HAL_UART_REGISTER_CALLBACKS */
8 k; @' R) {, a5 \) D8 h) o- ?, M - }; ]8 p6 r9 x3 B) C7 V
- }
! ^/ [2 ]" W) s5 @$ \, m1 h - else
4 `* c8 U( E; v8 o6 e" @9 @# e - {/ t* x; Z2 N- D& e2 f6 ` {5 S
- /* Clear RXNE interrupt flag */
5 ^- p% f9 \* u+ `$ ~+ O1 c t2 ?2 \ X - __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);, I. E7 M/ H4 x/ U
- }+ @% M) @; n! W4 ~1 J2 t/ c1 o& N
- }
复制代码
; e! R, N# w6 g& b5 G$ N) S问题3. shell 放在Mgr task里面,由于内存分配128*4 不够导致死机
* ?5 d3 {' N2 O4 L3 P/ O
3 ]+ N7 f) U8 F1 n( h+ w解决这个问题的方法是,去掉没有用的shell 指令,限制最多支持64条指令。 任务内存分配加大 256*4
) \! R, ]$ X( a, q: f" ]
& V3 x$ {2 w: L0 B: F! V; K) d最终效果图
; ~$ j! z1 H) W# P3 ~( p$ @
2 C0 u* j* v# M- S: V
6 ?. z! \5 x$ v6 U$ L
1 ]$ j) S1 C5 \# l
0 W1 u/ U" ]# Y' C |