

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# FreeRTOS 데모
<a name="freertos-next-steps"></a>

FreeRTOS는 주 FreeRTOS 디렉터리의 `demos` 폴더에 몇 개의 데모 애플리케이션을 포함하고 있습니다. FreeRTOS에서 실행할 수 있는 모든 예제는 `demos`의 `common` 폴더에 있습니다. 또한 `demos` 폴더에는 FreeRTOS 적격 플랫폼별로 폴더가 있습니다.

데모 애플리케이션을 사용하기 전에 [FreeRTOS 시작하기](freertos-getting-started.md)에서 자습서를 완료하는 것이 좋습니다. coreMQTT 에이전트 데모를 설정 및 실행하는 방법을 설명합니다.

## FreeRTOS 데모 실행
<a name="running-demos"></a>

다음 주제에서는 FreeRTOS 데모를 설정하고 실행하는 방법을 설명합니다.
+ [블루투스 로우 에너지 데모 애플리케이션](ble-demo.md)
+ [Microchip Curiosity PIC32MZEF용 데모 부트로더](microchip-bootloader.md)
+ [AWS IoT Device Defender 데모](dd-demo.md)
+ [AWS IoT Greengrass V1 Discovery 데모 애플리케이션](gg-demov1.md)
+ [AWS IoT Greengrass V2](gg-demov2.md)
+ [coreHTTP 데모](core-http-demo.md)
+ [AWS IoT Jobs 라이브러리 데모](freertos-jobs-demo.md)
+ [coreMQTT 데모](mqtt-demo.md)
+ [OTA(Over-the-Air) 업데이트 데모 애플리케이션](ota-demo.md)
+ [보안 소켓 에코 클라이언트 데모](secure-sockets-demo.md)
+ [AWS IoT 디바이스 섀도우 데모 애플리케이션](shadow-demo.md)

`freertos/demos/demo_runner/iot_demo_runner.c` 파일에 있는 `DEMO_RUNNER_RunDemos` 함수는 단일 데모 애플리케이션이 실행되는 분리된 스레드를 초기화합니다. 기본적으로 `DEMO_RUNNER_RunDemos`는 coreMQTT 에이전트 데모만 호출하고 시작합니다. FreeRTOS를 다운로드할 때 선택한 구성에 따라 또는 FreeRTOS를 다운로드한 위치에 따라 다른 예제 실행기 함수가 기본적으로 시작될 수 있습니다. 데모 애플리케이션을 활성화하려면 `freertos/vendors/vendor/boards/board/aws_demos/config_files/aws_demo_config.h` 파일을 열고 실행할 데모를 정의합니다.

**참고**  
모든 예제 조합이 함께 작용하는 것은 아닙니다. 조합에 따라, 메모리 제한으로 인해 선택한 대상에서 소프트웨어를 실행하지 못할 수도 있습니다. 한 번에 한 개의 데모를 실행할 것을 권장합니다.

## 데모 구성
<a name="configuring-demos"></a>

이 데모는 사용자가 빠르게 시작할 수 있도록 구성되었습니다. 해당 프로젝트에 맞게 일부 구성을 변경하여 해당 플랫폼에서 실행하는 버전을 만들 수도 있습니다. 구성 파일은 `vendors/vendor/boards/board/aws_demos/config_files`에서 찾을 수 있습니다.

# 블루투스 로우 에너지 데모 애플리케이션
<a name="ble-demo"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

## 개요
<a name="ble-demo-overview"></a>

