Uart Polling으로 LED를 On/Off 할 수 있게 되었다. 

https://pilimage.tistory.com/19

 

[C/STM32] 4. LED ON/OFF - Uart Polling 제어

LED를 버튼으로도 제어를 할 수 있게 되었다. https://pilimage.tistory.com/17 [C/STM32] 3. LED ON/Off - 버튼 채터링 추가 버튼을 누르고 있으면 LED가 On되고 버튼을 떼면 LED가 Off되는 것은 이제 쉽다. http..

pilimage.tistory.com

 

Polling방식에서는 데이터가 들어올 때까지 대기하는 시간 동안은 버튼을 눌러도 동작하지 않는 경우가 있었다.  (HAL_UART_Receive의 timeout 시간을 길게 하면 확실히 볼 수 있다.)

 

Uart Interrupt를 이용하여 이를 해결해보자 

 

먼저 Uart Interrput 기능을 설정하기 위해 PinOut & Configuration에서 사용하는 Uart를 선택하고 NVIC Settings  메뉴에서 Interrupt를 Enable 시킨 후, Code Generation을 한다. 

 

이제 Uart Interrupt 기능을 사용할 수 있게 되었다. 

 

먼저 메인 함수의 MX_USART1_UART_Init()을 한 후, HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)를 호출한다.(*pData 는 수신받을 변수, size는 수신받을 데이터 크기)HAL_UART_Receive_IT는 수신 인터럽트를 Enable 하고 수신 대기 상태로 만든다.인터럽트가 발생하면 HAL_UART_IRQHandler 가 호출된다. HAL_UART_IRQHandler에서 자동으로 인터럽트를 처리한 후 Callback 함수를 호출한다. 

여러 Callback 함수들이 있지만 수신과 관련된 RxCpltCallback을 사용한다. 

HAL_UART_RxCpltCallback은 수신을 완료했을때 Callback이 되며 __weak함수이므로 해당 weak 함수를 수정하지 말고 직접 따로 구현을 해주면 된다. 

 

먼저 구현한 HAL_UART_RxCpltCallback은 다음과 같다. 

uart1로 인터럽트가 수신이 되면 데이터를 저장하는 data_arr에 수신받은 데이터를 넣는다. 

수신받은 데이터를 HAL_UART_Transmit_IT로 송신하여 콘솔 창에 출력한다.

그 후, HAL_UART_Receive_IT를 호출하여 다시 수신 대기상태로 만든다. 

(HAL_UART_Receive_IT의 경우 1회용이라고 생각하고 한번 수신을 한 후, 계속  수신을 하려면 반복하여 호출해야 한다. )

 

이제 메인 함수의 루프에서 data_arr을 체크하여 LED를 동작시키면 된다. 

기존의 on/off 에서 LED1이면 LED on / LED0 이면 LED off가 되도록하였다.

 

1. RxCpltCallback에서 수신을 받은 후 idx++을 하기에 메인 루프에서는 idx-1을 하여 '\r' 또는 '\n'을 찾는다. 

2. 해당 조건에 들어가면 '\0'을 넣어 문자열의 끝을 알린다. 

3. 문자열을 비교하여 LED를 On/Off 한다. 

 

해당 코드로 기능들은 잘 동작한다. 

 

하지만 뭔가 찝찝하다. 

일단 메인 루프에 버튼 조작까지  주르륵 늘어있어서 가독성이 별로인 것 같다. 

버튼 조작 부분을 함수로 만들어 버리자

push_btn과 push_tick은 저장된 값을 알고 있어야 하므로 포인터 매개변수로 넘겨주자 

콘솔을 입력하는 부분도 함수로 만들자

data_arr 배열의 경우 RxCallback에도 호출되기 때문에 전역 변수로 사용하였다. 

 

메인의 소스가 훨씬 깔끔해진것 같다. 

하지만 그래도 찝찝하다. 

지금의  RxCpltCallback에서 데이터를 처리하는 방식으로는 문제가 발생할 것 같은 느낌적인 느낌이 난다.

 

만약 메인 루프의 use_console을 처리하는 중에 인터럽트가 발생하여 데이터를 수신한다면 idx가 변경되면서 문제가 생길 수 있지 않을까? 

