Transplant TouchGFX on ART-Pi H750 (3)——Transplant TouchGFX to RT-Thread system

table of Contents

Transplant TouchGFX on ART-Pi H750 (1)-Use STM32CUBMX to generate TouchGFX project
Transplant TouchGFX on ART-Pi H750 (2)-Make MDK's external QSPI-FLASH programming algorithm
Transplant TouchGFX on ART-Pi H750 ( Three)-Transplant TouchGFX to RT-Thread system Transplant TouchGFX
on ART-Pi H750 (four)-Use RT-Thread Studio to transplant TouchGFX and transplant TouchGFX
on ART-Pi H750 (5)-Make ST-LINK external QSPI-FLASH programming algorithm

experiment platform:

Hardware: RT-Thread official ART-PI H750 development version, Punctual Atom 4.3 inch RGBLCD screen (800*480)
Software: the latest version of STM32CubeH7 firmware library, TouchGFXDesigner v4.14 and STM32CubeMX V6.0.1, development environment MDK v5.29
Insert picture description here

Code download:

To be announced

Contact the author:

Follow the official account, view it for free, reply to "add group", join the technical exchange group
Insert picture description here

Getting to know RT-Thread

RT-Thread is a technology platform that integrates real-time operating system (RTOS) kernel, middleware components, and developer community. It was developed by Mr. Xiong Puxiang and integrated with open source community forces. RT-Thread is also a complete and rich component , Highly scalable, easy to develop, ultra-low power consumption, high-security IoT operating system. RT-Thread has all the key components required for an IoT OS platform, such as GUI, network protocol stack, secure transmission, low-power components, etc. After 11 years of cumulative development, RT-Thread already has the largest embedded open source community in China, and it is also widely used in energy, automotive, medical, consumer electronics and other industries. The cumulative installed capacity exceeds 600 million units, making it independent Developed, the most mature and stable open source RTOS with the largest installed capacity in China.

Since the release of the source code and open source in 2006, RT-Thread adheres to the concept of "open source and open", close to developers to meet market needs, and insists on making small and beautiful IoT operating systems, which can now perfectly cover different application scenarios for embedded and IoT :

  • The MCU in the small resource scenario is used for simple control of the RT-Thread Nano version (released in 2006, for Cortex-M, RISC-V, etc.);
  • Medium-scale IoT nodes use RT-Thread IoT OS version (released in 2017, for Cortex-M, Loongson, RISC-V, etc.);
  • Feature-rich smart devices use RT-Thread Smart microkernel version (released in 2020, for processors with MMU such as Cortex-A, Loongson, RISC-V, etc.).

How to obtain RT-Thread source code

github address: https://github.com/RT-Thread/rt-thread
gitee address: https://gitee.com/rtthread/rt-thread

How to learn RT-Thread

Change the operating system of TouchGFX

The operating system supported by STM32CubeMX by default is FreeRTOS. TouchGFX can run in applications with and without operating systems. If users want to change the operating system, they only need to reimplement the OSWrappers class to switch between different RTOSs.
Insert picture description here

Migrate TouchGFX to RT-Thread

1. Reimplement the OSWrappers class:

/**
  ******************************************************************************
  * File Name          : OSWrappers.cpp
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under Ultimate Liberty license
  * SLA0044, the "License"; You may not use this file except in compliance with
  * the License. You may obtain a copy of the License at:
  *                             www.st.com/SLA0044
  *
  ******************************************************************************
  */
#include <touchgfx/hal/OSWrappers.hpp>
#include <stm32h7xx_hal.h>
#include <touchgfx/hal/GPIO.hpp>
#include <touchgfx/hal/HAL.hpp>
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <rthw.h>
static rt_sem_t frame_buffer_sem;
static rt_mq_t vsync_q = 0;
using namespace touchgfx;

// Just a dummy value to insert in the VSYNC queue.
static uint8_t dummy = 0x5a;

/*
 * Initialize frame buffer semaphore and queue/mutex for VSYNC signal.
 */
void OSWrappers::initialize()
{
    
    

	frame_buffer_sem = rt_sem_create("gfx_sem", 1, RT_IPC_FLAG_PRIO);
    // Create a queue of length 1
    vsync_q = rt_mq_create("gfx_mq", 1, 1, RT_IPC_FLAG_PRIO);

}

/*
 * Take the frame buffer semaphore. Blocks until semaphore is available.
 */
void OSWrappers::takeFrameBufferSemaphore()
{
    
    
     rt_sem_take(frame_buffer_sem, RT_WAITING_FOREVER);
}

/*
 * Release the frame buffer semaphore.
 */
void OSWrappers::giveFrameBufferSemaphore()
{
    
    
    rt_sem_release(frame_buffer_sem);
}

/*
 * Attempt to obtain the frame buffer semaphore. If semaphore is not available, do
 * nothing.
 *
 * Note must return immediately! This function does not care who has the taken the semaphore,
 * it only serves to make sure that the semaphore is taken by someone.
 */
void OSWrappers::tryTakeFrameBufferSemaphore()
{
    
    
    rt_sem_trytake(frame_buffer_sem);
}