FreeRTOS 블루투스 로우 에너지에는 세 개의 데모 애플리케이션이 포함되어 있습니다.
+ [MQTT over 블루투스 로우 에너지](#ble-demo-mqtt) 데모 

  이 애플리케이션은 MQTT over 블루투스 로우 에너지 서비스를 사용하는 방법을 보여 줍니다.
+ [Wi-Fi 프로비저닝](#ble-demo-wifi) 데모

  이 애플리케이션은 블루투스 로우 에너지 Wi-Fi 프로비저닝 서비스를 사용하는 방법을 보여 줍니다.
+ [일반 속성 서버](#ble-demo-server) 데모

  이 애플리케이션은 FreeRTOS 블루투스 로우 에너지 미들웨어 API를 사용하여 간단한 GATT 서버를 생성하는 방법을 보여 줍니다.

**참고**  
FreeRTOS 데모를 설정하고 실행하려면 [FreeRTOS 시작하기](freertos-getting-started.md)의 단계를 따릅니다.

## 사전 조건
<a name="ble-demo-prereqs"></a>

이 데모를 따라 수행하려면 블루투스 로우 에너지 기능을 지원하는 마이크로 컨트롤러가 필요합니다. 또한 [FreeRTOS 블루투스 디바이스용 iOS SDK](freertos-ble-mobile.md#freertos-ble-ios) 또는 [FreeRTOS 블루투스 디바이스용 Android SDK](freertos-ble-mobile.md#freertos-ble-android)이 필요합니다.

### FreeRTOS Bluetooth Low Energy용 AWS IoT 및 Amazon Cognito 설정
<a name="set-up-ble-demo-aws"></a>

MQTT AWS IoT 에서 디바이스를에 연결하려면 AWS IoT 및 Amazon Cognito를 설정해야 합니다.

**설정하려면 AWS IoT**

1. [https://aws.amazon.com/](https://aws.amazon.com/) AWS 계정을 설정합니다.

1. [AWS IoT 콘솔](https://console.aws.amazon.com/iot/)을 열고 탐색 창에서 **관리**를 선택한 후 **사물**을 선택합니다.

1. **생성**을 선택한 후 **단일 사물 생성**을 선택합니다.

1. 디바이스에 대해 기억하기 쉬운 이름을 입력한 후 **다음**을 선택합니다.

1. 모바일 디바이스를 통해 클라우드에 마이크로 컨트롤러를 연결하는 경우 **인증서없이 사물 생성**을 선택합니다. 모바일 SDK는 디바이스 인증에 Amazon Cognito를 사용하기 때문에 블루투스 로우 에너지를 사용하는 데모용 디바이스 인증서를 생성할 필요가 없습니다.

   WiFi를 통해 마이크로 컨트롤러를 클라우드에 직접 연결하는 경우 **인증서 생성**을 선택하고 **활성화**를 선택한 후 사물 인증서, 퍼블릭 키, 프라이빗 키를 다운로드합니다.

1. 등록된 사물 목록에서 방금 생성한 사물을 선택한 다음 사물 페이지에서 **상호 작용**을 선택합니다. AWS IoT REST API 엔드포인트를 기록해 둡니다.

설정에 대한 자세한 내용은 [시작하기를 참조하세요 AWS IoT](https://docs.aws.amazon.com/iot/latest/developerguide/iot-gs.html).

**Amazon Cognito 사용자 풀을 생성하려면**

1. Amazon Cognito 콘솔로 이동하여 **사용자 풀 관리**를 선택합니다.

1. **사용자 풀 생성**을 선택합니다.

1. 사용자 풀에 이름을 지정한 다음 **기본값 검토**를 선택합니다.

1. 왼쪽 탐색 창에서 **앱 클라이언트**를 선택한 다음 **앱 클라이언트 추가**를 선택합니다.

1. 앱 클라이언트의 이름을 입력한 후 **앱 클라이언트 생성**을 선택합니다.

1. 왼쪽 탐색 창에서 **검토**를 선택한 후 **풀 생성**을 선택합니다.

   사용자 풀의 **일반 설정** 페이지에 나타나는 풀 ID를 기록해 둡니다.

1. 왼쪽 탐색 창에서 **앱 클라이언트**를 선택한 다음 **세부 정보 표시**를 선택합니다. 앱 클라이언트 ID와 앱 클라이언트 암호를 메모합니다.

**Amazon Cognito 자격 증명 풀을 생성하려면**

1. Amazon Cognito 콘솔에서 **자격 증명 풀 관리**를 선택합니다.

1. 자격 증명 풀의 이름을 입력합니다.

1. **인증 공급자**를 확장하고 **Cognito** 탭을 선택한 후 사용자 풀 ID와 앱 클라이언트 ID를 입력합니다.

1. **풀 생성**을 선택합니다.

1. **세부 정보 보기**를 확장하고 2개의 IAM 역할 이름을 적어 둡니다. **허용**을 선택하여 Amazon Cognito에 액세스할 인증된 자격 증명 및 인증되지 않은 자격 증명을 생성합니다.

1. **자격 증명 풀 편집**을 선택합니다. 자격 증명 풀 ID를 메모합니다. `us-west-2:12345678-1234-1234-1234-123456789012` 형식이어야 합니다.

Amazon Cognito 설정에 대한 자세한 내용은 [Amazon Cognito 시작하기](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-getting-started.html)를 참조하세요.

**IAM 정책을 생성하여 인증된 자격 증명에 연결하려면**

1. IAM 콘솔을 열고 탐색 창에서 **역할**을 선택합니다.

1. 인증된 자격 증명의 역할을 검색 및 선택하고 **정책 연결**를 선택한 후 **인라인 정책 추가**를 선택합니다.

1. **JSON** 탭을 선택하고 다음 JSON을 붙여 넣습니다.

------
#### [ JSON ]

****  

   ```
   {
      "Version":"2012-10-17",		 	 	 
      "Statement":[
         {
            "Effect":"Allow",
            "Action":[
               "iot:AttachPolicy",
               "iot:AttachPrincipalPolicy",
               "iot:Connect",
               "iot:Publish",
               "iot:Subscribe",
               "iot:Receive",
               "iot:GetThingShadow",
               "iot:UpdateThingShadow",
               "iot:DeleteThingShadow"
            ],
            "Resource":[
               "*"
            ]
         }
      ]
   }
   ```

------

1. **정책 검토**를 선택하고 정책 이름을 입력한 후 **정책 생성**을 선택합니다.

 AWS IoT 및 Amazon Cognito 정보를 보관합니다. AWS 클라우드로 모바일 애플리케이션을 인증하려면 엔드포인트와 IDs가 필요합니다.

### 블루투스 로우 에너지용 FreeRTOS 환경 설정
<a name="ble-demo-set-up"></a>

환경을 설정하려면 마이크로컨트롤러에 [블루투스 로우 에너지 라이브러리](freertos-ble-library.md)와 함께 FreeRTOS를 다운로드해야 하며 모바일 디바이스에 FreeRTOS Bluetooth 디바이스용 모바일 SDK를 다운로드하고 구성해야 합니다.

**FreeRTOS 블루투스 로우 에너지로 마이크로컨트롤러 환경을 설정하려면**

1. [GitHub](https://github.com/aws/amazon-freertos)에서 FreeRTOS를 복제하거나 다운로드합니다. 자세한 내용은 [README.md](https://github.com/aws/amazon-freertos/blob/main/README.md) 파일을 참조하십시오.

1. 마이크로컨트롤러에 FreeRTOS를 설정합니다.

   FreeRTOS 적격 마이크로컨트롤러에서 FreeRTOS를 시작하는 방법에 대한 자세한 내용은 [FreeRTOS 시작하기](https://docs.aws.amazon.com/freertos/latest/userguide/freertos-getting-started.html)에서 해당 보드에 대한 안내서를 참조하세요.
**참고**  
FreeRTOS 및 이식된 FreeRTOS 블루투스 로우 에너지 라이브러리를 지원하는 모든 블루투스 로우 에너지 사용 마이크로컨트롤러에서 데모를 실행할 수 있습니다. 현재 FreeRTOS [MQTT over 블루투스 로우 에너지](#ble-demo-mqtt) 데모 프로젝트는 다음 블루투스 로우 에너지 사용 디바이스에 완벽하게 이식됩니다.  
[Espressif ESP32-DevKitC 및 ESP-WROVER-KIT](https://docs.aws.amazon.com/freertos/latest/userguide/getting_started_espressif.html)
[Nordic nRF52840-DK](https://docs.aws.amazon.com/freertos/latest/userguide/getting_started_nordic.html)

## 공통 구성 요소
<a name="ble-demo-common"></a>

FreeRTOS 데모 애플리케이션에는 두 개의 공통 요소가 있습니다.
+ 네트워크 매니저
+ 블루투스 로우 에너지 모바일 SDK 데모 애플리케이션

### 네트워크 매니저
<a name="ble-demo-network-manager"></a>

네트워크 매니저는 마이크로 컨트롤러의 네트워크 연결을 관리하며, `demos/network_manager/aws_iot_network_manager.c`의 FreeRTOS 디렉터리에 있습니다. 네트워크 매니저를 Wi-Fi와 블루투스 로우 에너지 모두에 대해 활성화한 경우 데모는 기본적으로 블루투스 로우 에너지로 시작합니다. 블루투스 로우 에너지 연결이 끊어지고 보드가 Wi-Fi를 지원하는 경우 네트워크 매니저는 사용 가능한 Wi-Fi 연결로 전환하여 네트워크 연결이 끊어지지 않도록 보호합니다.

네트워크 매니저를 사용하여 네트워크 연결 유형을 활성화하려면 `vendors/vendor/boards/board/aws_demos/config_files/aws_iot_network_config.h`의 `configENABLED_NETWORKS` 파라미터에 네트워크 연결 유형을 추가합니다. 여기서 *벤더*는 공급업체의 이름이고 *보드*는 데모를 실행하는 데 사용하는 보드 이름입니다.

예를 들어, 블루투스 로우 에너지와 Wi-Fi를 모두 활성화한 경우 `#define configENABLED_NETWORKS`에서 `aws_iot_network_config.h`로 시작하는 행은 다음과 같습니다.

```
#define  configENABLED_NETWORKS  ( AWSIOT_NETWORK_TYPE_BLE | AWSIOT_NETWORK_TYPE_WIFI )
```

현재 지원되는 네트워크 연결 유형의 목록을 가져오려면 `aws_iot_network.h`에서 `#define AWSIOT_NETWORK_TYPE`으로 시작하는 줄을 참조하십시오.

### FreeRTOS 블루투스 로우 에너지 모바일 SDK 데모 애플리케이션
<a name="ble-sdk-app"></a>

FreeRTOS 블루투스 로우 에너지 모바일 SDK 데모 애플리케이션은 GitHub에서 [블루투스 디바이스를 위한 Android SDK](https://github.com/aws/amazon-freertos-ble-android-sdk) 아래의 `amazon-freertos-ble-android-sdk/app` 및 [블루투스 디바이스를 위한 iOS SDK](https://github.com/aws/amazon-freertos-ble-ios-sdk) 아래의 `amazon-freertos-ble-ios-sdk/Example/AmazonFreeRTOSDemo`에 있습니다. 이 예에서는 iOS 버전의 데모 모바일 애플리케이션의 스크린샷을 사용합니다.

**참고**  
iOS 디바이스를 사용하는 경우 데모 모바일 애플리케이션을 빌드하려면 Xcode가 필요합니다. Android 디바이스를 사용하는 경우 Android Studio를 사용하여 데모 모바일 애플리케이션을 빌드할 수 있습니다.

**iOS SDK 데모 애플리케이션을 구성하려면**

구성 변수를 정의할 경우 구성 파일에 제공된 자리 표시자 값의 형식을 사용합니다.

1. [FreeRTOS 블루투스 디바이스용 iOS SDK](freertos-ble-mobile.md#freertos-ble-ios)이 설치되어 있는지 확인합니다.

1. `amazon-freertos-ble-ios-sdk/Example/AmazonFreeRTOSDemo/`에서 다음 명령을 실행합니다.

   ```
   $ pod install
   ```

1. Xcode를 사용하여 `amazon-freertos-ble-ios-sdk/Example/AmazonFreeRTOSDemo/AmazonFreeRTOSDemo.xcworkspace` 프로젝트를 열고 서명 개발자 계정을 사용자 계정으로 변경합니다.

1. 리전에서 AWS IoT 정책을 생성합니다(아직 생성하지 않은 경우).
**참고**  
이 정책은 Amazon Cognito 인증 자격 증명에 대해 생성된 IAM 정책과 다릅니다.

   1. [AWS IoT 콘솔](https://console.aws.amazon.com/iot/)을 엽니다.

   1. 탐색 창에서 **보안**를 선택하고 **정책**를 선택한 다음 **생성**를 선택합니다. 정책을 식별할 이름을 입력합니다. **설명문 추가** 섹션에서 **고급 모드**를 선택합니다. 다음 JSON을 복사하여 정책 편집기 창에 붙여 넣습니다. *aws-region* 및 *aws-account*를 AWS 리전 및 계정 ID로 바꿉니다.

   1. **생성(Create)**을 선택합니다.

1. `amazon-freertos-ble-ios-sdk/Example/AmazonFreeRTOSDemo/AmazonFreeRTOSDemo/Amazon/AmazonConstants.swift`를 열고 다음 변수를 재정의합니다.
   + `region`: AWS 리전.
   + `iotPolicyName`: AWS IoT 정책 이름입니다.
   + `mqttCustomTopic`: 게시하려는 MQTT 주제.

1. `amazon-freertos-ble-ios-sdk/Example/AmazonFreeRTOSDemo/AmazonFreeRTOSDemo/Support/awsconfiguration.json`를 엽니다.

   `CognitoIdentity` 아래에서 다음 변수를 재정의합니다.
   + `PoolId`: Amazon Cognito 자격 증명 풀 ID.
   + `Region`: AWS 리전.

   `CognitoUserPool` 아래에서 다음 변수를 재정의합니다.
   + `PoolId`: Amazon Cognito 사용자 풀 ID.
   + `AppClientId`: 해당 앱 클라이언트 ID.
   + `AppClientSecret`: 해당 앱 클라이언트 암호.
   + `Region`: AWS 리전.

**Android SDK 데모 애플리케이션을 구성하려면**

구성 변수를 정의할 경우 구성 파일에 제공된 자리 표시자 값의 형식을 사용합니다.

1. [FreeRTOS 블루투스 디바이스용 Android SDK](freertos-ble-mobile.md#freertos-ble-android)이 설치되어 있는지 확인합니다.

1. 리전에서 AWS IoT 정책을 생성합니다(아직 생성하지 않은 경우).
**참고**  
이 정책은 Amazon Cognito 인증 자격 증명에 대해 생성된 IAM 정책과 다릅니다.

   1. [AWS IoT 콘솔](https://console.aws.amazon.com/iot/)을 엽니다.

   1. 탐색 창에서 **보안**를 선택하고 **정책**를 선택한 다음 **생성**를 선택합니다. 정책을 식별할 이름을 입력합니다. **설명문 추가** 섹션에서 **고급 모드**를 선택합니다. 다음 JSON을 복사하여 정책 편집기 창에 붙여 넣습니다. *aws-region* 및 *aws-account*를 AWS 리전 및 계정 ID로 바꿉니다.

   1. **생성(Create)**을 선택합니다.

1. [https://github.com/aws/amazon-freertos-ble-android-sdk/blob/master/app/src/main/java/software/amazon/freertos/demo/DemoConstants.java](https://github.com/aws/amazon-freertos-ble-android-sdk/blob/master/app/src/main/java/software/amazon/freertos/demo/DemoConstants.java)를 열고 다음 변수를 재정의합니다.
   + `AWS_IOT_POLICY_NAME`: AWS IoT 정책 이름입니다.
   + `AWS_IOT_REGION`: AWS 리전.

1. [ https://github.com/aws/amazon-freertos-ble-android-sdk/blob/master/app/src/main/res/raw/awsconfiguration.json](https://github.com/aws/amazon-freertos-ble-android-sdk/blob/master/app/src/main/res/raw/awsconfiguration.json)을 엽니다.

   `CognitoIdentity` 아래에서 다음 변수를 재정의합니다.
   + `PoolId`: Amazon Cognito 자격 증명 풀 ID.
   + `Region`: AWS 리전.

   `CognitoUserPool` 아래에서 다음 변수를 재정의합니다.
   + `PoolId`: Amazon Cognito 사용자 풀 ID.
   + `AppClientId`: 해당 앱 클라이언트 ID.
   + `AppClientSecret`: 해당 앱 클라이언트 암호.
   + `Region`: AWS 리전.

**블루투스 로우 에너지를 통해 마이크로 컨트롤러와의 보안 연결을 찾아보고 설정하려면**

1. 마이크로컨트롤러와 모바일 디바이스를 안전하게 페어링하려면(6단계) 입력 및 출력 기능을 모두 갖춘 직렬 터미널 에뮬레이터(예: TeraTerm)가 필요합니다. [터미널 에뮬레이터 설치](gsg-troubleshooting.md#uart-term)의 지침에 따라 터미널을 직렬 연결로 보드에 연결하도록 구성합니다.

1. 마이크로 컨트롤러에서 블루투스 로우 에너지 데모 프로젝트를 실행합니다.

1. 모바일 디바이스에서 블루투스 로우 에너지 모바일 SDK 데모 애플리케이션을 실행합니다.

   명령줄에서 Android SDK의 데모 애플리케이션을 시작하려면 다음 명령을 실행하십시오.

   ```
   $ ./gradlew installDebug
   ```

1. 블루투스 로우 에너지 모바일 SDK 데모 앱에서 **디바이스** 아래에 마이크로 컨트롤러가 표시되는지 확인합니다.  
![\[고유 식별자가 있는 ESP32 디바이스를 보여주는 디바이스 관리 페이지입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/ble-device-list1.png)
**참고**  
FreeRTOS를 지원하는 모든 디바이스와 범위 내에 있는 디바이스 정보 서비스(`freertos/.../device_information`)가 목록에 나타납니다.

1. 디바이스 목록에서 마이크로 컨트롤러를 선택합니다. 애플리케이션에서 보드와의 연결을 설정하고 연결된 디바이스 옆에 녹색 선이 나타납니다.  
![\[ESP32 디바이스 ID가 표시됩니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/ble-device-list2.png)

   선을 왼쪽으로 끌어서 마이크로컨트롤러를 연결 해제할 수 있습니다.  
![\[ESP32 디바이스 ID와 다른 디바이스 ID를 보여주는 디바이스 페이지입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/ble-device-list3.png)

1. 메시지가 표시되면 마이크로컨트롤러와 모바일 디바이스를 페어링합니다.  
![\[BLE 디바이스 연결 해제, MQTT 서비스 연결 해제, 광고 시작, 원격 디바이스에 대한 BLE 연결, 숫자 비교 프롬프트를 보여주는 콘솔 출력입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/pairing-board.png)  
![\["ESP32"에서 확인할 코드 "465520"을 보여주는 디바이스 "ESP32"에 대한 블루투스 페어링 요청 대화 상자입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/pairing-mobile.png)

   두 디바이스의 수 비교를 위한 코드가 동일한 경우 디바이스를 연결합니다.

**참고**  
블루투스 로우 에너지 모바일 SDK 데모 애플리케이션에서는 사용자 인증을 위해 Amazon Cognito를 사용합니다. Amazon Cognito 사용자 및 자격 증명 풀을 설정하고 IAM 정책을 인증된 자격 증명에 연결했는지 확인합니다.

## MQTT over 블루투스 로우 에너지
<a name="ble-demo-mqtt"></a>

MQTT over Bluetooth Low Energy 데모에서 마이크로컨트롤러는 MQTT 프록시를 통해 AWS 클라우드에 메시지를 게시합니다.

**데모 MQTT 주제를 구독하려면**

1.  AWS IoT 콘솔에 로그인합니다.

1. 탐색 창에서 **테스트**를 선택한 다음 **MQTT 테스트 클라이언트**를 선택하여 MQTT 클라이언트를 엽니다.

1. **구독 주제**에 ***thing-name*/example/topic1**을 입력한 다음 **주제 구독**을 선택합니다.

블루투스 로우 에너지를 사용하여 마이크로 컨트롤러를 모바일 디바이스와 연결하는 경우 MQTT 메시지는 모바일 디바이스의 블루투스 로우 에너지 모바일 SDK 데모 애플리케이션을 통해 라우팅됩니다.

**블루투스 로우 에너지를 통해 데모를 활성화하려면**

1. `vendors/vendor/boards/board/aws_demos/config_files/aws_demo_config.h`를 열고 `CONFIG_MQTT_BLE_TRANSPORT_DEMO_ENABLED`를 정의합니다.

1. `demos/include/aws_clientcredential.h`를 열고 AWS IoT 브로커 엔드포인트`clientcredentialMQTT_BROKER_ENDPOINT`로를 구성합니다. `clientcredentialIOT_THING_NAME`를 BLE 마이크로컨트롤러 디바이스의 사물 이름으로 구성합니다. AWS IoT 브로커 엔드포인트는 왼쪽 탐색 창에서 **설정을** 선택하여 AWS IoT 콘솔에서 가져오거나 명령을 실행하여 CLI를 통해 가져올 수 있습니다`aws iot describe-endpoint --endpoint-type=iot:Data-ATS`.
**참고**  
 AWS IoT 브로커 엔드포인트와 사물 이름은 모두 cognito 자격 증명과 사용자 풀이 구성된 리전과 동일한 리전에 있어야 합니다.

**데모를 실행하려면**

1. 마이크로 컨트롤러에서 데모 프로젝트를 빌드한 후 실행합니다.

1. [FreeRTOS 블루투스 로우 에너지 모바일 SDK 데모 애플리케이션](#ble-sdk-app)을 사용하여 보드와 모바일 디바이스를 연결했는지 확인합니다.

1. 데모 모바일 앱의 **디바이스** 목록에서 마이크로 컨트롤러를 선택한 다음 **MQTT 프록시**를 선택하여 MQTT 프록시 설정을 엽니다.  
![\[아래 MQTT 프록시, 네트워크 구성 및 사용자 지정 GATT MQTT 옵션이 있는 세 개의 ESP32 디바이스 IDs.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/ble-device-list4.png)

1. MQTT 프록시를 활성화한 후에는 MQTT 메시지가 `thing-name/example/topic1` 주제에 나타나고 데이터가 UART 터미널에 인쇄됩니다.

## Wi-Fi 프로비저닝
<a name="ble-demo-wifi"></a>

Wi-Fi 프로비저닝은 블루투스 로우 에너지를 통해 모바일 디바이스에서 마이크로컨트롤러로 Wi-Fi 네트워크 보안 인증 정보를 안전하게 전송할 수 있도록 해주는 FreeRTOS 블루투스 로우 에너지 서비스입니다. Wi-Fi 프로비저닝 서비스를 위한 소스 코드는 `freertos/.../wifi_provisioning`에서 찾을 수 있습니다.

**참고**  
Wi-Fi 프로비저닝 데모는 현재 Espressif ESP32-DevKitC에서 지원됩니다.

**데모를 활성화하려면**

1. Wi-Fi 프로비저닝 서비스를 활성화합니다. `vendors/vendor/boards/board/aws_demos/config_files/iot_ble_config.h`를 열고 `#define IOT_BLE_ENABLE_WIFI_PROVISIONING`을 `1`로 설정합니다. 여기서 *벤더*는 공급업체의 이름이고 *보드*는 데모를 실행하는 데 사용하는 보드 이름입니다.
**참고**  
Wi-Fi 프로비저닝 서비스는 기본적으로 비활성화되어 있습니다.

1. 블루투스 로우 에너지와 Wi-Fi를 모두 활성화하도록 [네트워크 매니저](#ble-demo-network-manager)를 구성합니다.

**데모를 실행하려면**

1. 마이크로 컨트롤러에서 데모 프로젝트를 빌드한 후 실행합니다.

1. [FreeRTOS 블루투스 로우 에너지 모바일 SDK 데모 애플리케이션](#ble-sdk-app)을 사용하여 마이크로컨트롤러와 모바일 디바이스를 페어링했는지 확인합니다.

1. 데모 모바일 앱의 **디바이스** 목록에서 마이크로 컨트롤러를 선택한 다음 **네트워크 구성**을 선택하여 네트워크 구성 설정을 엽니다.  
![\[아래 MQTT 프록시, 네트워크 구성 및 사용자 지정 GATT MQTT 옵션이 있는 세 개의 ESP32 디바이스 IDs.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/ble-device-list4.png)

1. 보드에 대한 **네트워크 구성**를 선택하면 마이크로 컨트롤러는 근처에 있는 네트워크 목록을 모바일 디바이스로 전송합니다. 사용 가능한 Wi-Fi 네트워크가 **스캔된 네트워크** 아래 목록에 표시됩니다.  
![\[저장된 네트워크가 없는 ESP32 디바이스 관리 인터페이스, 스캔한 두 개의 개방형 Wi-Fi 네트워크, 하나는 WPA2 보안 및 RSSI가 -29이고 다른 하나는 개방형 보안 및 RSSI가 -50인 네트워크.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/ble-network-config1.png)

   **스캔된 네트워크** 목록에서 네트워크를 선택한 후 필요한 경우 SSID 및 암호를 입력합니다.  
![\[빈 암호 필드가 있는 Wi-Fi 네트워크 암호 입력 대화 상자, 취소 및 저장 버튼.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/ble-wifi-password.png)

   마이크로컨트롤러가 네트워크에 연결되고 네트워크를 저장합니다. 네트워크가 **저장된 네트워크** 아래에 나타납니다.  
![\[저장되고 스캔된 WiFi 네트워크를 보여주는 네트워크 인터페이스로, 하나는 WPA2로 보호되고 다른 하나는 열린 상태이며 신호 강도 표시기가 있습니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/ble-network-config2.png)

데모 모바일 앱에서 여러 네트워크를 저장할 수 있습니다. 애플리케이션 및 데모를 재시작하면 마이크로 컨트롤러가 **저장된 네트워크** 목록의 맨 위에서부터 첫 번째 사용 가능한 저장 네트워크에 연결됩니다.

네트워크 우선 순위를 변경하거나 네트워크를 삭제하려면 **네트워크 구성** 페이지에서 **모드 편집**를 선택합니다. 네트워크 우선 순위를 변경하려면 우선 순위를 조정하려는 네트워크의 오른쪽을 선택하고 네트워크를 위 또는 아래로 끌어 놓습니다. 네트워크를 삭제하려면 삭제할 네트워크의 왼쪽에 있는 빨간색 버튼을 선택합니다.

![\[저장된 네트워크, 우선 순위를 삭제하거나 변경하는 편집 옵션, 스캔한 네트워크를 보여주는 Wifi 네트워크 설정 화면입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/ble-network-editing.png)


## 일반 속성 서버
<a name="ble-demo-server"></a>

이 예에서 마이크로 컨트롤러에 대한 데모 일반 속성(GATT) 서버 애플리케이션은 단순 카운터 값을 [FreeRTOS 블루투스 로우 에너지 모바일 SDK 데모 애플리케이션](#ble-sdk-app)에 전송합니다.

블루투스 로우 에너지 모바일 SDK를 사용하여 마이크로 컨트롤러의 GATT 서버에 연결되고 데모 모바일 애플리케이션과 병렬로 실행되는 모바일 디바이스를 위한 고유 GATT 클라이언트를 생성할 수 있습니다.

**데모를 활성화하려면**

1. 블루투스 로우 에너지 GATT 데모를 활성화하려면 `vendors/vendor/boards/board/aws_demos/config_files/iot_ble_config.h`에서(여기서 *벤더*는 공급업체의 이름이고 *보드*는 데모를 실행하는 데 사용하는 보드 이름임) `#define IOT_BLE_ADD_CUSTOM_SERVICES ( 1 )`를 정의문 목록에 추가합니다.
**참고**  
블루투스 로우 에너지 GATT 데모는 기본적으로 비활성화되어 있습니다.

1. `freertos/vendors/vendor/boards/board/aws_demos/config_files/aws_demo_config.h`를 열고 `#define CONFIG_CORE_MQTT_MUTUAL_AUTH_DEMO_ENABLED`를 주석으로 처리한 다음 `CONFIG_BLE_GATT_SERVER_DEMO_ENABLED`를 정의합니다.

**데모를 실행하려면**

1. 마이크로 컨트롤러에서 데모 프로젝트를 빌드한 후 실행합니다.

1. [FreeRTOS 블루투스 로우 에너지 모바일 SDK 데모 애플리케이션](#ble-sdk-app)을 사용하여 보드와 모바일 디바이스를 연결했는지 확인합니다.

1. 앱의 **디바이스** 목록에서 보드를 선택한 다음 **MQTT 프록시**를 선택하여 MQTT 프록시 옵션을 엽니다.  
![\[아래 MQTT 프록시, 네트워크 구성 및 사용자 지정 GATT MQTT 옵션이 있는 세 개의 ESP32 디바이스 IDs.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/ble-device-list4.png)

1. **디바이스** 목록으로 돌아가서 보드를 선택한 다음 **사용자 지정 GATT MQTT**를 선택하여 사용자 지정 GATT 서비스 옵션을 엽니다.

1. **카운터 시작**를 선택하여 ***your-thing-name*/example/topic** MQTT 주제에 대한 데이터 게시를 시작합니다.

   MQTT 프록시를 활성화한 후에는 Hello World 및 증분 카운터 메시지가 `your-thing-name/example/topic` 주제에 나타납니다.

# Microchip Curiosity PIC32MZEF용 데모 부트로더
<a name="microchip-bootloader"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

**참고**  
Microchip의 합의에 따라 AWS는 FreeRTOS 참조 통합 리포지토리 메인 브랜치에서 Curiosity PIC32MZEF(DM320104)를 제거하고 새 릴리스에는 더 이상 제공하지 않을 예정입니다. Microchip은 PIC32MZEF(DM320104)를 더 이상 새로운 설계에 사용하지 않는 것이 좋다는 [공지문](https://www.microchip.com/DevelopmentTools/ProductDetails/PartNO/DM320104)을 발표했습니다. PIC32MZEF 프로젝트 및 소스 코드는 이전 릴리스 태그를 통해 계속 액세스할 수 있습니다. Microchip은 고객이 새로운 설계에 Curiosity [PIC32MZ-EF-2.0 개발 보드(DM320209)](https://devices.amazonaws.com/detail/a3G0h0000077I69EAE/Curiosity-PIC32MZ-EF-2-0-Development-Board)를 사용할 것을 권장합니다. PIC32MZv1 플랫폼은 FreeRTOS 참조 통합 리포지토리의 [v202012.00](https://github.com/aws/amazon-freertos/tree/202012.00)에서 계속 찾을 수 있습니다. 그러나 FreeRTOS 참조의 [v202107.00](https://github.com/aws/amazon-freertos/tree/202107.00)에서는 이 플랫폼을 더 이상 지원하지 않습니다.

 이 데모 부트로더는 펌웨어 버전 확인, 암호화 서명 검증, 애플리케이션 셀프 테스트를 수행합니다. 이들 기능은 FreeRTOS에 대한 펌웨어 무선 업데이트(OTA)를 지원합니다.

펌웨어 검증에는 원격(OTA)으로 수신한 새 펌웨어의 신뢰성 및 무결성 검증이 포함됩니다. 부트로더는 부팅 전에 애플리케이션의 암호화 서명을 검증합니다. 데모에서는 SHA-256을 통한 ECDSA(Elliptic-Curve Digital Signature Algorithm)를 사용합니다. 제공된 유틸리티를 사용하여 디바이스에 플래시할 수 있는 서명된 애플리케이션을 생성할 수 있습니다.

부트로더는 OTA에 필요한 다음 기능을 지원합니다.
+ 디바이스에 애플리케이션 이미지를 유지하여 이미지 간에 전환합니다.
+ 수신된 OTA 이미지의 셀프 테스트 실행 및 실패 시 롤백을 허용합니다.
+ OTA 업데이트 이미지의 서명과 버전을 확인합니다.

**참고**  
FreeRTOS 데모를 설정하고 실행하려면 [FreeRTOS 시작하기](freertos-getting-started.md)의 단계를 따릅니다.

## 부트로더 상태
<a name="bootloader-states"></a>

부트로더 프로세스는 다음과 같은 상태 시스템으로 표시됩니다.

![\[오류 알림 옵션을 사용하여 초기화, 확인, 실행 상태 및 오류 상태를 보여주는 부트로더 상태 시스템을 시작합니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/bootloader-states.png)


다음 표에는 부트로더 상태에 대한 설명이 나와 있습니다.


| 부트로더 상태 | 설명 | 
| --- | --- | 
|  Initialization(초기화)  |  부트로더가 초기화 상태입니다.  | 
|  Verification(확인)  |  부트로더가 디바이스에 있는 이미지를 확인 중입니다.  | 
|  Execute Image(이미지 실행)  |  부트로더가 선택한 이미지를 시작 중입니다.  | 
|  Execute Default(기본 실행)  |  부트로더가 기본 이미지를 시작 중입니다.  | 
|  오류  |  부트로더가 오류 상태입니다.  | 

위 다이어그램에서 `Execute Image`와 `Execute Default`는 `Execution` 상태로 표시됩니다.

**부트로더 실행 상태**  
부트로더가 `Execution` 상태이고 확인된 선택 이미지를 시작할 준비가 되었습니다. 애플리케이션은 항상 하위 뱅크용으로 빌드되기 때문에 상위 뱅크에서 이미지를 시작할 경우 이미지를 실행하기 전에 뱅크가 바뀝니다.

**부트로더 기본 실행 상태**  
기본 이미지를 실행하는 구성 옵션이 활성화된 경우 부트로더는 기본 실행 주소에서 애플리케이션을 시작합니다. 이 옵션은 디버깅할 때를 제외하고는 비활성화해야 합니다.

**부트로더 오류 상태**  
부트로더가 오류 상태이고, 디바이스에 유효한 이미지가 없습니다. 부트로더가 사용자에게 알려야 합니다. 기본 구현은 콘솔에 로그 메시지를 전송하고, 보드의 LED를 계속 빠르게 깜박이는 것입니다.

## 플래시 디바이스
<a name="flash-device"></a>

Microchip Curiosity PIC32MZEF 플랫폼에는 두 개의 뱅크로 나뉜 2MB의 내부 프로그램 플래시가 있습니다. 이 플래시는 이 뱅크 두 개와 실시간 업데이트 간에 메모리 맵 스왑을 지원합니다. 데모 부트로더는 별도의 하위 부트 플래시 영역에서 프로그래밍됩니다.

![\[각각 부트로더, 애플리케이션 뱅크 0 및 애플리케이션 뱅크 1MB에 매핑된 2MB 리전의 하위 부팅 플래시, 하위 프로그램 플래시 및 상위 프로그램 플래시를 보여주는 메모리 레이아웃 다이어그램입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/flash-device.png)


## 애플리케이션 이미지 구조
<a name="application-image-structure"></a>

![\[헤더, 설명자, 애플리케이션 바이너리(서명자 서비스에서 서명) 및 매직 코드, 시퀀스 번호, 시작 및 종료 주소, 실행 주소, 하드웨어 ID와 같은 필드가 있는 트레일러 섹션을 보여주는 OTA 이미지 구조입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/application-image-structure.png)


이 다이어그램은 디바이스의 각 뱅크에 저장된 애플리케이션 이미지의 기본 구성 요소를 보여 줍니다.


| 구성 요소 | 크기(바이트) | 
| --- | --- | 
|  이미지 헤더  |  8 bytes  | 
|  이미지 설명자  |  24바이트  | 
|  애플리케이션 이진 파일  |   < 1MB - (324)  | 
|  트레일러  |  292바이트  | 

## 이미지 헤더
<a name="image-header"></a>

디바이스의 애플리케이션 이미지는 매직 코드와 이미지 플래그로 구성된 헤더로 시작해야 합니다.


| 헤더 필드 | 크기(바이트) | 
| --- | --- | 
|  매직 코드  |  7바이트  | 
|  이미지 플래그  |  1바이트  | 

### 매직 코드
<a name="magic-code"></a>

플래시 디바이스의 이미지는 매직 코드로 시작해야 합니다. 기본 매직 코드는 `@AFRTOS`입니다. 부트로더는 이미지를 부팅하기 전에 유효한 매직 코드가 있는지 검사합니다. 이것이 검증의 첫 단계입니다.

### 이미지 플래그
<a name="image-flags"></a>

이미지 플래그는 애플리케이션 이미지의 상태를 저장하는 데 사용됩니다. 플래그는 OTA 프로세스에서 사용됩니다. 두 뱅크의 이미지 플래그는 디바이스의 상태를 결정합니다. 실행 이미지가 커밋 대기 중으로 표시되면 디바이스는 OTA 셀프 테스트 단계입니다. 디바이스의 이미지가 유효한 것으로 표시되더라도 부팅할 때마다 동일한 검증 단계를 거칩니다. 이미지가 새 이미지로 표시된 경우, 부트로더는 해당 이미지를 커밋 대기 중으로 표시하고 검증 후 셀프 테스트를 위해 이미지를 시작합니다. 또한 부트로더는 감시 타이머를 초기화하고 시작함으로써 새 OTA 이미지가 셀프 테스트에 실패할 경우 디바이스가 재부팅되고, 부트로더는 이미지를 삭제하여 거부하고, 이전의 유효한 이미지를 실행하도록 합니다.

디바이스에는 유효한 이미지가 한 개만 있어야 합니다. 다른 이미지는 새 OTA 이미지이거나 커밋 대기 중(셀프 테스트) 상태일 수 있습니다. OTA 업데이트가 성공하면 디바이스에서 이전 이미지가 삭제됩니다.


| 상태 표시기 | 값 | 설명 | 
| --- | --- | --- | 
|  새로운 이미지  |  0xFF  |  애플리케이션 이미지가 새 이미지이며 실행되지 않습니다.  | 
|  커밋 대기 중  |  0xFE  |  애플리케이션 이미지가 테스트 실행용으로 표시되었습니다.  | 
|  유효함  |  0xFC  |  애플리케이션 이미지가 유효로 표시되고 커밋되었습니다.  | 
|  잘못됨  |  0xF8  |  애플리케이션 이미지가 잘못됨으로 표시되었습니다.  | 

## 이미지 설명자
<a name="image-descriptor"></a>

플래시 디바이스의 애플리케이션 이미지는 이미지 헤더 뒤에 이미지 설명자를 포함해야 합니다. 이미지 설명자는 구성 파일(`ota-descriptor.config`)을 사용하여 해당 설명자를 생성하고 이 설명자를 애플리케이션 이진 파일에 추가하는 포스트 빌드 유틸리티를 통해 생성됩니다. 이 빌드 후 단계의 출력은 이진 이미지이며 OTA에 사용할 수 있습니다.


| 설명자 필드 | 크기(바이트) | 
| --- | --- | 
|  시퀀스 번호  |  4 bytes  | 
|  시작 주소  |  4 bytes  | 
|  종료 주소  |  4 bytes  | 
|  실행 주소  |  4 bytes  | 
|  하드웨어 ID  |  4 bytes  | 
|  예약  |  4 bytes  | 

**시퀀스 번호**  
시퀀스 번호가 증가한 뒤에 새 OTA 이미지를 빌드해야 합니다. `ota-descriptor.config` 파일을 참조하십시오. 부트로더는 이 번호로 부팅할 이미지를 결정합니다. 유효한 값은 1\$14294967295입니다.

**시작 주소**  
디바이스에 있는 애플리케이션 이미지의 시작 주소입니다. 이미지 설명자가 애플리케이션 이진 파일에 추가되기 때문에 이 주소는 이미지 설명자의 시작입니다.

**종료 주소**  
디바이스에 있는 애플리케이션 이미지의 종료 주소입니다(이미지 트레일러 제외).

**실행 주소**  
이미지의 실행 주소입니다.

**하드웨어 ID**  
OTA 이미지가 올바른 플랫폼용으로 빌드되었는지 확인하기 위해 부트로더가 사용하는 고유한 하드웨어 ID입니다.

**예약**  
나중에 사용하기 위해 예약되어 있습니다.

## 이미지 트레일러
<a name="image-trailer"></a>

이미지 트레일러는 애플리케이션 이진 파일에 추가됩니다. 서명 유형 문자열, 서명 크기, 이미지의 서명 등이 들어 있습니다.


| 트레일러 필드 | 크기(바이트) | 
| --- | --- | 
|  서명 유형  |  32바이트  | 
|  서명 크기  |  4 bytes  | 
|  서명  |  256 bytes  | 

**서명 유형**  
이 서명 유형은 사용되는 암호화 알고리즘을 나타내며, 트레일러를 위한 마커 역할을 합니다. 부트로더는 ECDSA(Elliptic-Curve Digital Signature Algorithm)를 지원합니다. 기본값은 sig-sha256-ecdsa입니다.

**서명 크기**  
암호화 서명의 크기(바이트)입니다.

**서명**  
이미지 설명자와 함께 추가된 애플리케이션 이진 파일의 암호화 서명입니다.

## 부트로더 구성
<a name="bootloader-configuration"></a>

기본 부트로더 구성 옵션은 `freertos/vendors/microchip/boards/curiosity_pic32mzef/bootloader/config_files/aws_boot_config.h`에 제공됩니다. 일부 옵션은 디버그용으로만 제공됩니다.

**기본 시작 활성화**  
기본 주소에서 애플리케이션을 실행할 수 있도록 하고, 디버그용으로만 활성화합니다. 이미지는 검증 없이 기본 주소에서 실행됩니다.

**암호화 서명 검증 활성화**  
부팅 시 암호화 서명 검증을 활성화합니다. 실패한 이미지는 디바이스에서 삭제됩니다. 이 옵션은 디버그용으로만 제공되며, 프로덕션 환경에서 활성 상태로 유지해야 합니다.

**잘못된 이미지 삭제**  
뱅크에서 이미지 검증이 실패할 경우 전체 뱅크를 삭제합니다. 이 옵션은 디버그용이며, 프로덕션 환경에서 활성 상태여야 합니다.

**하드웨어 ID 검증 활성화**  
OTA 이미지의 설명자에 있는 하드웨어 ID와 부트로더에 프로그래밍된 하드웨어 ID를 검증합니다. 선택 사항이며, 하드웨어 검증이 필요하지 않은 경우 비활성화할 수 있습니다.

**주소 검증 활성화**  
OTA 이미지의 설명자에 있는 시작, 종료, 실행 주소를 검증합니다. 이 옵션을 항상 활성화해 놓는 것이 좋습니다.

## 부트로더 빌드
<a name="building-bootloader"></a>

데모 부트로더는 FreeRTOS 소스 코드 리포지토리의 `freertos/vendors/microchip/boards/curiosity_pic32mzef/aws_demos/mplab/`에 있는 `aws_demos` 프로젝트에 로드 가능한 프로젝트로 포함되어 있습니다. 빌드된 `aws_demos` 프로젝트는 먼저 부트로더를 빌드한 다음 애플리케이션을 빌드합니다. 최종 출력은 부트로더와 애플리케이션을 포함하여 통합 16진 이미지입니다. 암호화 서명이 있는 통합 16진 이미지를 생성할 수 있도록 `factory_image_generator.py` 유틸리티가 제공됩니다. 부트로더 유틸리티 스크립트는 `freertos/demos/ota/bootloader/utility/`에 있습니다.

### 부트로더 빌드 전 절차
<a name="bootloader-pre-build"></a>

이 빌드 전 절차는 코드 서명 인증서에서 퍼블릭 키를 추출하는 `codesigner_cert_utility.py` 유틸리티 스크립트를 실행하고, 퍼블릭 키를 포함하는 C 헤더 파일을 ASN.1(Abstract Syntax Notation One) 인코딩 형식으로 생성합니다. 이 헤더는 부트로더 프로젝트에 컴파일됩니다. 생성된 헤더에는 퍼블릭 키 배열과 키 길이, 두 개의 상수가 들어 있습니다. `aws_demos`를 사용하지 않고 부트로더 프로젝트를 빌드할 수도 있으며 일반 애플리케이션처럼 디버깅할 수 있습니다.

# AWS IoT Device Defender 데모
<a name="dd-demo"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

## 소개
<a name="dd-demo-introduction"></a>

이 데모에서는 AWS IoT Device Defender 라이브러리를 사용하여 [AWS IoT Device Defender](https://docs.aws.amazon.com/iot/latest/developerguide/device-defender.html)에 연결하는 방법을 보여줍니다. 이 데모는 coreMQTT 라이브러리를 사용하여 TLS(상호 인증)를 통해 AWS IoT MQTT 브로커 및 CoreJSON 라이브러리에 대한 MQTT 연결을 설정하고 AWS IoT Device Defender 서비스로부터 수신한 응답을 검증하고 파싱합니다. 데모에서는 디바이스에서 수집한 지표를 사용하여 JSON 형식의 보고서를 구성하는 방법과 구성된 보고서를 AWS IoT Device Defender 서비스에 제출하는 방법을 보여줍니다. 또한 전송된 보고서가 수락 또는 거부되었는지 확인하기 위해 coreMQTT 라이브러리에 콜백 함수를 등록하여 AWS IoT Device Defender 서비스로부터의 응답을 처리하는 방법도 보여줍니다.

**참고**  
FreeRTOS 데모를 설정하고 실행하려면 [FreeRTOS 시작하기](freertos-getting-started.md)의 단계를 따릅니다.

## 기능
<a name="dd-demo-functionality"></a>

이 데모에서는 지표를 수집하고, JSON 형식으로 Device Defender 보고서를 구성하고, AWS IoT MQTT 브로커와의 안전한 MQTT 연결을 통해 이 보고서를 AWS IoT Device Defender 서비스에 제출하는 방법을 보여주는 단일 애플리케이션 태스크를 생성합니다. 데모에는 표준 네트워킹 지표뿐만 아니라 사용자 지정 지표도 포함되어 있습니다. 데모에 포함된 사용자 지정 지표는 다음과 같습니다.
+ '`task_numbers`' 지표: FreeRTOS 태스크 ID의 목록입니다. 이 지표의 유형은 '숫자 목록'입니다.
+ '`stack_high_water_mark`' 지표: 데모 애플리케이션 태스크의 스택 하이 워터마크입니다. 이 지표의 유형은 '숫자'입니다.

네트워킹 지표를 수집하는 방법은 사용 중인 TCP/IP 스택에 따라 다릅니다. FreeRTOS\$1TCP 및 지원되는 lwIP 구성의 경우, 디바이스에서 실제 지표를 수집하여 AWS IoT Device Defender 보고서로 제출하는 지표 수집 구현을 제공합니다. [FreeRTOS\$1TCP](https://github.com/aws/amazon-freertos/blob/main/demos/device_defender_for_aws/metrics_collector/freertos_plus_tcp/metrics_collector.c) 및 [lwIP](https://github.com/aws/amazon-freertos/blob/main/demos/device_defender_for_aws/metrics_collector/lwip/metrics_collector.c)에 대한 구현은 GitHub에서 찾을 수 있습니다.

다른 TCP/IP 스택을 사용하는 보드의 경우 모든 네트워킹 지표를 0으로 반환하는 지표 수집 함수의 스텁 정의가 제공됩니다. 실제 지표를 전송하려면 네트워크 스택에 `freertos/demos/device_defender_for_aws/metrics_collector/stub/metrics_collector.c`의 함수를 구현합니다. 이 파일은 [GitHub ](https://github.com/aws/amazon-freertos/blob/main/demos/device_defender_for_aws/metrics_collector/stub/metrics_collector.c) 웹 사이트에서도 사용할 수 있습니다.

ESP32의 경우 기본 lwIP 구성에서는 코어 잠금을 사용하지 않으므로 데모에서 스텁 지표를 사용합니다. 참조 lwIP 지표 수집 구현을 사용하려면 `lwiopts.h`에서 다음 매크로를 정의합니다.

```
#define LINK_SPEED_OF_YOUR_NETIF_IN_BPS 0
#define LWIP_TCPIP_CORE_LOCKING         1
#define LWIP_STATS                      1
#define MIB2_STATS                      1
```

다음은 데모를 실행하면 생성되는 출력의 예입니다.

![\[DemoThing 애플리케이션의 MQTT 연결, 게시 및 메모리 사용량 이벤트를 보여주는 콘솔 로그 출력입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/Defender_p4_supported.png)


보드가 FreerTOS\$1TCP 또는 지원되는 lwIP 구성을 사용하지 않는 경우 출력은 다음과 같습니다.

![\[데모 애플리케이션에 대한 MQTT 연결 설정, 주제 구독 시도, 페이로드 게시 및 패킷 처리를 보여주는 로그 메시지입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/Defender_p4_unsupported.png)


데모의 소스 코드는 `freertos/demos/device_defender_for_aws/` 디렉터리 또는 [GitHub](https://github.com/aws/amazon-freertos/tree/main/demos/device_defender_for_aws) 웹 사이트에서 다운로드할 수 있습니다.

### AWS IoT Device Defender 주제 구독
<a name="dd-demo-subscribing"></a>

[subscribeToDefenderTopics](https://github.com/aws/amazon-freertos/blob/main/demos/device_defender_for_aws/defender_demo.c#L514-L530) 함수는 게시된 Device Defender 보고서에 대한 응답을 수신할 수 있는 MQTT 주제를 구독합니다. 매크로 `DEFENDER_API_JSON_ACCEPTED`를 사용하여 수락된 Device Defender 보고서에 대한 응답을 수신할 주제 문자열을 구성합니다. 매크로 `DEFENDER_API_JSON_REJECTED`를 사용하여 거부된 Device Defender 보고서에 대한 응답을 수신할 주제 문자열을 구성합니다.

### 디바이스 지표 수집
<a name="dd-demo-collecting-metrics"></a>

[collectDeviceMetrics](https://github.com/aws/amazon-freertos/blob/main/demos/device_defender_for_aws/defender_demo.c#L376-L511) 함수는 `metrics_collector.h`에 정의된 함수를 사용하여 네트워킹 지표를 수집합니다. 수집되는 지표는 송수신된 바이트 및 패킷 수, 열린 TCP 포트, 열린 UDP 포트, 설정된 TCP 연결입니다.

### AWS IoT Device Defender 보고서 생성
<a name="dd-demo-generating-report"></a>

[generateDeviceMetricsReport](https://github.com/aws/amazon-freertos/blob/main/demos/device_defender_for_aws/defender_demo.c#L552-L581) 함수는 `report_builder.h`에 정의된 함수를 사용하여 Device Defender 보고서를 생성합니다. 이 함수는 네트워킹 지표 및 버퍼를 사용하여 AWS IoT Device Defender에서 예상하는 형식으로 JSON 문서를 생성한 다음 제공된 버퍼에 씁니다. AWS IoT Device Defender에서 예상하는 JSON 문서의 형식은 *AWS IoT 개발자 안내서*의 [디바이스 측 지표](https://docs.aws.amazon.com/iot/latest/developerguide/detect-device-side-metrics.html)에 지정되어 있습니다.

### AWS IoT Device Defender 보고서 게시
<a name="dd-demo-publishing-report"></a>

AWS IoT Device Defender 보고서는 JSON AWS IoT Device Defender 보고서 게시용 MQTT 주제에 게시됩니다. 보고서는 GitHub 웹 사이트의 이 [코드 조각](https://github.com/aws/amazon-freertos/blob/main/demos/device_defender_for_aws/defender_demo.c#L691-L695)에 나와 있는 매크로 `DEFENDER_API_JSON_PUBLISH`를 사용하여 구성됩니다.

### 응답 처리를 위한 콜백
<a name="dd-demo-callback-handling"></a>

[publishCallback](https://github.com/aws/amazon-freertos/blob/main/demos/device_defender_for_aws/defender_demo.c#L302-L373) 함수는 들어오는 MQTT 게시 메시지를 처리합니다. AWS IoT Device Defender 라이브러리의 `Defender_MatchTopic` API를 사용하여 들어오는 MQTT 메시지가 AWS IoT Device Defender 서비스가 전송한 것인지 확인합니다. AWS IoT Device Defender 서비스가 전송한 메시지인 경우 수신한 JSON 응답을 파싱하고 응답에서 보고서 ID를 추출합니다. 그런 다음 보고서 ID가 보고서에서 전송된 ID와 동일한지 확인합니다.

# AWS IoT Greengrass V1 Discovery 데모 애플리케이션
<a name="gg-demov1"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

FreeRTOS용 AWS IoT Greengrass Discovery 데모를 실행하려면 먼저 AWS, AWS IoT Greengrass, AWS IoT를 설정해야 합니다. AWS를 설정하려면 [AWS계정 및 권한 설정](freertos-prereqs.md#freertos-account-and-permissions)의 지침을 수행합니다. AWS IoT Greengrass를 설정하려면 Greengrass 그룹을 생성한 후 Greengrass 코어를 추가해야 합니다. AWS IoT Greengrass 설정에 대한 자세한 내용은 [AWS IoT Greengrass 시작하기](https://docs.aws.amazon.com/greengrass/latest/developerguide/gg-gs.html)를 참조하십시오.

AWS 및 AWS IoT Greengrass를 설정한 후 AWS IoT Greengrass에 대해 몇 가지 추가 권한을 구성해야 합니다.

**AWS IoT Greengrass 권한을 설정하려면**

1. [IAM 콘솔](https://console.aws.amazon.com/iam/home)로 이동합니다.

1. 탐색 창에서 **역할**을 선택한 후 **Greengrass\$1ServiceRole**을 찾아 선택합니다.

1. **정책 연결**을 선택하고 **AmazonS3FullAccess**와 **AWSIoTFullAccess**를 선택한 후 **정책 연결**을 선택합니다.

1. [AWS IoT 콘솔](https://console.aws.amazon.com/iotv2/)로 이동합니다.

1. 탐색 창에서 **Greengrass**를 선택하고 **그룹**을 선택한 후 앞에서 만든 Greengrass 그룹을 선택합니다.

1. **설정**을 선택한 후 **역할 추가**를 선택합니다.

1. **Greengrass\$1ServiceRole**을 선택한 후 **저장**을 선택합니다.

보드를 AWS IoT에 연결하고 FreeRTOS 데모를 구성합니다.

1. [에 MCU 보드 등록AWS IoT](freertos-prereqs.md#get-started-freertos-thing)

   보드를 등록한 후에는 새로운 Greengrass 정책을 생성하여 디바이스 인증서에 연결해야 합니다.

**새로운 AWS IoT Greengrass 정책을 만들려면**

   1. [AWS IoT 콘솔](https://console.aws.amazon.com/iotv2/)로 이동합니다.

   1. 탐색 창에서 **Secure(보안)**를 선택하고 **Policies(정책)**를 선택한 다음 **Create(생성)**를 선택합니다.

   1. 정책을 식별할 이름을 입력합니다.

   1. **Add statements(설명문 추가)** 섹션에서 **Advanced mode(고급 모드)**를 선택합니다. 다음 JSON을 복사하여 정책 편집기 창에 붙여넣습니다.

      ```
      {
            "Effect": "Allow",
            "Action": [
              "greengrass:*"
            ],
            "Resource": "*"
      }
      ```

      이 정책은 모든 리소스에 대한 AWS IoT Greengrass 권한을 부여합니다.

   1. **생성(Create)**을 선택합니다.

**AWS IoT Greengrass 정책을 디바이스의 인증서에 연결하려면**

   1. [AWS IoT 콘솔](https://console.aws.amazon.com/iotv2/)로 이동합니다.

   1. 탐색 창에서 **관리**를 선택하고 **사물**을 선택한 후 앞에서 만든 사물을 선택합니다.

   1. **보안**을 선택한 후 디바이스에 연결된 인증서를 선택합니다.

   1. **정책**을 선택하고 **작업**을 선택한 후 **정책 연결**을 선택합니다.

   1. 앞에서 만든 Greengrass 정책을 선택한 후 **연결**을 선택합니다.

1. [FreeRTOS 다운로드](freertos-prereqs.md#freertos-download)
**참고**  
FreeRTOS 콘솔에서 FreeRTOS를 다운로드하는 경우 **AWS IoT - *플랫폼에 연결*** 대신 **AWS IoT Greengrass - *플랫폼에 연결***을 선택합니다.

1. [FreeRTOS 데모 구성](freertos-prereqs.md#freertos-configure).

   `freertos/vendors/vendor/boards/board/aws_demos/config_files/aws_demo_config.h`를 열고 `#define CONFIG_CORE_MQTT_MUTUAL_AUTH_DEMO_ENABLED`를 주석으로 처리한 다음 `CONFIG_GREENGRASS_DISCOVERY_DEMO_ENABLED`를 정의합니다.

AWS IoT 및 AWS IoT Greengrass를 설정하고 FreeRTOS를 다운로드하고 구성하면 디바이스에서 Greengrass 데모를 빌드, 플래시 및 실행할 수 있습니다. 보드의 하드웨어 및 소프트웨어 개발 환경을 설정하려면 [보드별 시작 안내서](getting-started-guides.md)의 지침을 수행해야 합니다.

Greengrass 데모는 코어에 Greengrass 코어 및 AWS IoT MQTT 클라이언트에 일련의 메시지를 게시합니다. AWS IoT MQTT 클라이언트에서 메시지를 보려면 [AWS IoT 콘솔](https://console.aws.amazon.com/iotv2/)을 열어 **테스트**를 선택하고, **MQTT 테스트 클라이언트**를 선택한 다음 `freertos/demos/ggd`에 구독을 추가합니다.

MQTT 클라이언트에서 다음 문자열이 표시되어야 합니다.

```
Message from Thing to Greengrass Core: Hello world msg #1!
Message from Thing to Greengrass Core: Hello world msg #0!
Message from Thing to Greengrass Core: Address of Greengrass Core found! 123456789012.us-west-2.compute.amazonaws.com
```

## Amazon EC2 인스턴스 사용
<a name="gg-demo-ec2"></a>

**Amazon EC2 인스턴스로 작업하는 경우**

1. Amazon EC2 인스턴스와 연결된 퍼블릭 DNS(IPv4) 찾기 - Amazon EC2 콘솔로 이동한 다음 왼쪽 탐색 패널에서 **인스턴스**를 선택합니다. Amazon EC2 인스턴스를 선택한 다음 **설명** 패널을 선택합니다. **Public DNS (IPv4)**에 대한 항목을 찾아 기록해 둡니다.

1. **보안 그룹**에 대한 항목을 찾아 Amazon EC2 인스턴스에 연결된 보안 그룹을 선택합니다.

1. **Inbound rules(인바운드 규칙)** 탭을 선택한 다음 **Edit inbound rules(인바운드 규칙 편집)**을 선택하고 다음 규칙을 추가합니다.  
**인바운드 규칙**    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/gg-demov1.html)

1. AWS IoT 콘솔에서 **Greengrass**를 선택하고 **Groups**을 선택한 다음 앞에서 만든 Greengrass 그룹을 선택합니다. **설정**을 선택합니다. **Local connection detection(로컬 연결 감지)**을 **Manually manage connection information(수동으로 연결 정보 관리)**으로 변경합니다.

1. 탐색 창에서 **Cores(코어)**를 선택한 다음 그룹 코어를 선택합니다.

1. **Connectivity(연결)**를 선택하고 코어 엔드포인트가 하나만 있는지(나머지는 모두 삭제) 확인하고 IP 주소(변경될 수 있으므로)가 아닌지 확인합니다. 가장 좋은 방법은 첫 번째 단계에서 기록해 두었던 Public DNS(IPv4)를 사용하는 것입니다.

1. 생성한 FreeRTOS IoT 사물을 GG 그룹에 추가합니다.

   1. 뒤로 화살표를 선택하여 AWS IoT Greengrass 그룹 페이지로 돌아갑니다. 탐색 창에서 **Devices(디바이스)**를 선택한 다음 **Add Device(디바이스 추가)**를 선택합니다.

   1. **Select an IoT Thing(IoT 사물 선택)**을 선택합니다. 디바이스를 선택한 다음 **Finish(완료)**를 선택합니다.

1. 필요한 구독 추가 - **Greengrass 그룹** 페이지에서 **구독**을 선택한 다음, **구독 추가**를 선택하고 여기에 표시된 대로 정보를 입력합니다.  
**구독**    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/gg-demov1.html)

   여기서 ‘소스’는 보드를 등록할 때 AWS IoT 콘솔에서 생성한 AWS IoT 사물에 부여된 이름입니다. 여기에 나와 있는 예제에서는 ‘TIGG1’입니다.

1. AWS IoT Greengrass 그룹 배포를 시작하고 배포가 성공적인지 확인합니다. 이제 AWS IoT Greengrass 검색 데모를 성공적으로 실행할 수 있어야 합니다.

# AWS IoT Greengrass V2
<a name="gg-demov2"></a>

## AWS IoT Greengrass V2 디바이스와의 호환성
<a name="ggv2-compatibility"></a>

 AWS IoT Greengrass V2의 클라이언트 디바이스 지원은 AWS IoT Greengrass V1과 이전 버전 호환됩니다. 애플리케이션 코드를 변경하지 않고도 FreeRTOS 클라이언트 디바이스를 V2 코어 디바이스에 연결할 수 있습니다. 클라이언트 디바이스를 V2 코어 디바이스에 연결할 수 있게 하려면 다음을 수행합니다.
+  Greengrass 소프트웨어를 Greengrass 코어 디바이스에 배포합니다. [클라이언트 디바이스를 코어 디바이스에 연결](https://docs.aws.amazon.com//greengrass/v2/developerguide/connect-client-devices.html)을 참조하여 디바이스를 AWS IoT Greengrass V2에 연결합니다.
+  [클라이언트 디바이스, AWS IoT Core 클라우드 서비스, Greengrass 구성 요소 간에 메시지(Lambda 함수 포함)를 전달하려면 MQTT 브리지 구성 요소](https://docs.aws.amazon.com//greengrass/v2/developerguide/mqtt-bridge-component.html)를 배포하고 구성합니다.
+ [IP 탐지기 구성 요소](https://docs.aws.amazon.com//greengrass/v2/developerguide/ip-detector-component.html)를 배포하여 연결 정보를 자동으로 탐지하거나 엔드포인트를 수동으로 관리합니다.
+ 자세한 내용은 [로컬 AWS IoT 디바이스와의 상호 작용](https://docs.aws.amazon.com//greengrass/v2/developerguide/interact-with-local-iot-devices.html)을 참조하세요.

자세한 내용은 AWS 설명서에서 [AWS IoT Greengrass V2에서 AWS IoT Greengrass V1 애플리케이션 실행](https://docs.aws.amazon.com//greengrass/v2/developerguide/migrate-from-v1.html#connect-v1-greengrass-devices)을 참조하세요.

# coreHTTP 데모
<a name="core-http-demo"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

이러한 데모는 coreHTTP 라이브러리 사용 방법을 알아보는 데 유용하게 활용할 수 있습니다.

**Topics**
+ [coreHTTP 상호 인증 데모](core-http-ma-demo.md)
+ [coreHTTP 기본 Amazon S3 업로드 데모](core-http-s3-upload-demo.md)
+ [coreHTTP 기본 S3 다운로드 데모](core-http-s3-download-demo.md)
+ [coreHTTP 기본 다중 스레드 데모](core-http-bmt-demo.md)

# coreHTTP 상호 인증 데모
<a name="core-http-ma-demo"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

## 소개
<a name="core-http-ma-demo-intro"></a>

coreHTTP(상호 인증) 데모 프로젝트에서는 클라이언트와 서버 간 상호 인증을 통한 TLS를 사용하여 HTTP 서버에 연결하는 방법을 보여줍니다. 이 데모에서는 mbedTLS 기반 전송 인터페이스 구현을 사용하여 서버 및 클라이언트 인증 TLS 연결을 설정하고 HTTP의 요청 응답 워크플로를 보여줍니다.

**참고**  
FreeRTOS 데모를 설정하고 실행하려면 [FreeRTOS 시작하기](freertos-getting-started.md)의 단계를 따릅니다.

## 기능
<a name="core-http-ma-demo-functionality"></a>

이 데모는 다음 작업을 완료하는 방법을 보여주는 예제가 포함된 단일 애플리케이션 태스크를 생성합니다.
+  AWS IoT 엔드포인트의 HTTP 서버에 연결합니다.
+ POST 요청 전송
+ 응답 수신
+ 서버 연결 해제

이러한 단계를 완료하면 데모에서 다음 스크린샷과 비슷한 출력이 생성됩니다.

![\[AWS IoT 데모 초기화, TLS 세션 설정, HTTP POST 요청 및 성공적인 데모 완료를 나타내는 메모리 지표를 보여주는 로그 출력입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/coreHTTP.output.png)


 AWS IoT 콘솔은 다음 스크린샷과 유사한 출력을 생성합니다.

![\[AWS IoT 2020년 11월 20일 19:09:09 UTC에 주제에 게시된 "Hello from AWS IoT console" 메시지를 보여주는 콘솔.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/coreHTTP.console.png)


## 소스 코드 구성
<a name="core-http-s3-ma-demo-source-code-organization"></a>

데모 소스 파일은 이름이 `http_demo_mutual_auth.c`이며 `freertos/demos/coreHTTP/` 디렉터리 및 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_mutual_auth.c) 웹 사이트에서 찾을 수 있습니다.

## AWS IoT HTTP 서버에 연결
<a name="core-http-ma-demo-connecting"></a>

[ connectToServerWithBackoffRetries](https://github.com/aws/amazon-freertos/blob/main/demos/common/http_demo_helpers/http_demo_utils.c#L131-L170) 함수는 AWS IoT HTTP 서버에 상호 인증된 TLS 연결을 시도합니다. 연결이 실패하면 제한 시간이 경과한 후 다시 시도합니다. 최대 시도 횟수에 도달하거나 최대 제한 시간 값에 도달할 때까지 제한 시간 값은 기하급수적으로 증가합니다. `RetryUtils_BackoffAndSleep` 함수는 기하급수적으로 증가하는 제한 시간 값을 제공하고 최대 시도 횟수에 도달하면 `RetryUtilsRetriesExhausted`를 반환합니다. `connectToServerWithBackoffRetries` 함수는 구성된 시도 횟수 이후에도 브로커에 대한 TLS 연결을 설정할 수 없는 경우 실패 상태를 반환합니다.

## HTTP 요청 전송 및 응답 수신
<a name="core-http-ma-demo-send-receive"></a>

[ prvSendHttpRequest](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_mutual_auth.c#L402-L507) 함수는 AWS IoT HTTP 서버로 POST 요청을 보내는 방법을 보여줍니다. 에서 REST API를 요청하는 방법에 대한 자세한 내용은 [디바이스 통신 프로토콜 - HTTPS](https://docs.aws.amazon.com/iot/latest/developerguide/http.html)를 AWS IoT참조하세요. 응답은 동일한 coreHTTP API 직접 호출 `HTTPClient_Send`로 수신됩니다.

# coreHTTP 기본 Amazon S3 업로드 데모
<a name="core-http-s3-upload-demo"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

## 소개
<a name="core-http-s3-upload-demo-intro"></a>

이 예제에서는 Amazon Simple Storage Service(S3) HTTP 서버에 PUT 요청을 전송하고 소용량 파일을 업로드하는 방법을 보여줍니다. 업로드 후 파일 크기를 확인하기 위한 GET 요청도 수행합니다. 이 예제에서는 mbedTLS를 사용하는 [네트워크 전송 인터페이스](https://freertos.org/network-interface.html)를 사용하여 coreHTTP를 실행하는 IoT 디바이스 클라이언트와 Amazon S3 HTTP 서버 간에 상호 인증된 연결을 설정합니다.

**참고**  
FreeRTOS 데모를 설정하고 실행하려면 [FreeRTOS 시작하기](freertos-getting-started.md)의 단계를 따릅니다.

### 단일 스레드와 다중 스레드
<a name="core-http-s3-upload-demo-threads"></a>

coreHTTP 사용 모델에는 *단일 스레드*와 *다중 스레드*(멀티태스킹)의 두 가지가 있습니다. 이 섹션의 데모는 하나의 스레드에서 HTTP 라이브러리를 실행하지만 실제로는 단일 스레드 환경에서 coreHTTP를 사용하는 방법을 보여줍니다. 이 데모에서는 한 가지 태스크만 HTTP API를 사용합니다. 단일 스레드 애플리케이션은 HTTP 라이브러리를 반복적으로 직접 호출해야 하지만, 다중 스레드 애플리케이션은 대신 에이전트(또는 대몬(daemon)) 태스크 내에서 백그라운드로 HTTP 요청을 전송할 수 있습니다.

## 소스 코드 구성
<a name="core-http-s3-upload-demo-source-code-organization"></a>

데모 소스 파일은 이름이 `http_demo_s3_upload.c`이며 `freertos/demos/coreHTTP/` 디렉터리 및 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_upload.c) 웹 사이트에서 찾을 수 있습니다.

## Amazon S3 HTTP 서버 연결 구성
<a name="core-http-s3-upload-demo-configure-server"></a>

이 데모는 미리 서명된 URL을 사용하여 Amazon S3 HTTP 서버에 연결하고 다운로드할 객체에 대한 액세스 권한을 부여합니다. Amazon S3 HTTP 서버의 TLS 연결은 서버 인증만 사용합니다. 애플리케이션 수준에서는 객체 액세스가 미리 서명된 URL 쿼리의 파라미터를 사용하여 인증됩니다. 아래 단계에 따라 AWS에 대한 연결을 구성합니다.

1.  AWS 계정 설정:

   1. 아직 생성하지 않았다면 [AWS 계정을 생성합니다](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/).

   1. 계정 및 권한은 AWS Identity and Access Management (IAM)을 사용하여 설정됩니다. IAM을 사용하여 계정의 각 사용자에 대한 권한을 관리합니다. 기본적으로 사용자는 루트 소유자가 부여할 때까지는 아무 권한도 없습니다.

      1.  AWS 계정에 사용자를 추가하려면 [ IAM 사용 설명서를](https://docs.aws.amazon.com/IAM/latest/UserGuide/) 참조하세요.

      1. 이 정책을 추가하여 AWS 계정에 FreeRTOS 및에 액세스할 수 AWS IoT 있는 권한을 부여합니다.
         + AmazonS3FullAccess

1. *Amazon Simple Storage Service 사용 설명서*의 [S3 버킷을 생성하려면 어떻게 해야 합니까?](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-bucket.html)의 단계에 따라 Amazon S3에서 버킷을 생성합니다.

1. [S3 버킷에 파일 및 폴더를 업로드하려면 어떻게 해야 합니까?](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/upload-objects.html)의 단계에 따라 파일을 Amazon S3에 업로드합니다.

1. `FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/presigned_url_generator/presigned_urls_gen.py` 파일에 있는 스크립트를 사용하여 미리 서명된 URL을 생성합니다.

   사용 지침은 `FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/presigned_url_generator/README.md` 파일을 참조하세요.

## 기능
<a name="core-http-s3-upload-demo-functionality"></a>

이 데모는 먼저 TLS 서버 인증을 사용하여 Amazon S3 HTTP 서버에 연결합니다. 그런 다음 `democonfigDEMO_HTTP_UPLOAD_DATA`에 지정된 데이터를 업로드하기 위한 HTTP 요청을 생성합니다. 파일을 업로드한 후 파일 크기를 요청하여 파일이 성공적으로 업로드되었는지 확인합니다. 데모의 소스 코드는 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_upload.c) 웹 사이트에서 찾을 수 있습니다.

### Amazon S3 HTTP 서버에 연결
<a name="core-http-s3-upload-demo-connecting"></a>

[connectToServerWithBackoffRetries](https://github.com/aws/amazon-freertos/blob/main/demos/common/http_demo_helpers/http_demo_utils.c#L131-L170) 함수는 HTTP 서버에 TCP 연결을 시도합니다. 연결이 실패하면 제한 시간이 경과한 후 다시 시도합니다. 최대 시도 횟수에 도달하거나 최대 제한 시간 값에 도달할 때까지 제한 시간 값은 기하급수적으로 증가합니다. `connectToServerWithBackoffRetries` 함수는 구성된 시도 횟수 이후에도 브로커에 대한 TCP 연결을 설정할 수 없는 경우 실패 상태를 반환합니다.

`prvConnectToServer` 함수는 서버 인증만 사용하여 Amazon S3 HTTP 서버에 연결하는 방법을 보여줍니다. `FreeRTOS-Plus/Source/Application-Protocols/network_transport/freertos_plus_tcp/using_mbedtls/using_mbedtls.c` 파일에 구현된 mbedTLS 기반 전송 인터페이스를 사용합니다. `prvConnectToServer`의 정의는 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_upload.c#L306-L366) 웹 사이트에서 찾을 수 있습니다.

### 데이터 업로드
<a name="core-http-s3-upload-demo-upload-data"></a>

`prvUploadS3ObjectFile` 함수는 PUT 요청을 생성하고 업로드할 파일을 지정하는 방법을 보여줍니다. 파일이 업로드되는 Amazon S3 버킷과 업로드할 파일의 이름은 미리 서명된 URL에 지정됩니다. 메모리를 절약하기 위해 요청 헤더와 응답 수신 모두에 동일한 버퍼가 사용됩니다. 응답은 `HTTPClient_Send` API 함수를 사용하여 동기식으로 수신됩니다. Amazon S3 HTTP 서버에서 `200 OK` 응답 상태 코드를 전송해야 합니다. 다른 모든 상태 코드는 오류입니다.

`prvUploadS3ObjectFile()`의 소스 코드는 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_upload.c#L539-L632) 웹 사이트에서 찾을 수 있습니다.

### 업로드 확인
<a name="core-http-s3-upload-demo-verifying-data"></a>

`prvVerifyS3ObjectFileSize` 함수는 `prvGetS3ObjectFileSize`를 호출하여 S3 버킷에 있는 객체의 크기를 검색합니다. Amazon S3 HTTP 서버는 현재 미리 서명된 URL을 사용하는 HEAD 요청을 지원하지 않으므로 0번째 바이트가 요청됩니다. 파일 크기는 응답의 `Content-Range` 헤더 필드에 포함되어 있습니다. 서버에서 `206 Partial Content` 응답을 전송해야 합니다. 다른 모든 응답 상태 코드는 오류입니다.

`prvGetS3ObjectFileSize()`의 소스 코드는 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_upload.c#L370-L535) 웹 사이트에서 찾을 수 있습니다.

# coreHTTP 기본 S3 다운로드 데모
<a name="core-http-s3-download-demo"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

## 소개
<a name="core-http-s3-download-demo-intro"></a>

이 데모는 [범위 요청](https://tools.ietf.org/html/rfc7233)을 사용하여 Amazon S3 HTTP 서버에서 파일을 다운로드하는 방법을 보여줍니다. HTTP 요청을 생성하는 데 `HTTPClient_AddRangeHeader`를 사용하면 coreHTTP API에서 범위 요청이 기본적으로 지원됩니다. 마이크로컨트롤러 환경에서는 범위 요청을 적극 권장합니다. 큰 파일을 단일 요청 대신 별도의 범위로 다운로드하면 네트워크 소켓을 차단하지 않고 파일의 각 섹션을 처리할 수 있습니다. 범위 요청을 사용하면 TCP 연결에서 재전송이 필요한 패킷 손실의 위험이 줄어들어 디바이스의 전력 소비가 향상됩니다.

이 예제에서는 mbedTLS를 사용하는 [네트워크 전송 인터페이스](https://freertos.org/network-interface.html)를 사용하여 coreHTTP를 실행하는 IoT 디바이스 클라이언트와 Amazon S3 HTTP 서버 간에 상호 인증된 연결을 설정합니다.

**참고**  
FreeRTOS 데모를 설정하고 실행하려면 [FreeRTOS 시작하기](freertos-getting-started.md)의 단계를 따릅니다.

### 단일 스레드와 다중 스레드
<a name="core-http-s3-download-demo-threads"></a>

coreHTTP 사용 모델에는 *단일 스레드*와 *다중 스레드*(멀티태스킹)의 두 가지가 있습니다. 이 섹션의 데모는 하나의 스레드에서 HTTP 라이브러리를 실행하지만 실제로는 단일 스레드 환경에서 coreHTTP를 사용하는 방법을 보여줍니다(데모에서는 하나의 태스크만 HTTP API를 사용함). 단일 스레드 애플리케이션은 HTTP 라이브러리를 반복적으로 직접 호출해야 하지만, 다중 스레드 애플리케이션은 대신 에이전트(또는 대몬(daemon)) 태스크 내에서 백그라운드로 HTTP 요청을 전송할 수 있습니다.

## 소스 코드 구성
<a name="core-http-s3-download-demo-source-code"></a>

데모 프로젝트는 이름이 `http_demo_s3_download.c`이며 `freertos/demos/coreHTTP/` 디렉터리 및 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_download.c) 웹 사이트에서 찾을 수 있습니다.

## Amazon S3 HTTP 서버 연결 구성
<a name="core-http-s3-download-demo-configure-server"></a>

이 데모는 미리 서명된 URL을 사용하여 Amazon S3 HTTP 서버에 연결하고 다운로드할 객체에 대한 액세스 권한을 부여합니다. Amazon S3 HTTP 서버의 TLS 연결은 서버 인증만 사용합니다. 애플리케이션 수준에서는 객체 액세스가 미리 서명된 URL 쿼리의 파라미터를 사용하여 인증됩니다. 아래 단계에 따라 AWS에 대한 연결을 구성합니다.

1.  AWS 계정 설정:

   1. 아직 생성하지 않았다면 [AWS 계정을 생성하고 활성화합니다](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/).

   1. 계정 및 권한은 AWS Identity and Access Management (IAM)을 사용하여 설정됩니다. IAM을 사용하면 계정의 각 사용자에게 부여된 권한을 관리할 수 있습니다. 기본적으로 사용자는 루트 소유자가 부여할 때까지는 아무 권한도 없습니다.

      1.  AWS 계정에 사용자를 추가하려면 [IAM 사용 설명서를](https://docs.aws.amazon.com/IAM/latest/UserGuide/) 참조하세요.

      1. 다음 정책을 추가하여 AWS 계정에 FreeRTOS 및에 액세스할 수 AWS IoT 있는 권한을 부여합니다.
         + AmazonS3FullAccess

1. *Amazon Simple Storage Service 사용 설명서*의 [S3 버킷을 생성하려면 어떻게 해야 합니까?](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-bucket.html)의 단계에 따라 S3에서 버킷을 생성합니다.

1. [S3 버킷에 파일 및 폴더를 업로드하려면 어떻게 해야 합니까?](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/upload-objects.html)의 단계에 따라 파일을 S3에 업로드합니다.

1. `FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/presigned_url_generator/presigned_urls_gen.py` 파일에 있는 스크립트를 사용하여 미리 서명된 URL을 생성합니다. 사용 지침은 `FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/presigned_url_generator/README.md` 섹션을 참조하세요.

## 기능
<a name="core-http-s3-download-demo-functionality"></a>

데모는 먼저 파일의 크기를 검색합니다. 그런 다음 `democonfigRANGE_REQUEST_LENGTH`의 범위 크기를 사용하여 루프에서 각 바이트 범위를 순차적으로 요청합니다.

데모의 소스 코드는 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_download.c) 웹 사이트에서 찾을 수 있습니다.

### Amazon S3 HTTP 서버에 연결
<a name="core-http-s3-download-demo-connecting"></a>

[connectToServerWithBackoffRetries()](https://github.com/aws/amazon-freertos/blob/main/demos/common/http_demo_helpers/http_demo_utils.c#L131-L170) 함수는 HTTP 서버에 TCP 연결을 시도합니다. 연결이 실패하면 제한 시간이 경과한 후 다시 시도합니다. 최대 시도 횟수에 도달하거나 최대 제한 시간 값에 도달할 때까지 제한 시간 값은 기하급수적으로 증가합니다. `connectToServerWithBackoffRetries()` 함수는 구성된 시도 횟수 이후에도 서버에 대한 TCP 연결을 설정할 수 없는 경우 실패 상태를 반환합니다.

`prvConnectToServer()` 함수는 서버 인증만 사용하여 Amazon S3 HTTP 서버에 연결하는 방법을 보여줍니다. [FreeRTOS-Plus/Source/Application-Protocols/network\$1transport/freertos\$1plus\$1tcp/using\$1mbedtls/using\$1mbedtls.c](https://github.com/FreeRTOS/FreeRTOS/blob/202012.00/FreeRTOS-Plus/Source/Application-Protocols/network_transport/freertos_plus_tcp/using_mbedtls/using_mbedtls.c) 파일에 구현된 mbedTLS 기반 전송 인터페이스를 사용합니다.

`prvConnectToServer()`의 소스 코드는 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_download.c#L273-L333)에서 찾을 수 있습니다.

### 범위 요청 생성
<a name="core-http-s3-download-demo-creating-range-request"></a>

`HTTPClient_AddRangeHeader()` API 함수는 바이트 범위를 HTTP 요청 헤더로 직렬화하여 범위 요청을 구성할 수 있도록 지원합니다. 이 데모에서는 범위 요청을 사용하여 파일 크기를 검색하고 파일의 각 섹션을 요청합니다.

`prvGetS3ObjectFileSize()` 함수는 S3 버킷에 있는 파일의 크기를 검색합니다. Amazon S3에 대한 이 첫 번째 요청에 `Connection: keep-alive` 헤더가 추가되어 응답이 전송된 후에도 연결을 열린 상태로 유지합니다. S3 HTTP 서버는 현재 미리 서명된 URL을 사용하는 HEAD 요청을 지원하지 않으므로 0번째 바이트가 요청됩니다. 파일 크기는 응답의 `Content-Range` 헤더 필드에 포함되어 있습니다. 서버에서 `206 Partial Content` 응답을 전송해야 하며, 수신된 다른 모든 응답 상태 코드는 오류입니다.

`prvGetS3ObjectFileSize()`의 소스 코드는 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_download.c#L337-L502)에서 찾을 수 있습니다.

이 데모는 파일 크기를 검색한 후 다운로드할 파일의 각 바이트 범위에 대해 새 범위 요청을 생성합니다. 파일의 각 섹션에 대해 `HTTPClient_AddRangeHeader()`를 사용합니다.

### 범위 요청 전송 및 응답 수신
<a name="core-http-s3-download-demo-send-request"></a>

`prvDownloadS3ObjectFile()` 함수는 전체 파일이 다운로드될 때까지 루프에서 범위 요청을 전송합니다. `HTTPClient_Send()` API 함수는 요청을 전송하고 동기식으로 응답을 수신합니다. 함수가 반환되면 응답이 `xResponse`로 수신됩니다. 그런 다음 상태 코드가 `206 Partial Content`인지 확인되고 지금까지 다운로드한 바이트 수가 `Content-Length` 헤더 값만큼 증가합니다.

`prvDownloadS3ObjectFile()`의 소스 코드는 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_download.c#L506-L651)에서 찾을 수 있습니다.

# coreHTTP 기본 다중 스레드 데모
<a name="core-http-bmt-demo"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

## 소개
<a name="core-http-bmt-demo-intro"></a>

이 데모는 [FreeRTOS의 스레드 안전 대기열](https://freertos.org/a00018.html)을 사용하여 처리 대기 중인 요청 및 응답을 보관합니다. 이 데모에서 주목해야 할 세 가지 태스크가 있습니다.
+ 메인 태스크는 요청 대기열에 요청이 표시되기를 기다립니다. 네트워크를 통해 해당 요청을 전송한 다음 응답을 응답 대기열에 배치합니다.
+ 요청 태스크는 서버에 전송할 HTTP 라이브러리 요청 객체를 생성하여 요청 대기열에 배치합니다. 각 요청 객체는 애플리케이션이 다운로드하도록 구성한 S3 파일의 바이트 범위를 지정합니다.
+ 응답 태스크는 응답 대기열에 응답이 표시되기를 기다립니다. 그런 다음 수신한 모든 응답을 로그합니다.

이 기본 다중 스레드 데모는 서버 인증만 포함된 TLS 연결을 사용하도록 구성되어 있으며, 이는 Amazon S3 HTTP 서버에 필요합니다. 애플리케이션 계층 인증은 [미리 서명된 URL 쿼리](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html)의 [서명 버전 4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) 파라미터를 사용하여 수행됩니다.

## 소스 코드 구성
<a name="core-http-bmt-demo-source"></a>

데모 프로젝트는 이름이 `http_demo_s3_download_multithreaded.c`이며 `freertos/demos/coreHTTP/` 디렉터리 및 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreHTTP/http_demo_s3_download_multithreaded.c) 웹 사이트에서 찾을 수 있습니다.

## 데모 프로젝트 빌드
<a name="core-http-bmt-demo-building"></a>

이 데모 프로젝트는 [Visual Studio의 무료 Community 에디션](https://visualstudio.microsoft.com/vs/community/)을 사용합니다. 데모를 빌드하려면

1. Visual Studio IDE 내에서 `mqtt_multitask_demo.sln` Visual Studio 솔루션 파일을 엽니다.

1. IDE의 **빌드** 메뉴에서 **솔루션 빌드**를 선택합니다.

**참고**  
Microsoft Visual Studio 2017 또는 이전 버전을 사용하는 경우 **프로젝트 -> RTOSDemos 속성 -> 플랫폼 도구 세트**에서 현재 버전과 호환되는 **플랫폼 도구 세트**를 선택해야 합니다.

## 데모 프로젝트 구성
<a name="core-http-bmt-demo-configuring"></a>

이 데모는 [FreeRTOS\$1TCP TCP/IP 스택](https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/index.html)을 사용하므로 [TCP/IP 스타터 프로젝트](https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html)에 제공된 지침을 따라 다음을 수행합니다.

1. [필수 구성 요소](https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html#prerequisites)(예: WinPCap)를 설치합니다.

1. 선택적으로 [고정 또는 동적 IP 주소, 게이트웨이 주소 및 넷마스크를 설정](https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html#static-dynamic)합니다.

1. 선택적으로 [MAC 주소를 설정](https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html#mac-addr)합니다.

1. 호스트 시스템에서 [이더넷 네트워크 인터페이스를 선택](https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html#network-interface)합니다.

1. **중요한 것은** HTTP 데모를 실행하기 전에 [네트워크 연결을 테스트](https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html#connectivity-test)하는 것입니다.

## Amazon S3 HTTP 서버 연결 구성
<a name="core-http-bmt-demo-configuring-connection"></a>

*coreHTTP 기본 다운로드 데모*의 [Amazon S3 HTTP 서버 연결 구성](core-http-s3-download-demo.md#core-http-s3-download-demo-configure-server) 지침을 따릅니다.

## 기능
<a name="core-http-bmt-demo-functionality"></a>

이 데모에서 총 세 가지 태스크가 생성됩니다.
+ 네트워크를 통해 요청을 전송하고 응답을 수신하는 태스크.
+ 전송할 요청을 생성하는 태스크.
+ 수신된 응답을 처리하는 태스크.

이 데모에서, 메인 태스크: 

1. 요청 및 응답 대기열을 생성합니다.

1. 서버와의 연결을 생성합니다.

1. 요청 및 응답 태스크를 생성합니다.

1. 요청 대기열이 네트워크를 통해 요청을 전송할 때까지 기다립니다.

1. 네트워크를 통해 수신한 응답을 응답 대기열에 배치합니다.

요청 태스크:

1. 각 범위 요청을 생성합니다.

응답 태스크:

1. 수신된 각 응답을 처리합니다.

## Typedefs
<a name="core-http-bmt-demo-typedefs"></a>

이 데모는 다중 스레딩을 지원하기 위해 다음 구조를 정의합니다.

**요청 항목**

다음 구조는 요청 대기열에 배치할 요청 항목을 정의합니다. 요청 태스크가 HTTP 요청을 생성하면 요청 항목이 대기열에 복사됩니다.

```
/**
 * @brief Data type for the request queue.
 *
 * Contains the request header struct and its corresponding buffer, to be
 * populated and enqueued by the request task, and read by the main task. The
 * buffer is included to avoid pointer inaccuracy during queue copy operations.
 */
typedef struct RequestItem
{
    HTTPRequestHeaders_t xRequestHeaders;
    uint8_t ucHeaderBuffer[ democonfigUSER_BUFFER_LENGTH ];
} RequestItem_t;
```

**응답 항목**

다음 구조는 응답 대기열에 배치할 응답 항목을 정의합니다. 메인 HTTP 태스크가 네트워크를 통해 응답을 수신하면 응답 항목이 대기열에 복사됩니다.

```
/**
 * @brief Data type for the response queue.
 *
 * Contains the response data type and its corresponding buffer, to be enqueued
 * by the main task, and interpreted by the response task. The buffer is
 * included to avoid pointer inaccuracy during queue copy operations.
 */
typedef struct ResponseItem
{
    HTTPResponse_t xResponse;
    uint8_t ucResponseBuffer[ democonfigUSER_BUFFER_LENGTH ];
} ResponseItem_t;
```

## 메인 HTTP 전송 태스크
<a name="core-http-bmt-demo-main-task"></a>

메인 애플리케이션 태스크:

1. 호스트 주소의 미리 서명된 URL을 파싱하여 Amazon S3 HTTP 서버와의 연결을 설정합니다.

1. S3 버킷 내 객체에 대한 경로의 미리 서명된 URL을 파싱합니다.

1. 서버 인증 TLS를 사용하여 Amazon S3 HTTP 서버에 연결합니다.

1. 요청 및 응답 대기열을 생성합니다.

1. 요청 및 응답 태스크를 생성합니다.

`prvHTTPDemoTask()` 함수가 이 설정을 수행하고 데모 상태를 제공합니다. 이 함수의 소스 코드는 [GitHub](https://github.com/FreeRTOS/FreeRTOS/blob/main/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/DemoTasks/S3DownloadMultithreadedHTTPExample.c#L451-L650)에서 찾을 수 있습니다.

`prvDownloadLoop()` 함수에서 메인 태스크는 요청 대기열의 요청을 차단하고 대기합니다. 요청을 수신하면 `HTTPClient_Send()` API 함수를 사용하여 전송합니다. API 함수가 성공하면 응답이 응답 대기열에 배치합니다.

`prvDownloadLoop()`의 소스 코드는 [GitHub](https://github.com/FreeRTOS/FreeRTOS/blob/main/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/DemoTasks/S3DownloadMultithreadedHTTPExample.c#L1071-L1174)에서 찾을 수 있습니다.

## HTTP 요청 태스크
<a name="core-http-bmt-demo-request-task"></a>

요청 태스크는 `prvRequestTask` 함수에 지정됩니다. 이 함수의 소스 코드는 [GitHub](https://github.com/FreeRTOS/FreeRTOS/blob/main/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/DemoTasks/S3DownloadMultithreadedHTTPExample.c#L778-L876)에서 찾을 수 있습니다.

요청 태스크는 Amazon S3 버킷에서 파일 크기를 검색합니다. 이 작업은 `prvGetS3ObjectFileSize` 함수로 수행됩니다. Amazon S3에 대한 이 첫 번째 요청에 ‘Connection: keep-alive’ 헤더가 추가되어 응답이 전송된 후에도 연결을 열린 상태로 유지합니다. Amazon S3 HTTP 서버는 현재 미리 서명된 URL을 사용하는 HEAD 요청을 지원하지 않으므로 0번째 바이트가 요청됩니다. 파일 크기는 응답의 `Content-Range` 헤더 필드에 포함되어 있습니다. 서버에서 `206 Partial Content` 응답을 전송해야 하며, 수신된 다른 모든 응답 상태 코드는 오류입니다.

`prvGetS3ObjectFileSize`의 소스 코드는 [GitHub](https://github.com/FreeRTOS/FreeRTOS/blob/main/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/DemoTasks/S3DownloadMultithreadedHTTPExample.c#L757-L774)에서 찾을 수 있습니다.

요청 태스크는 파일 크기를 검색한 후 파일의 각 범위를 요청합니다. 각 범위 요청은 기본 태스크가 전송할 수 있도록 요청 대기열에 배치됩니다. 파일 범위는 데모 사용자가 매크로 `democonfigRANGE_REQUEST_LENGTH`에서 구성합니다. HTTP 클라이언트 라이브러리 API에서 `HTTPClient_AddRangeHeader` 함수를 사용하는 범위 요청이 기본적으로 지원됩니다. `prvRequestS3ObjectRange` 함수는 `HTTPClient_AddRangeHeader()` 사용 방법을 보여줍니다.

`prvRequestS3ObjectRange` 함수의 소스 코드는 [GitHub](https://github.com/FreeRTOS/FreeRTOS/blob/main/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/DemoTasks/S3DownloadMultithreadedHTTPExample.c#L694-L753)에서 찾을 수 있습니다.

## HTTP 응답 태스크
<a name="core-http-bmt-demo-response-task"></a>

응답 태스크는 응답 대기열에서 네트워크를 통해 수신되는 응답을 대기합니다. 메인 태스크는 HTTP 응답을 성공적으로 수신하면 응답 대기열을 채웁니다. 이 태스크는 상태 코드, 헤더, 본문을 로그하여 응답을 처리합니다. 예를 들어 실제 애플리케이션은 응답 본문을 플래시 메모리에 쓰는 방식으로 응답을 처리할 수 있습니다. 응답 상태 코드가 `206 partial content`가 아닌 경우 태스크는 데모가 실패한다고 메인 태스크에 알립니다. 응답 태스크는 `prvResponseTask` 함수에 지정됩니다. 이 함수의 소스 코드는 [GitHub](https://github.com/FreeRTOS/FreeRTOS/blob/main/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/HTTP_S3_Download_Multithreaded/DemoTasks/S3DownloadMultithreadedHTTPExample.c#L961-L1047)에서 찾을 수 있습니다.

# AWS IoT Jobs 라이브러리 데모
<a name="freertos-jobs-demo"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

## 소개
<a name="freertos-jobs-demo-introduction"></a>

AWS IoT Jobs 라이브러리 데모는 MQTT 연결을 통해 [AWS IoT Jobs 서비스](https://docs.aws.amazon.com/iot/latest/developerguide/iot-jobs.html)에 연결하고, AWS IoT에서 작업을 검색하고, 디바이스에서 이 작업을 처리하는 방법을 보여줍니다. AWS IoT Jobs 데모 프로젝트는 [FreeRTOS Windows 포트](https://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html)를 사용하므로 Windows의 [Visual Studio Community](https://visualstudio.microsoft.com/vs/community/) 버전으로 빌드하고 평가할 수 있습니다. 마이크로컨트롤러 하드웨어는 필요하지 않습니다. 이 데모는 [coreMQTT 상호 인증 데모](mqtt-demo-ma.md)와 동일한 방식으로 TLS를 사용하여 AWS IoT MQTT 브로커에 대한 보안 연결을 설정합니다.

**참고**  
FreeRTOS 데모를 설정하고 실행하려면 [FreeRTOS 시작하기](freertos-getting-started.md)의 단계를 따릅니다.

## 소스 코드 구성
<a name="freertos-jobs-demo-source-code-org"></a>

데모 코드는 `jobs_demo.c` 파일에 있으며 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/jobs_for_aws/jobs_demo.c) 웹 사이트 또는 `freertos/demos/jobs_for_aws/` 디렉터리에서 찾을 수 있습니다.

## AWS IoT MQTT 브로커 연결 구성
<a name="freertos-jobs-demo-configure-mqtt-broker"></a>

이 데모에서는 AWS IoT MQTT 브로커에 대한 MQTT 연결을 사용합니다. 이 연결은 [coreMQTT 상호 인증 데모](mqtt-demo-ma.md)와 동일한 방식으로 구성됩니다.

## 기능
<a name="freertos-jobs-demo-functionality"></a>

이 데모에서는 AWS IoT에서 작업을 수신하고 디바이스에서 이 작업을 처리하는 데 사용되는 워크플로를 보여줍니다. 이 데모는 대화형이며 AWS IoT 콘솔 또는 AWS Command Line Interface(AWS CLI)를 사용하여 작업을 생성해야 합니다. 작업 생성에 대한 자세한 내용은 *AWS CLI 명령 참조*의 [create-job](https://docs.aws.amazon.com/cli/latest/reference/iot/create-job.html)을 참조하세요. 이 데모는 메시지를 콘솔에 출력할 수 있도록 작업 문서에서 `action` 키가 `print`로 설정되어야 합니다.

이 작업 문서의 형식은 다음과 같습니다.

```
{
    "action": "print",
    "message": "ADD_MESSAGE_HERE"
}
```

AWS CLI를 사용하여 다음 예제 명령으로 작업을 생성할 수 있습니다.

```
aws iot create-job \
    --job-id t12 \
    --targets arn:aws:iot:region:123456789012:thing/device1 \
    --document '{"action":"print","message":"hello world!"}'
```

또한 이 데모는 메시지를 주제에 다시 게시할 수 있도록 `action` 키가 `publish`로 설정된 작업 문서도 사용합니다. 이 작업 문서의 형식은 다음과 같습니다.

```
{
    "action": "publish",
    "message": "ADD_MESSAGE_HERE",
    "topic": "topic/name/here"
}
```

데모는 데모를 종료하도록 `action` 키가 `exit`로 설정된 작업 문서를 수신할 때까지 루프를 반복합니다. 이 작업 문서의 형식은 다음과 같습니다.

```
{
    "action: "exit"
}
```

### Jobs 데모의 진입점
<a name="freertos-jobs-demo-functionality-entry-point"></a>

Jobs 데모 진입점 함수의 소스 코드는 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/jobs_for_aws/jobs_demo.c#L773-L967)에서 찾을 수 있습니다. 이 함수는 다음 작업을 수행합니다.

1. `mqtt_demo_helpers.c`의 헬퍼 함수를 사용하여 MQTT 연결을 설정합니다.

1. `mqtt_demo_helpers.c`의 헬퍼 함수를 사용하여 `NextJobExecutionChanged` API에 대한 MQTT 주제를 구독합니다. 주제 문자열은 AWS IoT Jobs 라이브러리에 정의된 매크로를 사용하여 이전에 어셈블되었습니다.

1. `mqtt_demo_helpers.c`의 헬퍼 함수를 사용하여 `StartNextPendingJobExecution` API에 대한 MQTT 주제에 게시합니다. 주제 문자열은 AWS IoT Jobs 라이브러리에 정의된 매크로를 사용하여 이전에 어셈블되었습니다.

1. `prvEventCallback`를 반복적으로 직접 호출하여 처리를 위해 `MQTT_ProcessLoop`에 전달되는 메시지를 수신합니다.

1. 데모가 종료 작업을 수신하면 `mqtt_demo_helpers.c` 파일의 헬퍼 함수를 사용하여 MQTT 주제 구독을 취소하고 연결을 끊습니다.

### 수신된 MQTT 메시지에 대한 콜백
<a name="freertos-jobs-demo-functionality-callback"></a>

[prvEventCallback](https://github.com/aws/amazon-freertos/blob/main/demos/jobs_for_aws/jobs_demo.c#L674-L769) 함수는 AWS IoT Jobs `Jobs_MatchTopic` 라이브러리에서 을 호출하여 들어오는 MQTT 메시지를 분류합니다. 메시지 유형이 새 작업에 해당하는 경우 `prvNextJobHandler()`가 호출됩니다.

[PrvNextJobHandler](https://github.com/aws/amazon-freertos/blob/main/demos/jobs_for_aws/jobs_demo.c#L601-L670) 함수 및 이 함수가 호출하는 함수는 JSON 형식의 메시지에서 작업 문서를 파싱하고 작업에 지정된 작업을 실행합니다. 특히 주목할 것은 `prvSendUpdateForJob` 함수입니다.

### 실행 중인 작업에 대한 업데이트 전송
<a name="freertos-jobs-demo-functionality-send-update"></a>

[prvSendUpdateForJob()](https://github.com/aws/amazon-freertos/blob/main/demos/jobs_for_aws/jobs_demo.c#L413-L457) 함수는 Jobs 라이브러리에서 `Jobs_Update()`를 호출하여 바로 이어지는 MQTT 게시 작업에 사용되는 주제 문자열을 채웁니다.

# coreMQTT 데모
<a name="mqtt-demo"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

이러한 데모는 coreMQTT 라이브러리 사용 방법을 알아보는 데 유용하게 활용할 수 있습니다.

**Topics**
+ [coreMQTT 상호 인증 데모](mqtt-demo-ma.md)
+ [coreMQTT 에이전트 연결 공유 데모](mqtt-demo-cs.md)

# coreMQTT 상호 인증 데모
<a name="mqtt-demo-ma"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

## 소개
<a name="mqtt-demo-ma-introduction"></a>

coreMQTT 상호 인증 데모 프로젝트는 클라이언트와 서버 간 상호 인증 TLS를 사용하여 MQTT 브로커에 연결하는 방법을 보여줍니다. 이 데모에서는 mbedTLS 기반 전송 인터페이스 구현을 사용하여 서버 및 클라이언트 인증 TLS 연결을 설정하고 [QoS 1](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html#_Toc442180914) 수준에서 MQTT의 구독-게시 워크플로를 보여줍니다. 이 데모는 주제 필터를 구독하고, 필터와 일치하는 주제에 게시하고, QoS 1 수준에서 서버로부터 해당 메시지가 다시 수신될 때까지 대기합니다. 브로커에 게시하고 브로커로부터 동일한 메시지를 다시 수신하는 이 주기는 무한정 반복됩니다. 이 데모의 메시지는 QoS 1 수준에서 전송되므로 MQTT 사양에 따라 최소 한 번의 전송이 보장됩니다.

**참고**  
FreeRTOS 데모를 설정하고 실행하려면 [FreeRTOS 시작하기](freertos-getting-started.md)의 단계를 따릅니다.

## 소스 코드
<a name="mqtt-demo-ma-source-code"></a>

데모 소스 파일은 이름이 `mqtt_demo_mutual_auth.c`이며 `freertos/demos/coreMQTT/` 디렉터리 및 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c) 웹 사이트에서 찾을 수 있습니다.

## 기능
<a name="mqtt-demo-ma-functionality"></a>

이 데모는 브로커에 연결하고, 브로커의 주제를 구독하고, 브로커의 주제에 게시한 다음, 마지막으로 브로커와의 연결을 끊는 방법을 보여주는 일련의 예제를 반복하는 단일 애플리케이션 작업을 생성합니다. 데모 애플리케이션은 동일한 주제를 구독하고 게시합니다. 데모가 MQTT 브로커에 메시지를 게시할 때마다 브로커는 동일한 메시지를 데모 애플리케이션에 다시 보냅니다.

데모를 성공적으로 완료하면 다음 이미지와 비슷한 출력이 생성됩니다.

![\[성공적으로 완료 시 MQTT 데모 터미널 출력\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/coremqtt-mad-output.png)


 AWS IoT 콘솔은 다음 이미지와 유사한 출력을 생성합니다.

![\[성공적으로 완료 시 MQTT 데모 콘솔 출력\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/coremqtt-mad-console.png)


## 지수 백오프 및 지터를 사용한 재시도 로직
<a name="mqtt-demo-ma-retry-logic"></a>

[prvBackoffForRetry](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L671-L717) 함수는 서버와의 실패한 네트워크 작업(예: TLS 연결 또는 MQTT 구독 요청)을 지수 백오프 및 지터를 사용하여 재시도할 수 있는 방법을 보여줍니다. 이 함수는 다음 재시도의 백오프 기간을 계산하고, 재시도 횟수가 모두 소진되지 않은 경우 백오프 지연을 수행합니다. 백오프 기간을 계산하려면 난수를 생성해야 하므로 함수는 PKCS11 모듈을 사용하여 난수를 생성합니다. 공급업체 플랫폼에서 지원하는 경우 PKCS11 모듈을 사용하면 순수 난수 생성기(TRNG)에 액세스할 수 있습니다. 연결 재시도 시 디바이스와의 충돌 가능성이 완화되도록 디바이스별 엔트로피 소스를 난수 생성기에 시드하는 것이 좋습니다.

## MQTT 브로커에 연결
<a name="mqtt-demo-ma-connecting"></a>

[prvConnectToServerWithBackoffRetries](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L721-L782) 함수는 MQTT 브로커에 상호 인증된 TLS 연결을 시도합니다. 연결이 실패하면 백오프 기간 후에 다시 시도합니다. 최대 시도 횟수에 도달하거나 최대 백오프 기간에 도달할 때까지 백오프 기간은 기하급수적으로 증가합니다. `BackoffAlgorithm_GetNextBackoff` 함수는 기하급수적으로 증가하는 백오프 값을 제공하고 최대 시도 횟수에 도달하면 `RetryUtilsRetriesExhausted`를 반환합니다. `prvConnectToServerWithBackoffRetries` 함수는 구성된 시도 횟수 이후에도 브로커에 대한 TLS 연결을 설정할 수 없는 경우 실패 상태를 반환합니다.

[prvCreateMQTTConnectionWithBroker](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L785-L848) 함수는 클린 세션을 통해 MQTT 브로커에 대한 MQTT 연결을 설정하는 방법을 보여줍니다. 이 함수는 `FreeRTOS-Plus/Source/Application-Protocols/platform/freertos/transport/src/tls_freertos.c` 파일에 구현된 TLS 전송 인터페이스를 사용합니다. `xConnectInfo`에서 브로커의 유지 기간(초)을 설정하고 있다는 점을 염두에 두세요.

다음 함수는 `MQTT_Init` 함수를 사용하여 MQTT 컨텍스트에서 TLS 전송 인터페이스와 시간 함수를 설정하는 방법을 보여줍니다. 또한 이벤트 콜백 함수 포인터(`prvEventCallback`)가 어떻게 설정되는지도 보여줍니다. 이 콜백은 들어오는 메시지를 보고하는 데 사용됩니다.

## MQTT 주제 구독
<a name="mqtt-demo-ma-subscribing"></a>

[prvMQTTSubscribeWithBackoffRetries](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L871-L969) 함수는 MQTT 브로커에서 주제 필터를 구독하는 방법을 보여줍니다. 이 예제에서는 하나의 주제 필터를 구독하는 방법을 보여 주지만, 동일한 subscribe API 직접 호출에서 주제 필터 목록을 전달하여 둘 이상의 주제 필터를 구독할 수도 있습니다. 또한 MQTT 브로커가 구독 요청을 거부하는 경우 구독은 지수 백오프를 사용하여 `RETRY_MAX_ATTEMPTS`에 설정된 횟수 만큼 재시도됩니다.

## 주제에 게시
<a name="mqtt-demo-ma-publishing"></a>

[prvMQTTPublishToTopic](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L972-L1004) 함수는 MQTT 브로커에 주제 필터를 게시하는 방법을 보여줍니다.

## 들어오는 메시지 수신
<a name="mqtt-demo-ma-receiving"></a>

애플리케이션은 앞서 설명한 대로 브로커에 연결하기 전에 이벤트 콜백 함수를 등록합니다. `prvMQTTDemoTask` 함수는 `MQTT_ProcessLoop` 함수를 호출하여 들어오는 메시지를 수신합니다. 함수는 들어오는 MQTT 메시지를 수신하면 애플리케이션이 등록한 이벤트 콜백 함수를 호출합니다. [prvEventCallback](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L1139-L1154) 함수는 이러한 이벤트 콜백 함수의 한 예입니다. `prvEventCallback`은 들어오는 패킷 유형을 검사하고 적절한 핸들러를 호출합니다. 아래 예제에서 함수는 들어오는 게시 메시지를 처리하기 위해 `prvMQTTProcessIncomingPublish()`를 호출하거나 확인(ACK)을 처리하기 위해 `prvMQTTProcessResponse()`를 호출합니다.

## 들어오는 MQTT 게시 패킷 처리
<a name="mqtt-demo-ma-processing"></a>

[prvMQTTProcessIncomingPublish](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L1108-L1135) 함수는 MQTT 브로커의 게시 패킷을 처리하는 방법을 보여줍니다.

## 주제 구독 취소
<a name="mqtt-demo-ma-unsubscribing"></a>

워크플로의 마지막 단계는 브로커가 `mqttexampleTOPIC`에서 게시된 메시지를 보내지 않도록 주제 구독을 취소하는 것입니다. 다음은 [prvMQTTUnsubscribeFromTopic](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT/mqtt_demo_mutual_auth.c#L1007-L1043) 함수의 정의입니다.

## 데모에 사용된 루트 CA 변경
<a name="mqtt-demo-ma-root-ca"></a>

기본적으로 FreeRTOS 데모는 Amazon Root CA 1 인증서(RSA 2048비트 키)를 사용하여 AWS IoT Core 서버로 인증합니다. Amazon 루트 CA 3 인증서(ECC 256비트 키)를 비롯한 다른 [CA 인증서를 서버 인증](https://docs.aws.amazon.com/iot/latest/developerguide/server-authentication.html#server-authentication-certs)에 사용할 수 있습니다. coreMQTT 상호 인증 데모에서 루트 CA를 변경하려면 

1. 텍스트 편집기에서 `freertos/vendors/vendor/boards/board/aws_demos/config_files/mqtt_demo_mutual_auth_config.h` 파일을 엽니다.

1. 파일에서 다음 줄을 찾습니다.

   ```
    * #define democonfigROOT_CA_PEM    "...insert here..." 
   ```

   이 줄의 주석 처리를 해제하고 필요한 경우 주석 블록 끝 ` */`를 붙여넣습니다.

1. 사용하려는 CA 인증서를 복사하여 `"...insert here..."` 텍스트에 붙여넣습니다. 결과는 다음 예제와 같아야 합니다.

   ```
   #define democonfigROOT_CA_PEM   "-----BEGIN CERTIFICATE-----\n"\
   "MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5\n"\
   "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n"\
   "Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG\n"\
   "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg\n"\
   "Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl\n"\
   "ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j\n"\
   "QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr\n"\
   "ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr\n"\
   "BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM\n"\
   "YyRIHN8wfdVoOw==\n"\
   "-----END CERTIFICATE-----\n"
   ```

1. (선택 사항) 다른 데모의 루트 CA를 변경할 수 있습니다. 각 `freertos/vendors/vendor/boards/board/aws_demos/config_files/demo-name_config.h` 파일마다 1\$13단계를 반복합니다.

# coreMQTT 에이전트 연결 공유 데모
<a name="mqtt-demo-cs"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

## 소개
<a name="mqtt-demo-cs-introduction"></a>

coreMQTT 연결 공유 데모 프로젝트에서는 다중 스레드 애플리케이션을 사용하여 클라이언트와 서버 간의 상호 인증과 함께 TLS를 사용하여 AWS MQTT 브로커에 대한 연결을 설정하는 방법을 보여줍니다. 이 데모에서는 mbedTLS 기반 전송 인터페이스 구현을 사용하여 서버 및 클라이언트 인증 TLS 연결을 설정하고 [QoS 1](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html#_Toc442180914) 수준에서 MQTT의 구독-게시 워크플로를 보여줍니다. 이 데모는 주제 필터를 구독하고, 필터와 일치하는 주제에 게시하고, QoS 1 수준에서 서버로부터 해당 메시지가 다시 수신될 때까지 대기합니다. 브로커에 게시하고 브로커로부터 동일한 메시지를 다시 수신하는 이 주기는 생성된 태스크 각각에 대해 여러 번 반복됩니다. 이 데모의 메시지는 QoS 1 수준에서 전송되므로 MQTT 사양에 따라 최소 한 번의 전송이 보장됩니다.

**참고**  
FreeRTOS 데모를 설정하고 실행하려면 [FreeRTOS 시작하기](freertos-getting-started.md)의 단계를 따릅니다.

이 데모는 스레드 안전 대기열을 사용하여 MQTT API와 상호 작용하는 명령을 보관합니다. 이 데모에서 주목해야 할 두 가지 태스크가 있습니다.
+ MQTT 에이전트(메인) 태스크는 명령 대기열의 명령을 처리하고, 다른 태스크는 대기열에 명령을 배치합니다. 이 작업은 루프를 시작하여 명령 대기열의 명령을 처리합니다. 종료 명령을 수신하면 이 태스크는 루프를 중단합니다.
+ 데모 구독/게시 태스크는 MQTT 주제에 대한 구독을 생성한 다음 게시 작업을 생성하여 명령 대기열로 푸시합니다. 그러면 MQTT 에이전트 태스크가 이러한 게시 작업을 실행합니다. 데모 구독/게시 태스크는 명령 완료 콜백 실행으로 표시되는 게시 완료 시까지 기다렸다가 다음 게시가 시작되기 전에 잠시 지연합니다. 이 태스크는 애플리케이션 태스크에서 coreMQTT 에이전트 API를 사용하는 방법의 예를 보여줍니다.

들어오는 게시 메시지의 경우 coreMQTT 에이전트는 단일 콜백 함수를 호출합니다. 이 데모에는 구독한 주제에 대해 들어오는 게시 메시지에 대해 간접 호출할 콜백을 지정할 수 있는 구독 관리자도 포함되어 있습니다. 이 데모에서 에이전트의 수신 게시 콜백은 구독 관리자를 간접 호출하여 구독을 등록한 모든 태스크에 게시를 팬 아웃합니다.

이 데모에서는 상호 인증 TLS 연결을 사용하여 AWS에 연결합니다. 데모 도중 예기치 않게 네트워크 연결이 끊어지면 클라이언트는 지수 백오프 로직을 사용하여 재연결을 시도합니다. 클라이언트가 성공적으로 재연결되었지만 브로커가 이전 세션을 재개할 수 없는 경우 클라이언트는 이전 세션과 동일한 주제를 다시 구독합니다.

### 단일 스레드와 다중 스레드
<a name="mqtt-demo-cs-single-vs-multi"></a>

coreMQTT 사용 모델에는 단일 스레드와 다중 스레드(멀티태스킹)의 두 가지가 있습니다. 단일 스레드 모델은 단일 스레드에서만 coreMQTT 라이브러리를 사용하므로 MQTT 라이브러리에서 명시적 호출을 반복해야 합니다. 여기에 설명된 데모에 나와 있는 것처럼 다중 스레드 사용 사례는 에이전트(또는 대몬(daemon)) 태스크 내에서 MQTT 프로토콜을 백그라운드에서 대신 실행할 수 있습니다. 에이전트 태스크에서 MQTT 프로토콜을 실행하면 MQTT 상태를 명시적으로 관리하거나 `MQTT_ProcessLoop` API 함수를 직접 호출할 필요가 없습니다. 또한 에이전트 태스크를 사용하면 뮤텍스와 같은 동기화 프리미티브 없이도 여러 애플리케이션 태스크가 단일 MQTT 연결을 공유할 수 있습니다.

## 소스 코드
<a name="mqtt-demo-cs-source-code"></a>

데모 소스 파일은 이름이 `mqtt_agent_task.c` 및 `simple_sub_pub_demo.c`이며 `freertos/demos/coreMQTT_Agent/` 디렉터리 및 [GitHub](https://github.com/aws/amazon-freertos/tree/main/demos/coreMQTT_Agent/) 웹 사이트에서 찾을 수 있습니다.

## 기능
<a name="mqtt-demo-cs-functionality"></a>

이 데모에서는 최소 두 개의 태스크를 생성합니다. 하나는 MQTT API 호출 요청을 처리하는 메인 태스크이고 다른 하나는 해당 요청을 생성하는 구성 가능한 수의 서브 태스크입니다. 이 데모에서는 메인 태스크가 세 개의 서브 태스크를 생성하고, 처리 루프를 호출하고, 나중에 정리됩니다. 메인 태스크는 브로커에 대한 단일 MQTT 연결을 생성하고, 이 연결은 서브 태스크 간에 공유됩니다. 서브 태스크는 브로커와 MQTT 구독을 생성한 다음 브로커에 메시지를 게시합니다. 각 서브 태스크는 게시에 고유한 주제를 사용합니다.

## 메인 태스크
<a name="mqtt-demo-cs-main-task"></a>

메인 애플리케이션 태스크 [RunCoreMQTTAgentDemo](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT_Agent/mqtt_agent_task.c#L435-L480)는 영구 MQTT 세션을 설정하고, 서브 태스크를 생성하고, 종료 명령을 수신할 때까지 처리 루프 [MQTTAgent\$1CommandLoop](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT_Agent/mqtt_agent_task.c#L856)를 실행합니다. 네트워크 연결이 예기치 않게 끊어지면 데모가 백그라운드에서 브로커에 다시 연결되고 브로커와 다시 구독을 설정합니다. 처리 루프가 종료되면 브로커와의 연결이 끊깁니다.

### 명령
<a name="mqtt-demo-cs-main-task-commands"></a>

coreMQTT 에이전트 API를 간접 호출하면 명령이 생성되어 에이전트 태스크의 대기열로 전송되고 `MQTTAgent_CommandLoop()`에서 처리됩니다. 명령이 생성될 때 선택적 완료 콜백 및 컨텍스트 파라미터가 전달될 수 있습니다. 해당 명령이 완료되면 전달된 컨텍스트 및 명령의 결과로 생성된 모든 반환 값을 사용하여 완료 콜백이 간접 호출됩니다. 완료 콜백의 서명은 다음과 같습니다.

```
typedef void (* MQTTAgentCommandCallback_t )( void * pCmdCallbackContext,
                                              MQTTAgentReturnInfo_t * pReturnInfo );
```

명령 완료 컨텍스트는 사용자 정의되며, 이 데모에서는 [MQTTAgentCommandContext 구조](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT_Agent/simple_sub_pub_demo.c#L105-L115)입니다.

다음과 같은 경우 명령이 완료된 것으로 간주됩니다.
+ QoS > 0으로 구독, 구독 취소 및 게시: 해당 확인 패킷이 수신된 후.
+ 기타 모든 작업: 해당 coreMQTT API가 호출된 후.

게시 정보, 구독 정보, 완료 컨텍스트를 포함하여 명령에서 사용하는 모든 구조는 명령이 완료될 때까지 범위 내에 있어야 합니다. 완료 콜백을 간접 호출하기 전에는 호출 태스크가 명령의 구조를 재사용해서는 안 됩니다. 완료 콜백은 MQTT 에이전트에 의해 간접 호출되므로 명령을 생성한 태스크가 아닌 에이전트 태스크의 스레드 컨텍스트에서 실행됩니다. 태스크 알림 또는 대기열과 같은 프로세스 간 통신 메커니즘을 사용하여 호출 태스크에 명령 완료를 알릴 수 있습니다.

### 명령 루프 실행
<a name="mqtt-demo-cs-command-loop"></a>

명령은 `MQTTAgent_CommandLoop()`에서 지속적으로 처리됩니다. 처리할 명령이 없는 경우 루프는 대기열에 명령이 하나 추가될 때까지 최대 `MQTT_AGENT_MAX_EVENT_QUEUE_WAIT_TIME` 동안 대기하고, 명령이 추가되지 않으면 `MQTT_ProcessLoop()`를 한 번 반복 실행합니다. 이렇게 하면 MQTT Keep-Alive를 관리할 수 있을 뿐 아니라 대기열에 명령이 없는 경우에도 들어오는 모든 게시를 수신할 수 있습니다.

명령 루프 함수가 반환하는 이유는 다음과 같습니다.
+ 명령이 `MQTTSuccess` 이외의 상태 코드를 반환합니다. 오류 처리 방법을 결정할 수 있도록 명령 루프가 오류 상태를 반환합니다. 이 데모에서는 TCP 연결이 다시 설정되고 재연결이 시도됩니다. 오류가 발생하는 경우 MQTT를 사용하는 다른 태스크의 개입 없이 백그라운드에서 재연결이 실행될 수 있습니다.
+ 연결 해제 명령(`MQTTAgent_Disconnect`)이 처리됩니다. TCP 연결을 끊을 수 있도록 명령 루프가 종료됩니다.
+ 종료 명령(`MQTTAgent_Terminate`)이 처리됩니다. 또한 이 명령은 대기열에 남아 있거나 승인 패킷을 기다리는 모든 명령을 반환 코드 `MQTTRecvFailed`와 함께 오류로 표시합니다.

### 구독 관리자
<a name="mqtt-demo-cs-subscription-manager"></a>

데모에서는 여러 주제를 사용하므로 구독 관리자를 사용하면 구독한 주제를 고유한 콜백 또는 태스크와 편리하게 연결할 수 있습니다. 이 데모의 구독 관리자는 단일 스레드이므로 여러 태스크에서 동시에 사용해서는 안 됩니다. 이 데모에서 구독 관리자 함수는 MQTT 에이전트에 전달되는 콜백 함수에서만 호출되며 에이전트 태스크의 스레드 컨텍스트에서만 실행됩니다.

## 간단한 구독-게시 태스크
<a name="mqtt-demo-cs-sub-pub"></a>

[prvSimpleSubscribePublishTask](https://github.com/aws/amazon-freertos/blob/main/demos/coreMQTT_Agent/simple_sub_pub_demo.c#L447-L569)의 각 인스턴스는 MQTT 주제에 대한 구독을 생성하고 해당 주제에 대한 게시 작업을 생성합니다. 여러 게시 유형을 설명하기 위해 짝수 번호 태스크는 QoS 0(게시 패킷 전송 시 완료)을 사용하고 홀수 번호 태스크는 QoS 1(PUBACK 패킷 수신 시 완료)을 사용합니다.

# OTA(Over-the-Air) 업데이트 데모 애플리케이션
<a name="ota-demo"></a>

FreeRTOS에는 무선 업데이트(OTA) 라이브러리의 기능을 시연하는 데모 애플리케이션이 포함되어 있습니다. OTA 데모 애플리케이션은 `freertos/demos/ota/ota_demo_core_mqtt/ota_demo_core_mqtt.c` 또는 `freertos/demos/ota/ota_demo_core_http/ota_demo_core_http.c` 파일에 위치합니다.

OTA 데모 애플리케이션은 다음을 수행합니다.

1. FreeRTOS 네트워크 스택과 MQTT 버퍼 풀을 초기화합니다.

1. `vRunOTAUpdateDemo()`를 사용하여 OTA 라이브러리 연습을 위한 태스크를 생성합니다.

1. `_establishMqttConnection()`를 사용하여 MQTT 클라이언트를 생성합니다.

1. 를 사용하여 AWS IoT MQTT 브로커에 연결하고 MQTT 연결 해제 콜백을 `IotMqtt_Connect()` 등록합니다`prvNetworkDisconnectCallback`.

1. `OTA_AgentInit()`를 호출하여 OTA 작업을 생성하고, OTA 작업이 완료될 때 사용할 콜백을 등록합니다.

1. `xOTAConnectionCtx.pvControlClient = _mqttConnection;`을 사용하여 MQTT 연결을 재사용합니다.

1. MQTT 연결이 끊어지면 애플리케이션은 OTA 에이전트를 일시 중단하고 지수 지연 및 지터를 사용하여 재연결을 시도한 다음 OTA 에이전트를 다시 시작합니다.

OTA 업데이트를 사용하려면 먼저 [FreeRTOS 무선 업데이트(OTA)](freertos-ota-dev.md)에 명시된 모든 사전 조건을 완료해야 합니다.

OTA 업데이트를 위한 설정을 완료한 경우 OTA 기능을 지원하는 플랫폼에서 FreeRTOS OTA 데모를 다운로드, 빌드, 플래시 및 실행합니다. 디바이스별 데모 지침은 다음 FreeRTOS 적격 디바이스에서 사용할 수 있습니다.
+ [Texas Instruments CC3220SF-LAUNCHXL](download-ota-ti.md)
+ [Microchip Curiosity PIC32MZEF](download-ota-mchip.md)
+ [Espressif ESP32](download-ota-esp.md)
+ [Renesas RX65N에서 FreeRTOS OTA 데모를 다운로드, 빌드, 플래시, 실행합니다.](download-rx65n-ota.md)

디바이스에서 OTA 데모 애플리케이션을 빌드, 플래시 및 실행한 후 AWS IoT 콘솔 또는를 사용하여 OTA 업데이트 작업을 AWS CLI 생성할 수 있습니다. OTA 업데이트 작업을 생성했으면, 터미널 에뮬레이터를 연결하여 OTA 업데이트의 진행 상황을 확인합니다. 프로세스 중에 발생한 오류를 기록해 둡니다.

OTA 업데이트 작업이 성공하면 다음과 같은 출력이 표시됩니다. 간결하게 하기 위해 이 예제에서는 일부 행을 목록에서 제거했습니다.

```
    249 21207 [iot_thread] [ota_demo_core_mqtt.c:1850] [INFO] [MQTT]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    250 21247 [MQTT Agent Task] [core_mqtt.c:886] [INFO] [MQTT] Packet received. ReceivedBytes=601.
    251 21247 [MQTT Agent Task] [core_mqtt.c:1045] [INFO] [MQTT] De-serialized incoming PUBLISH packet: DeserializerResult=MQTTSuccess.
    252 21248 [MQTT Agent Task] [core_mqtt.c:1058] [INFO] [MQTT] State record updated. New state=MQTTPubAckSend.
    253 21249 [MQTT Agent Task] [ota_demo_core_mqtt.c:976] [INFO] [MQTT] Received job message callback, size 548.
    254 21252 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[execution.jobId: AFR_OTA-9702f1a3-b747-4c3e-a0eb-a3b0cf83ddbb]
    255 21253 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[execution.jobDocument.afr_ota.streamname: AFR_OTA-945d320b-a18b-441b-b435-4a18d4e7671f]
    256 21255 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[execution.jobDocument.afr_ota.protocols: ["MQTT"]]
    257 21256 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[filepath: aws_demos.bin]
    258 21257 [OTA Agent Task] [ota.c:1684] [INFO] [OTA] Extracted parameter: [key: value]=[filesize: 1164016]
    259 21258 [OTA Agent Task] [ota.c:1684] [INFO] [OTA] Extracted parameter: [key: value]=[fileid: 0]
    260 21259 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[certfile: ecdsa-sha256-signer.crt.pem]
    261 21260 [OTA Agent Task] [ota.c:1575] [INFO] [OTA] Extracted parameter [ sig-sha256-ecdsa: MEQCIE1SFkIHHiZAvkPpu6McJtx7SYoD... ]
    262 21261 [OTA Agent Task] [ota.c:1684] [INFO] [OTA] Extracted parameter: [key: value]=[fileType: 0]
    263 21262 [OTA Agent Task] [ota.c:2199] [INFO] [OTA] Job document was accepted. Attempting to begin the update.
    264 21263 [OTA Agent Task] [ota.c:2323] [INFO] [OTA] Job parsing success: OtaJobParseErr_t=OtaJobParseErrNone, Job name=AFR_OTA-9702f1a3-b747-4c3e-a0eb-a3b0cf83ddbb
    265 21318 [iot_thread] [ota_demo_core_mqtt.c:1850] [INFO] [MQTT]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    266 21418 [iot_thread] [ota_demo_core_mqtt.c:1850] [INFO] [MQTT]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    267 21469 [OTA Agent Task] [ota.c:938] [INFO] [OTA] Setting OTA data interface.
    268 21470 [OTA Agent Task] [ota.c:2839] [INFO] [OTA] Current State=[CreatingFile], Event=[ReceivedJobDocument], New state=[CreatingFile]
    269 21482 [MQTT Agent Task] [core_mqtt.c:886] [INFO] [MQTT] Packet received. ReceivedBytes=3.
    270 21483 [OTA Agent Task] [ota_demo_core_mqtt.c:1503] [INFO] [MQTT] SUBSCRIBED to topic $aws/things/__test_infra_thing71/streams/AFR_OTA-945d320b-a18b-441b-b435-4a18d4e7671f/data/cbor to bro
    271 21484 [OTA Agent Task] [ota.c:2839] [INFO] [OTA] Current State=[RequestingFileBlock], Event=[CreateFile], New state=[RequestingFileBlock]
    272 21518 [iot_thread] [ota_demo_core_mqtt.c:1850] [INFO] [MQTT]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    273 21532 [MQTT Agent Task] [core_mqtt_agent_command_functions.c:76] [INFO] [MQTT] Publishing message to $aws/things/__test_infra_thing71/streams/AFR_OTA-945d320b-a18b-441b-b435-4a18d4e7671f/
    274 21534 [OTA Agent Task] [ota_demo_core_mqtt.c:1553] [INFO] [MQTT] Sent PUBLISH packet to broker $aws/things/__test_infra_thing71/streams/AFR_OTA-945d320b-a18b-441b-b435-4a18d4e7671f/get/cbor
    275 21534 [OTA Agent Task] [ota_mqtt.c:1112] [INFO] [OTA] Published to MQTT topic to request the next block: topic=$aws/things/__test_infra_thing71/streams/AFR_OTA-945d320b-a18b-441b-b435-4a1
    276 21537 [OTA Agent Task] [ota.c:2839] [INFO] [OTA] Current State=[WaitingForFileBlock], Event=[RequestFileBlock], New state=[WaitingForFileBlock]
    277 21558 [MQTT Agent Task] [core_mqtt.c:886] [INFO] [MQTT] Packet received. ReceivedBytes=4217.
    278 21559 [MQTT Agent Task] [core_mqtt.c:1045] [INFO] [MQTT] De-serialized incoming PUBLISH packet: DeserializerResult=MQTTSuccess.
    279 21560 [MQTT Agent Task] [core_mqtt.c:1058] [INFO] [MQTT] State record updated. New state=MQTTPublishDone.
    280 21561 [MQTT Agent Task] [ota_demo_core_mqtt.c:1026] [INFO] [MQTT] Received data message callback, size 4120.
    281 21563 [OTA Agent Task] [ota.c:2464] [INFO] [OTA] Received valid file block: Block index=0, Size=4096
    282 21566 [OTA Agent Task] [ota.c:2683] [INFO] [OTA] Number of blocks remaining: 284
     
    ... // Output removed for brevity
     
    3672 42745 [OTA Agent Task] [ota.c:2464] [INFO] [OTA] Received valid file block: Block index=284, Size=752
    3673 42747 [OTA Agent Task] [ota.c:2633] [INFO] [OTA] Received final block of the update.
    (428298) ota_pal: No such certificate file: ecdsa-sha256-signer.crt.pem. Using certificate in ota_demo_config.h.
    3674 42818 [iot_thread] [ota_demo_core_mqtt.c:1850] [INFO] [MQTT]  Received: 285   Queued: 285   Processed: 284   Dropped: 0
    3675 42918 [iot_thread] [ota_demo_core_mqtt.c:1850] [INFO] [MQTT]  Received: 285   Queued: 285   Processed: 284   Dropped: 0
     
    ... // Output removed for brevity
     
    3678 43197 [OTA Agent Task] [ota.c:2654] [INFO] [OTA] Received entire update and validated the signature.
    3685 43215 [OTA Agent Task] [ota_demo_core_mqtt.c:862] [INFO] [MQTT] Received OtaJobEventActivate callback from OTA Agent.
     
    ... // Output removed for brevity
     
    2 39 [iot_thread] [INFO ][DEMO][390] ---------STARTING DEMO---------
     
    [0;32mI (3633) WIFI: WIFI_EVENT_STA_CONNECTED
    [0;32mI (4373) WIFI: SYSTEM_EVENT_STA_GOT_IP
     
    ... // Output removed for brevity 
     
    4 351 [sys_evt] [INFO ][DEMO][3510] Connected to WiFi access point, ip address: 255.255.255.0.
    5 351 [iot_thread] [INFO ][DEMO][3510] Successfully initialized the demo. Network type for the demo: 1
    6 351 [iot_thread] [ota_demo_core_mqtt.c:1902] [INFO] [MQTT] OTA over MQTT demo, Application version 0.9.1
    7 351 [iot_thread] [ota_demo_core_mqtt.c:1323] [INFO] [MQTT] Creating a TLS connection to <endpoint>-ats.iot.us-west-2.amazonaws.com:8883.
    9 718 [iot_thread] [core_mqtt.c:886] [INFO] [MQTT] Packet received. ReceivedBytes=2.
    10 718 [iot_thread] [core_mqtt_serializer.c:970] [INFO] [MQTT] CONNACK session present bit not set.
    11 718 [iot_thread] [core_mqtt_serializer.c:912] [INFO] [MQTT] Connection accepted.
     
    ... // Output removed for brevity
     
    17 736 [OTA Agent Task] [ota_demo_core_mqtt.c:1503] [INFO] [MQTT] SUBSCRIBED to topic $aws/things/__test_infra_thing71/jobs/notify-next to broker.
    18 737 [OTA Agent Task] [ota_mqtt.c:381] [INFO] [OTA] Subscribed to MQTT topic: $aws/things/__test_infra_thing71/jobs/notify-next
    30 818 [iot_thread] [ota_demo_core_mqtt.c:1850] [INFO] [MQTT]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    31 819 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[execution.jobId: AFR_OTA-9702f1a3-b747-4c3e-a0eb-a3b0cf83ddbb]
    32 820 [OTA Agent Task] [ota.c:1684] [INFO] [OTA] Extracted parameter: [key: value]=[execution.statusDetails.updatedBy: 589824]
    33 822 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[execution.jobDocument.afr_ota.streamname: AFR_OTA-945d320b-a18b-441b-b435-4a18d4e7671f]
    34 823 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[execution.jobDocument.afr_ota.protocols: ["MQTT"]]
    35 824 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[filepath: aws_demos.bin]
    36 825 [OTA Agent Task] [ota.c:1684] [INFO] [OTA] Extracted parameter: [key: value]=[filesize: 1164016]
    37 826 [OTA Agent Task] [ota.c:1684] [INFO] [OTA] Extracted parameter: [key: value]=[fileid: 0]
    38 827 [OTA Agent Task] [ota.c:1645] [INFO] [OTA] Extracted parameter: [key: value]=[certfile: ecdsa-sha256-signer.crt.pem]
    39 828 [OTA Agent Task] [ota.c:1575] [INFO] [OTA] Extracted parameter [ sig-sha256-ecdsa: MEQCIE1SFkIHHiZAvkPpu6McJtx7SYoD... ]
    40 829 [OTA Agent Task] [ota.c:1684] [INFO] [OTA] Extracted parameter: [key: value]=[fileType: 0]
    41 830 [OTA Agent Task] [ota.c:2102] [INFO] [OTA] In self test mode.
    42 830 [OTA Agent Task] [ota.c:1936] [INFO] [OTA] New image has a higher version number than the current image: New image version=0.9.1, Previous image version=0.9.0
    43 832 [OTA Agent Task] [ota.c:2120] [INFO] [OTA] Image version is valid: Begin testing file: File ID=0
    53 896 [OTA Agent Task] [ota.c:794] [INFO] [OTA] Beginning self-test.
    62 971 [OTA Agent Task] [ota_demo_core_mqtt.c:1553] [INFO] [MQTT] Sent PUBLISH packet to broker $aws/things/__test_infra_thing71/jobs/AFR_OTA-9702f1a3-b747-4c3e-a0eb-a3b0cf83ddbb/update to br63 971 [MQTT Agent Task] [core_mqtt.c:1045] [INFO] [MQTT] De-serialized incoming PUBLISH packet: DeserializerResult=MQTTSuccess.
    65 973 [MQTT Agent Task] [core_mqtt.c:1058] [INFO] [MQTT] State record updated. New state=MQTTPublishDone.
    64 973 [OTA Agent Task] [ota_demo_core_mqtt.c:902] [INFO] [MQTT] Successfully updated with the new image.
```

# 무선(OTA) 데모 구성
<a name="ota-demo-specific-config"></a>

OTA 데모 구성은 `aws_iot_ota_update_demo.c`에서 제공하는 데모별 구성 옵션입니다. 이러한 구성은 OTA 라이브러리 구성 파일에 제공된 OTA 라이브러리 구성과 다릅니다.

**OTA\$1DEMO\$1KEEP\$1ALIVE\$1SECONDS**  
MQTT 클라이언트의 경우 이 구성은 한 제어 패킷의 전송을 완료한 후 다음 제어 패킷의 전송을 시작하는 데 소요될 수 있는 최대 시간 간격입니다. 제어 패킷이 없는 경우 PINGREQ가 전송됩니다. 브로커는 이 유지 기간의 1.5배 이내에 메시지 또는 PINGREQ 패킷을 전송하지 않는 클라이언트와의 연결을 끊어야 합니다. 이 구성은 애플리케이션의 요구 사항에 따라 조정해야 합니다.

**OTA\$1DEMO\$1CONN\$1RETRY\$1BASE\$1INTERVAL\$1SECONDS**  
네트워크 연결을 재시도하기 전의 기본 간격(초)입니다. OTA 데모는 이 기본 시간 간격 이후에 재연결을 시도합니다. 시도가 실패할 때마다 간격이 두 배로 늘어납니다. 이 기본 지연의 최대값까지의 임의 지연도 간격에 추가됩니다.

**OTA\$1DEMO\$1CONN\$1RETRY\$1MAX\$1INTERVAL\$1SECONDS**  
네트워크 연결을 재시도하기 전의 최대 간격(초)입니다. 재연결 지연은 시도가 실패할 때마다 두 배로 늘어나지만 이 최대값에 같은 간격의 지터를 더한 값까지만 지연될 수 있습니다.

# Texas Instruments CC3220SF-LAUNCHXL에 대한 FreeRTOS OTA 데모 다운로드, 빌드, 플래시 및 실행
<a name="download-ota-ti"></a>

**중요**  <a name="deprecation-message"></a>
이 라이브러리는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.<a name="download-demo"></a>

**FreeRTOS 및 OTA 데모 코드를 다운로드하려면**
+ GitHub 사이트 [https://github.com/FreeRTOS/FreeRTOS](https://github.com/FreeRTOS/FreeRTOS)에서 소스 코드를 다운로드할 수 있습니다.<a name="build-demo"></a>

**데모 애플리케이션을 빌드하려면**

1. 의 지침에 따라 `aws_demos` 프로젝트를 Code Composer Studio로 가져오[FreeRTOS 시작하기](freertos-getting-started.md)고, AWS IoT 엔드포인트, Wi-Fi SSID 및 암호, 보드의 프라이빗 키 및 인증서를 구성합니다.

1.  `freertos/vendors/vendor/boards/board/aws_demos/config_files/aws_demo_config.h`를 열고 `#define CONFIG_CORE_MQTT_MUTUAL_AUTH_DEMO_ENABLED`를 주석으로 처리한 다음 `CONFIG_OTA_MQTT_UPDATE_DEMO_ENABLED` 또는 `CONFIG_OTA_HTTP_UPDATE_DEMO_ENABLED`를 정의합니다.

1. 솔루션을 빌드하고 오류 없이 빌드되는지 확인합니다.

1. 터미널 에뮬레이터를 시작하고 다음 설정을 사용하여 보드에 연결합니다.
   + 전송 속도: 115200
   + 데이터 비트: 8
   + 패리티: 없음
   + 정지 비트: 1

1. 보드에서 프로젝트를 실행하여 Wi-Fi 및 AWS IoT MQTT 메시지 브로커에 연결할 수 있는지 확인합니다.

실행되면 터미널 에뮬레이터에 다음과 같은 텍스트가 표시됩니다.

```
    0 1000 [Tmr Svc] Simple Link task created
    Device came up in Station mode
    1 2534 [Tmr Svc] Write certificate...
    2 5486 [Tmr Svc] [ERROR] Failed to destroy object. PKCS11_PAL_DestroyObject failed.
    3 5486 [Tmr Svc] Write certificate...
    4 5776 [Tmr Svc] Security alert threshold = 15
    5 5776 [Tmr Svc] Current number of alerts = 1
    6 5778 [Tmr Svc] Running Demos.
    7 5779 [iot_thread] [INFO ][DEMO][5779] ---------STARTING DEMO---------
    8 5779 [iot_thread] [INFO ][INIT][5779] SDK successfully initialized.
    Device came up in Station mode
    [WLAN EVENT] STA Connected to the AP: afrlab-pepper , BSSID: 74:83:c2:b4:46:27
    [NETAPP EVENT] IP acquired by the device
    Device has connected to afrlab-pepper
    Device IP Address is 192.168.36.176 
    9 8283 [iot_thread] [INFO ][DEMO][8282] Successfully initialized the demo. Network type for the demo: 1
    10 8283 [iot_thread] [INFO] OTA over MQTT demo, Application version 0.9.0
    11 8283 [iot_thread] [INFO] Creating a TLS connection to <endpoint>-ats.iot.us-west-2.amazonaws.com:8883.
    12 8852 [iot_thread] [INFO] Creating an MQTT connection to <endpoint>-ats.iot.us-west-2.amazonaws.com.
    13 8914 [iot_thread] [INFO] Packet received. ReceivedBytes=2.
    14 8914 [iot_thread] [INFO] CONNACK session present bit not set.
    15 8914 [iot_thread] [INFO] Connection accepted.
    16 8914 [iot_thread] [INFO] Received MQTT CONNACK successfully from broker.
    17 8914 [iot_thread] [INFO] MQTT connection established with the broker.
    18 8915 [iot_thread] [INFO]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    19 8953 [OTA Agent T] [INFO] Current State=[RequestingJob], Event=[Start], New state=[RequestingJob]
    20 9008 [MQTT Agent ] [INFO] Packet received. ReceivedBytes=3.
    21 9015 [OTA Agent T] [INFO] SUBSCRIBED to topic $aws/things/__test_infra_thing73/jobs/notify-next to broker.
    22 9015 [OTA Agent T] [INFO] Subscribed to MQTT topic: $aws/things/__test_infra_thing73/jobs/notify-next
    23 9504 [MQTT Agent ] [INFO] Publishing message to $aws/things/__test_infra_thing73/jobs/$next/get.
    24 9535 [MQTT Agent ] [INFO] Packet received. ReceivedBytes=2.
    25 9535 [MQTT Agent ] [INFO] Ack packet deserialized with result: MQTTSuccess.
    26 9536 [MQTT Agent ] [INFO] State record updated. New state=MQTTPublishDone.
    27 9537 [OTA Agent T] [INFO] Sent PUBLISH packet to broker $aws/things/__test_infra_thing73/jobs/$next/get to broker.
    28 9537 [OTA Agent T] [WARN] OTA Timer handle NULL for Timerid=0, can't stop.
    29 9537 [OTA Agent T] [INFO] Current State=[WaitingForJob], Event=[RequestJobDocument], New state=[WaitingForJob]
    30 9539 [MQTT Agent ] [INFO] Packet received. ReceivedBytes=120.
    31 9539 [MQTT Agent ] [INFO] De-serialized incoming PUBLISH packet: DeserializerResult=MQTTSuccess.
    32 9540 [MQTT Agent ] [INFO] State record updated. New state=MQTTPublishDone.
    33 9540 [MQTT Agent ] [INFO] Received job message callback, size 62.
    34 9616 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=execution
    35 9616 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=execution.jobId
    36 9617 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=execution.jobDocument
    37 9617 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=execution.jobDocument.afr_ota
    38 9617 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=execution.jobDocument.afr_ota.protocols
    39 9618 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=execution.jobDocument.afr_ota.files
    40 9618 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=filesize
    41 9618 [OTA Agent T] [INFO] Failed job document content check: Required job document parameter was not extracted: parameter=fileid
    42 9619 [OTA Agent T] [INFO] Failed to parse JSON document as AFR_OTA job: DocParseErr_t=7
    43 9619 [OTA Agent T] [INFO] No active job available in received job document: OtaJobParseErr_t=OtaJobParseErrNoActiveJobs
    44 9619 [OTA Agent T] [ERROR] Failed to execute state transition handler: Handler returned error: OtaErr_t=OtaErrJobParserError
    45 9620 [OTA Agent T] [INFO] Current State=[WaitingForJob], Event=[ReceivedJobDocument], New state=[CreatingFile]
    46 9915 [iot_thread] [INFO]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    47 10915 [iot_thread] [INFO]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    48 11915 [iot_thread] [INFO]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    49 12915 [iot_thread] [INFO]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    50 13915 [iot_thread] [INFO]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
    51 14915 [iot_thread] [INFO]  Received: 0   Queued: 0   Processed: 0   Dropped: 0
```

# Microchip Curiosity PIC32MZEF에 대한 FreeRTOS OTA 데모 다운로드, 빌드, 플래시 및 실행
<a name="download-ota-mchip"></a>

**중요**  <a name="deprecation-message"></a>
이 라이브러리는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

**참고**  
Microchip의 합의에 따라 AWS는 FreeRTOS 참조 통합 리포지토리 메인 브랜치에서 Curiosity PIC32MZEF(DM320104)를 제거하고 새 릴리스에는 더 이상 제공하지 않을 예정입니다. Microchip은 PIC32MZEF(DM320104)를 더 이상 새로운 설계에 사용하지 않는 것이 좋다는 [공지문](https://www.microchip.com/DevelopmentTools/ProductDetails/PartNO/DM320104)을 발표했습니다. PIC32MZEF 프로젝트 및 소스 코드는 이전 릴리스 태그를 통해 계속 액세스할 수 있습니다. Microchip은 고객이 새로운 설계에 Curiosity [PIC32MZ-EF-2.0 개발 보드(DM320209)](https://devices.amazonaws.com/detail/a3G0h0000077I69EAE/Curiosity-PIC32MZ-EF-2-0-Development-Board)를 사용할 것을 권장합니다. PIC32MZv1 플랫폼은 FreeRTOS 참조 통합 리포지토리의 [v202012.00](https://github.com/aws/amazon-freertos/tree/202012.00)에서 계속 찾을 수 있습니다. 그러나 FreeRTOS 참조의 [v202107.00](https://github.com/aws/amazon-freertos/tree/202107.00)에서는 이 플랫폼을 더 이상 지원하지 않습니다.<a name="mch-dowload-demo"></a>

**FreeRTOS OTA 데모 코드를 다운로드하려면**
+ GitHub 사이트 [https://github.com/FreeRTOS/FreeRTOS](https://github.com/FreeRTOS/FreeRTOS)에서 소스 코드를 다운로드할 수 있습니다.<a name="mch-build-demo"></a>

**OTA 업데이트 데모 애플리케이션을 빌드하려면**

1. 의 지침에 따라 `aws_demos` 프로젝트를 MPLAB X IDE로 [FreeRTOS 시작하기](freertos-getting-started.md) 가져오고, AWS IoT 엔드포인트, Wi-Fi SSID 및 암호, 보드용 프라이빗 키 및 인증서를 구성합니다.

1. `vendors/vendor/boards/board/aws_demos/config_files/ota_demo_config.h` 파일을 열고 인증서를 입력합니다.

   ```
   [] = "your-certificate-key";
   ```

1. 코드 서명 인증서의 내용을 여기에 붙여넣습니다.

   ```
   #define otapalconfigCODE_SIGNING_CERTIFICATE [] = "your-certificate-key";
   ```

   `aws_clientcredential_keys.h`와 동일한 형식에 따릅니다. 각 줄은 줄 바꿈 문자('\$1n')로 끝나고 따옴표로 묶여 있어야 합니다.

   예를 들어, 인증서는 다음과 비슷합니다.

   ```
   "-----BEGIN CERTIFICATE-----\n"
   "MIIBXTCCAQOgAwIBAgIJAM4DeybZcTwKMAoGCCqGSM49BAMCMCExHzAdBgNVBAMM\n"
   "FnRlc3Rf62lnbmVyQGFtYXpvbi5jb20wHhcNMTcxMTAzMTkxODM1WhcNMTgxMTAz\n"
   "MTkxODM2WjAhMR8wHQYDVQBBZZZ0ZXN0X3NpZ25lckBhbWF6b24uY29tMFkwEwYH\n"
   "KoZIzj0CAQYIKoZIzj0DAQcDQgAERavZfvwL1X+E4dIF7dbkVMUn4IrJ1CAsFkc8\n"
   "gZxPzn683H40XMKltDZPEwr9ng78w9+QYQg7ygnr2stz8yhh06MkMCIwCwYDVR0P\n"
   "BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMAoGCCqGSM49BAMCA0gAMEUCIF0R\n"
   "r5cb7rEUNtWOvGd05MacrgOABfSoVYvBOK9fP63WAqt5h3BaS123coKSGg84twlq\n"
   "TkO/pV/xEmyZmZdV+HxV/OM=\n"
   "-----END CERTIFICATE-----\n";
   ```

1. [Python 3](https://www.python.org/downloads/) 이상을 설치합니다.

1. `pip install pyopenssl`을 실행하여 `pyOpenSSL`을 설치합니다.

1. 코드 서명 인증서를 `demos/ota/bootloader/utility/codesigner_cert_utility/` 경로에 .pem 형식으로 복사합니다. 인증서 파일의 이름을 `aws_ota_codesigner_certificate.pem`으로 바꿉니다.

1.  `freertos/vendors/vendor/boards/board/aws_demos/config_files/aws_demo_config.h`를 열고 `#define CONFIG_CORE_MQTT_MUTUAL_AUTH_DEMO_ENABLED`를 주석으로 처리한 다음 `CONFIG_OTA_MQTT_UPDATE_DEMO_ENABLED` 또는 `CONFIG_OTA_HTTP_UPDATE_DEMO_ENABLED`를 정의합니다.

1. 솔루션을 빌드하고 오류 없이 빌드되는지 확인합니다.

1. 터미널 에뮬레이터를 시작하고 다음 설정을 사용하여 보드에 연결합니다.
   + 전송 속도: 115200
   + 데이터 비트: 8
   + 패리티: 없음
   + 정지 비트: 1

1. 보드에서 디버거를 분리하고 보드에서 프로젝트를 실행하여 Wi-Fi 및 AWS IoT MQTT 메시지 브로커에 연결할 수 있는지 확인합니다.

프로젝트를 실행할 때 MPLAB X IDE에서 출력 창을 열어야 합니다. **ICD4** 탭이 선택되는지 확인합니다. 다음과 같이 출력되어야 합니다.

```
Bootloader version 00.09.00
[prvBOOT_Init] Watchdog timer initialized.
[prvBOOT_Init] Crypto initialized.

[prvValidateImage] Validating image at Bank : 0
[prvValidateImage] No application image or magic code present at: 0xbd000000
[prvBOOT_ValidateImages] Validation failed for image at 0xbd000000

[prvValidateImage] Validating image at Bank : 1
[prvValidateImage] No application image or magic code present at: 0xbd100000
[prvBOOT_ValidateImages] Validation failed for image at 0xbd100000

[prvBOOT_ValidateImages] Booting default image.


>0 36246 [IP-task] vDHCPProcess: offer ac140a0eip
                                                 1 36297 [IP-task] vDHCPProcess: offer ac140a0eip
                 2 36297 [IP-task]

IP Address: 172.20.10.14
3 36297 [IP-task] Subnet Mask: 255.255.255.240
4 36297 [IP-task] Gateway Address: 172.20.10.1
5 36297 [IP-task] DNS Server Address: 172.20.10.1


6 36299 [OTA] OTA demo version 0.9.2
7 36299 [OTA] Creating MQTT Client...
8 36299 [OTA] Connecting to broker...
9 38673 [OTA] Connected to broker.
10 38793 [OTA Task] [prvSubscribeToJobNotificationTopics] OK: $aws/things/devthingota/jobs/$next/get/accepted
11 38863 [OTA Task] [prvSubscribeToJobNotificationTopics] OK: $aws/things/devthingota/jobs/notify-next
12 38863 [OTA Task] [OTA_CheckForUpdate] Request #0
13 38964 [OTA] [OTA_AgentInit] Ready.
14 38973 [OTA Task] [prvParseJSONbyModel] Extracted parameter [ clientToken: 0:devthingota ]
15 38973 [OTA Task] [prvParseJSONbyModel] parameter not present: execution
16 38973 [OTA Task] [prvParseJSONbyModel] parameter not present: jobId
17 38973 [OTA Task] [prvParseJSONbyModel] parameter not present: jobDocument
18 38973 [OTA Task] [prvParseJSONbyModel] parameter not present: streamname
19 38973 [OTA Task] [prvParseJSONbyModel] parameter not present: files
20 38975 [OTA Task] [prvParseJSONbyModel] parameter not present: filepath
21 38975 [OTA Task] [prvParseJSONbyModel] parameter not present: filesize
22 38975 [OTA Task] [prvParseJSONbyModel] parameter not present: fileid
23 38975 [OTA Task] [prvParseJSONbyModel] parameter not present: certfile
24 38975 [OTA Task] [prvParseJSONbyModel] parameter not present: sig-sha256-ecdsa
25 38975 [OTA Task] [prvParseJobDoc] Ignoring job without ID.
26 38975 [OTA Task] [prvOTA_Close] Context->0x8003b620
27 38975 [OTA Task] [prvPAL_Abort] Abort - OK
28 39964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
29 40964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
30 41964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
31 42964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
32 43964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
33 44964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
34 45964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
35 46964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
36 47964 [OTA] State: Ready  Received: 1   Queued: 1   Processed: 1   Dropped: 0
```

터미널 에뮬레이터에 다음과 같은 텍스트가 표시됩니다.

```
AWS Validate: no valid signature in descr: 0xbd000000
AWS Validate: no valid signature in descr: 0xbd100000


>AWS Launch:  No Map performed. Running directly from address: 0x9d000020?
AWS Launch:  wait for app at: 0x9d000020
WILC1000: Initializing...
0 0 

>[None] Seed for randomizer: 1172751941
1 0 [None] Random numbers: 00004272 00003B34 00000602 00002DE3
Chip ID 1503a0

[spi_cmd_rsp][356][nmi spi]: Failed cmd response read, bus error...

[spi_read_reg][1086][nmi spi]: Failed cmd response, read reg (0000108c)...

[spi_read_reg][1116]Reset and retry 10 108c

Firmware ver. : 4.2.1

Min driver ver : 4.2.1

Curr driver ver: 4.2.1

WILC1000: Initialization successful!

Start Wi-Fi Connection...
Wi-Fi Connected
2 7219 [IP-task] vDHCPProcess: offer c0a804beip
3 7230 [IP-task] vDHCPProcess: offer c0a804beip
4 7230 [IP-task] 

IP Address: 192.168.4.190
5 7230 [IP-task] Subnet Mask: 255.255.240.0
6 7230 [IP-task] Gateway Address: 192.168.0.1
7 7230 [IP-task] DNS Server Address: 208.67.222.222


8 7232 [OTA] OTA demo version 0.9.0
9 7232 [OTA] Creating MQTT Client...
10 7232 [OTA] Connecting to broker...
11 7232 [OTA] Sending command to MQTT task.
12 7232 [MQTT] Received message 10000 from queue.
13 8501 [IP-task] Socket sending wakeup to MQTT task.
14 10207 [MQTT] Received message 0 from queue.
15 10256 [IP-task] Socket sending wakeup to MQTT task.
16 10256 [MQTT] Received message 0 from queue.
17 10256 [MQTT] MQTT Connect was accepted. Connection established.
18 10256 [MQTT] Notifying task.
19 10257 [OTA] Command sent to MQTT task passed.
20 10257 [OTA] Connected to broker.
21 10258 [OTA Task] Sending command to MQTT task.
22 10258 [MQTT] Received message 20000 from queue.
23 10306 [IP-task] Socket sending wakeup to MQTT task.
24 10306 [MQTT] Received message 0 from queue.
25 10306 [MQTT] MQTT Subscribe was accepted. Subscribed.
26 10306 [MQTT] Notifying task.
27 10307 [OTA Task] Command sent to MQTT task passed.
28 10307 [OTA Task] [OTA] Subscribed to topic: $aws/things/Microchip/jobs/$next/get/accepted

29 10307 [OTA Task] Sending command to MQTT task.
30 10307 [MQTT] Received message 30000 from queue.
31 10336 [IP-task] Socket sending wakeup to MQTT task.
32 10336 [MQTT] Received message 0 from queue.
33 10336 [MQTT] MQTT Subscribe was accepted. Subscribed.
34 10336 [MQTT] Notifying task.
35 10336 [OTA Task] Command sent to MQTT task passed.
36 10336 [OTA Task] [OTA] Subscribed to topic: $aws/things/Microchip/jobs/notify-next

37 10336 [OTA Task] [OTA] Check For Update #0
38 10336 [OTA Task] Sending command to MQTT task.
39 10336 [MQTT] Received message 40000 from queue.
40 10366 [IP-task] Socket sending wakeup to MQTT task.
41 10366 [MQTT] Received message 0 from queue.
42 10366 [MQTT] MQTT Publish was successful.
43 10366 [MQTT] Notifying task.
44 10366 [OTA Task] Command sent to MQTT task passed.
45 10376 [IP-task] Socket sending wakeup to MQTT task.
46 10376 [MQTT] Received message 0 from queue.
47 10376 [OTA Task] [OTA] Set job doc parameter [ clientToken: 0:Microchip ]
48 10376 [OTA Task] [OTA] Missing job parameter: execution
49 10376 [OTA Task] [OTA] Missing job parameter: jobId
50 10376 [OTA Task] [OTA] Missing job parameter: jobDocument
51 10378 [OTA Task] [OTA] Missing job parameter: ts_ota
52 10378 [OTA Task] [OTA] Missing job parameter: files
53 10378 [OTA Task] [OTA] Missing job parameter: streamname
54 10378 [OTA Task] [OTA] Missing job parameter: certfile
55 10378 [OTA Task] [OTA] Missing job parameter: filepath
56 10378 [OTA Task] [OTA] Missing job parameter: filesize
57 10378 [OTA Task] [OTA] Missing job parameter: sig-sha256-ecdsa
58 10378 [OTA Task] [OTA] Missing job parameter: fileid
59 10378 [OTA Task] [OTA] Missing job parameter: attr
60 10378 [OTA Task] [OTA] Returned buffer to MQTT Client.
61 11367 [OTA] [OTA] Queued: 1   Processed: 1   Dropped: 0
62 12367 [OTA] [OTA] Queued: 1   Processed: 1   Dropped: 0
63 13367 [OTA] [OTA] Queued: 1   Processed: 1   Dropped: 0
64 14367 [OTA] [OTA] Queued: 1   Processed: 1   Dropped: 0
65 15367 [OTA] [OTA] Queued: 1   Processed: 1   Dropped: 0
66 16367 [OTA] [OTA] Queued: 1   Processed: 1   Dropped: 0
```

이 출력은 Microchip Curiosity PIC32MZEF가 OTA 업데이트에 필요한 MQTT 주제에 연결하고 AWS IoT 구독할 수 있음을 보여줍니다. 대기 중인 OTA 업데이트 작업이 없으므로 `Missing job parameter` 메시지가 필요합니다.

# Espressif ESP32에 대한 FreeRTOS OTA 데모 다운로드, 빌드, 플래시 및 실행
<a name="download-ota-esp"></a>

**중요**  <a name="deprecation-message"></a>
이 라이브러리는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

1. [GitHub](https://github.com/aws/amazon-freertos)에서 FreeRTOS 소스를 다운로드합니다. 자세한 내용은 [README.md](https://github.com/aws/amazon-freertos/blob/main/README.md) 파일을 참조하십시오. 모든 필요한 소스와 라이브러리가 포함된 IDE에서 프로젝트를 생성합니다.

1. [Espressif 시작하기](https://docs.aws.amazon.com/freertos/latest/userguide/getting_started_espressif.html)의 지침에 따라 필요한 GCC 기반 도구 체인을 설정합니다.

1. `freertos/vendors/vendor/boards/board/aws_demos/config_files/aws_demo_config.h`를 열고 `#define CONFIG_CORE_MQTT_MUTUAL_AUTH_DEMO_ENABLED`를 주석으로 처리한 다음 `CONFIG_OTA_MQTT_UPDATE_DEMO_ENABLED` 또는 `CONFIG_OTA_HTTP_UPDATE_DEMO_ENABLED`를 정의합니다.

1. `vendors/espressif/boards/esp32/aws_demos` 디렉터리에서 `make`를 실행하여 데모 프로젝트를 빌드합니다. [Espressif 시작하기](https://docs.aws.amazon.com/freertos/latest/userguide/getting_started_espressif.html)에 설명된 대로 `make flash monitor`를 실행하여 데모 프로그램을 플래시하고 출력을 확인할 수 있습니다.

1. OTA 업데이트 데모를 실행하기 전에:
   + `freertos/vendors/vendor/boards/board/aws_demos/config_files/aws_demo_config.h`를 열고 `#define CONFIG_CORE_MQTT_MUTUAL_AUTH_DEMO_ENABLED`를 주석으로 처리한 다음 `CONFIG_OTA_MQTT_UPDATE_DEMO_ENABLED` 또는 `CONFIG_OTA_HTTP_UPDATE_DEMO_ENABLED`를 정의합니다.
   + `vendors/vendor/boards/board/aws_demos/config_files/ota_demo_config.h`를 열고 다음 위치에서 SHA-256/ECDSA 코드 서명 인증서를 복사합니다.

     ```
     #define otapalconfigCODE_SIGNING_CERTIFICATE [] = "your-certificate-key";
     ```

# Renesas RX65N에서 FreeRTOS OTA 데모를 다운로드, 빌드, 플래시, 실행합니다.
<a name="download-rx65n-ota"></a>

**중요**  <a name="deprecation-message"></a>
이 라이브러리는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

이 장에서는 Renesas RX65N에서 FreeRTOS OTA 데모 애플리케이션을 다운로드, 빌드, 플래시, 실행하는 방법을 보여줍니다.

**Topics**
+ [운영 환경 설정](#download-rx65n-ota-environment)
+ [AWS 리소스 설정](#download-rx65n-ota-setup)
+ [헤더 파일을 가져오고 구성하고 aws\$1demos 및 boot\$1loader를 빌드합니다.](#download-rx65n-ota-import-configure)

## 운영 환경 설정
<a name="download-rx65n-ota-environment"></a>

이 섹션의 절차에서는 다음 환경을 사용합니다.
+ **IDE**: e2 studio 7.8.0, e2 studio 2020-07
+ **도구 체인**: CCRX Compiler v3.0.1
+ **대상 디바이스**: RSKRX65N-2MB
+ **디버거**: E2, E2 Lite 에뮬레이터
+ **소프트웨어**: Renesas Flash Programmer, Renesas 보안 플래시 프로그래머.exe, Tera Term

**하드웨어를 설정하려면**

1. E2 Lite 에뮬레이터 및 USB 직렬 포트를 RX65N 보드 및 PC에 연결합니다.

1. 전원을 RX65N에 연결합니다.

## AWS 리소스 설정
<a name="download-rx65n-ota-setup"></a>

1. FreeRTOS 데모를 실행하려면 AWS IoT 서비스에 액세스할 권한이 있는 IAM 사용자가 있는 AWS 계정이 있어야 합니다. 아직 [AWS계정 및 권한 설정](freertos-prereqs.md#freertos-account-and-permissions)의 단계를 완료하지 않았다면 지금 수행합니다.

1. OTA 업데이트를 설정하려면 [OTA 업데이트 사전 조건](ota-prereqs.md)의 단계를 따릅니다. 특히 [MQTT를 사용한 OTA 업데이트 사전 조건](ota-mqtt-freertos.md)의 단계를 따르십시오.

1. [AWS IoT 콘솔](https://console.aws.amazon.com/iot/home)을 엽니다.

1. 왼쪽 탐색 창에서 **관리**를 선택한 후 **사물**을 선택하여 사물을 하나 생성합니다.

    AWS IoT에서 사물이란 특정 디바이스 또는 논리적 엔터티의 표현입니다. 사물은 물리적 장치 또는 센서일 수 있습니다(예: 전구 또는 벽면 스위치). 또한 애플리케이션의 인스턴스와 같은 논리적 엔터티이거나에 연결되지 AWS IoT는 않지만에 연결된 디바이스(예: 엔진 센서 또는 제어판이 있는 자동차)와 관련된 물리적 엔터티일 수도 있습니다.는 사물을 관리하는 데 도움이 되는 사물 레지스트리를 AWS IoT 제공합니다.

   1. **생성**을 선택하고 **단일 사물 생성**을 선택합니다.

   1. 사물의 **이름**을 입력하고 **다음**을 선택합니다.

   1. [**Create certificate**]를 선택합니다.

   1. 생성된 세 개의 파일을 다운로드한 다음 **활성화**를 선택합니다.

   1. **정책 연결**을 선택합니다.  
![\[다운로드할 파일이 표시된 콘솔 화면\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/download-these-files-rx65n.png)

   1. [디바이스 정책](ota-mqtt-freertos.md#ota-mqtt-freertos-device-policy)에서 생성한 정책을 선택합니다.

      MQTT를 사용하여 OTA 업데이트를 수신하는 각 디바이스는에 사물로 등록해야 하며 AWS IoT 사물에는 나열된 것과 같은 연결된 정책이 있어야 합니다. `"Action"` 및 `"Resource"` 객체의 항목에 대한 자세한 내용은 [AWS IoT 핵심 정책 작업](https://docs.aws.amazon.com/iot/latest/developerguide/iot-policy-actions.html) 및 [AWS IoT 핵심 작업 리소스](https://docs.aws.amazon.com/iot/latest/developerguide/iot-action-resources.html)에서 확인할 수 있습니다.

**참고**
      + `iot:Connect` 권한을 통해 디바이스는 MQTT를 AWS IoT 통해에 연결할 수 있습니다.
      +  AWS IoT 작업(`.../jobs/*`) 항목에 대한 `iot:Subscribe` 및 `iot:Publish` 권한을 사용하면 연결된 디바이스에서 작업 알림과 작업 문서를 수신하고 작업 실행 완료 상태를 게시할 수 있습니다.
      +  AWS IoT OTA 스트림(`.../streams/*`) 주제에 대한 `iot:Subscribe` 및 `iot:Publish` 권한을 통해 연결된 디바이스는 OTA 업데이트 데이터를 가져올 수 있습니다 AWS IoT. MQTT를 통해 펌웨어 업데이트를 수행하려면 이러한 권한이 필요합니다.
      + `iot:Receive` 권한을 통해 AWS IoT Core 는 연결된 디바이스에 해당 주제에 대한 메시지를 게시할 수 있습니다. MQTT 메시지를 전송할 때마다 이 권한을 확인합니다. 이 권한을 사용하면 주제를 현재 구독 중인 클라이언트에 대한 액세스 권한을 취소할 수 있습니다.

1. 코드 서명 프로필을 생성하고 코드 서명 인증서를 등록하려면 AWS

   1. 키와 인증을 생성하려면 [Renesas MCU 펌웨어 업데이트 디자인 정책](https://www.renesas.com/us/en/document/apn/renesas-mcu-firmware-update-design-policy)의 섹션 7.3 "OpenSSL을 이용하여 ECDSA-SHA256 키 페어 생성"을 참조하세요.

   1. [AWS IoT 콘솔](https://console.aws.amazon.com/iot/home)을 엽니다. 왼쪽 탐색 창에서 **관리**를 선택하고 **작업**을 선택합니다. **작업 생성**을 선택하고 **OTA 업데이트 작업 생성**을 선택합니다.

   1. **업데이트할 디바이스 선택**에서 **선택**을 선택하고 이전에 생성한 사물을 선택합니다. **다음**을 선택합니다.

   1. **FreeRTOS OTA 업데이트 작업 생성** 페이지에서 다음을 수행합니다.

      1. **펌웨어 이미지 전송을 위한 프로토콜 선택**에서 **MQTT**를 선택합니다.

      1. **펌웨어 이미지 선택 및 서명**에서 **나를 위해 새 펌웨어 이미지에 서명**을 선택합니다.

      1. **코드 서명 프로필**에서 **생성**을 선택합니다.

      1. **코드 서명 프로필 생성** 창에서 **프로필 이름**을 입력합니다. **디바이스 하드웨어 플랫폼**에서 **Windows 시뮬레이터**를 선택합니다. **코드 서명 인증서**에서 **가져오기**를 선택합니다.

      1. 인증서(`secp256r1.crt`), 인증서 프라이빗 키(`secp256r1.key`) 및 인증서 체인(`ca.crt`)을 찾아 선택합니다.

      1. **디바이스에 있는 코드 서명 인증서의 경로 이름**을 입력합니다. 그런 다음 **생성**을 선택합니다.

1. 에 대한 코드 서명에 대한 액세스 권한을 부여하려면의 단계를 AWS IoT따릅니다[에 대한 코드 서명에 대한 액세스 권한 부여 AWS IoT](code-sign-policy.md).

PC에 Tera Term이 설치되어 있지 않은 경우 [https://ttssh2.osdn.jp/index.html.en](https://ttssh2.osdn.jp/index.html.en)에서 다운로드하여 여기에 표시된 대로 설정할 수 있습니다. 디바이스의 USB 직렬 포트를 PC에 연결했는지 확인하세요.

![\[Tera Term 직렬 포트 설정 창\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/tera-team-rx65n.png)


## 헤더 파일을 가져오고 구성하고 aws\$1demos 및 boot\$1loader를 빌드합니다.
<a name="download-rx65n-ota-import-configure"></a>

시작하려면 최신 버전의 FreeRTOS 패키지를 선택합니다. 그러면 이 패키지가 GitHub에서 다운로드되고 자동으로 프로젝트로 가져와집니다. 그러므로 FreeRTOS 구성과 애플리케이션 코드 작성에 집중할 수 있습니다.

1. e2 studio 시작.

1. **파일**을 선택하고 **가져오기…**를 선택합니다.

1. **Renesas GitHub FreeRTOS(IoT 라이브러리 포함) 프로젝트**를 선택합니다.  
![\[e-squared studio 가져오기 창\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/import-renesas-project-rx65n.png)

1. **추가 버전 확인...**을 선택하여 다운로드 대화 상자를 표시합니다.  
![\[e-squared studio 다운로드 대화 창\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/check-more-version-rx65n.png)

1. 최신 패키지를 선택합니다.  
![\[e-squared studio 모듈 다운로드 대화 창\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/choose-latest-version-rx65n.png)

1. **동의**를 선택하여 최종 사용자 사용권 계약을 수락합니다.  
![\[e-squared studio EULA 대화 창\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/eula-rx65n.png)

1. 다운로드가 완료될 때까지 기다립니다.  
![\[다운로드 진행률 표시줄\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/downloading-rx65n.png)

1. **aws\$1demos** 및 **boot\$1loader** 프로젝트를 선택한 다음 **마침**을 선택하여 프로젝트를 가져옵니다.  
![\[프로젝트 가져오기 창\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/import-projects-rx65n.png)

1. 두 프로젝트 모두 프로젝트 속성을 엽니다. 탐색 창에서 **도구 체인 편집기**를 선택합니다.

   1. **현재 도구 체인**을 선택합니다.

   1. **현재 빌더**를 선택합니다.  
![\[e-squared studio 속성 창\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/project-properties-rx65n.png)

1. 탐색 창에서 **설정**을 선택합니다. **도구 체인** 탭을 선택하고 **버전**을 선택합니다.  
![\[Renesas CCRX 버전 v3.01.00에 대한 도구 체인 통합 설정과 도구 체인을 변경할 수 있는 옵션.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/project-properties-toolchain-rx65n.png)

   **도구 설정** 탭을 선택하고 **변환기**를 확장한 다음 **출력**을 선택합니다. 기본 창에서 **출력 16진수 파일**이 선택되어 있는지 확인한 다음 **출력 파일 유형**을 선택합니다.  
![\[출력 16진수 파일, 출력 파일 유형, 출력 디렉터리 및 파일 분할 옵션과 같은 컴파일러 및 링커 옵션을 보여주는 C/C++ 빌드 구성 설정 창입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/project-properties-settings-rx65n.png)  
![\[스택 분석, 도구 체인 편집기, C/C++ 일반, MCU, 프로젝트 참조 등의 옵션이 포함된 인터페이스 설정 트리\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/project-properties-settings-2-rx65n.png)

1. 부트 로더 프로젝트에서 `projects\renesas\rx65n-rsk\e2studio\boot_loader\src\key\code_signer_public_key.h`를 열고 퍼블릭 키를 입력합니다. 퍼블릭 키를 생성하는 방법에 대한 자세한 내용은 [RX65N에서 Amazon 웹 서비스를 사용하여 FreeRTOS OTA를 구현하는 방법](https://www.renesas.com/us/en/document/apn/rx-family-how-implement-freertos-ota-using-amazon-web-services-rx65n) 및 [Renesas MCU 펌웨어 업데이트 디자인 정책](https://www.renesas.com/us/en/document/apn/renesas-mcu-firmware-update-design-policy) 섹션 7.3 "OpenSSL을 사용하여 ECDSA-SHA256 키 페어 생성하기"를 참조하세요.  
![\[CODE_SIGNER_PUBLIC_KEY에 대한 정의가 있는 C 헤더 파일과 PEM 인코딩 코드 서명자 퍼블릭 키 변수를 보여주는 Code Editor입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/open-bootloader-project-rx65n.png)

   그런 다음 프로젝트를 빌드하여 `boot_loader.mot`를 생성합니다.

1. `aws_demos` 프로젝트를 엽니다.

   1. [AWS IoT 콘솔](https://console.aws.amazon.com/iot/home)을 엽니다.

   1. 왼쪽 탐색 창에서 **설정**을 선택합니다. **디바이스 데이터 엔드포인트** 텍스트 상자에서 사용자 지정 엔드포인트를 기록해 둡니다.

   1. **관리**를 선택하고 **사물**을 선택합니다. 보드의 AWS IoT 사물 이름을 기록해 둡니다.

   1. `aws_demos` 프로젝트에서 `demos/include/aws_clientcredential.h`를 열고 다음 값을 지정합니다.

      ```
      #define clientcredentialMQTT_BROKER_ENDPOINT[] = "Your AWS IoT endpoint";
      #define clientcredentialIOT_THING_NAME "The AWS IoT thing name of your board"
      ```  
![\[AWS IoT 사물 이름 및 브로커 엔드포인트 구성 설정을 보여주는 코드 조각입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/client-credential-rx65n.png)

   1. `tools/certificate_configuration/CertificateConfigurator.html` 파일을 엽니다.

   1. 이전에 다운로드한 인증서 PEM 파일과 프라이빗 키 PEM 파일을 가져옵니다.

   1. **aws\$1clientcredential\$1keys.h 생성 및 저장**을 선택하고 `demos/include/` 디렉터리에서 이 파일로 바꿉니다.  
![\[AWS IoT 콘솔에서 클라이언트 인증서와 프라이빗 키 PEM 파일을 제공하는 필드와 aws_clientcredential_keys.h 파일을 생성하고 저장하는 버튼이 있는 인증서 구성 도구입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/certificate-config-tool-rx65n.png)

   1. `vendors/renesas/boards/rx65n-rsk/aws_demos/config_files/ota_demo_config.h` 파일을 열고 다음 값을 지정합니다.

      ```
      #define otapalconfigCODE_SIGNING_CERTIFICATE [] = "your-certificate-key";
      ```

      여기서 *your-certificate-key*는 `secp256r1.crt` 파일의 값입니다. 인증서의 각 줄 뒤에 ‘\$1’를 추가해야 합니다. `secp256r1.crt` 파일을 생성하는 방법에 대한 자세한 내용은 [RX65N에서 Amazon 웹 서비스를 사용하여 FreeRTOS OTA를 구현하는 방법](https://www.renesas.com/us/en/document/apn/rx-family-how-implement-freertos-ota-using-amazon-web-services-rx65n) 및 [Renesas MCU 펌웨어 업데이트 디자인 정책](https://www.renesas.com/us/en/document/apn/renesas-mcu-firmware-update-design-policy) 섹션 7.3 "OpenSSL을 사용하여 ECDSA-SHA256 키 페어 생성하기"를 참조하세요.  
![\[수정된 인증서 데이터가 있는 PEM 인코딩 코드 서명자 인증서 상수 문자열을 정의하는 C 코드를 보여주는 소스 코드 파일입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/codesigner-cert-rx65n.png)

1. **작업 A: 펌웨어의 초기 버전 설치**

   1. `vendors/renesas/boards/board/aws_demos/config_files/aws_demo_config.h` 파일을 열고 `#define CONFIG_CORE_MQTT_MUTUAL_AUTH_DEMO_ENABLED`를 주석으로 처리한 다음 `CONFIG_OTA_MQTT_UPDATE_DEMO_ENABLED` 또는 `CONFIG_OTA_HTTP_UPDATE_DEMO_ENABLED`를 정의합니다.

   1. `demos/include/ aws_application_version.h` 파일을 열고 펌웨어의 초기 버전을 `0.9.2`로 설정합니다.  
![\[메이저, 마이너 및 빌드 버전 번호에 대한 매크로를 포함하여 애플리케이션의 버전 정의를 보여주는 코드 조각입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/firmware-version-rx65n.png)

   1. **섹션 뷰어**에서 다음 설정을 변경합니다.  
![\[메모리 주소, SU, SI, 레지스터와 같은 섹션 이름, 네트워크 버퍼, 예외 및 작업 버튼과 같은 인터페이스 구성 요소를 보여주는 섹션 뷰어 창입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/section-viewer-rx65n.png)

   1. **빌드**를 선택하여 `aws_demos.mot` 파일을 생성합니다.

1. Renesas 보안 플래시 프로그래머를 사용하여 `userprog.mot` 파일을 생성합니다. `userprog.mot`는 `aws_demos.mot` 및 `boot_loader.mot`의 조합입니다. 이 파일을 RX65N-RSK로 플래시하여 초기 펌웨어를 설치할 수 있습니다.

   1. [https://github.com/renesas/Amazon-FreeRTOS-Tools](https://github.com/renesas/Amazon-FreeRTOS-Tools)를 다운로드하고 `Renesas Secure Flash Programmer.exe`를 엽니다.

   1. **초기 펌웨어** 탭을 선택한 후 다음 파라미터를 설정합니다.
      + **프라이빗 키 경로** - `secp256r1.privatekey`의 위치입니다.
      + **부트 로더 파일 경로** - `boot_loader.mot`(`projects\renesas\rx65n-rsk\e2studio\boot_loader\HardwareDebug`)의 위치입니다.
      + **파일 경로** - `aws_demos.mot`(`projects\renesas\rx65n-rsk\e2studio\aws_demos\HardwareDebug`)의 위치입니다.  
![\[MCU, 펌웨어 확인, 시퀀스 번호, AES 키 경로 및 파일 경로 필드가 있는 보안 플래시 프로그래머 창을 Renesas합니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/secure-flash-rx65n.png)

   1. `init_firmware`라는 이름의 디렉터리를 생성합니다. `userprog.mot`를 생성하여 `init_firmware` 디렉터리에 저장합니다. 생성이 성공했는지 확인합니다.

1. RX65N-RSK에서 초기 펌웨어를 플래시합니다.

   1. [https://www.renesas.com/tw/en/products/software-tools/tools/programmer/renesas-flash-programmer-programming-gui.html](https://www.renesas.com/tw/en/products/software-tools/tools/programmer/renesas-flash-programmer-programming-gui.html)에서 최신 버전의 Renesas 플래시 프로그래머(프로그래밍 GUI)를 다운로드합니다.

   1. `vendors\renesas\rx_mcu_boards\boards\rx65n-rsk\aws_demos\flash_project\erase_from_bank\ erase.rpj` 파일을 열어 뱅크에 있는 데이터를 지웁니다.

   1. **시작**을 선택하여 뱅크를 지웁니다.  
![\[RX 그룹 마이크로컨트롤러 프로젝트 세부 정보, 파일 경로, 지우기, 프로그램, 시작 및 확인 버튼을 사용한 확인과 같은 플래시 작업 옵션을 보여주는 Renesas 플래시 프로그래머 창입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/flash-programmer-erasing-rx65n.png)

   1. `userprog.mot`를 플래시하려면 **찾아보기…**를 선택하고 `init_firmware` 디렉터리로 이동한 다음, `userprog.mot` 파일을 선택하고 **시작**을 선택합니다.  
![\[마이크로컨트롤러 RX 그룹, 프로그램 파일을 탐색하는 옵션, 지우기 및 시작 버튼, 삭제할 선택한 블록의 상태 세부 정보를 포함한 지우기 작업 설정을 보여주는 Renesas 플래시 프로그래머 창입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/flash-programmer-complete-rx65n.png)

1. RX65N-RSK에 펌웨어 버전 0.9.2(초기 버전)가 설치되었습니다. 이제 RX65N-RSK 보드에서 OTA 업데이트를 수신합니다. PC에서 Tera Term을 연 경우 초기 펌웨어가 실행될 때 다음과 같은 내용이 표시됩니다.

   ```
   -------------------------------------------------
   RX65N secure boot program
   -------------------------------------------------
   Checking flash ROM status.
   bank 0 status = 0xff [LIFECYCLE_STATE_BLANK]
   bank 1 status = 0xfc [LIFECYCLE_STATE_INSTALLING]
   bank info = 1. (start bank = 0)
   start installing user program.
   copy secure boot (part1) from bank0 to bank1...OK
   copy secure boot (part2) from bank0 to bank1...OK
   update LIFECYCLE_STATE from [LIFECYCLE_STATE_INSTALLING] to [LIFECYCLE_STATE_VALID]
   bank1(temporary area) block0 erase (to update LIFECYCLE_STATE)...OK
   bank1(temporary area) block0 write (to update LIFECYCLE_STATE)...OK
   swap bank...
   -------------------------------------------------
   RX65N secure boot program
   -------------------------------------------------
   Checking flash ROM status.
   bank 0 status = 0xf8 [LIFECYCLE_STATE_VALID]
   bank 1 status = 0xff [LIFECYCLE_STATE_BLANK]
   bank info = 0. (start bank = 1)
   integrity check scheme = sig-sha256-ecdsa
   bank0(execute area) on code flash integrity check...OK
   jump to user program
   0 1 [ETHER_RECEI] Deferred Interrupt Handler Task started
   1 1 [ETHER_RECEI] Network buffers: 3 lowest 3
   2 1 [ETHER_RECEI] Heap: current 234192 lowest 234192
   3 1 [ETHER_RECEI] Queue space: lowest 8
   4 1 [IP-task] InitializeNetwork returns OK
   5 1 [IP-task] xNetworkInterfaceInitialise returns 0
   6 101 [ETHER_RECEI] Heap: current 234592 lowest 233392
   7 2102 [ETHER_RECEI] prvEMACHandlerTask: PHY LS now 1
   8 3001 [IP-task] xNetworkInterfaceInitialise returns 1
   9 3092 [ETHER_RECEI] Network buffers: 2 lowest 2
   10 3092 [ETHER_RECEI] Queue space: lowest 7
   11 3092 [ETHER_RECEI] Heap: current 233320 lowest 233320
   12 3193 [ETHER_RECEI] Heap: current 233816 lowest 233120
   13 3593 [IP-task] vDHCPProcess: offer c0a80a09ip
   14 3597 [ETHER_RECEI] Heap: current 233200 lowest 233000
   15 3597 [IP-task] vDHCPProcess: offer c0a80a09ip
   16 3597 [IP-task] IP Address: 192.168.10.9
   17 3597 [IP-task] Subnet Mask: 255.255.255.0
   18 3597 [IP-task] Gateway Address: 192.168.10.1
   19 3597 [IP-task] DNS Server Address: 192.168.10.1
   20 3600 [Tmr Svc] The network is up and running
   21 3622 [Tmr Svc] Write certificate...
   22 3697 [ETHER_RECEI] Heap: current 232320 lowest 230904
   23 4497 [ETHER_RECEI] Heap: current 226344 lowest 225944
   24 5317 [iot_thread] [INFO ][DEMO][5317] ---------STARTING DEMO---------
   
   25 5317 [iot_thread] [INFO ][INIT][5317] SDK successfully initialized.
   26 5317 [iot_thread] [INFO ][DEMO][5317] Successfully initialized the demo. Network type for the demo: 4
   27 5317 [iot_thread] [INFO ][MQTT][5317] MQTT library successfully initialized.
   28 5317 [iot_thread] [INFO ][DEMO][5317] OTA demo version 0.9.2
   
   29 5317 [iot_thread] [INFO ][DEMO][5317] Connecting to broker...
   
   30 5317 [iot_thread] [INFO ][DEMO][5317] MQTT demo client identifier is rx65n-gr-rose (length 13).
   31 5325 [ETHER_RECEI] Heap: current 206944 lowest 206504
   32 5325 [ETHER_RECEI] Heap: current 206440 lowest 206440
   33 5325 [ETHER_RECEI] Heap: current 206240 lowest 206240
   38 5334 [ETHER_RECEI] Heap: current 190288 lowest 190288
   39 5334 [ETHER_RECEI] Heap: current 190088 lowest 190088
   40 5361 [ETHER_RECEI] Heap: current 158512 lowest 158168
   41 5363 [ETHER_RECEI] Heap: current 158032 lowest 158032
   42 5364 [ETHER_RECEI] Network buffers: 1 lowest 1
   43 5364 [ETHER_RECEI] Heap: current 156856 lowest 156856
   44 5364 [ETHER_RECEI] Heap: current 156656 lowest 156656
   46 5374 [ETHER_RECEI] Heap: current 153016 lowest 152040
   47 5492 [ETHER_RECEI] Heap: current 141464 lowest 139016
   48 5751 [ETHER_RECEI] Heap: current 140160 lowest 138680
   49 5917 [ETHER_RECEI] Heap: current 138280 lowest 138168
   59 7361 [iot_thread] [INFO ][MQTT][7361] Establishing new MQTT connection.
   62 7428 [iot_thread] [INFO ][MQTT][7428] (MQTT connection 81cfc8, CONNECT operation 81d0e8) Wait complete with result SUCCESS.
   63 7428 [iot_thread] [INFO ][MQTT][7428] New MQTT connection 4e8c established.
   64 7430 [iot_thread] [OTA_AgentInit_internal] OTA Task is Ready.
   65 7430 [OTA Agent T] [prvOTAAgentTask] Called handler. Current State [Ready] Event [Start] New state [RequestingJob]
   66 7431 [OTA Agent T] [INFO ][MQTT][7431] (MQTT connection 81cfc8) SUBSCRIBE operation scheduled.
   67 7431 [OTA Agent T] [INFO ][MQTT][7431] (MQTT connection 81cfc8, SUBSCRIBE operation 818c48) Waiting for operation completion.
   68 7436 [ETHER_RECEI] Heap: current 128248 lowest 127992
   69 7480 [OTA Agent T] [INFO ][MQTT][7480] (MQTT connection 81cfc8, SUBSCRIBE operation 818c48) Wait complete with result SUCCESS.
   70 7480 [OTA Agent T] [prvSubscribeToJobNotificationTopics] OK: $aws/things/rx65n-gr-rose/jobs/$next/get/accepted
   71 7481 [OTA Agent T] [INFO ][MQTT][7481] (MQTT connection 81cfc8) SUBSCRIBE operation scheduled.
   72 7481 [OTA Agent T] [INFO ][MQTT][7481] (MQTT connection 81cfc8, SUBSCRIBE operation 818c48) Waiting for operation completion.
   73 7530 [OTA Agent T] [INFO ][MQTT][7530] (MQTT connection 81cfc8, SUBSCRIBE operation 818c48) Wait complete with result SUCCESS.
   74 7530 [OTA Agent T] [prvSubscribeToJobNotificationTopics] OK: $aws/things/rx65n-gr-rose/jobs/notify-next
   75 7530 [OTA Agent T] [prvRequestJob_Mqtt] Request #0
   76 7532 [OTA Agent T] [INFO ][MQTT][7532] (MQTT connection 81cfc8) MQTT PUBLISH operation queued.
   77 7532 [OTA Agent T] [INFO ][MQTT][7532] (MQTT connection 81cfc8, PUBLISH operation 818b80) Waiting for operation completion.
   78 7552 [OTA Agent T] [INFO ][MQTT][7552] (MQTT connection 81cfc8, PUBLISH operation 818b80) Wait complete with result SUCCESS.
   79 7552 [OTA Agent T] [prvOTAAgentTask] Called handler. Current State [RequestingJob] Event [RequestJobDocument] New state [WaitingForJob]
   80 7552 [OTA Agent T] [prvParseJSONbyModel] Extracted parameter [ clientToken: 0:rx65n-gr-rose ]
   81 7552 [OTA Agent T] [prvParseJSONbyModel] parameter not present: execution
   82 7552 [OTA Agent T] [prvParseJSONbyModel] parameter not present: jobId
   83 7552 [OTA Agent T] [prvParseJSONbyModel] parameter not present: jobDocument
   84 7552 [OTA Agent T] [prvParseJSONbyModel] parameter not present: afr_ota
   85 7552 [OTA Agent T] [prvParseJSONbyModel] parameter not present: protocols
   86 7552 [OTA Agent T] [prvParseJSONbyModel] parameter not present: files
   87 7552 [OTA Agent T] [prvParseJSONbyModel] parameter not present: filepath
   99 7651 [ETHER_RECEI] Heap: current 129720 lowest 127304
   100 8430 [iot_thread] [INFO ][DEMO][8430] State: Ready  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   101 9430 [iot_thread] [INFO ][DEMO][9430] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   102 10430 [iot_thread] [INFO ][DEMO][10430] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   103 11430 [iot_thread] [INFO ][DEMO][11430] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   104 12430 [iot_thread] [INFO ][DEMO][12430] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   105 13430 [iot_thread] [INFO ][DEMO][13430] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   106 14430 [iot_thread] [INFO ][DEMO][14430] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   107 15430 [iot_thread] [INFO ][DEMO][15430] State: WaitingForJob  Received: 1   Queued: 0   Processed: 0   Dropped: 0
   ```

1. **작업 B: 펌웨어 버전 업데이트**

   1. `demos/include/aws_application_version.h` 파일을 열고 `APP_VERSION_BUILD` 토큰 값을 `0.9.3`으로 높입니다.

   1. 프로젝트를 다시 빌드합니다.

1. Renesas 보안 플래시 프로그래머로 `userprog.rsu` 파일을 생성하여 펌웨어의 버전을 업데이트합니다.

   1. `Amazon-FreeRTOS-Tools\Renesas Secure Flash Programmer.exe` 파일을 엽니다.

   1. **펌웨어 업데이트** 탭을 선택한 후 다음 파라미터를 설정합니다.
      + **파일 경로** - `aws_demos.mot` 파일(`projects\renesas\rx65n-rsk\e2studio\aws_demos\HardwareDebug`)의 위치입니다.

   1. `update _firmware`이라는 디렉터리를 생성합니다. `userprog.rsu`를 생성하여 `update_firmware` 디렉터리에 저장합니다. 생성이 성공했는지 확인합니다.  
![\[MCU 선택, 펌웨어 확인 유형, 시퀀스 번호, AES MAC 키 필드 및 보안 펌웨어 생성을 위한 파일 경로 입력이 포함된 보안 플래시 프로그래머 창을 Renesas합니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/update-firmware-rx65n.png)

1. [업데이트를 저장할 Amazon S3 버킷 생성](dg-ota-bucket.md)에 설명된 대로 펌웨어 업데이트 `userproj.rsu`를 Amazon S3 버킷에 업로드합니다.  
![\[폴더, 업로드, 버전 및 권한 옵션이 있는 Amazon S3 버킷 관리 인터페이스\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/upload-firmware-rx65n.png)

1. RX65N-RSK 펌웨어를 업데이트하는 작업을 생성합니다.

   AWS IoT 작업은 하나 이상의 연결된 디바이스에 보류 중인 [작업을](https://docs.aws.amazon.com/iot/latest/developerguide/iot-jobs.html) 알리는 서비스입니다. 작업을 사용하여 디바이스 플릿을 관리하거나, 디바이스의 펌웨어 및 보안 인증서를 업데이트하거나, 디바이스 재시작 및 진단과 같은 관리 작업을 수행할 수 있습니다.

   1. [AWS IoT 콘솔](https://console.aws.amazon.com/iotv2/)에 로그인합니다. 탐색 창에서 **관리**를 선택하고 **작업**을 선택합니다.

   1. **작업 생성**을 선택하고 **OTA 업데이트 작업 생성**을 선택합니다. 사물을 선택하고 **다음**을 선택합니다.

   1. 다음과 같이 FreeRTOS OTA 업데이트 작업을 생성합니다.
      + **MQTT**를 선택합니다.
      + 이전 섹션에서 생성한 코드 서명 프로필을 선택합니다.
      + Amazon S3 버킷에 업로드한 펌웨어 이미지를 선택합니다.
      + **디바이스에 있는 펌웨어 이미지의 경로 이름**에 **test**를 입력합니다.
      + 이전 섹션에서 생성한 IAM 역할을 선택합니다.

   1. **다음**을 선택합니다.  
![\[새 펌웨어에 서명하고, 이전에 서명된 펌웨어를 선택하고, 사용자 지정 서명된 펌웨어를 사용하고, 코드 서명 프로파일, 펌웨어 이미지 파일, 디바이스 경로 및 OTA 업데이트 작업을 위한 IAM 역할을 지정하는 옵션이 포함된 펌웨어 이미지 서명 및 OTA 업데이트 설정입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/create-job-next-rx65n.png)

   1. ID를 입력한 다음 **생성**을 선택합니다.

1. Tera Term을 다시 열어 펌웨어가 OTA 데모 버전 0.9.3으로 성공적으로 업데이트되었는지 확인합니다.  
![\[브로커에 대한 스레드의 초기화 및 연결을 보여주는 명령줄 출력입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/update-successful-rx65n.png)

1.  AWS IoT 콘솔에서 작업 상태가 **성공**인지 확인합니다.  
![\[1개의 리소스가 성공했음을 보여주는 AFR OTA-demo 테스트 작업 개요입니다.\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/completed-succeeded-rx65n.png)

# 자습서: FreeRTOS Bluetooth Low Energy를 사용하여 Espressif ESP32 OTA 업데이트 수행
<a name="ota-updates-esp32-ble"></a>

**중요**  <a name="deprecation-message"></a>
이 라이브러리는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

이 자습서에서는 Android 디바이스의 MQTT 블루투스 로우 에너지 프록시에 연결된 Espressif ESP32 마이크로컨트롤러를 업데이트하는 방법을 보여줍니다. 무선(OTA) 업데이트 작업을 사용하여 AWS IoT Over-the-air 업데이트합니다. 디바이스는 Android 데모 앱에 입력된 Amazon Cognito 자격 증명을 AWS IoT 사용하여에 연결합니다. 권한이 부여된 운영자가 클라우드에서 OTA 업데이트를 시작합니다. 디바이스가 Android 데모 앱을 통해 연결되면 OTA 업데이트가 시작되고 디바이스의 펌웨어가 업데이트됩니다.

FreeRTOS 버전 2019.06.00 메이저 이상에는 Wi-Fi 프로비저닝 및 AWS IoT 서비스에 대한 보안 연결에 사용할 수 있는 Bluetooth Low Energy MQTT 프록시 지원이 포함되어 있습니다. 블루투스 로우 에너지 기능을 사용하면 Wi-Fi 없이도 모바일 디바이스와 페어링하여 연결할 수 있는 저전력 디바이스를 구축할 수 있습니다. 디바이스는 일반 액세스 프로필(GAP) 및 일반 속성(GATT) 프로필을 사용하는 Android 또는 iOS 블루투스 로우 에너지 SDK를 통해 연결하여 MQTT로 통신할 수 있습니다.

블루투스 로우 에너지를 통한 OTA 업데이트를 허용하기 위해 따라야 할 단계는 다음과 같습니다.

1. **스토리지 구성:** Amazon S3 버킷 및 정책을 생성하고 업데이트를 수행할 수 있는 IAM 사용자를 구성합니다.

1. **코드 서명 인증서 생성:** 서명 인증서를 생성하고 IAM 사용자가 펌웨어 업데이트에 서명하도록 허용합니다.

1. **Amazon Cognito 인증 구성:** 보안 인증 정보 공급자, 사용자 풀, 애플리케이션의 사용자 풀 액세스 권한을 생성합니다.

1. **FreeRTOS 구성:** 블루투스 로우 에너지, 클라이언트 보안 인증 정보 및 코드 서명 퍼블릭 인증서를 설정합니다.

1. **Android 앱 구성:** 보안 인증 정보 공급자, 사용자 풀을 설정하고 Android 디바이스에 애플리케이션을 배포합니다.

1. **OTA 업데이트 스크립트 실행:** OTA 업데이트를 시작하려면 OTA 업데이트 스크립트를 사용합니다.

업데이트 작동 방식에 대한 자세한 내용은 [FreeRTOS 무선 업데이트(OTA)](freertos-ota-dev.md) 섹션을 참조하세요. 블루투스 로우 에너지 MQTT 프록시 기능을 설정하는 방법에 대한 자세한 내용은 Richard Kang의 [Using 블루투스 로우 에너지 with FreeRTOS on Espressif ESP32](https://aws.amazon.com/blogs/iot/using-bluetooth-low-energy-with-amazon-freertos-on-espressif-esp32/) 게시물을 참조하세요.

## 사전 조건
<a name="ota-updates-esp32-ble-prereq"></a>

이 자습서의 단계를 수행하려면 다음 리소스가 필요합니다.
+ ESP32 개발 보드.
+ MicroUSB-USB A 케이블.
+  AWS 계정(프리 티어면 충분함).
+ Android v 6.0 이상 및 블루투스 버전 4.2 이상이 탑재된 Android 스마트폰.

개발용 컴퓨터에는 다음이 필요합니다.
+ Xtensa 도구 체인과 FreeRTOS 소스 코드 및 예제를 위한 충분한 디스크 공간(최대 500Mb).
+ Android Studio 설치.
+ [AWS CLI](https://aws.amazon.com/cli/) 설치.
+ Python3 설치.
+ [Python용 boto3 AWS Software 개발자 키트(SDK)](https://github.com/boto/boto3)입니다.

이 자습서의 단계에서는 Xtensa 도구 체인, ESP-IDF 및 FreeRTOS 코드가 홈 디렉터리의 `/esp` 디렉터리에 설치되어 있다고 가정합니다. `$PATH` 변수에 `~/esp/xtensa-esp32-elf/bin`을 추가해야 합니다.

## 1단계: 스토리지 구성
<a name="ota-updates-esp32-ble-step1"></a>

1. 펌웨어 이미지를 보관할 버전 관리가 활성화된 [업데이트를 저장할 Amazon S3 버킷 생성](dg-ota-bucket.md).

1. [OTA 업데이트 서비스 역할 생성](create-service-role.md) 단계를 수행하고 이 역할에 다음 관리형 정책을 추가합니다.
   + AWSIotLogging
   + AWSIotRuleActions
   + AWSIotThingsRegistration
   + AWSFreeRTOSOTAUpdate

1. OTA 업데이트를 수행할 수 있는 [사용자를 생성](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html)합니다. 이 사용자는 계정에 서명하여 IoT 디바이스에 펌웨어 업데이트를 배포할 수 있으며 모든 디바이스에서 OTA 업데이트를 수행할 수 있습니다. 액세스는 신뢰할 수 있는 엔터티로만 제한되어야 합니다.

1. [OTA 사용자 정책 생성](create-ota-user-policy.md) 단계를 수행한 후 IAM 사용자에 연결합니다.

## 2단계: 코드 서명 인증서 생성
<a name="ota-updates-esp32-ble-step2"></a>

1. 펌웨어 이미지를 보관할 버전 관리가 활성화된 Amazon S3 버킷을 생성합니다.

1. 펌웨어 서명에 사용할 수 있는 코드 서명 인증서를 생성합니다. 인증서를 가져올 때 인증서 Amazon 리소스 이름(ARN)을 적어 둡니다.

   ```
   aws acm import-certificate --profile=ota-update-user --certificate file://ecdsasigner.crt --private-key file://ecdsasigner.key
   ```

   출력 예시:

   ```
   {
   "CertificateArn": "arn:aws:acm:us-east-1:<account>:certificate/<certid>"
   }
   ```

   나중에 ARN을 사용하여 서명 프로필을 생성할 것입니다. 원하는 경우 다음 명령을 사용하여 지금 프로필을 만들 수 있습니다.

   ```
   aws signer put-signing-profile --profile=ota-update-user --profile-name esp32Profile --signing-material certificateArn=arn:aws:acm:us-east-1:account:certificate/certid --platform AmazonFreeRTOS-Default --signing-parameters certname=/cert.pem
   ```

   출력 예시:

   ```
   {
   "arn": "arn:aws:signer::<account>:/signing-profiles/esp32Profile"
   }
   ```

## 3단계: Amazon Cognito 인증 구성
<a name="ota-updates-esp32-ble-step3"></a>

**AWS IoT 정책 생성**

1. [AWS IoT 콘솔](https://console.aws.amazon.com/iot/)에 로그인합니다.

1. 콘솔의 오른쪽 상단에서 **내 계정**을 선택합니다. **계정 설정**에서 12자리 계정 ID를 기록해 둡니다.

1. 왼쪽 탐색 창에서 **설정**을 선택합니다. **디바이스 데이터 엔드포인트**에서 엔드포인트 값을 기록해 둡니다. 엔드포인트는 `xxxxxxxxxxxxxx.iot.us-west-2.amazonaws.com`과 비슷합니다. 이 예제에서 AWS 리전은 "us-west-2"입니다.

1. 왼쪽 탐색 창에서 **보안**을 선택하고 **정책**를 선택한 다음 **생성**을 선택합니다. 계정에 아무 정책도 없는 경우 “아직 정책이 없습니다.” 라는 메시지가 표시되고 **정책 생성**을 선택할 수 있습니다.

1. 정책의 이름을 입력합니다(예: "esp32\$1mqtt\$1proxy\$1iot\$1policy").

1. **설명문 추가** 섹션에서 **고급 모드**를 선택합니다. 다음 JSON을 복사하여 정책 편집기 창에 붙여 넣습니다. `aws-account-id`를 계정 ID로 바꾸고 `aws-region`을 현재 리전(예: "us-west-2")으로 바꿉니다.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "iot:Connect",
               "Resource": "arn:aws:iot:us-east-1:123456789012:*"
           },
           {
               "Effect": "Allow",
               "Action": "iot:Publish",
               "Resource": "arn:aws:iot:us-east-1:123456789012:*"
           },
           {
               "Effect": "Allow",
               "Action": "iot:Subscribe",
               "Resource": "arn:aws:iot:us-east-1:123456789012:*"
           },
           {
               "Effect": "Allow",
               "Action": "iot:Receive",
               "Resource": "arn:aws:iot:us-east-1:123456789012:*"
           }
       ]
   }
   ```

------

1. **생성(Create)**을 선택합니다.

**AWS IoT 사물 생성**

1. [AWS IoT 콘솔](https://console.aws.amazon.com/iot/)에 로그인합니다.

1. 왼쪽 탐색 창에서 **관리**를 선택한 후 **사물**을 선택합니다.

1. 오른쪽 상단에서 **생성**을 선택합니다. 계정에 등록된 사물이 없는 경우 “아직 등록한 사물이 없습니다.”라는 메시지가 표시되고 **사물 등록**을 선택할 수 있습니다.

1. ** AWS IoT 사물 생성** 페이지에서 **단일 사물 생성을** 선택합니다.

1. **디바이스를 사물 레지스트리에 추가** 페이지에 사물의 이름을 입력합니다(예: "esp32-ble"). 영숫자, 하이픈(-) 및 밑줄() 문자만 허용됩니다. **다음**을 선택합니다.

1. **사물에 대한 인증서 추가** 페이지의 **원클릭 인증서 생성**에서 **인증서 생성**을 선택합니다. 인증 및 권한 부여에 Amazon Cognito 보안 인증 정보를 사용하는 BLE 프록시 모바일 앱을 사용하기 때문에 디바이스 인증서가 필요하지 않습니다.

**Amazon Cognito 앱 클라이언트 생성**

1. [Amazon Cognito 콘솔](https://console.aws.amazon.com/cognito/users/)에 로그인합니다.

1. 오른쪽 상단의 탐색 배너에서 **사용자 풀 생성**을 선택합니다.

1. 풀 이름을 입력합니다(예: "esp32\$1mqtt\$1proxy\$1user\$1pool").

1. [**Review defaults**]를 선택합니다.

1. **앱 클라이언트**에서 **앱 클라이언트 추가**를 선택한 다음 **앱 클라이언트 추가**를 선택합니다.

1. 앱 클라이언트 이름을 입력합니다(예: "mqtt\$1app\$1client").

1. **클라이언트 비밀 생성**이 선택되어 있는지 확인합니다.

1. **앱 클라이언트 생성**을 선택합니다.

1. **풀 세부 정보로 돌아가기**를 선택합니다.

1. 사용자 풀의 **검토** 페이지에서 **사용자 생성**을 선택합니다. “사용자 풀이 성공적으로 생성되었습니다.”라는 메시지가 표시됩니다. 풀 ID를 기록해 둡니다.

1. 탐색 창에서 **앱 클라이언트**를 선택합니다.

1. **세부 정보 표시**를 선택합니다. 앱 클라이언트 ID와 앱 클라이언트 비밀을 기록해 둡니다.

**Amazon Cognito ID 풀 생성**

1. [Amazon Cognito 콘솔](https://console.aws.amazon.com/cognito/federated)에 로그인합니다.

1. **새 자격 증명 풀 생성**을 선택합니다.

1. ID 풀의 이름을 입력합니다(예: "mqtt\$1proxy\$1identity\$1pool").

1. **인증 공급자**를 확장합니다.

1. **Cognito** 탭을 선택합니다.

1. 이전 단계에서 기록해 둔 사용자 풀 ID와 앱 클라이언트 ID를 입력합니다.

1. **풀 생성**을 선택합니다.

1. 다음 페이지에서 인증된 자격 증명 및 인증되지 않은 자격 증명에 대한 새 역할을 생성하려면 **허용**을 선택합니다.

1. 자격 증명 풀 ID(`us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` 형식)를 기록해 둡니다.

**IAM 정책을 인증된 자격 증명에 연결**

1. [Amazon Cognito 콘솔](https://console.aws.amazon.com/cognito/federated)을 엽니다.

1. 방금 생성한 자격 증명 풀(예: "mqtt\$1proxy\$1identity\$1pool")을 선택합니다.

1. **자격 증명 풀 편집**을 선택합니다.

1. 인증된 역할에 할당된 IAM 역할을 기록해 둡니다(예: "Cognito\$1mqtt\$1proxy\$1identity\$1poolAuth\$1Role").

1. [IAM 콘솔(IAM console)](https://console.aws.amazon.com/iam/home)을 엽니다.

1. 탐색 창에서 **역할**을 선택합니다.

1. 할당된 역할(예: "Cognito\$1mqtt\$1proxy\$1identity\$1poolAuth\$1Role")을 검색하여 선택합니다.

1. **인라인 정책 추가**를 선택한 후 **JSON**을 선택합니다.

1. 다음 정책을 입력합니다.

------
#### [ JSON ]

****  

   ```
   {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
          {
             "Effect": "Allow",
             "Action": [
                "iot:AttachPolicy",
                "iot:AttachPrincipalPolicy",
                "iot:Connect",
                "iot:Publish",
                "iot:Subscribe"
             ],
             "Resource": "*"
          }]
       }
   ```

------

1. **정책 검토**를 선택합니다.

1. 정책 이름을 입력합니다(예: "mqttProxyCognitoPolicy").

1. **정책 생성**을 선택합니다.

## 4단계: Amazon Freertos 구성
<a name="ota-updates-esp32-ble-step4"></a>

1. [FreeRTOS GitHub 리포지토리](https://github.com/aws/amazon-freertos)에서 최신 버전의 Amazon FreeRTOS 코드를 다운로드합니다.

1. OTA 업데이트 데모를 활성화하려면 [Espressif ESP32-DevKitC 및 ESP-WROVER-KIT 시작하기](getting_started_espressif.md)의 단계를 따릅니다.

1. 다음 파일을 추가로 수정합니다.

   1. `vendors/espressif/boards/esp32/aws_demos/config_files/aws_demo_config.h`를 열고 `CONFIG_OTA_UPDATE_DEMO_ENABLED`를 정의합니다.

   1. `vendors/espressif/boards/esp32/aws_demos/common/config_files/aws_demo_config.h`를 열고 `democonfigNETWORK_TYPES`를 `AWSIOT_NETWORK_TYPE_BLE`로 변경합니다.

   1. `demos/include/aws_clientcredential.h`를 열고 `clientcredentialMQTT_BROKER_ENDPOINT`의 엔드포인트 URL을 입력합니다.

      `clientcredentialIOT_THING_NAME`의 사물 이름을 입력합니다(예: "esp32-ble"). Amazon Cognito 보안 인증 정보를 사용할 때는 인증서를 추가할 필요가 없습니다.

   1. `vendors/espressif/boards/esp32/aws_demos/config_files/aws_iot_network_config.h`를 열고 `configSUPPORTED_NETWORKS` 및 `configENABLED_NETWORKS`를 `AWSIOT_NETWORK_TYPE_BLE`만 포함하도록 변경합니다.

   1. `vendors/vendor/boards/board/aws_demos/config_files/ota_demo_config.h` 파일을 열고 인증서를 입력합니다.

      ```
      #define otapalconfigCODE_SIGNING_CERTIFICATE [] = "your-certificate-key";
      ```

   애플리케이션이 시작하여 데모 버전을 출력합니다.

   ```
   11 13498 [iot_thread] [INFO ][DEMO][134980] Successfully initialized the demo. Network type for the demo: 2
   12 13498 [iot_thread] [INFO ][MQTT][134980] MQTT library successfully initialized.
   13 13498 [iot_thread] OTA demo version 0.9.20
   14 13498 [iot_thread] Creating MQTT Client...
   ```

## 5단계: Android 앱 구성
<a name="ota-updates-esp32-ble-step5"></a>

1. [amazon-freertos-ble-android-sdk](https://github.com/aws/amazon-freertos-ble-android-sdk) GitHub 리포지토리에서 Android 블루투스 로우 에너지 SDK 및 샘플 앱을 다운로드합니다.

1. `app/src/main/res/raw/awsconfiguration.json` 파일을 열고 다음 JSON 샘플의 지침에 따라 Pool Id, Region, AppClientId, AppClientSecret을 입력합니다.

   ```
   {
     "UserAgent": "MobileHub/1.0",
     "Version": "1.0",
     "CredentialsProvider": {
       "CognitoIdentity": {
         "Default": {
           "PoolId": "Cognito->Manage Identity Pools->Federated Identities->mqtt_proxy_identity_pool->Edit Identity Pool->Identity Pool ID",
           "Region": "Your region (for example us-east-1)"
         }
       }
     },
   
     "IdentityManager": {
       "Default": {}
     },
   
     "CognitoUserPool": {
       "Default": {
         "PoolId": "Cognito-> Manage User Pools -> esp32_mqtt_proxy_user_pool -> General Settings -> PoolId",
         "AppClientId": "Cognito-> Manage User Pools -> esp32_mqtt_proxy_user_pool -> General Settings -> App clients ->Show Details",
         "AppClientSecret": "Cognito-> Manage User Pools -> esp32_mqtt_proxy_user_pool -> General Settings -> App clients ->Show Details",
         "Region": "Your region (for example us-east-1)"
       }
     }
   }
   ```

1. `app/src/main/java/software/amazon/freertos/DemoConstants.java`를 열고 이전에 생성한 정책 이름(예: *esp32\$1mqtt\$1proxy\$1iot\$1policy*)과 리전(예: *us-east-1*)을 입력합니다.

1. 데모 앱을 빌드하고 설치합니다.

   1. Android Studio에서 **빌드**를 선택한 다음 **모바일 앱 만들기**를 선택합니다.

   1. **실행**을 선택한 다음 **앱 실행**을 선택합니다. Android Studio의 logcat 창으로 이동하여 로그 메시지를 모니터링할 수 있습니다.

   1. Android 디바이스의 로그인 화면에서 계정을 생성합니다.

   1. 사용자를 생성합니다. 사용자가 이미 있는 경우 보안 인증 정보를 입력합니다.

   1. Amazon FreeRTOS 데모가 디바이스 위치에 액세스할 수 있도록 허용합니다.

   1. 블루투스 로우 에너지 디바이스를 스캔합니다.

   1. 찾은 디바이스의 슬라이더를 **켜기**로 이동합니다.

   1. ESP32용 직렬 포트 디버그 콘솔에서 **y**를 누릅니다.

   1. **페어링 및 연결**을 선택합니다.

1. 연결이 설정되면 **더 보기...** 링크가 활성화됩니다. 연결이 완료되면 Android 디바이스 logcat에서 연결 상태가 "BLE\$1CONNECTED"로 변경되어야 합니다.

   ```
   2019-06-06 20:11:32.160 23484-23497/software.amazon.freertos.demo I/FRD: BLE connection state changed: 0; new state: BLE_CONNECTED
   ```

1. 메시지를 전송하기 전에 Amazon FreeRTOS 디바이스와 Android 디바이스가 MTU를 협상합니다. logcat에 다음 결과가 표시됩니다.

   ```
   2019-06-06 20:11:46.720 23484-23497/software.amazon.freertos.demo I/FRD: onMTUChanged : 512 status: Success
   ```

1. 디바이스가 앱에 연결되고 MQTT 프록시를 사용하여 MQTT 메시지를 보내기 시작합니다. 디바이스가 통신할 수 있는지 확인하려면 MQTT\$1CONTROL 특성 데이터 값을 01로 변경되어야 합니다.

   ```
   2019-06-06 20:12:28.752 23484-23496/software.amazon.freertos.demo D/FRD: <-<-<- Writing to characteristic: MQTT_CONTROL with data: 01
   2019-06-06 20:12:28.839 23484-23496/software.amazon.freertos.demo D/FRD: onCharacteristicWrite for: MQTT_CONTROL; status: Success; value: 01
   ```

1. 디바이스가 페어링되면 ESP32 콘솔에 프롬프트가 표시됩니다. BLE를 활성화하려면 **y**를 누릅니다. 이 단계를 수행할 때까지 데모는 작동하지 않습니다.

   ```
   E (135538) BT_GATT: GATT_INSUF_AUTHENTICATION: MITM Required
   W (135638) BT_L2CAP: l2cble_start_conn_update, the last connection update command still pending.
   E (135908) BT_SMP: Value for numeric comparison = 391840
   15 13588 [InputTask] Numeric comparison:391840
   16 13589 [InputTask] Press 'y' to confirm
   17 14078 [InputTask] Key accepted
   W (146348) BT_SMP: FOR LE SC LTK IS USED INSTEAD OF STK
   18 16298 [iot_thread] Connecting to broker...
   19 16298 [iot_thread] [INFO ][MQTT][162980] Establishing new MQTT connection.
   20 16298 [iot_thread] [INFO ][MQTT][162980] (MQTT connection 0x3ffd5754, CONNECT operation 0x3ffd586c) Waiting for operation completion.
   21 16446 [iot_thread] [INFO ][MQTT][164450] (MQTT connection 0x3ffd5754, CONNECT operation 0x3ffd586c) Wait complete with result SUCCESS.
   22 16446 [iot_thread] [INFO ][MQTT][164460] New MQTT connection 0x3ffc0ccc established.
   23 16446 [iot_thread] Connected to broker.
   ```

## 6단계: OTA 업데이트 스크립트 실행
<a name="ota-updates-esp32-ble-step6"></a>

1. 사전 조건을 설치하려면 다음 명령을 실행합니다.

   ```
   pip3 install boto3
   ```

   ```
   pip3 install pathlib
   ```

1. `demos/include/aws_application_version.h`에서 FreeRTOS 애플리케이션 버전을 높입니다.

1. 새 .bin 파일을 빌드합니다.

1. python 스크립트 [ start\$1ota.py](https://github.com/aws-samples/amazon-freertos-ota-scripts/blob/master/scripts/start_ota.py)를 다운로드합니다. 스크립트에 대한 도움말을 보려면 터미널 창에서 다음 명령을 실행합니다.

   ```
   python3 start_ota.py -h
   ```

   다음과 같은 내용이 표시되어야 합니다.

   ```
   usage: start_ota.py [-h] --profile PROFILE [--region REGION]
                       [--account ACCOUNT] [--devicetype DEVICETYPE] --name NAME
                       --role ROLE --s3bucket S3BUCKET --otasigningprofile
                       OTASIGNINGPROFILE --signingcertificateid
                       SIGNINGCERTIFICATEID [--codelocation CODELOCATION]
   Script to start OTA update
   optional arguments:
   -h, --help            show this help message and exit
   --profile PROFILE     Profile name created using aws configure
   --region REGION       Region
   --account ACCOUNT     Account ID
   --devicetype DEVICETYPE thing|group
   --name NAME           Name of thing/group
   --role ROLE           Role for OTA updates
   --s3bucket S3BUCKET   S3 bucket to store firmware updates
   --otasigningprofile OTASIGNINGPROFILE
                         Signing profile to be created or used
   --signingcertificateid SIGNINGCERTIFICATEID
                         certificate id (not arn) to be used
   --codelocation CODELOCATION
                         base folder location (can be relative)
   ```

1. 제공된 CloudFormation 템플릿을 사용하여 리소스를 생성한 경우 다음 명령을 실행합니다.

   ```
   python3 start_ota_stream.py --profile otausercf --name esp32-ble --role ota_ble_iot_role-sample --s3bucket afr-ble-ota-update-bucket-sample --otasigningprofile abcd --signingcertificateid certificateid
   ```

   ESP32 디버그 콘솔에서 업데이트가 시작되는 것을 확인할 수 있습니다.

   ```
   38 2462 [OTA Task] [prvParseJobDoc] Job was accepted. Attempting to start transfer.
   ---
   49 2867 [OTA Task] [prvIngestDataBlock] Received file block 1, size 1024
   50 2867 [OTA Task] [prvIngestDataBlock] Remaining: 1290
   51 2894 [OTA Task] [prvIngestDataBlock] Received file block 2, size 1024
   52 2894 [OTA Task] [prvIngestDataBlock] Remaining: 1289
   53 2921 [OTA Task] [prvIngestDataBlock] Received file block 3, size 1024
   54 2921 [OTA Task] [prvIngestDataBlock] Remaining: 1288
   55 2952 [OTA Task] [prvIngestDataBlock] Received file block 4, size 1024
   56 2953 [OTA Task] [prvIngestDataBlock] Remaining: 1287
   57 2959 [iot_thread] State: Active  Received: 5   Queued: 5   Processed: 5   Dropped: 0
   ```

1. OTA 업데이트가 완료되면 OTA 업데이트 프로세스에 필요한 경우 디바이스가 다시 시작됩니다. 그런 다음 업데이트된 펌웨어를 사용하여 연결을 시도합니다. 업그레이드가 성공하면 업데이트된 펌웨어가 활성 상태로 표시되고 콘솔에서 업데이트된 버전을 확인할 수 있습니다.

   ```
   13 13498 [iot_thread] OTA demo version 0.9.21
   ```

# AWS IoT 디바이스 섀도우 데모 애플리케이션
<a name="shadow-demo"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

## 소개
<a name="shadow-demo-introduction"></a>

이 데모에서는 AWS IoT 디바이스 섀도우 라이브러리를 사용하여 [AWS 디바이스 섀도우 서비스에](https://docs.aws.amazon.com/iot/latest/developerguide/iot-device-shadows.html) 연결하는 방법을 보여줍니다. [coreMQTT 라이브러리](coremqtt.md)를 사용하여 MQTT 브로커 및 coreJSON 라이브러리 구문 분석기에 대한 TLS(상호 인증)와 AWS IoT MQTT 연결을 설정하여 AWS 섀도우 서비스에서 받은 섀도우 문서를 구문 분석합니다. 데모에서는 섀도우 문서 업데이트 방법, 섀도우 문서 삭제 방법 등 기본적인 섀도우 작업을 보여줍니다. 또한 coreMQTT 라이브러리에 콜백 함수를 등록하여 AWS IoT 디바이스 섀도우 서비스에서 전송되는 섀도우 `/update` 및 `/update/delta` 메시지와 같은 메시지를 처리하는 방법도 보여줍니다.

이 데모는 섀도우 문서(상태) 업데이트 요청과 업데이트 응답이 동일한 애플리케이션에서 수행되므로 학습용으로만 사용됩니다. 실제 프로덕션 시나리오에서는 디바이스가 현재 연결되어 있지 않더라도 외부 애플리케이션이 원격으로 디바이스 상태 업데이트를 요청합니다. 디바이스가 연결되어 있으면 업데이트 요청을 확인합니다.

**참고**  
FreeRTOS 데모를 설정하고 실행하려면 [FreeRTOS 시작하기](freertos-getting-started.md)의 단계를 따릅니다.

## 기능
<a name="shadow-demo-functionality"></a>

이 데모에서는 원격 디바이스 상태 전환을 시뮬레이션하는 섀도우 `/update` 및 `/update/delta` 콜백을 보여주는 일련의 예제를 반복하는 단일 애플리케이션 태스크를 생성합니다. 새 `desired` 상태가 포함된 섀도우 업데이트를 전송하고 디바이스가 새 `desired` 상태에 대한 응답으로 `reported` 상태를 변경할 때까지 기다립니다. 또한 섀도우 `/update` 콜백은 변화하는 섀도우 상태를 인쇄하는 데 사용됩니다. 또한이 데모는 MQTT 브로커에 대한 보안 AWS IoT MQTT 연결을 사용하며 디바이스 섀도우에 `powerOn` 상태가 있다고 가정합니다.

데모는 다음 작업을 수행합니다.

1. `shadow_demo_helpers.c`의 헬퍼 함수를 사용하여 MQTT 연결을 설정합니다.

1.  AWS IoT 디바이스 섀도우 라이브러리에 정의된 매크로를 사용하여 디바이스 섀도우 작업에 사용할 MQTT 주제 문자열을 어셈블합니다.

1. 디바이스 섀도우를 삭제하는 데 사용되는 MQTT 주제에 게시하여 기존 디바이스 섀도우를 삭제합니다.

1. `shadow_demo_helpers.c`의 헬퍼 함수를 사용하여 `/update/delta`, `/update/accepted` 및 `/update/rejected`에 대한 MQTT 주제를 구독합니다.

1. `powerOn`의 헬퍼 함수를 사용하여 원하는 `shadow_demo_helpers.c` 상태를 게시합니다. 그러면 `/update/delta` 메시지가 디바이스로 전송됩니다.

1. 에서 수신 MQTT 메시지를 처리하고 디바이스 섀도우 라이브러리()에서 정의한 함수를 사용하여 메시지가 AWS IoT 디바이스 섀도우와 관련이 있는지 `prvEventCallback`확인합니다`Shadow_MatchTopic`. 메시지가 디바이스 섀도우 `/update/delta` 메시지인 경우 메인 데모 함수는 보고된 상태를 업데이트하는 두 번째 메시지를 `powerOn`에 게시합니다. `/update/accepted` 메시지가 수신되면 `clientToken`이 이전에 업데이트 메시지에 게시된 것과 동일한지 확인합니다. 그러면 데모가 종료됩니다.

![\[섀도우 데모 터미널 출력\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/shadow-demo-output.png)


데모는 `freertos/demos/device_shadow_for_aws/shadow_demo_main.c` 파일 또는 [GitHub](https://github.com/aws/amazon-freertos/blob/main/demos/device_shadow_for_aws/shadow_demo_main.c)에서 찾을 수 있습니다.

다음 스크린샷은 데모가 성공할 경우 예상되는 출력을 보여줍니다.

![\[성공을 나타내는 섀도우 데모 터미널 출력\]](http://docs.aws.amazon.com/ko_kr/freertos/latest/userguide/images/shadow-demo-screenshot.png)


## AWS IoT MQTT 브로커에 연결
<a name="shadow-demo-connect-mqtt"></a>

 AWS IoT MQTT 브로커에 연결하기 위해 `MQTT_Connect()`에서와 동일한 방법을 사용합니다[coreMQTT 상호 인증 데모](mqtt-demo-ma.md).

## 섀도우 문서 삭제
<a name="shadow-demo-delete-document"></a>

섀도우 문서를 삭제하려면 AWS IoT 디바이스 섀도우 라이브러리에서 정의한 매크로를 사용하여 빈 메시지와 `xPublishToTopic` 함께를 호출합니다. 그러면 `MQTT_Publish`를 사용하여 `/delete` 주제에 게시합니다. 다음 코드 섹션은 `prvShadowDemoTask` 함수에서 이 작업이 어떻게 이루어지는지 보여줍니다.

```
/* First of all, try to delete any Shadow document in the cloud. */
returnStatus = PublishToTopic( SHADOW_TOPIC_STRING_DELETE( THING_NAME ),
                               SHADOW_TOPIC_LENGTH_DELETE( THING_NAME_LENGTH ),
                               pcUpdateDocument,
                               0U );
```

## 섀도우 주제 구독
<a name="shadow-demo-subscribe"></a>

디바이스 섀도우 주제를 구독하여 브로 AWS IoT 커로부터 섀도우 변경 사항에 대한 알림을 받습니다. 디바이스 섀도우 주제는 디바이스 섀도우 라이브러리에 정의된 매크로에 의해 어셈블됩니다. 다음 코드 섹션은 `prvShadowDemoTask` 함수에서 이 작업이 어떻게 이루어지는지 보여줍니다.

```
/* Then try to subscribe shadow topics. */
if( returnStatus == EXIT_SUCCESS )
{
    returnStatus = SubscribeToTopic( 
                     SHADOW_TOPIC_STRING_UPDATE_DELTA( THING_NAME ),
                     SHADOW_TOPIC_LENGTH_UPDATE_DELTA( THING_NAME_LENGTH ) );
}

if( returnStatus == EXIT_SUCCESS )
{
    returnStatus = SubscribeToTopic( 
                     SHADOW_TOPIC_STRING_UPDATE_ACCEPTED( THING_NAME ),
                     SHADOW_TOPIC_LENGTH_UPDATE_ACCEPTED( THING_NAME_LENGTH ) );
}

if( returnStatus == EXIT_SUCCESS )
{
    returnStatus = SubscribeToTopic( 
                     SHADOW_TOPIC_STRING_UPDATE_REJECTED( THING_NAME ),
                     SHADOW_TOPIC_LENGTH_UPDATE_REJECTED( THING_NAME_LENGTH ) );
}
```

## 섀도우 업데이트 전송
<a name="shadow-demo-send-updates"></a>

섀도우 업데이트를 전송하기 위해 이 데모는 디바이스 섀도우 라이브러리에 정의된 매크로를 사용하여 JSON 형식 메시지와 함께 `xPublishToTopic`을 호출합니다. 그러면 `MQTT_Publish`를 사용하여 `/delete` 주제에 게시합니다. 다음 코드 섹션은 `prvShadowDemoTask` 함수에서 이 작업이 어떻게 이루어지는지 보여줍니다.

```
#define SHADOW_REPORTED_JSON    \
    "{"                         \
    "\"state\":{"               \
    "\"reported\":{"            \
    "\"powerOn\":%01d"          \
    "}"                         \
    "},"                        \
    "\"clientToken\":\"%06lu\"" \
    "}"
snprintf( pcUpdateDocument,
          SHADOW_REPORTED_JSON_LENGTH + 1,
          SHADOW_REPORTED_JSON,
           ( int ) ulCurrentPowerOnState,
           ( long unsigned ) ulClientToken );

xPublishToTopic( SHADOW_TOPIC_STRING_UPDATE( THING_NAME ),
                 SHADOW_TOPIC_LENGTH_UPDATE( THING_NAME_LENGTH ),
                 pcUpdateDocument,
                 ( SHADOW_DESIRED_JSON_LENGTH + 1 ) );
```

## 섀도우 델타 메시지 및 섀도우 업데이트 메시지 처리
<a name="shadow-demo-delta-and-update"></a>

`MQTT_Init` 함수를 사용하여 [coreMQTT 클라이언트 라이브러리](https://www.freertos.org/iot-device-shadow/device-shadow-demo.html#handle-shadow-messages)에 등록된 사용자 콜백 함수는 들어오는 패킷 이벤트를 알려줍니다. GitHub에서 콜백 함수 [prvEventCallback](https://github.com/aws/amazon-freertos/blob/main/demos/device_shadow_for_aws/shadow_demo_main.c#L671-L753)을 참조하세요.

이 콜백 함수는 들어오는 패킷이 `MQTT_PACKET_TYPE_PUBLISH` 유형임을 확인하고 디바이스 섀도우 라이브러리 API `Shadow_MatchTopic`을 사용하여 들어오는 메시지가 섀도우 메시지임을 확인합니다.

들어오는 메시지가 `ShadowMessageTypeUpdateDelta` 유형의 섀도우 메시지인 경우에는 [prvUpdateDeltaHandler](https://github.com/aws/amazon-freertos/blob/main/demos/device_shadow_for_aws/shadow_demo_main.c#L464-L580)를 직접 호출하여 이 메시지를 처리합니다. 핸들러 `prvUpdateDeltaHandler`는 coreJSON 라이브러리를 사용하여 메시지를 파싱해 `powerOn` 상태에 대한 델타 값을 가져오고 이를 로컬에서 유지 관리되는 현재 디바이스 상태와 비교합니다. 두 값이 다를 경우 섀도우 문서의 새 `powerOn` 상태 값을 반영하도록 로컬 디바이스 상태가 업데이트됩니다.

들어오는 메시지가 `ShadowMessageTypeUpdateAccepted` 유형의 섀도우 메시지인 경우에는 [prvUpdateAcceptedHandler](https://github.com/aws/amazon-freertos/blob/main/demos/device_shadow_for_aws/shadow_demo_main.c#L584-L667)를 직접 호출하여 이 메시지를 처리합니다. 핸들러 `prvUpdateAcceptedHandler`는 coreJSON 라이브러리를 사용하여 메시지를 파싱해 메시지에서 `clientToken`을 가져옵니다. 이 핸들러 함수는 JSON 메시지의 클라이언트 토큰이 애플리케이션에서 사용하는 클라이언트 토큰과 일치하는지 확인합니다. 일치하지 않을 경우 함수는 경고 메시지를 로그합니다.

# 보안 소켓 에코 클라이언트 데모
<a name="secure-sockets-demo"></a>

**중요**  <a name="deprecation-message-demo"></a>
이 데모는 더 이상 사용되지 않는 Amazon-FreeRTOS 리포지토리에서 호스팅됩니다. 새 프로젝트를 생성할 때는 [여기서 시작](freertos-getting-started-modular.md)하는 것이 좋습니다. 현재 사용되지 않는 Amazon-FreeRTOS 리포지토리를 기반으로 하는 기존 FreeRTOS 프로젝트가 이미 있는 경우에는 [Amazon-FreeRTOS Github 리포지토리 마이그레이션 가이드](github-repo-migration.md) 섹션을 참조하세요.

다음 예제에서는 단일 RTOS 작업을 사용합니다. 이 예제의 소스 코드는 `demos/tcp/aws_tcp_echo_client_single_task.c`에서 찾을 수 있습니다.

시작하기 전에 마이크로컨트롤러에 FreeRTOS를 다운로드하고 FreeRTOS 데모 프로젝트를 빌드 및 실행했는지 확인합니다. [GitHub](https://github.com/aws/amazon-freertos)에서 FreeRTOS를 복제하거나 다운로드할 수 있습니다. 자세한 내용은 [README.md](https://github.com/aws/amazon-freertos/blob/main/README.md) 파일을 참조하십시오.

**데모를 실행하려면**

**참고**  
FreeRTOS 데모를 설정하고 실행하려면 [FreeRTOS 시작하기](freertos-getting-started.md)의 단계를 따릅니다.  
TCP 서버와 클라이언트 데모는 현재 Cypress CYW943907AEVAL1F 및 CYW954907AEVAL1F 개발 키트에서 지원되지 않습니다.

1. FreeRTOS 이식 안내서의 [TLS 에코 서버 설정](https://docs.aws.amazon.com/freertos/latest/portingguide/tls-echo-server.html)에 나와 있는 지침을 따르세요.

   TLS 에코 서버를 실행하고 포트 9000에서 수신 대기해야 합니다.

   설정 중에 다음 네 파일을 생성해야 합니다.
   + `client.pem`(클라이언트 인증서)
   + `client.key`(클라이언트 프라이빗 키)
   + `server.pem`(서버 인증서)
   + `server.key`(서버 프라이빗 키)

1. `tools/certificate_configuration/CertificateConfigurator.html` 도구를 사용하여 클라이언트 인증서(`client.pem`)와 클라이언트 프라이빗 키(`client.key`)를 `aws_clientcredential_keys.h`에 복사합니다.

1. `FreeRTOSConfig.h` 파일을 엽니다.

1. `configECHO_SERVER_ADDR0`, `configECHO_SERVER_ADDR1`, `configECHO_SERVER_ADDR2`, `configECHO_SERVER_ADDR3` 변수를 TLS Echo Server가 실행되는 IP 주소를 구성하는 정수 네 개로 설정합니다.

1. `configTCP_ECHO_CLIENT_PORT` 변수를 TLS Echo Server가 수신 대기하는 포트인 `9000`으로 설정합니다.

1. `configTCP_ECHO_TASKS_SINGLE_TASK_TLS_ENABLED` 변수를 `1`로 설정합니다.

1. `tools/certificate_configuration/PEMfileToCString.html` 도구를 사용하여 서버 인증서(`server.pem`)를 `cTlsECHO_SERVER_CERTIFICATE_PEM` 파일의 `aws_tcp_echo_client_single_task.c`에 복사합니다.

1. `freertos/vendors/vendor/boards/board/aws_demos/config_files/aws_demo_config.h`를 열고 `#define CONFIG_CORE_MQTT_MUTUAL_AUTH_DEMO_ENABLED`를 주석으로 처리한 다음 `CONFIG_OTA_MQTT_UPDATE_DEMO_ENABLED` 또는 `CONFIG_OTA_HTTP_UPDATE_DEMO_ENABLED`를 정의합니다.

마이크로컨트롤러와 TLS Echo Server는 동일한 네트워크에 있어야 합니다. 데모가 (`main.c`)를 시작하면 `Received correct string from echo server`라는 로그 메시지가 표시됩니다.