'전체 글'에 해당되는 글 49건

  1. 2021.05.15 [STM32] CLI - (1)

TAB키 자동완성 기능 (2021. 05. 17)

cli.c
0.02MB
cli.h
0.00MB
cli_function.c
0.00MB

 

TAB키를 누르면 알맞은 커맨드가 자동완성되는 기능을 만들었다.

 

필요한 기능들은 전부 구현한 것 같다. 하지만 코드들이 전부 그때그때 추가한 것들 이어서 어떻게 해석해야 할지 잘 모르겠다.....

 

나중에 다시 만들어야겠다.

 

 

 

 

======================================================

 

UART RX DMA 사용 버전 (2021. 05. 16)

cli.c
0.02MB
cli.h
0.00MB
cli_function.c
0.00MB
main.c
0.01MB
print.c
0.01MB
print.h
0.00MB
stm32f4xx_it.c
0.01MB

 

UART 받는 부분을 DMA로 처리한 방식이다.

 

다른 코드가 작동하는 중에 키보드를 입력하면 입력한 키가 버퍼에 들어가 CLI 처리 함수에서 한 번에 처리한다.

 

그 외의 부분은 똑같다.

 

 

추가적으로 UART RX DMA 설정에서 Circular 모드로 코드를 생성한다.

 

 

======================================================

 

 

UART RX Interrupt 사용 버전

cli.c
0.01MB
cli.h
0.00MB
cli_function.c
0.00MB
main.c
0.01MB
print.c
0.01MB
print.h
0.00MB
stm32f4xx_it.c
0.01MB

 

https://ddtxrx.tistory.com/entry/STM32-CLI-%EA%B8%B0%EB%B3%B8-%EB%BC%88%EB%8C%80

 

[STM32] CLI Basic - (0)

수정 (2021. 05. 13) 값을 입력받아서 사용할 수 있게 코드를 만들었다. cli_function.c 파일을 보면 쉽게 이해할 수 있다. ======================================= 수정 (2021. 05. 01) 스페이스로 CLI명령..

ddtxrx.tistory.com

 

이전에 작성한 CLI 코드를 작성하면서 수정된 내용이 쓰여있는 글이다.

 

CubeMX 설정은 UART, Interrupt, DMA설정을 해주면 되며 위의 글과 똑같이 해주면 된다.

 

 

 

코드 - (0)

초기화 코드 ... (0)

1
2
3
4
5
6
7
8
9
10
11
PRINTF_INIT(USART1, DMA2, LL_DMA_STREAM_7);
 
CLI_BLOCK_INIT();
 
TERMINAL_INIT(USART1,"TEST","START APP");
 
while (1){
 
    TERMINAL_CONTROL_CLI();
 
}
 
cs

 

main.c에서 while(1) 무한루프에 들어가기 전에 설정해주는 함수들이다.

 

PRINTF() 함수를 사용하기 위해 초기화해주는  PRINTF_INIT 함수가 있고

 

CLI_BLOCK_INIT() 함수를 사용하여 사용할 명령어를 초기화한다.

 

TERMINAL_INIT() 함수의 경우 어떤 UART를 사용하는지와 현재 프로그램의 이름, 처음 시작하면 나오는 메시지를 설정할 수 있다.

 

while(1) 문 내부의 TERMINAL_CONTROL_CLI() 함수는 CLI를 작동하는 코드이다.

 

 

 

CLI BLOCK 생성 ... (1)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
DEF_CLI(sum,"sum VV VV"){
    uint8_t x[10]={0,};
    uint8_t y[10]={0,};
    uint8_t i=0;
    int X,Y;
    CLI_GET_ARG(x,0);
    CLI_GET_ARG(y,1);
    for(i=0;i<10;i++){
        PRINTF("0x%02X ",x[i]);
    }
    PRINTF("\r\n");
    for(i=0;i<10;i++){
        PRINTF("0x%02X ",y[i]);
    }
    PRINTF("\r\n");
    X=atoi(x);
    Y=atoi(y);
 
    PRINTF("SUM1: %d\r\n",X+Y);
}
 
