C
Qt Quick Ultralite freertos_app_switch の例
Qt Quick のUltraliteアプリケーションと別のアプリケーションを、ソフトリセットを介して切り替える方法を示します。
概要
freertos_app_switch は、ソフトリセットと、ソフトリセットの合間に状態を保持するメモリ位置を利用して、Qt Quick のUltraliteアプリケーションと別のアプリケーションを切り替える方法を示しています。また、この例では、Qt Quick のUltraliteアプリケーションを再起動し、アプリケーションの初期化手順を再実行する方法についても説明しています。
起動時には、2つのアプリケーションを切り替えるために特定のメモリアドレスが使用されます。
Application #1は、Qt Quick のUltraliteアプリケーションそのものであり、ブート選択メカニズムへのユーザーインターフェースを提供します。
Application #2は、フレームバッファに直接書き込みを行い、LEDを数秒間点滅させた後、デバイスを再起動して最初のアプリケーションを起動する別のアプリケーションです。
注: ソフトリセットを使用する際は注意が必要です 。ハードウェア周辺機器が正しく再初期化されることを確認してください。一部の周辺機器は、プログラムされる前にリセット信号を必要としたり、特定の状態にある必要がある場合があります。
注: ここで紹介したリセットメカニズムは 、ハードリセット(電源のオン/オフ)や、状態を保持するための不揮発性メモリを使用するように適応させることも可能です。
対象プラットフォーム
コードの概要
アプリケーションのエントリポイント
main() 関数は、ハードウェアおよびプラットフォームの初期化を行い、さらにボード固有のInitLED() 関数を使用してLEDを初期化します。
... int main() { Qul::initHardware(); Qul::initPlatform(); initLED(); ...
次に、メモリからboot の値が読み込まれます。
int boot = readBootValue();
readBootValue() メソッドは、単に特定のメモリ位置から読み取るだけであり、boardutils.c で定義されています。
int readBootValue() { int *ptr = &__BOOT_VAL_ADDR; return *ptr; }
boot 変数のアドレスは、board.cmake ファイル内のリンカ定義シンボルを介して設定できます。
set(BOOT_VAL_ADDR 0x81400000)
if (IAR)
target_link_options(freertos_app_switch PRIVATE --define_symbol __BOOT_VAL_ADDR=${BOOT_VAL_ADDR})
else()
target_link_options(freertos_app_switch PRIVATE -Xlinker --defsym=__BOOT_VAL_ADDR=${BOOT_VAL_ADDR})
endif()boot の値に基づいて、異なるFreeRTOS タスクが作成されます。Application #1 を実行するQt Quick Ultralite タスク、あるいはApplication #2 を実装する別のタスクのいずれかです。
if (boot != APP2) { Qul::PlatformInterface::log("Application #1...QUL Application Switch\r\n"); if (xTaskCreate(App1_thread, "QulExec", QUL_STACK_SIZE, 0, 4, &QulTask) != pdPASS) { Qul::PlatformInterface::log("Task creation failed!\r\n"); configASSERT(false); } } else { Qul::PlatformInterface::log("Application #2...blinking LED\r\n"); if (xTaskCreate(App2_thread, "LedToggle", configMINIMAL_STACK_SIZE, 0, 4, &LedTask) != pdPASS) { Qul::PlatformInterface::log("LED task creation failed!\r\n"); configASSERT(false); } } vTaskStartScheduler(); ...
Qt Quick Ultralite を実行するApplication #1 タスクは、単にアプリケーションのルート項目を設定し、exec() 関数を呼び出すだけです。
static void App1_thread(void *argument) { (void) argument; Qul::Application app; static appswitch item; app.setRootItem(&item); app.exec(); }
Application #2 タスクは、displayApp2Background() を介して生画像をフレームバッファに直接書き込み、その後、数サイクルにわたってLEDを点滅させます。
static void App2_thread(void *argument) { (void) argument; displayApp2Background(); //Blink for N_BLINKS times then reboot into App1 for (int i = 0; i < N_BLINKS; ++i) { xTaskNotifyWait(0, ULONG_MAX, NULL, pdMS_TO_TICKS(500)); toggleLED(); taskYIELD(); } reset(APP1); }
QML
Qt Quick Ultralite のユーザーインターフェースは、freertos_app_switch.qml で実装されています。次回の起動時に実行するアプリケーションは 2 つのラジオボタンで選択され、リセットボタンでソフトリセットが実行されます。
...
Button {
id: resetButton
text: "Reset!"
anchors.centerIn: parent
onClicked: {
console.log("Chosen application #", DevControl.application, "...Resetting system!")
DevControl.resetDevice();
}
}
...DevControl オブジェクトは、UI と抽象化されたハードウェア間のインターフェースとして使用されます。
void DevControl::HWResetDevice() { reset(application.value()); }
パブリックメソッドresetDevice() を使用すると、Qul::Property<int> application の値をブートメモリの指定位置に書き込んだ後、NVIC_SystemReset() を呼び出してソフトリセットをトリガーできます。
void writeBootValue(int app) { int *ptr = &__BOOT_VAL_ADDR; *ptr = app; QUL_CleanInvalidateDCache_by_Addr((void *) ptr, 4); } void reset(int app) { writeBootValue(app); NVIC_SystemReset(); }
注: NXP i.MX RT1170 バイナリの書き込み直後に、デバイスをもう一度リセットする必要があります。そうしないと、NVIC_SystemReset() によるソフトリセットが正常に動作しない可能性があります。
ファイル:
- freertos_app_switch/CMakeLists.txt
- freertos_app_switch/appswitch.qml
- freertos_app_switch/mcu_freertos_app_switch.qmlproject
- freertos_app_switch/src/boardutils.h
- freertos_app_switch/src/devcontrol.cpp
- freertos_app_switch/src/devcontrol.h
- freertos_app_switch/src/main.cpp
- freertos_app_switch/src/mimxrt1050-evk-freertos/bg_image.h
- freertos_app_switch/src/mimxrt1050-evk-freertos/boardutils.c
- freertos_app_switch/src/mimxrt1064-evk-freertos/bg_image.h
- freertos_app_switch/src/mimxrt1064-evk-freertos/boardutils.c
- freertos_app_switch/src/mimxrt1170-evkb-freertos/bg_image.h
- freertos_app_switch/src/mimxrt1170-evkb-freertos/boardutils.c
- freertos_app_switch/src/mimxrt1170-evkb-freertos/qul_display_helpers.cpp
- freertos_app_switch/src/mimxrt1170-evkb-freertos/qul_display_helpers.h
- freertos_app_switch/src/stm32f769i-discovery-freertos/bg_image.h
- freertos_app_switch/src/stm32f769i-discovery-freertos/boardutils.c
「FreeRTOS 」アプリケーションのビルドプロセスも参照してください 。
特定のQtライセンスの下で利用可能です。
詳細はこちら。