当前位置: 首页 > news >正文

TouchGFX字库外置的另一种处理方式

最近有个带UI的项目,采用STM32F429做主控方案,对比touchgfx、lvgl和emwin,发现TouchGFX性能最好,并且界面设计工具也很好用,于是选择此图形引擎。

最开始是熟悉UI设计工具,需要一个表格控件,无奈没有,大概研究了一下设计特性,找到了解决方法,还真好用,并且还支持用其他控件作为CELL内容,而lvgl和emwin都没这功能。设计了两个界面后开始研究输入法,看到了这个大佬的视频

https://www.bilibili.com/video/BV1Ba411o7tk/?spm_id_from=333.337.search-card.all.click&vd_source=30b48b29951e4676ebb3f21245a65bcf

太帅了,还直接公布源码,于是下载下来。这里又得夸奖一下TouchGFX,支持Container导入超出,于是直接使用此方法将键盘相关的内容搬到了我当前项目上,顺利生成代码。

编译时重大问题出现了,st芯片的空间不够了。于是又开始研究字库外置。

1.配置designer,激活bin文件方法,最后生成的字库文件大于8M了,外部flash只有8M,于是修改bpp参数,调到2,近5M的样子,又生成了另一个小点的字体,近3M的样子,刚好合适。这里只是找到了字库的参数设置,使其能放入外部flash中,但最开始并没有说要用这个文件。

2.在官方文档里找到两篇文章

使用非内存映射闪存存储字体数据 | TouchGFX Documentation
使用串行闪存存储图像和字体 | TouchGFX Documentation

着手研究这个,本来TouchGFX可以支持映射方式读取数据,什么是映射方式呢,我的理解就是直接寻址,但至少也得是QSPI接口,我这个硬件只是普通SPI接口,另外芯片也不支持QSPI映射模式,听说至少得F7,所以这个方式不行,只能采用非内存映射方式,那么这又是个什么模式呢?说白了就是不支持直接寻址,举个例子,直接寻址就是东西放那儿,你想要什么直接去拿,非直接寻址就是东西在另一个地方,这个地方可能比较高,你直接拿不到,需要用楼梯,或者其他人帮你拿,你就稍微等一下。这儿也是这样,GFX有读取数据的接口,需要你去实现他。

但是也不是那么容易,首先生成的代码是包含字库数据的,肯定直接构建项目是链接不通过的,需要修改链接脚本,将字库部分的数据链接到另外的地址,通过写外部flash烧写算法将数据写入到flash中,这个功能又研究了两天,最后实现了,至于怎么做,网上有不少资料。构建成功后查看map文件,确实将字库数据链接到了指定的地方,然后整个项目也能烧写成功,但是运行时直接进hardfault了。

接下来还是继续研究那两篇文章,官方有个针对G071芯片的模板,生成代码后进行对比,我这边少了几个文件,而我本身那个项目完全不知道怎么才会生成那些文件,这点应该是没做好。简单复制那几个文件后,添加了几个实现代码段,编译下载,能正常运行起来了,但是文字的地方是空白,也就是说没有读出数据。接下来重点对比两个项目文件内容,把不一样的地方分析一下进行合并,最后又测试,很不幸,又开始进hardfault了。

到这里很想放弃了,因为GFX内部代码无法看到,已经不知道从哪儿着手了。直到我在armbbs论坛里进行了求助,得到了管理员的点播,可以采用另一个方式解决,在此向他表示诚挚的谢意!

3.这个方式结合上面两个方式。因为板子有设计16M的SDRAM,前8M都剩很多,后面8M完全可以用来放字库数据。于是着手测试此方法,项目最开始移植过fatfs,直接跑一遍将flash格式化,再下载usb-spi文件系统的程序,插电脑上,将两个字库文件复制进去。

完事后又遇到一个问题,这里被Notepad++坑惨了,流程是这样的,我在电脑上用它打开其中一个字库文件,使用hexeditor查看,然后板子这边用fatfs读取数据出来进行对比,结果开始那几个字节都不一样,于是又下载usb那个程序,复制出里面的字库文件,依然用++打开,发现是一样的。这就麻烦了,肯定问题出在fatfs这边了吧,各种查原因,也没发现哪儿错了,我都准备不用文件系统了,想直接通过串口写数据到flash中,开始用C#编写上位机,写了一条代码,那就是读取对应文件的所有Byte,我调试时发现数据竟然和我板子里的一样,这时才想起换一个工具查看文件内容,果不其然,notepad++里面的hexeditor有问题,真tm操蛋。好了,又回到起点,将下面代码针对我板子的情况修改一下