/*
 * Release the frame buffer semaphore in a way that is safe in interrupt context. Called
 * from ISR.
 *
 * Release the frame buffer semaphore in a way that is safe in interrupt context.
 * Called from ISR.
 */
void OSWrappers::giveFrameBufferSemaphoreFromISR()
{
    
    
    // Since this is called from an interrupt, FreeRTOS requires special handling to trigger a
    // re-scheduling. May be applicable for other OSes as well.
		rt_sem_release(frame_buffer_sem);
}

/*
 * Signal that a VSYNC has occurred. Should make the vsync queue/mutex available.
 *
 * Note This function is called from an ISR, and should (depending on OS) trigger a
 * scheduling.
 */
void OSWrappers::signalVSync()
{
    
    
    if (vsync_q)
    {
    
    
        rt_mq_send(vsync_q, &dummy, 1);
    }
}

/*
 * This function blocks until a VSYNC occurs.
 *
 * Note This function must first clear the mutex/queue and then wait for the next one to
 * occur.
 */
void OSWrappers::waitForVSync()
{
    
    
    // First make sure the queue is empty, by trying to remove an element with 0 timeout.
    rt_mq_recv(vsync_q, &dummy, 1, 0);

    // Then, wait for next VSYNC to occur.
    rt_mq_recv(vsync_q, &dummy, 1, RT_WAITING_FOREVER);
}

/*
 * A function that causes executing task to sleep for a number of milliseconds.
 *
 * A function that causes executing task to sleep for a number of milliseconds.
 * This function is OPTIONAL. It is only used by the TouchGFX in the case of
 * a specific frame refresh strategy (REFRESH_STRATEGY_OPTIM_SINGLE_BUFFER_TFT_CTRL).
 * Due to backwards compatibility, in order for this function to be useable by the HAL
 * the function must be explicitly registered:
 * hal.registerTaskDelayFunction(&OSWrappers::taskDelay)
 *
 * see HAL::setFrameRefreshStrategy(FrameRefreshStrategy s)
 * see HAL::registerTaskDelayFunction(void (*delayF)(uint16_t))
 */
void OSWrappers::taskDelay(uint16_t ms)
{
    
    
     rt_thread_mdelay(ms);
}

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

2. Add peripherals needed by touchgfx to rtthread.
Migration ideas: review the components required by touchgfx, just add them as needed in rtthread. For detailed steps, please refer to this tutorial: Use RTThread and TouchGFX to implement DIY digital meters (two )-Porting TouchGFX to RTThread system
Insert picture description here

ART-PI actual combat demonstration

1. Open the project in the previous section and import a game routine.
Insert picture description here
Because this project is relatively large, except for pictures and fonts, the amount of code has exceeded 128k, so you cannot download the code directly like the previous project. In this case, you can refer to the ST official development board to put all the code in the external flash space, and the internal 128k space is used to make the bootloader. After the bootloader is powered on, it maps the qspi address, and then jumps to the qspi flash Run the program at the address.

2. Make bootloader

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <drv_common.h>
#include "w25qxx.h"

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

/* defined the LED0 pin: PB1 */
#define LED0_PIN    GET_PIN(I, 8)

#define VECT_TAB_OFFSET      0x00000000UL
#define APPLICATION_ADDRESS  (uint32_t)0x90000000

typedef void (*pFunction)(void);
pFunction JumpToApplication;

int main(void)
{
    
    
    /* set LED0 pin mode to output */
    rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);

    W25QXX_Init();

    W25Q_Memory_Mapped_Enable();//地址映射

    SCB_DisableICache();
    SCB_DisableDCache();

    SysTick->CTRL = 0;

    JumpToApplication = (pFunction)(*(__IO uint32_t *)(APPLICATION_ADDRESS + 4));
    __set_MSP(*(__IO uint32_t *)APPLICATION_ADDRESS);

    JumpToApplication();//跳转

    return RT_EOK;
}

3. Make APP to
modify the scatter-loading file, put all the code in the external flash,
Insert picture description here
add interrupt remapping

static int vtor_config(void)
{
    
    
    /* Vector Table Relocation in Internal QSPI_FLASH */
    SCB->VTOR = QSPI_BASE;
    return 0;
}
INIT_BOARD_EXPORT(vtor_config);

4. Add the touch gt9147 software package
Insert picture description here
and assign xy coordinates to touchgfx in STM32TouchController.cpp

bool STM32TouchController::sampleTouch(int32_t& x, int32_t& y)
{
    
    
    /**
     * By default sampleTouch returns false,
     * return true if a touch has been detected, otherwise false.
     *
     * Coordinates are passed to the caller by reference by x and y.
     *
     * This function is called by the TouchGFX framework.
     * By default sampleTouch is called every tick, this can be adjusted by HAL::setTouchSampleRate(int8_t);
     *
     */
	struct  rt_touch_data *read_data;
	read_data = read_coordinate();

	if (read_data->event == RT_TOUCH_EVENT_DOWN || read_data->event == RT_TOUCH_EVENT_MOVE)
	{
    
    
		x = read_data->x_coordinate;
	    y = read_data->y_coordinate;
		return true;
	}
	else
	{
    
    
		return false;
	}
}

Burning demo

Insert picture description here

Guess you like

Origin blog.csdn.net/sinat_31039061/article/details/108638097