[nRF52] 4. CLI 적용
목적
- 개발하면서 쉽게 테스트할 수 있도록 CLI (command line interface) 적용해보자.
Git
https://github.com/tlaehdtlr/nrf52_ble_base
- 14 commit : [Feat] Enable debug log
- 15 commit : [Feat] Add cli via uart
- 16 commit : [Feat] Add commands
1. 뜬금 없는 Debug 강화
1-1. 에러 발생
작업을 하면서 programming 할 때마다 처음에 아래와 같은 에러가 발생한다.
디버그 모드에서는 나오지 않기 때문에 런타임 상황에서 디버깅 방법을 강화할 필요가 있었다.
1-2. 분석 및 적용
APP_ERROR_CHECK 함수를 따라가보면 app_error_weak 라이브러리를 이용하고 있다. weak 함수기 때문에 커스텀해도 되겠지만, 그냥 define 으로 해결되기에 간단하게 했다.
1-3. ToDo
생각보다 디버깅을 위한 많은 라이브러리가 제공되고 있었다. 아직 softdevice를 적극적으로 사용하고 있지 않아서 큰 문제는 없지만, 상황이 발생했을 때를 대비하여 관련 라이브러리를 메모만 해두자.
- nrf_assert
- ser_conn_error_handling
- sdk_errors
2. CLI example 분석
nRF5_SDK_17.0.0_9d13099\examples\peripheral\cli\pca10100 를 참고하여 사용할 부분을 파악해보자.
2-1. 훑어보기
- RAM 사용이 적지 않아 보이니 유의해야겠다.
- CLI 입출력이 이벤트 처리 방식이 아닌 것 같다.
- FDS (flash data storage) 모듈을 사용하고 있어 synchronous read, asynchronous write 이다.
- demo cli cmds.c 를 확인해보면 커맨드를 추가하고, 처리 함수 지정하는 방식으로 간단하다.
2-2. 구상
- UART 이용
- main MCU 로써 사용될 것 같지 않다.
(base code 라면서 너무 일찍 architecture 를 그리나 싶다...) - (1) PC 와 interface 로 UART 를 사용
- (2) main MCU와 UART 로 연결하면 USB 로도 제어가 가능
- main MCU 가 bridge 역할을 하며 (PC-nrf52) 통신이 가능해진다.
- 참고로 이것을 이용해서 DFU 도 가능하다.
- main MCU 로써 사용될 것 같지 않다.
LOG 를 확인하기 위해 UART 로 사용 중인데, CLI 또한 UART 로 사용한다면 어떤 문제가 생길지 확인해 볼 필요가 있다.
일단 시도해보고 문제되면 CLI 와 LOG 의 backend 를 RTT, UART 따로 구현해야겠다.
3. CLI 적용
3-1. LOG, CLI 를 UART 로
(1) 충돌 방지
-
LOG module 을 사용
- NRF_LOG_DEFAULT_BACKENDS_INIT() 과 config.h 의 NRF_LOG_BACKEND_UART_ENABLED
nrf_log_backend_uart_init();
backend_id = nrf_log_backend_add(&uart_log_backend, NRF_LOG_SEVERITY_DEBUG);
ASSERT(backend_id >= 0);
nrf_log_backend_enable(&uart_log_backend);
-
CLI module
-
nrf_cli_init() 에 uart를 backend 로 지정하면
-
if ((err_code == NRF_SUCCESS) && log_backend && NRF_CLI_LOG_BACKEND)
{
int32_t id = nrf_log_backend_add(p_cli->p_log_backend, init_lvl);
if (id < 0)
{
return NRF_ERROR_NO_MEM;
}
nrf_log_backend_enable(p_cli->p_log_backend);
}
-
2개 함수가 같은 동작을 함으로 에러가 발생한다.
- 따라서 같이 사용할 때는 NRF_LOG_DEFAULT_BACKENDS_INIT 을 제외하고 nrf_cli_init 만 쓰자.
(2) 적용
LOG module 을 사용
- NRF_LOG_DEFAULT_BACKENDS_INIT() 과 config.h 의 NRF_LOG_BACKEND_UART_ENABLED
nrf_log_backend_uart_init(); backend_id = nrf_log_backend_add(&uart_log_backend, NRF_LOG_SEVERITY_DEBUG); ASSERT(backend_id >= 0); nrf_log_backend_enable(&uart_log_backend);
CLI module
-
nrf_cli_init() 에 uart를 backend 로 지정하면
-
if ((err_code == NRF_SUCCESS) && log_backend && NRF_CLI_LOG_BACKEND) { int32_t id = nrf_log_backend_add(p_cli->p_log_backend, init_lvl); if (id < 0) { return NRF_ERROR_NO_MEM; } nrf_log_backend_enable(p_cli->p_log_backend); }
2개 함수가 같은 동작을 함으로 에러가 발생한다.
- 따라서 같이 사용할 때는 NRF_LOG_DEFAULT_BACKENDS_INIT 을 제외하고 nrf_cli_init 만 쓰자.
cli, queue module 추가해주고, idle 상태일 때 CLI 처리하도록 해보았다.
- 기본적으로 cli command 들이 나오는 것은 nrf_cli_process() 함수를 뜯어보면 된다.
- nrf_cli_process -> cli_state_collect
- CLI 와 LOG 를 같이 쓰는데 문제가 없는 것으로 보이니 그냥 써야겠다.
- 다음은 나의 커맨드를 등록하는 것이다. 이를 위해 base_cmds.c 를 만들겠다.
3-2. Command 추가
인자를 3개 받는 걸로 가뿐하게 하나 만들어보자.
- base_cmds.h/c 생성
- 커맨드, 함수, 메시지, 서브 커맨드
- 동적으로 설정하는 것도 있어보이지만 굳이 안 써도 될 것 같다. (정확하게 뭔지도 잘 모르겠다...)
(1) CLI 예제처럼 커맨드 만들어보기
구조는 위와 같고... 커맨드를 입력하면~
이렇게 만들어봤는데, sub arguments 가 많아지면 코드가 너무 많아지는 것 같다.
NRF_CLI_CREATE_STATIC_SUBCMD_SET 을 계속 쓰는 것보다 argv와 strcmp 를 사용하는게 코드 가독성이 훨씬 좋을 것 같다. (call stack을 생각했을 때 불리할 지도?)
만들까 말까... 할까 말까.... 꾹 참고 base 니까 하나 만들겠다.
(2) 조금은 간단하게 만들기 (주관적)
음~ 확실히 편한 것 같다. (사용자에게 input 에 대해 자세한 로그를 띄우려면 hard coding이 필요하다. 귀찮으니 퉁쳤다!)
하지만 내 프로젝트에는 2번 커맨드를 만든 것처럼 짜야겠다. (나만 이용할 것이니까!)
(3) 추가로 tab을 누르면 모든 커맨드(밑의 그림)가 나오긴 하지만 내가 등록한 커맨드만 띄우고 싶어졌다.
help를 입력하면~
마음이 좀 편안해졌다.
4. 참고
Memory usage
Flash : (201.4 -> 219.2) +17.8KB
RAM : (29.0 -> 30.1) +1.1KB
4-1) Logger module
- https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.3.0%2Flib_nrf_log.html&cp=5_1_3_26_4&anchor=nrf_log_performance
- logger 공식 문서인데 설명이 굉장히 잘 나와있다. CLI 를 만들면서 겹칠 수 밖에 없는 것이기에 다시 한 번 정독하길 추천한다.
4-2) 키워드로 log, CLI, simultaneously 를 Devzone 에 검색하는 것도 좋겠다. (여러 글들을 보며 UART 로 같이 써도 되겠다는 판단을 내렸다.)
Author And Source
이 문제에 관하여([nRF52] 4. CLI 적용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@hellodongsik/nRF52-4.-CLI-적용저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)