예를 들어 LED0을 수신받고 use_console의 루틴으로 들어갔는데 바로 LED1을 수신 받으면 data_arr[idx]='\0'을 처리할 때 idx가 바뀌어 다음 LED1이 동작이 안되지 않을까?

 

수신 데이터를 처리하는데 있어서 싸늘하다....불안한다...

이를 좀 더 보완하고자 링 버퍼(Ring Buffer)를 이용한 인터럽트를 사용해보자

언제? 

다음글에서 ....

 

반응형

LED를 버튼으로도 제어를 할 수 있게 되었다. 

https://pilimage.tistory.com/17

 

[C/STM32] 3. LED ON/Off - 버튼 채터링 추가

버튼을 누르고 있으면 LED가 On되고 버튼을 떼면 LED가 Off되는 것은 이제 쉽다. https://pilimage.tistory.com/16 [C/STM32] 2. LED ON/OFF - 버튼 제어 추가 1초 간격으로 LED를 On/off를 하는 것은 이제 쉽다...

pilimage.tistory.com

 

버튼을 손으로 누르는 것 말고 PC로 제어를 할 수 있을까? 

당연히 가능하다.

 

Uart 통신을 이용하여 on이 들어오면 LED가 켜지고, off가 들어오면 LED가 꺼지도록 해보겠다. 

 

USB 컨버터가 없어도 STM32F746은 문제 없다. 

우리에겐 전원 겸 디버깅 용인 ST-LINK가 있다. 

ST-LINK에 VCP포트가 있다.

VCP란 Virtual COM Port로 USB를 통해 PC와 시리얼 통신을 가능하게 해준다.

그러므로 ST-LINK의 VCP_TX/RX를 Uart로 이용하면 된다. 

회로도에서 VCP_TX는 PA9 , VCP_RX는 PB7 인 것을 확인하고 해당 번호의 핀을 클릭하여 각각 USART1_TX, USART1_RX로 선택한다. (선택시 해당 핀 노란색으로 변화)

이제 핀 맵 왼쪽의 Connectivity 항목에서 USART1을 선택하고 Mode를 Asynchronous(비동기)로 선택한다. 

파라미터는 기본적으로 Baudrate는 115200 , word length는 8 bits , Paritiy 는 None , Stop Bits는 1로 설정한다.

그리고 Code Generation을 누르면 환경 설정은 끝이난다. 

 

그리고 이제 다음 상황을 생각하여 소스를 작성하였다.

a. on이 입력되면 LED가 켜지고 off가 들어오면 LED가 꺼지도록 함

b.  on / off 만 정확히 입력되어야 LED 제어, 그외의 입력은 무시 

 -> ex) onnnnn, offff, onoff 등은 동작 무시

c.  테스트에 minicom을 사용하여 키보드로 엔터를 입력할 시 개행문자로 \r (CR)로 입력받음

 -> 터미널마다, 운영체제마다 엔터를 눌렀을 때, 개행문자가 \r :  (CR), \n : (LF) , \r\n : (CRLF)로 다르게 입력

d.  minicom을 이용한 터미널에서 입력한 글씨를 출력하고 가독성을 위해 \n을 추가하여 Uart Transmit을 사용

 

1. HAL_UART_Receive 함수를 사용하여 rcv_data라는 변수에 1바이트씩 데이터를 받아 data_arr라는 버퍼에 저장시켰다. 

2. 받은 데이터가 '\r'이면 문자열의 끝을 알려주는 \0을 추가하였다.

3. strcmp를 사용하여 정확히 on , off만 입력되었을 때 기능이 동작하도록 하였다. 

4. 입력받은 데이터에 \n을 붙여 다시 pc로 전송하여 터미널에서 입력한 데이터를 볼 수 있도록 하였다.

5. 문자열 비교가 끝나면 다음 입력을 위해 idx=0으로 하여 버퍼를 재사용할 수 있도록 한다.

 

위의 소스코드대도 빌드하면 on이 입력되면 LED가 켜지고, off가 입력되면 LED가 꺼진다. 

 

원하는 대로 동작을 시켰지만 특정상황에서만 (\r로 개행될 때) 동작하는 것이 좀 찜찜할 수 도 있다. 

