测试ST 官网的 FreeRTOS3 i( Y1 Z# T9 `' [" Q4 C, Z
, w8 Y. B" {6 O1 B7 ~$ }移植shell
, `/ d' `- s' I7 ?7 l# a( C3 `7 b/ c主要是串口对接, 需要重写两个函数
4 t+ `1 C% `3 `5 q: F. F- s8 a1 @- y4 v: {
- int fputc(int ch, FILE *f)
7 D2 o) b9 D, t - {
, j1 x7 t, }8 [( F' q - /* Place your implementation of fputc here */- G& Q0 X2 T; C6 T4 }+ m
- /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */9 R, y' g9 T: F5 u. I+ o
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, UART_TIMEOUT_VALUE);! k6 x4 V5 Y' i
- return ch;
( Q' a( [6 y1 x. c+ n! a$ q - }7 \/ p1 X* P ]0 M9 w0 W. U+ }6 h
- // #endif
. e* y4 R5 }' v9 D - : ^8 z- b2 K( M+ @/ @5 Q o
- char shell_buf[RXBUFFERSIZE]={0};; i- [. d0 c) y- F
- char shell_len=0;# X* \# U" Z7 G6 `2 V% A
- char *shell_buf_head=NULL;* }7 ~5 c+ I& n4 S Z9 K, {) r& e2 G8 ]
7 Z i- |9 J4 ?# T( k" J
$ H- w( N/ H+ T9 N, Z- int fgetc(FILE *f)
$ c" D3 {/ I2 j! u9 \ - {( w; J( j) Z* ^: c9 i
- , \9 u; g: R7 c1 C$ w0 a
- while (0 == shell_len) {. j5 N3 V2 s! A( d
- osDelay(1);
7 `" D: I5 l9 b: Q - }9 [2 X0 Y5 u: e0 ]& b3 _
- char ch = *shell_buf_head;
8 L7 k1 w7 g- A9 B- o1 U - shell_buf_head ++;
& t+ ]' T1 ^) j6 j1 r6 n - shell_len --;
% w0 `" e7 @! W - * m8 m5 v/ L3 l8 k
- return ch;- M! @" d$ [' L; q
- }
复制代码
3 r4 y" O' }: C( y ^' e6 v; }增加了一个回调函数, 收到数据拷贝到shell_buf, 然后重新初始化串口中断接收参数,指针,size,count/ R/ S1 y I) a
6 ~, C: B% E( ?9 A; E- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)+ z7 r6 Q* z1 O/ m- e9 L4 G
- {
5 |' n0 C3 u6 E+ l4 Y3 S - /* Set transmission flag: transfer complete */5 _& }5 t9 `3 r! z
- if(UartHandle->Instance == USART1) {
( L. O% a7 ^) F: h9 V9 }) T - // UartReady = SET;& h. h7 P7 U5 b" c$ R" w
- shell_len = UartHandle->pRxBuffPtr - aRxBuffer;
* y7 V' }9 \' o - shell_buf_head = shell_buf;
! M# D" Q" @2 w0 V - memcpy(shell_buf, aRxBuffer, shell_len);
* P. }4 H2 S e0 ]' o
4 t% j# x1 [' f- UartHandle->pRxBuffPtr = aRxBuffer;: h! s3 r( w8 T
- UartHandle->RxXferSize = RXBUFFERSIZE;
5 z( I$ i# |* y& Y9 Y( g - UartHandle->RxXferCount = RXBUFFERSIZE;, t7 O! d) k( c8 U. _
- }2 D7 w0 j: [5 ~6 `1 t$ Q4 q" W+ h( C& e
* W5 T- _" {7 X I; l6 q7 j' C/ |- }
复制代码 ( [/ N% c1 z( z1 q1 ^. T
遇到的问题, 1. fgetc 不能直接调用HAL_UART_Receive, 否则会死等,导致其他任务无法运行。
# P& \) y" e7 ?; q4 c
/ }2 `( ?+ A* e& v1 j解决这个问题的方法是,接收采用中断方式。
! [1 x. [* t1 Q8 @ V+ U% K- C# [! [' ^1 J
问题2. STM32CubeMX 生成的代码,串口中断接收是固定长度的方式, 对于shell 不适用。4 d0 P0 p5 M( F% A9 t/ B% H& i
" P X7 T6 h! I7 i
解决这个问题的方法是,修改中断处理程序,如果是调试用的串口,直接处理接收数据4 M8 F) g8 h0 U5 D, D8 a3 }
" a: }' C1 R! R8 `. B7 s
- static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)0 B0 j- c4 l+ C
- {! L5 ?/ b2 n5 d& @
- uint16_t uhMask = huart->Mask;
# O( G* \" @/ l, @1 s - uint16_t uhdata;
. ^2 S, g0 X3 Y' C& F
4 a, |* E" B- D5 a( G- /* Check that a Rx process is ongoing */* t7 V4 d. [+ U* l Y
- if (huart->RxState == HAL_UART_STATE_BUSY_RX); e9 P0 M5 ~& P5 n$ J
- {# t' _9 d. R2 s; U6 G5 M
- uhdata = (uint16_t) READ_REG(huart->Instance->RDR);. Z' ~8 C, e6 w% a
- *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);2 A/ s, `' x! x
- huart->pRxBuffPtr++;
% s9 y3 ] M4 A5 _( J& w& d - huart->RxXferCount--;
8 j1 b6 U& c6 d* ]0 w9 N
^7 {" h6 Q1 W1 Y5 S- if(USART1 == huart->Instance) {) ?+ V$ k9 v" ?+ E' o* }
- HAL_UART_RxCpltCallback(huart);
3 Q$ Z' C) l9 o3 r- P/ w - }3 v5 u. r j4 k/ v/ `1 u* X% D8 A
- if (huart->RxXferCount == 0U) {1 K/ s8 G' u8 I. m5 f
- /* Disable the UART Parity Error Interrupt and RXNE interrupts */
[" W# Q( I; O3 J9 Q4 d6 B - CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));
8 M- h, w% |& Z% v9 T
0 _! P h+ M# c# ^5 `9 D; r' D- /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */* p9 ^' u2 B! c
- CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
0 y; B% b) \! p4 O
+ H ~1 w$ B( {0 o! w8 c3 C0 t- /* Rx process is completed, restore huart->RxState to Ready */
8 g6 o# f2 n$ a5 Q8 p+ n: v, U - huart->RxState = HAL_UART_STATE_READY;
- r6 m. L7 P6 j) s L - 9 J6 y. w$ w" D- z" b; `
- /* Clear RxISR function pointer */7 D k2 a/ f- I. t1 H; W( O# w6 T
- huart->RxISR = NULL;+ h: m1 r! W5 r- {5 n# @
% Y$ X4 r' }& |. K2 \- #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)3 B, o. k( U4 c
- /*Call registered Rx complete callback*/
: t- _1 v8 `! U - huart->RxCpltCallback(huart);
( ^( ~/ E1 Q2 C1 H) N - #else* ^8 R+ Q9 G6 T$ k6 ^$ ?2 R: F
- /*Call legacy weak Rx complete callback*/& V7 [: c n5 R$ k2 e
- HAL_UART_RxCpltCallback(huart);
# Y' U" }5 s( U8 E3 c0 z8 Y - #endif /* USE_HAL_UART_REGISTER_CALLBACKS */! w1 S7 L& p. b2 E
- }2 u2 P; v) g' h: u2 N
- }+ y1 d7 C5 b5 W n2 a
- else
$ o5 p/ u7 O# `5 S$ Y' f6 A - {5 e" H9 G+ M( N9 l: k$ c
- /* Clear RXNE interrupt flag */
: c# ^3 \4 l. D( P, j1 W ~ - __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);- G% g. M" O9 B* \4 V5 u f; y4 w
- }
4 U- g) s" z0 y" G9 j2 I( |( w: @ - }
复制代码
3 o' d5 j* x; c- t' ?问题3. shell 放在Mgr task里面,由于内存分配128*4 不够导致死机2 d, ~8 |7 x4 V4 M8 O
& A! W0 k; \2 v8 t& ]
解决这个问题的方法是,去掉没有用的shell 指令,限制最多支持64条指令。 任务内存分配加大 256*4
; s$ Y: p' ~- s
' f5 g9 J+ m) D$ T最终效果图
0 h( O! h( w: Q/ A7 ^; i( _4 i/ j) f" o
. s2 t3 ?5 l+ G( L5 P0 w
! U' O9 i/ a1 C; T6 {
4 O+ `4 E7 g; b |