void CLI_BLOCK_INIT(){
    ADD_CLI(test1,"aaa");
    ADD_CLI(test2,"bbb");
    ADD_CLI(test3,"ccc  aaa");
    ADD_CLI(test4,"arg test VV");
    ADD_CLI(test5,"arg2 test VV and VV");
    ADD_CLI(test6,"arg3 VV VV");
 
    ////////////////////////////
    ADD_CLI(sum,"sum VV VV");
    ////////////////////////////
 
    ADD_CLI(sum2,"sum VV VV VV");
    ADD_CLI(sum3, "sum3 VV VV VV");
}
cs

 

 

cli_function.c 파일을 보면 어떻게 명령어를 만들고 초기화하는지 나와있다.

 

DEF_CLI()와 ADD_CLI() 매크로를 사용하여 CLI명령어를 만든다.

 

추가로 CLI_GET_ARG() 함수는 명령어에서 'VV'에 해당하는 부분의 문자열을 읽어오는 함수이다.

 

예를 들어 sum 3 5 라고 입력하면 CLI_GET_ARG(x,0)은 x에 "3" 문자열을 복사한다.

 

실제 명령어를 실행하면 이런 식으로 출력된다.

 

 

INTERRUPT ... (2)

 

1
2
3
4
5
6
7
8
9
10
void USART1_IRQHandler(void)
{
 
    ////////////////////////////////////////////////// CLI
    TERMINAL_UART_IRQ();
    //////////////////////////////////////////////////
 
    PRINTF_UART_IRQ();
 
}
 
cs

 

작성한 코드는 기본적으로 UART Interrupt를 사용한다.

 

TERMINAL_UART_IRQ() 함수는 UART를 통해 키보드 입력을 받을 때 실행된다.

 

PRINTF_UART_IRQ() 함수는 PRINTF() 함수를 사용하기 위해 사용한다.

 

 

INLINE ... (3)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
static inline uint32_t TERMINAL_IDLE_IS_ACTIVE_FLAG(USART_TypeDef* UART){
    return LL_USART_IsActiveFlag_IDLE(UART);
}
 
static inline void TERMINAL_IDLE_CLEAR_FLAG(USART_TypeDef* UART){
    LL_USART_ClearFlag_IDLE(UART);
}
 
static inline uint32_t TERMINAL_RX_IS_ACTIVE_FLAG(USART_TypeDef* UART){
    return LL_USART_IsActiveFlag_RXNE(UART);
}
 
static inline void TERMINAL_RX_CLEAR_FLAG(USART_TypeDef* UART){
    LL_USART_ClearFlag_RXNE(UART);
}
 
static inline void TERMINAL_INTERRUPT_INIT(USART_TypeDef* UART){
    LL_USART_EnableIT_RXNE(UART);
    LL_USART_EnableIT_IDLE(UART);
}
 
static inline uint8_t TERMINAL_RECEIVEDATA(USART_TypeDef* UART){
    return LL_USART_ReceiveData8(UART);
}
 
cs

 

작성한 CLI 코드는 LL 드라이버를 기반으로 작성돼있다. 따라서 MCU에 따라 코드가 달라질 수 있다.

 

PRINTF() 코드 또한 코드가 달라지는 부분이 있다.

 

코드를 쉽게 변경하도록 LL 드라이버에 의존성이 있는 부분을 static inline 함수로 만들었다.

 

예를 들어 STM32F303RE MCU의 경우 LL_USART_ClearFlag_RXNE(); 코드를 사용하지 않아도 Flag가 Clear 되어 해당 부분을 주석 처리해서 사용했다.

 

 

 

결과 - (1)

 

실제 작동하는 모습이다. 위에 sum 명령어를 작동한 내용도 있으니 참고하면 된다.

 

TAB 키를 누르면 명령어를 보여주고 방향키 아래, 위를 누르면 조금 전에 사용했던 명령어들을 다시 불러올 수 있다.

 

 

 

-

CLI BLOCK 생성, TAB키, 명령어 불러오는 기능을 만들었다.

 

TAB키를 사용하여 명령어 자동완성 기능만 만들면 될 것 같다.

'임베디드 > STM32' 카테고리의 다른 글

[STM32] CLI Basic - (0)  (2) 2021.03.20
[STM32] Circular Buffer printf  (0) 2021.03.16
[STM32] STM32cubeMX linux  (0) 2021.02.23
[STM32] 간단한 ICM20948 쿼터니언  (0) 2020.09.18
[STM32] LL 드라이버 - MS5611  (0) 2020.08.28
Posted by DDTXRX
,