测试ST 官网的 FreeRTOS
% X0 b& D& r- H" N: d x
/ j8 Y$ ^4 T# Q) q4 i) c$ Y移植shell
2 L3 u1 p: w1 v0 i3 t/ c主要是串口对接, 需要重写两个函数
3 e, i/ V* D7 I) J u
3 s% @( i- K+ Z+ \5 \- int fputc(int ch, FILE *f)" {+ ?4 x5 J$ y
- {
7 [' X6 O8 u8 J6 L - /* Place your implementation of fputc here */2 Y/ i& \# S: i9 D9 ? ~) a/ D
- /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */' ~5 B& s! V* z, [% w
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, UART_TIMEOUT_VALUE);
3 m, O! M8 r! e6 R U0 k - return ch;
+ y0 ?: K% c: ^, E - }3 ^9 y" \/ b2 `9 n* }% N
- // #endif M! h0 M) u7 o
* Q$ @+ s! t$ U1 n3 N7 E( D' ?- char shell_buf[RXBUFFERSIZE]={0};
! m% A) Z$ o: I @- S# I0 t - char shell_len=0;8 j/ \7 U5 ]( I. V/ z8 [
- char *shell_buf_head=NULL;2 t. I3 O) [* h* u) |5 B
- % t# o0 `9 e. d! T8 S# I
0 u; x" ^, s1 ]; ^& U- int fgetc(FILE *f)
- g" a" z* ~; z2 t2 Z. R9 Q _ - {
: ~( y) h& c y% r- f! F) T
% M5 W0 y( s4 v# f- while (0 == shell_len) {
. i0 e$ k1 E5 ^; n - osDelay(1);
9 o0 E' e B) H- q6 u. K - }
, |# U" F: `/ {1 b0 z5 b; l - char ch = *shell_buf_head;
3 ~. D* O$ p# b! m+ c. k) w" }, n - shell_buf_head ++;
! J- _, ]) ~6 k# f - shell_len --;
1 a( p/ t/ I( z+ v7 Y - F" U0 k4 Y# R& Q
- return ch;( Z6 u4 q$ z3 Y" G# Y M
- }
复制代码
8 B( n `) h, q7 W6 f; j8 `增加了一个回调函数, 收到数据拷贝到shell_buf, 然后重新初始化串口中断接收参数,指针,size,count* |! Y: W$ g C
! ^6 e$ F0 I1 r- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)# y% J% g' v$ U/ R- M# C/ C
- {
, ?: W3 S% F! E- \ [7 Q# t - /* Set transmission flag: transfer complete */5 X* S' h8 u9 G3 b# u! h
- if(UartHandle->Instance == USART1) {
?' F0 E8 z* D# g" v8 F3 I4 l - // UartReady = SET;6 A& s! \# `4 B, {5 D( j- a9 z8 o
- shell_len = UartHandle->pRxBuffPtr - aRxBuffer;
/ y% M# R6 P7 R5 @ - shell_buf_head = shell_buf;
+ R$ \1 Q( I, F& i* T l- x; [6 Y9 | - memcpy(shell_buf, aRxBuffer, shell_len);/ c, h6 T( X8 o. s+ z; C
- ! U- w% p K3 w! k/ y
- UartHandle->pRxBuffPtr = aRxBuffer;- j! X) M/ U B( h: m
- UartHandle->RxXferSize = RXBUFFERSIZE;# W2 K' }+ _# S
- UartHandle->RxXferCount = RXBUFFERSIZE;6 r. _: l% U+ ^; N t P0 j. ^( ?) B
- }* A, f; z* R0 I$ k( J9 t
/ ]" L: f0 c- L- P2 u4 i- }
复制代码 4 e6 d6 |# R1 Y8 s
遇到的问题, 1. fgetc 不能直接调用HAL_UART_Receive, 否则会死等,导致其他任务无法运行。
2 p- @' }. A+ M* @
" Z# U$ W2 r; O3 `8 x$ P解决这个问题的方法是,接收采用中断方式。
: p; Q0 h. D( ]7 }' _! k
, D. p( B/ S/ P( V' X; _ ^' ^/ v问题2. STM32CubeMX 生成的代码,串口中断接收是固定长度的方式, 对于shell 不适用。6 c) W& D7 v+ Q }$ t& W' C
2 [1 L( m: v- U- L! c2 M解决这个问题的方法是,修改中断处理程序,如果是调试用的串口,直接处理接收数据/ ^7 D( w# H* R8 n
$ |, `" h3 [8 o5 C- static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)0 V( \7 K i- P" v' _
- {
8 x! t4 Z1 L. j! Z i% V0 k) l( | - uint16_t uhMask = huart->Mask;& \+ ]- f% P) S9 b! w" R% [
- uint16_t uhdata;
6 v: b$ h0 E" q- R% F" A O4 m% e - + E# b. s$ }' `9 \8 W0 I \! |7 A9 \
- /* Check that a Rx process is ongoing */
5 ~% R- h6 N) H$ H" d+ z5 g - if (huart->RxState == HAL_UART_STATE_BUSY_RX)
- _5 u) i( z/ x# X - {" s. M6 I8 C4 X$ D" z4 O# `$ {1 Q
- uhdata = (uint16_t) READ_REG(huart->Instance->RDR);* }$ \3 O% O: [4 z Q1 B8 [
- *huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
- Z6 p1 o9 L- D+ J - huart->pRxBuffPtr++;
7 r$ d' c: f9 q - huart->RxXferCount--;
) ^( K, M8 Q$ R2 _' ~ - ' _8 A. M' g1 D* E- x2 l
- if(USART1 == huart->Instance) {
. ~; d4 n1 W: U, m - HAL_UART_RxCpltCallback(huart);: p5 D7 V+ O' _7 [3 G9 A
- }
" b4 p' Z5 f1 [9 w5 V, {& q' ]6 l7 e - if (huart->RxXferCount == 0U) {6 v; l' L! r! j! o+ \' p
- /* Disable the UART Parity Error Interrupt and RXNE interrupts */& F* b+ @3 p2 e3 a: U0 M/ j' `
- CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE));8 V7 ]: Y! E# ^. r
8 p# E& m, _) J T$ }- /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
- m; P3 v0 Z! c& m - CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);1 [) p8 I' ~9 w1 l
. q4 Q* A; q( V: M* g& F4 p; A- /* Rx process is completed, restore huart->RxState to Ready */
/ b7 u" K: a4 K9 x% H# F7 i/ c - huart->RxState = HAL_UART_STATE_READY;
' b+ @ R2 S% _( v
+ I) T+ J% I- Z" R( I1 A4 Y- /* Clear RxISR function pointer */
- ]( W, n) G" ?/ R( R j/ I% r - huart->RxISR = NULL;% G0 W7 `0 v+ \6 x: t/ X
- 1 F: E' n/ o9 d7 z
- #if (USE_HAL_UART_REGISTER_CALLBACKS == 1)! m3 J& D) d7 b3 m
- /*Call registered Rx complete callback*/# d) T! v0 Y+ f+ o- H
- huart->RxCpltCallback(huart);
/ U% Z- r7 X( j: l7 W( I/ U: n# ] - #else
# }: Z" d3 M i' u - /*Call legacy weak Rx complete callback*/. L) U9 d! n" f0 l
- HAL_UART_RxCpltCallback(huart);
/ Z* ]4 m& I# y - #endif /* USE_HAL_UART_REGISTER_CALLBACKS */7 R4 a% S: f0 T% Z
- }& I- S' o# z0 c1 f+ ^ T2 L1 E
- }
! f1 t! S! R" }/ O$ } - else5 N/ B [% x! V, F, H
- {
0 j0 b0 @% y/ x' Z2 O - /* Clear RXNE interrupt flag *// Z2 u( Z6 {9 l5 n7 M
- __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST);
; q- h: V n2 i5 l - }. A+ D. S$ Q8 W5 Y
- }
复制代码
+ t" m) d& K1 U7 F' m问题3. shell 放在Mgr task里面,由于内存分配128*4 不够导致死机' \: j: h8 Y: S f3 Y% j
' ~4 Q( M0 V# D7 ?! R解决这个问题的方法是,去掉没有用的shell 指令,限制最多支持64条指令。 任务内存分配加大 256*4
0 m% T/ V. G. A X0 [$ U' L8 ~2 v; O1 z- [
最终效果图
( I3 [" R M3 s0 z- a/ ?; F8 t( b! N% |8 b# `8 s# ~
% {9 \* }# W! w7 G7 d. Q* g7 j% d, y! M( i
2 Y2 v5 a1 g B) |
|