본문 바로가기
임베디드 개발/STM32 (ARM Cortex-M)

STM32 ] TouchGFX, 하드웨어와 상호작용하기

by eteo 2023. 7. 18.

 

1. TouchGFX Designer에서 사용보드를 선택하고 New Project를 생성한다.

 

 

 

2. Designer 툴에서 GUI를 만들고 Generate Code를 한다.

 

 

 

 

3. 프로젝트 경로에 들어가면 .ioc 파일과 STM32CubeIDE 프로젝트 파일이 있다.

 

 

 

4. STM32CubeMX로 .ioc 파일을 편집하고 STM32CubeIDE로 .cproject를 열어 편집할 수 있다.

 

 

 

 

5. 하드웨어 상호작용 코드 작성

 

아래 경로에서 main.c와 gui관련 .cpp 파일을 수정할 수 있다.

 

TouchGFX는 OS없이도 실행할 수는 있지만 그렇게 하면 다른 Task와 TouchGFX 함께 실행하기 어렵기 때문에 FreeRTOS 환경에서 테스트하며 개발되었고 자동생성 코드도 FreeRTOS와 같이 제공된다.

 

그리고 <프로젝트명>\Core\Src\ 에 있는 파일들은 <프로젝트명>\Application\User\ 경로에 Linked File 타입으로 추가되어 있다.

 

 

 

 

 

 

 

TouchGFX는 MVP 디자인 패턴을 따르기 때문에 하드웨어와 인터페이스하는 코드는 Model에만 배치하는 것이 좋다.

 

간단하게는 Model에서 바로 #include "main.h"나 #include "stm32f7xx_hal.h" 을 추가하고 HAL 드라이버함수를 사용해도 되고 아니면 한번 더 래핑해서 extern으로 불러쓸 수도 있다. 

 

 

 

 

공식 문서의 Backend Commnunication 예시는 아래 링크에서 확인할 수 있다.

 

 

https://support.touchgfx.com/docs/development/ui-development/touchgfx-engine-features/backend-communication

 

Backend Communication | TouchGFX Documentation

In most applications, the UI needs to be connected to the rest of your system somehow, and send and receive data. This could be interfacing with hardware peripherals (sensor data, A/D conversions, serial communication, ...) or interfacing with other softwa

support.touchgfx.com

 

 

 

 

 

 

 

 

 

 

 

 

참고로 하드웨어 상호작용 코드는 TouchGFX designer 실행시 오류가 나므로 아래 전처리문으로 감싸준다.

#ifndef SIMULATOR
// ...
#endif

 

 

 

디버깅할때는 Configuration에서 External Loader를 체크해야 한다. 내부 플래시는 코드용으로 사용되고, GUI를 구현하기 위해 필요한 그래픽 라이브러리, 이미지 파일, 폰트 파일 등의 데이터들은 용량이 크기 때문에 External Loader를 통해 QSPI 인터페이스 외부 플래시에 저장하는 것 같다.

 

 

 

 

스크린1 기능 : Green Led(LD2)의 상태를 실시간 전시한다.

스크린2 기능 : 화면 버튼 터치를 통해 Red Led(LD1)의 ON/OFF를 제어한다.

 

 

 

 

 

 

 

기타 참고글.

 

TouchGFX와 다른 Task를 함께 수행하는 법 :

https://support.touchgfx.com/docs/basic-concepts/operating-system#modeltick

// Model.cpp

void Model::tick()
{
   //run other tasks here
   music_task_tick();
   bluetooth_task_tick();
}


// OSWrappers.cpp

static volatile uint8_t vsync_sem = 0;

void OSWrappers::signalVSync()
{
    vsync_sem = 1;
}

void OSWrappers::waitForVSync()
{
    vsync_sem = 0; //clear the flag, so we wait for the next vsync
    do {
        // Perform other work while waiting
        music_task_tick();
        bluetooth_task_tick();
    } while(!vsync_sem);
}

 

TouchGFX main loop에서 수행하는 작업 :

https://support.touchgfx.com/docs/basic-concepts/rendering

while(true) {
    collect();    // Collect events from outside
    update();     // Update the application ui model
    render();     // Render new updated graphics to the framebuffer
    wait();       // Wait for 'go' from display
}