그 예로, echo on > /dev/ttyACM0 처럼 에코를 이용하여 on 또는 off를 보내면 \n이 마지막에 보내져서 기능이 동작하지 않는다..

 

그래서 \r이나 \n을 만나면 판단을 하도록 하였다. 

on인지 off인지 비교하는 부분에서 strcmp대신 strncmp를 이용하여 정해진 길이만큼만 비교하여 on인지 off인지 구분하였다. 

strncmp를 사용하여 문자열의 처음부분만 비교를 하다보니 onoff나 ontime 등도 on으로 인식한다는 문제가 있다.

strstr로 문자열을 검색하는 것 보다는 처음부분 비교하는게 좀 더 나을것 같아서 strncmp를 이용하였다. 

 

on/off를 입력하여 LED도 제어를 해보았다. 

이번 과정에서 가장 큰 문제점은 무엇일까?

 

메인의 while문에 HAL_UART_Receive를 사용하였기에 데이터가 들어올 때까지 timeout(위에서는 100ms)의 시간동안 대기한다. 

즉, 계속해서 Uart를 체크하는 Polling방식을 사용하였기 때문에 데이터가 들어올때까지 대기하는 시간동안은 버튼을 눌러도 동작하지 않는다.  HAL_UART_Receive의 timeout 시간을 길게하면 확실히 볼 수 있다.

 

이러한 현상을 막는 방법은 없을까?

당연히 있다. 

 

바로 인터럽트를 이용하는 방법이다. 

인터럽트를 사용한 방법은 다음 글로...

 

반응형

1호선의 송탄역 근처에 위치한 피자클럽
토요일 점심으로 다녀왔다.


경기 평택시 신장로 36

 

버스에서 찍은 외관

외관에서부터 '역사'가 느껴지는 것 같다..
문을  열고 들어가면 실내가 엄청 넓었고 다행히 사람이 적었다.
실내도 개인적으로 응답하라 시리즈에서 외식하러 갈 만한 추억의 느낌이 들었다.

모든 피자는 반반으로 주문이 가능하다.
사이지는 레귤러와 라지가 있는데 라지로 고구마 반 포테이토 반을 주문했다.
라지는 23,000 레귤러는 기억이..16,000이였나..?

피클과 포크, 접시는 셀프로 이용할 수 있었다.

좌측:고구마 우측:포테이토
따뜻한 피자는 맛이 없을 수 있을까?

고구마피자의 경우, 고구마 무스를 이용한 피자가 아니라 고구마 조각을 올린 스타일이였다.
약간의 계피맛+달콤한 고구마? 무스가 피자 끝 부분에 있는데 바삭한 피자끝부분과 먹으니 살짝 달콤한 디저트먹는  느낌?

포테이토피자의 경우, 감자튀김이 올라간 스타일이였는데 이 토핑이 조금 적은 것이 아쉬웠다

피자는 도우가 두툼하고 바삭하며 특히 피자 끝부분이 바삭했고 토핑의 양은 조금 아쉬웠지만 피자 자체의 맛은 있었다.

실내 분위기나 피자나 왠지모르게 추억의 정통피자?의 느낌이 많이 났고 송탄역에서 배부른 점심을 먹었다

반응형

버튼을 누르고 있으면 LED가 On되고 버튼을 떼면 LED가 Off되는 것은 이제 쉽다. 

https://pilimage.tistory.com/16

 

[C/STM32] 2. LED ON/OFF - 버튼 제어 추가

1초 간격으로 LED를 On/off를 하는 것은 이제 쉽다. https://pilimage.tistory.com/15 [C/STM32] 1. LED ON/OFF 가장 쉬운 LED ON/OFF를 해보자 . 먼저 프로젝트를 만들고 Clock & Configuration에서 Clock을 설정..

pilimage.tistory.com

 

버튼을 한 번 누르면 LED가 켜지고 다시 한 번 더 누르면 LED가 꺼질 수는 없는가?

당연히 가능하다. 

 

버튼이 눌렸다는 인식은 여러가지 방법으로 가능하겠지만 인터럽트를 사용하지 않고 폴링으로 해보겠다. 

 

폴링 방식이란 무엇인가?

