안녕하세요.
계속 이어서 Shell에 기능구현을 이어나가도록 하겠습니다.
이 글은 아래와 같이 전편 글을 좀 보시고 오셔야지 이해가 되실 것입니다. :)
전편글을 아래와 같이 첨부하니, 참고해 주세요.
Shell이란? UART를 이용한 Shell 기능 구현 1편 (TC275 인피니언 MCU)
그러면 이제 나만의 Shell을 한번 만들어 보도록 하겠습니다.
아래 Driver_AscShel_Pritf는
인피니언에서 제공한 함수를 잘 참고해서 만들어 보았습니다.
결국 마치 visual C에 printf함수처럼 사용하여
uart라인으로 뿌려서 테라텀으로 확인하기 위한 API입니다.
void Driver_AscShell_Printf(pchar format, ...)
{
IfxStdIf_DPipe *stdif = &g_AsclinShellInterface.stdIf.asc;
if (!stdif->txDisabled)
{
char message[STDIF_DPIPE_MAX_PRINT_SIZE + 1];
Ifx_SizeT count;
va_list args;
va_start(args, format);
vsprintf((char *)message, format, args);
va_end(args);
count = (Ifx_SizeT)strlen(message);
IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, count < STDIF_DPIPE_MAX_PRINT_SIZE);
IfxStdIf_DPipe_write(stdif, (void *)message, &count, TIME_INFINITE);
}
else
{
/*No Code*/
}
}
이렇게 위와 같이 만들고
아래와 같이 한번 UART 라인을 통해 Tx해보도록 하겠습니다.
그리고 원하는데로 나오는 것을 볼 수 있네요.
그런데, 이 Shell이라는 기능을 uart 많은 로직을 두어 만들어서,
좀, 사용하는게 많이 불편합니다.
위에보면 Shell> 이라는 나오는데
이건 제가 의도한 바가 아닙니다.
지금 Shell을 포팅한 코드가 복잡하고, 무겁습니다
아예 Shell이라고 포팅한 코드를 다 삭제하고 직접 Shell기능을 만들어 보아야 겠습니다.
조금더 편한 API가 필요합니다.
즉, 다시 기본으로 돌아가서
UART Driver를 직접 Control하고
직접 Printf 함수를 만들어서 UART라인에 전송해 보도록 하겠습니다.
혹시 지금까지 작성한 프로젝트가 필요하신 분은
아래 링크에서 다운받으시길 바랍니다.
https://cafe.naver.com/binaryembedded/156
그럼 다시 시작해 보도록 하겠습니다.
우선 UART를 처음부터 다시 초기화 하도록 하겠습니다.
궁금하신 분은 아래 글을 참고해 주세요.
https://cafe.naver.com/binaryembedded
ASC0번과 동일하게 ASC1 모듈을 초기화하였습니다.
또한 a까지 발사시킨엇을 확인하실 수 있습니다.
즉, Rx와 Tx는 Uart로 뚤었다는 것을 의미합니다.
이제부터 나만의 Shell을 만들어 보도록 하겠습니다.
만들더라도 쌩으로 시작하면 힘드니까
아래에서 함수에서 필요한 부분을 발췌하도록 하겠습니다.
static void AscPrintf_Screen(uint8_t* pnuDataBuf)
{
while(*pnuDataBuf != 0)
{
g_AsclinAscShell.txData[0] = pnuDataBuf[0];
g_AsclinAscShell.count = 1;
IfxAsclin_Asc_write(&g_AsclinAscShell.drivers.asc1, g_AsclinAscShell.txData, &g_AsclinAscShell.count, TIME_INFINITE);
pnuDataBuf++;
}
}
static void AscPrintf(void* pnuData, ...)
{
va_list p_arg;
va_start(p_arg, (uint8_t*)pnuData);
vsprintf((char*)arrAscOutputBuf, (const char*)pnuData, p_arg);
va_end(p_arg);
AscPrintf_Screen(arrAscOutputBuf);
}
보이시나요?
AscPrintf함수를 만들었습니다.
이 함수가 바로 마치 Visual Studio에서 사용한 printf 처럼 사용되는 함수입니다.
그리고, 한번 발사시켜 보겠습니다.
발사할 항목은 마치 Visual Studio에서 사용했던 Printf 함수처럼 날려보겠습니다.
void Driver_AscShell_TxTest(void)
{
uint32_t TestInput[5]= {'a', 'b', 'c', 'd', 'e'};
AscPrintf("\n\r****************************\n\r");
AscPrintf("TestInput[0] = %c\n\r", TestInput[0]);
AscPrintf("TestInput[1] = %c\n\r", TestInput[1]);
AscPrintf("TestInput[2] = %c\n\r", TestInput[2]);
AscPrintf("TestInput[3] = %c\n\r", TestInput[3]);
AscPrintf("TestInput[4] = %c\n\r", TestInput[4]);
AscPrintf("\n\r****************************\n\r");
}
아래와 같이 테라텀에 나오는것을 볼 수 있습니다.
이제 uart를 통해서 쉽게 디버깅을 할 수 있을 것 같습니다.
그렇다면 이제 나만의 Shell을 만들 차례입니다.
처음 글에서 예시를 들었던
'a' 라는 데이터를 컴퓨터를 통해 전달받으면
ADC값을 테라텀으로 전송하는 작업을 하도록 하겠습니다.
a라는 데이터를 MCU가 Rx(수신)하게 되면
아래 인터럽트 함수가 뜨게 됩니다.
그러면 그 데이터를 취득하여 그것이 'a'라면
위에서 만든 AscPrintf함수를 통해서 adc측정값을 날리라는 코드입니다.
void ASC_Rx1IntHandler(void)
{
IfxAsclin_Asc_isrReceive(&g_AsclinAscShell.drivers.asc1);
IfxAsclin_Asc_read(&g_AsclinAscShell.drivers.asc1, g_AsclinAscShell.rxData, &g_AsclinAscShell.count, TIME_INFINITE);
u8nuRxData = g_AsclinAscShell.rxData[0];
g_AsclinAscShell.txData[0] = u8nuRxData;
IfxAsclin_Asc_write(&g_AsclinAscShell.drivers.asc1, g_AsclinAscShell.txData, &g_AsclinAscShell.count, TIME_INFINITE);
if(u8nuRxData == 'a')
{
AscPrintf("\n\rADC Data = %d\n\r",adcDataResult[0]);
}
}
따라서 a를 입력하면
바로 ADC Data값을 전달해 주는 Shell이 완성이 드디어 완성이 되었습니다
이러한 방법을 사용하면
더 쉽게 command를 줄 수 있을 것입니다.
이제부터 이 기능을 이용해서,
정말 디버깅을 실시간으로 손쉽게 할 수 있을 것 같네요.!!!
해당코드는 아래 링크에서 다운로드 가능하니, 참고하시면 좋을 것 같습니다.
https://cafe.naver.com/binaryembedded/157
'Embedded SW > Embedded SW Introduction' 카테고리의 다른 글
UART란? UART 예제코드 포팅 및 동작 확인 (TC275 인피니언) (1) | 2022.09.19 |
---|---|
Shell이란? UART를 이용한 Shell 기능 구현 1편 (TC275 인피니언 MCU) (0) | 2022.09.18 |
Stack 예제를 통한 정리 2편 (자료구조, MCU 모두 정리) (0) | 2022.09.17 |
Stack 예제를 통한 정리 1편 (자료구조, MCU 모두 정리) (0) | 2022.09.17 |
Flash Driver API 최적화 작업 2편(TC275 인피니언) (1) | 2022.09.17 |
댓글