#define FONT_CACHE_SIZE   0xA00000       //字符缓冲区大小,这里设为10MB
    uint8_t *fontCacheAddr = (uint8_t *)(SDRAM_START_ADDR+frame_size*3+BITMAP_CACHE_SIZE);//分配内存空间
    int fd;
    struct stat fileState;

    fd = open("/sdcard/touchgfx/font.bin", O_RDONLY);

    if(fd >=0)
    {
        stat("/sdcard/touchgfx/font.bin",&fileState);
        read(fd, fontCacheAddr, fileState.st_size);
        close(fd);
        //placement new 就地new->不需要重新分配新的空间
        new (&binaryFont)BinaryFont((const touchgfx::BinaryFontData *)fontCacheAddr);

        TypedTextDatabase::setFont(Typography::TEST, &binaryFont);
    }
    else {
        rt_kprintf("open failed!\r\n");
    }

最后编译下载,启动时屏幕还是花屏,怀着忐忑的心情等了几秒,最后正常弹出那一刻,心里是无比激动。

总结,采用此方式前提,有可直接寻址的存储,并且容量要足够大。然后开机需要等几秒,需要做一个启动界面。至于速度,可以采用dma方式进行优化,或者用更快的接口,比如sdio。

相关文章:

TouchGFX字库外置的另一种处理方式

最近有个带UI的项目,采用STM32F429做主控方案,对比touchgfx、lvgl和emwin,发现TouchGFX性能最好,并且界面设计工具也很好用,于是选择此图形引擎。 最开始是熟悉UI设计工具,需要一个表格控件,无…...

jvm的垃圾回收算法有哪些

jvm的垃圾回收算法有标记-清除、复制、标记-整理、分代回收算法,它们分别有不同的实现: 一、标记-清除算法 利用可达性分析算法分析之后,将未被标记的对象[即不可达对象]清除,以便回收它们所占用的内存。 缺点: 1、需…...

untiy 连接两个UI或一段固定一段跟随鼠标移动的线段

注意,仅适用于UI,且Canvas必须是Camera模式,不能用在3D物体上,3D物体请使用LineRenender 先创建一个图片,将锚点固定在左边 然后在脚本中添加如下内容 public RectTransform startObj;//起点物体public RectTransfor…...

如何成为顶级开源项目的贡献者

概述 对于程序员来讲,成为顶级开源项目的贡献者是一件有意义的事,当然,这也绝非易事。如果你正从事人工智能有关的工作,那么你一定了解诸如Google Tensorflow,Facebook Pytorch这样的开源项目。下面我们就说一说如何成…...

Threads and QObjects

QThread inherits QObject. It emits signals to indicate that the thread started or finished executing, and provides a few slots as well. QThread 派生于 QObject。QThread 会发射信号通知线程启动或终止执行任务,并且也会提供槽函数使用。 More interest…...

Tcp是怎样进行可靠准确的传输数据包的?

概述 很多时候,我们都在说Tcp协议,Tcp协议解决了什么问题,在实际工作中有什么具体的意义,想到了这些我想你的技术会更有所提升,Tcp协议是程序员编程中的最重要的一块基石,Tcp是怎样进行可靠准确的传输数据…...

[SWPUCTF 2022 新生赛]numgame

这道题有点东西网页一段计算框,只有加和减数字,但是永远到大不了20,页面也没啥特别的,准备看源码,但是打不开,我以为是环境坏掉了,看wp别人也这样,只不过大佬的开发者工具可以打开&a…...

java异常机制分析

java异常机制分析 本文实例分析了java的异常机制,分享给大家供大家参考。相信有助于大家提高大家Java程序异常处理能力。具体分析如下: 众所周知,java中的异常(Exception)机制很重要,程序难免会出错,异常机制可以捕获…...

浅谈Python中的内存管理 程序的内存布局

Python中的内存管理 Python 的内存管理是通过私有堆空间来实现的。这个私有堆内存中存储了所有 Python 对象和数据结构。Python 的解释器自身则拥有对堆空间的访问权,程序员不能直接访问这个私有堆,但可以通过解释器的 API 来进行某些操作。 以下是 Py…...

(具体解决方案)训练GAN深度学习的时候出现生成器loss一直上升但判别器loss趋于0