버튼의 상태를 주기적으로 확인하는 방식으로 메인 루프에서 버튼의 상태를 계속 확인하면서 버튼이 눌려졌다는 상황을 판단한다.

 

버튼을 확인하는 방법은 버튼이 눌렸을 때의 tick과 버튼이 떨어졌을 때의 tick을 이용하여 

버튼이 떨어졌을 때 동작하도록 만들었다. 

btn_state는 버튼의 상태를 의미하고 초기값은 0이다. 

push_btn은 버튼이 눌린 상태를 표시하는 flag로 초기값은 0이다

stable_time은 채터링 방지 시간으로 초기값은 100ms로 하였다

 

1. push_btn의 초기값이 0이므로 if문에 해당된다. 

2. 버튼이 눌려져 btn_state가 1이되면 push_btn을 1로 바꾸고 그 때의 tick을 얻는다.

3. push_btn이 1이므로 else 구문으로 들어간다. 

4. 버튼이 떨어져서 btn_state가 0이 되면 그 때의 tick과 버튼을 눌렀을 때의 tick을 비교하여 stable_time보다 크면 LED를 반전 시켰다. 

5.  stable_time보다 작으면 push_btn = 0으로 바꾸어 초기 상태로 돌아간다. 

 

* Chattering (채터링)이란? 

버튼(=스위치)를 누르거나 떨어질 때, 0(LOW) -> 1(HIGH) 또는 1(HIGH)->0(LOW) 으로 한순간에 변하는 것이 아니라 떨어졌다 붙었다 하는 현상을 말한다. 

 

 

* void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

 GPIO 핀의 출력을 반전시키는 함수로 LED의 ON/OFF에 사용하였다.

 

 

반응형

1초 간격으로 LED를 On/off를 하는 것은 이제 쉽다. 

https://pilimage.tistory.com/15

 

[C/STM32] 1. LED ON/OFF

가장 쉬운 LED ON/OFF를 해보자 . 먼저 프로젝트를 만들고 Clock & Configuration에서 Clock을 설정하자 HSI : 내부 클럭 HSE : 외부 클럭 PLLCLK : 내부 클럭 또는 외부 클럭을 적절히 곱하거나 나누어 원하..

pilimage.tistory.com

 

자동으로 말고 내가 버튼을 눌러서 LED를 제어할 수 없는가?

당연히 가능하다. 

 

먼저 STM32F746 회로도를 보면 유저가 사용할 수 있는 버튼이 있다. 

B_USER 버튼
B_USER - PI11

B_USER 버튼은 핀 PI11에 연결된 것을 확인할 수 있다. 

 

Pinout & Configuration 에서 PI11을 검색하여 핀 위치를 찾는다. 

PI11입장에서 버튼의 신호를 받아야 버튼이 눌렸는지 안눌렸는지 알 수 있기에 PI11을 클릭한 뒤, GPIO_Input으로 설정해준다. 

또한 코드 작성의 편의를 위해 PI11을 우클릭하여 Enter User Label을 눌러 BTN1로 이름을 붙인다. 

System Core - GPIO 항목을 눌러 핀 세팅을 확인하고 Code Generation을 한다. 

코드를 작성할 준비는 모두 끝났다

이번에 사용할 HAL 라이브러리의 함수는 2가지이다. 

 

GPIO를 읽는 Read와 GPIO를 쓰는 Write

즉 ,버튼의 입력을 확인하는 HAL_GPIO_ReadPin 과 LED출력을 조절할 HAL_GPIO_WritePin 이다.

 

GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)

HAL_GPIO_ReadPin은 GPIOx에는 GPIO 구조체의 포인터를, GPIO_Pin에는 해당 핀을 넣어 핀 상태인 GPIO_PinState ( 0 또는 1 )를 리턴한다. 

 

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)

GPIOx에는 GPIO 구조체의 포인터를, GPIO_Pin에는 해당 핀을, PinState에는 출력을 할려면 1(=GPIO_PIN_SET) 아니면 0(GPIO_PIN_RESET)을 넣으면 된다.

 

 

먼저 버튼을 누른 상태에서만 LED가 켜지는 동작을 작성해 보자 

1. 메인 루프에서 BTN1의 상태를 계속 읽는다. 

2. BTN1이 눌려져 있으면, LED1을 On한다. 

