본문 바로가기

AWS IoT/펌웨어

[AWS LED Button] ESP32 (4) : AWS_IoT_Client 객체

C언어에서 객체라니..? 자바 공부를 하기 전이었으면 당황스러웠겠지만 자바와 RTOS를 공부하고나니 객체 지향 프로그래밍이라는 것이 특정 언어에 종속되는 개념이 아니라는 것을 알았습니다. 태생이 객체 지향 프로그래밍을 위해 개발된 자바나 C# 보다 약간 번거롭지만, C언어로도 객체 지향을 어느정도 흉내낼 수 있습니다. 


간단하게 RTOS를 예로 들면 "테스크 함수"가 클래스 역할, "테스크 핸들"이 객체 역할을 한다고 볼 수 있습니다. "테스크 함수 A"를 사용하여 "테스크 1", "테스크 2"를 만들고 "테스크 핸들 1", "테스크 핸들 2"를 할당 받았을 때, "테스크 1"과 "테스크 2"는 동일한 "테스크 함수 A"를 참조하지만, 다른 메모리 공간을 리소스로 사용합니다. 그리고 그 공간을 각각 "테스크 핸들 1"과 "테스크 핸들 2"로 접근할 수 있습니다. 테스크 핸들을 객체라고 볼 수 있습니다. 전 JVM의 동작 흐름과 RTOS의  동작 흐름이 거의 비슷한 것처럼 보였습니다.


그리고 대부분 MCU 제조사에서 제공되는 SDK도 C언어로 객체 지향으로 구현되어 제공됩니다. 제가 옛날에 포스팅한 CAN 통신을 예로 들어보겠습니다. HAL_CAN_Init 함수는 CAN_HandleTypeDef 포인터 변수 타입을 매개변수로 받아 초기화를 수행합니다. 이것이 CAN_HandleTypeDef 구조체 변수가 객체가 됩니다.. 그리고 대부분의 CAN 함수는 특정 파일에 모여있을 것입니다. 오래되서 기억이 잘 안나네요. CAN 함수가 모여 있는 파일을 클래스라고 보면 됩니다. 만약 서로 다른 두개의 CAN_HandleTypeDef 구조체 변수에 대해 HAL_CAN_Init 함수로 각각 초기화해 주면, 각 CAN_HandleTypeDef 구조체 변수가 동일한 CAN 함수를 사용하더라도 서로 다른 상태를 갖고 그에 따라 제어 흐름도 달라질 것입니다.


C 언어에서 객체라는 개념이 혼란스러울 것 같아 간단히 설명하려고 했는데 너무 길어졌네요. 위 내용은 그냥 참고정도만 하면 될 것 같습니다.


아무튼 AWS_IoT_Client 타입 변수는 C언어 AWS IoT SDK에서 제공하는 클라이언트에 대한 인스턴스입니다. AWS IoT를 브로커로 하는 MQTT 통신에서 클라이언트 역할을 하기 위해 필요한 모든 함수들은  AWS_IoT_Client 객체 단위로 제어됩니다. 테스트해 보지는 않았지만 아마 하나의 ESP32에서 두개의 AWS_IoT_Client 객체를 만들어 두개의 사물을 구현할 수도 있을 것입니다. 단, 이때 client id는 서로 달라야 합니다. MQTT 프로토콜 상 동일한 client id로 동시에 접속되면 둘 중 하나의 연결이 끊어지기 때문입니다. C언어 AWS IoT SDK 뿐만 아니라, 모든 AWS IoT SDK에는 항상 AWS_IoT_Client 객체가 있습니다.


ESP32 SDK에서는 Subscribe/PublishThingShadow 예제를 제공합니다. 사실 AWS LED Button도 두 예제를 결합하고 몇개의 기능을 추가한 것에 불과합니다. 하지만 두 예제를 자세히 보면 두 예제 모두 AWS IoT와 통신하기 위해 AWS_IoT_Client 객체를 사용하지만, 서로 다른 모듈을 사용합니다. Subscribe/Publish 예제는 aws_iot_mqtt 모듈을 사용하고 ThingShadow는 aws_iot_shadow 모듈을 사용합니다. 하지만 aws_iot_shadow 모듈을 자세히 살펴보면 aws_iot_mqtt 모듈에 몇가지 사전설정을 한 후 포장한 모듈에 불과합니다. 따라서 aws_iot_shadow 모듈은 aws_iot_mqtt 모듈의 모든 기능을 포함하고 있습니다. 즉, AWS_IoT_Client 객체를 aws_iot_shadow_init 함수로 초기화 시켜도, 해당 객체를 사용하여 aws_iot_mqtt_subscribe/publish 함수를 사용할 수 있습니다.