今天小陶在训练CGAN的时候出现了绷不住的情况,那就是G_loss(生成器的loss值)一路狂飙,一直上升到了6才逐渐平稳。而D_loss(判别器的loss值)却越来越小,具体的情况就看下面的图片吧。其实这在GAN…...

Redis 安装以及配置隧道连接

目录 1.CentOS 1. 安装Redis 2. Redis 启动和停⽌ 3. 操作Redis 2.Ubuntu 1. 安装Redis 2. Redis 启动/停⽌ 3. 操作 Redis 3.开启隧道 3.1 Xshell 配置隧道 3.2 windTerm 配置隧道 3.3 FinalShell配置隧道 4.可视化客户端连接 Another Redis Desktop Manager 1.Cen…...

FFmpeg 使用总结

FFmpeg 简介 FFmpeg的名称来自MPEG视频编码标准,前面的“FF”代表“Fast Forward”,FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。可以轻易地实现多种视频格式之间的相互转换。包括如下几个部分&#xf…...

出现Error: Cannot find module ‘compression-webpack-plugin‘错误

错误: 解决:npm install --save-dev compression-webpack-plugin1.1.12 版本问题...

Elasticsearch 摄取管道 — 检测到管道的死循环

在数据处理和摄取领域,管道在组织和自动化数据从源到目的地的流动方面发挥着至关重要的作用。 管道是数据按顺序通过的一系列处理阶段,每个阶段负责特定任务。 然而,有时,管道可能会遇到一个重大挑战,称为 “Cycle det…...

C# ListBox自动滚动方法

1、方法1:添加记录后,选择最后一条记录,让滚动条滚动到底部,再自动取消 listBox1.Items.Add(t ":a good day"); listBox1.SelectedIndex listBox1.Items.Count - 1; listBox1.SelectedIndex -1; //是否取消选中行…...

使用(Ajax原理)Promise + XHR实现请求数据

使用Promise XHR获取省份列表 步骤&#xff1a; * 1. 创建Promise对象 * 2. 执行XHR异步代码&#xff0c;获取省份列表 * 3. 关联成功或失败函数&#xff0c;做后续处理 代码示例 <script>// 1. 创建Promise对象const p new Promise((resolve,reject) > {// 2. 执行…...

【HTML】<input>

分类 text password number button reset submit hidden radio checkbox file image color range tel email&#xff08;火狐有校验&#xff0c;360浏览器无校验。&#xff09; url datetime&#xff08;火狐、360浏览器不支持&#xff09; search date、month、week、time、da…...

数据结构中一些零碎且易忘的知识点

树 并查集&#xff1a; 并查集的应用&#xff1a; 判断连通性、判环Kruskal算法排序并查集 并查集的存储方式 逻辑&#xff1a;双亲表示法的树存储&#xff1a;数组 并查集的时间复杂度&#xff08;m为并查集长度&#xff09; find&#xff1a;优化前为 O ( m ) O(m) O(m)&…...

2023上半年京东烘干机行业品牌销售排行榜(京东商品数据)

随着人们消费水平的提高&#xff0c;追求健康品质消费的用户越来越多&#xff0c;这样的消费升级为市场的发展带来很大的动力。同时&#xff0c;随着洗衣机市场趋向饱和&#xff0c;增长趋于平缓&#xff0c;更新换代和结构升级成为行业的主旋律。 在这一市场背景下&#xff0…...

ADS版图画封装学习笔记

ADS版图画封装 因为晶体管ATF54143在ADS中是没有封装的&#xff0c;所以要在ADS中画ATF54143的封装&#xff0c;操作步骤如下&#xff1a; 在ADS中新建layout&#xff0c;命名为ATF54143_layout&#xff0c; 根据datasheet知道封装的大小&#xff0c;进行绘制 在layout的con…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...

前端调试HTTP状态码

1xx&#xff08;信息类状态码&#xff09; 这类状态码表示临时响应&#xff0c;需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分&#xff0c;客户端应继续发送剩余部分。 2xx&#xff08;成功类状态码&#xff09; 表示请求已成功被服务器接收、理解并处…...

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”&#xff1a;输入模块&#xff08;GPIO、温度、V_REFINT&#xff09;1.4.2 信号 “调度站”&#xff1a;多路开关1.4.3 信号 “加工厂”&#xff1a;ADC 转换器&#xff08;规则组 注入…...