3. BTN1이 안눌려져 있으면 LED1을 Off한다.

 

if문을 쓰기 싫다 코드를 한 줄로 줄이고 싶다면 다음과 같이 작성해도 된다.

1. 메인루프에서 LED1을 BTN1의 상태를 읽어 출력한다. 

HAL_GPIO_ReadPin이 GPIO_PinState를 리턴하므로 이렇게 한 줄로도 줄일 수 있다. 

 

반응형

가장 쉬운 LED ON/OFF를 해보자 .

 

먼저 프로젝트를 만들고 Clock & Configuration에서 Clock을 설정하자 

HSI  : 내부 클럭 
HSE : 외부 클럭
PLLCLK : 내부 클럭 또는 외부 클럭을 적절히 곱하거나 나누어 원하는 클럭으로 만들어 사용 

 

클럭은 PLLCLK을 사용하여 32Mhz를 만들었다. 

(내부 16Mhz / 16 * 192 / 6 = 32 Mhz  ,  일단 APB~~등등은 동일하게 설정)

 

Pinout & Configuration에서 이제 LED Pin을 설정한다. 

먼저 사용할 LED인 LD1과 연결된 Pin을 회로도에서 확인한다. 

또한 회로도에서 LED 다이오드의 방향을 보면 PI1에서 Output을 출력해야 LED가 켜지는 것을 확인할 수 있다.

 

LD1은 PI1과 연결되어 있으므로 핀맵에서 PI1을 찾는다. 

직접 찾아도 되지만 아래 검색을 이용하면 더 쉽게 찾을 수 있다

PI1을 클릭하고 GPIO_Output으로 선택하면 해당 핀이 초록색으로 변하고 이름이 GPIO_Output으로 변한다.

코드를 작성할 때 편의를 위해서 해당 핀을 다시 우클릭하고 Enter User Label을 눌러 LED1로 이름을 바꿔준다.

핀 선택이 잘되었다 보고 싶으면 System Core의 GPIO 창을 눌러 확인한다. 

확인까지 하였으면 상단 메뉴의 톱니바퀴 모양인 Code Generation을 눌러 코드를 생성해보자

 

Core - Src - main.c 를 확인해보면 설정한 클럭과 GPIO핀(LED1)들이 main함수 시작에서 초기화 되는 것을 확인할 수 있다. 

 

main.c
clock config
LED1 init

 

이제 설정은 끝났고, HAL 라이브러리를 사용하여 설정한 LED를 조작해보자.

 

LED1은 GPIO핀으로 출력을 조절하여 LED를 On/Off 할 수 있고 다음 HAL 함수를 통해 GPIO 출력을 조절할 수 있다. 

 

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)

 

GPIOx에는 GPIO 구조체의 포인터를, GPIO_Pin에는 해당 핀을, PinState에는 출력을 할려면 1(=GPIO_PIN_SET) 아니면 0(GPIO_PIN_RESET)을 넣으면 된다.

 

PI1핀의 이름을 LED1로 바꾸었기에 아래와 같이 메인 소스를 작성하면 1초 간격으로 LED가 On/off를 반복하는 것을 볼 수 있다. 

(이름을 바꾸지 않았다면 구조체는 GPIOI~ , 핀은 GPIO_PIN_1 등으로 설정되며 알아보기가 힘들 수도 있다. )

동작은 정말 간단한다. 

LED1에 출력을 High로 주었다가 Low로 주었다가를 반복하면 된다. 

 

해당 소스를 빌드해서 이제 넣으면 되는데 어떻게 넣을까? 

상단의 Run을 눌러도 되고 Debug를 눌러도 된다. (단 Debug의 경우 빌드를 먼저 해야함)

이 때 Debug Configurations 나 Run Configurations를 눌러 Debugger 설정을 할 수 있다. 

Debugger 설정을 다음과 같이 ST-Link로 해주면 전원을 넣는다고 연결한 USB를 통해서도 프로그램을 올릴 수 있다.  

 

이제 Run 버튼을 누르면 해당 프로그램이 올라간다. 

 

실제 보드가 1초 간격으로 On/Off 되는 것을 확인할 수 있다. 

 

반응형

stm32이란 것이 아무것도 모르고 펌웨어 프로그램을 시작했다.

