目錄
在ART-Pi H750上移植TouchGFX(一)——使用STM32CUBMX生成TouchGFX工程
在ART-Pi H750上移植TouchGFX(二)——制作MDK的外部QSPI-FLASH燒錄演算法
在ART-Pi H750上移植TouchGFX(三)——移植TouchGFX到RT-Thread系統
在ART-Pi H750上移植TouchGFX(四)——使用RT-Thread Studio移植TouchGFX
在ART-Pi H750上移植TouchGFX(五)——制作ST-LINK的外部QSPI-FLASH燒錄演算法
實驗平臺:
硬體: RT-Thread官方ART-PI H750開發版,正點原子4.3寸RGBLCD屏(800*480)
軟體: 最新版本的STM32CubeH7韌體庫,TouchGFXDesigner v4.14和 STM32CubeMX V6.0.1,開發環境MDK v5.29

代碼下載:
待公布
聯系作者:
關注公眾號,免費查看,回復“加群”,加入技術交流群

初識RT-Thread
RT-Thread 是一個集實時作業系統(RTOS)內核、中間件組件和開發者社區于一體的技術平臺,由熊譜翔先生帶領并集合開源社區力量開發而成,RT-Thread 也是一個組件完整豐富、高度可伸縮、簡易開發、超低功耗、高安全性的物聯網作業系統,RT-Thread 具備一個 IoT OS 平臺所需的所有關鍵組件,例如GUI、網路協議堆疊、安全傳輸、低功耗組件等等,經過11年的累積發展,RT-Thread 已經擁有一個國內最大的嵌入式開源社區,同時被廣泛應用于能源、車載、醫療、消費電子等多個行業,累積裝機量超過 6億 臺,成為國人自主開發、國內最成熟穩定和裝機量最大的開源 RTOS,
自2006年發布原始碼并開源,RT-Thread堅持“開源、開放”的理念,貼近開發者滿足市場需求,堅持做小而美的物聯網作業系統,當前已可完美覆寫面向嵌入式及IoT不同應用場景:
- 小資源場景的MCU用于簡單控制使用RT-Thread Nano版本(2006年發布,針對Cortex-M、RISC-V等);
- 中等規模的IoT節點使用RT-Thread IoT OS版本(2017年發布,針對Cortex-M、龍芯、RISC-V等);
- 功能豐富的智能設備使用RT-Thread Smart微內核版本(2020年發布,針對帶MMU的處理器如Cortex-A、龍芯、RISC-V等),
如何獲取RT-Thread源代碼
github地址:https://github.com/RT-Thread/rt-thread
gitee地址:https://gitee.com/rtthread/rt-thread
如何學習RT-Thread
- RT-Thread系統官方學習檔案,https://www.rt-thread.org/document/site/
- 了解RT-Thread系統的內核,下載安裝Env工具和RT-Thread Studio開發工具,
- 學習RT-Thread的設備驅動、組件和軟體包的使用方法,
更換TouchGFX的作業系統
STM32CubeMX默認支持的作業系統為FreeRTOS,TouchGFX可以運行在帶作業系統和不帶作業系統的應用中,用戶想要更換作業系統,只需要重新實作OSWrappers類,便可以切換不同的RTOS,

移植TouchGFX到RT-Thread
1.重新實作OSWrappers類:
/**
******************************************************************************
* File Name : OSWrappers.cpp
******************************************************************************
* @attention
*
* <h2><center>© 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. 在rtthread中添加touchgfx需要的外設
移植思路:回顧一下touchgfx需要的組件構成,只需要在rtthread中按需添加即可,詳細步驟可以參考此教程:使用RTThread和TouchGFX實作DIY數字儀表(二)——把TouchGFX移植到RTThread系統

ART-PI實戰演示
1.打開上一節的工程,匯入一個游戲例程

由于此工程比較大,除了圖片和字體,代碼量已經超過了128k,所以不能像上一個工程那樣直接下載代碼了,這種情況,可以參考ST官方開發板的做法,把所有的代碼都放到外部flash的空間,內部的128k空間,用來制作bootloader,bootloader上電后對qspi地址映射,然后跳轉到qspi flash的地址運行程式,
2.制作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.制作APP
修改分散加載檔案,使代碼全部放到外部flash

添加中斷重映射
static int vtor_config(void)
{
/* Vector Table Relocation in Internal QSPI_FLASH */
SCB->VTOR = QSPI_BASE;
return 0;
}
INIT_BOARD_EXPORT(vtor_config);
4.添加觸摸gt9147軟體包

然后在STM32TouchController.cpp中給touchgfx賦值xy坐標
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;
}
}
燒錄演示

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/92538.html
標籤:其他
上一篇:鴻蒙不是Linux也不是安卓
下一篇:思科模擬器除錯