지금도 이론이나 기초는 터무니 없이 부족하며

단순히 필요한 것만 찾아서 그 때 그 때 어거지로 사용하고 있다고 생각한다.. 

 

그래서 처음부터 이것저것 천천히 다시 해보려고 한다. 

 

STM32F746G Discovery 보드와 STM32CubeIDE를 사용한다. 

 

먼저 갓 STM32CubeIDE를 아래 링크에서 설치하자

https://www.st.com/en/development-tools/stm32cubeide.html

 

STM32CubeIDE - STMicroelectronics

STM32CubeIDE - Integrated Development Environment for STM32, STM32CubeIDE-RPM, STM32CubeIDE-Lnx, STM32CubeIDE-Win, STM32CubeIDE-DEB, STM32CubeIDE-Mac, STMicroelectronics

www.st.com

앞으로 진행할 여러 실습을 위해 STM32F746G보드로 프로젝트 만들자.

 

프로젝트를 만들고 Debug폴더의 .ioc를 더블클릭하여 Configuration Tool을 연다.

프로젝트 이름은 test

Pinout & Configuration에서는 핀 세팅과 설정들을 변경할 수 있다. 

 

Clock Configuration을 누르면 Clock Tree가 나온다.

클럭을 설정하는 곳인데 HSI,HSE,PLLCLK 등등 이런저런? 것들이 나온다. 

쉽게 생각하면 다음과 같다.

 

HSI  : 내부 클럭 
HSE : 외부 클럭
PLLCLK : 내부 클럭 또는 외부 클럭을 적절히 곱하거나 나누어 원하는 클럭으로 만들어 사용 

 

여기서 원하는 클럭을 만들어 사용하면 된다. 

 

이렇게 클럭과 핀 등을 세팅하고 톱니바퀴 모양의 Code Generation 을 누르면 해당 설정들이 적용된 코드가 만들어진다. 

 

요약하자면 아래 와 같은 과정을 통해 stm32를 이용하여 원하는 코드를 작성하고 디버깅할 환경을 만들 수 있다. 

 

1. 보드에 맞게 프로젝트 생성

2. 클럭 설정

3. 사용할 핀 세팅 및 설정 

4. Code Generation

 

반응형

만들었던 Stack 함수들을 이용하여 괄호 문제를 풀어보았다. 

Stack 함수 : https://pilimage.tistory.com/12

 

[C]구조체를 이용한 Stack 구현

Stack이란? : 데이터를 일시적으로 저장하는 방법 LIFO (Last In First Out, 후입선출)의 구조로나중에 들어온 데이터가 먼저 나가는 방식 배열을 크게 잡고 사용하여도 되지만 학습을 위하여 malloc을 사

pilimage.tistory.com

int main(){
    int num;
    int i,j;
    int err=0;

    scanf("%d",&num);
    char input[50];

    int *errList;
    errList=(int*)malloc(sizeof(int)*num);
    Stack s;
    
    for(i=0;i<num;i++){
        memset(input,0x00,sizeof(input));
        scanf("%s",input);
        initStack(&s,strlen(input));
        for(j=0;j<strlen(input);j++){
            if(input[j]=='('){
                pushStack(&s,input[j]);
            }else{
                if(popStack(&s)==0){
                    errList[i]=1;
                }
            }
        }
        if (!isEmptyStack(&s)){
            errList[i]=1;
        }
        DelStack(&s);
    }

    for(i=0;i<num;i++){
        if(errList[i]){
            printf("NO\n");
        }else{
            printf("YES\n");
        }
    }
    free(errList);
    return 0;
}

입력을 받아서 ' ( '를 만나면 스택에 push하고 ' ) '를 만나면 pop을 하도록하였다. 

' ) '을 만나서 pop을 할때, ' ( '와 ' ) '는 한 쌍이므로 ' ) '를 만났는데 스택에 ' ( '가 없어서 pop을 하지 못한다면 에러로 처리하였다. 

입력을 다 서치하고, 스택에 데이터인 ' ( '가 남아 있다면 에러로 처리하였다.

err flag과 errList를 이용하여 마지막에 결과를 출력하도록 하였다.

테스트 결과

 

반응형

+ Recent posts