96SEO 2026-02-19 20:47 0
。

这是一套软件#xff0c;用在我们的实际生产中#xff0c;
工人只要按…电子产品量产测试与烧写工具。
这是一套软件用在我们的实际生产中
其他按钮无法点击接上对应模块后会自动测试测试通过时图标就会变绿。
上所有图标都变绿时就表示测试、烧写全部完成某项保持红色的话就表示对应模块测试失败。
详细介绍Linux基础项目开发1:量产工具——显示系统(二)_linux入门项目-CSDN博客
TouchscreenGetInputEvent(PInputEvent
NetinputGetInputEvent(PInputEvent
RegisterInputDevice(PInputDevice
详细介绍Linux基础项目开发1:量产工具——输入系统三)-CSDN博客
详细介绍Linux基础项目开发1:量产工具——文字系统四)-CSDN博客
详细介绍Linux基础项目开发1:量产工具——UI系统(五)_linux
详细介绍Linux基础项目开发1:量产工具——页面系统(六)-CSDN博客
处理输入事件GetButtonByInputEvent(PInputEvent
详细介绍Linux基础项目开发1:量产工具——业务系统(七)_量产工具开发-CSDN博客
初始化显示系统在disp_manager.c这个中间管理器中初始化显示器选择是framebuffer的应用端还是Web的网络端这里如果还想要加入其他设备都可以在这里调用这个设备的初始化函数这里我们先拿framebuffer举例。
假设有一个FramebufferInit函数用于初始化framebufferFramebufferInit();
这里会在framebuffer.c注册framebuffer操作的结构体到显示管理器的链表中。
{RegisterDisplay(g_tFramebufferOpr);
定义一个DispOpr结构体实例用于描述framebuffer的操作。
将上面的显示设备framebuffer操作的结构体注册到disp_manager.c这个链表中
当放到这个链表里后会有很多设备那么我们选择哪个模块呢这里我们就需要disp_manager.c中编写一个设备选择函数SelectDefaultDisplay(char
}这里disp_manager.h定义一个结构体DispOpr用于描述显示操作的接口。
DispOpr是结构体类型PDispOpr是指向DispOpr的指针类型*2.6
选择好了显示设备需要在disp_manager.c中编写初始化代码进行设备初始化
g_DispDefault-GetBuffer(g_tDispBuff);
}在这之前我们需要先在disp_manager.h中定义一个DispBuff用于存储显示缓冲区的信息这样会更好的调用显示缓冲信息。
DispBuff是结构体类型PDispBuff是指向DispBuff的指针类型2.7
调用framebuffer.c中的DeviceInit(void)进行初始化设备。
再调用framebuffer.c中的FbGetBuffer(PDispBuff
ptDispBuff)获取设备的framebuffer缓冲区信息。
想在这块内存上绘制一个像素再以这个像素作为起点确定图标来绘制图片绘制像素这个最基本的函数应该在disp_manager.c这里实现在屏幕上画一个像素点。
根据屏幕的bpp每像素位数计算像素在缓冲区中的位置unsigned
我们绘制好图像以后需要刷到硬件上面我们需要在disp_manager.c中再提供一个FlushDisplayRegion()函数。
g_DispDefault-FlushRegion(ptRegion,
初始化显示系统SelectDefaultDisplay(fb);
选择默认的显示设备这里是帧缓冲设备InitDefaultDisplay();
获取显示缓冲区FlushDisplayRegion(region,
详细介绍Linux基础项目开发1:量产工具——显示系统(二)_linux入门项目-CSDN博客
一个字符串用于存储与事件相关的额外信息长度限制为1024个字符char
指向函数的指针该函数用于获取输入事件。
它接受一个指向InputEvent结构体的指针作为参数并返回一个整数值int
指向函数的指针该函数用于初始化输入设备。
它不接受任何参数并返回一个整数值int
指向函数的指针该函数用于退出或释放输入设备。
它不接受任何参数并返回一个整数值int
指向另一个InputDevice结构体的指针用于链接多个输入设备形成链表struct
TouchscreenGetInputEvent,.DeviceInit
TouchscreenDeviceInit,.DeviceExit
TouchscreenGetInputEvent(PInputEvent
TouchscreenGetInputEvent(PInputEvent
INPUT_TYPE_TOUCH;ptInputEvent-iX
samp.pressure;ptInputEvent-tTime
如果初始化失败打印错误信息并返回-1printf(ts_setup
初始化触摸屏设备g_tTouchscreenDev.DeviceInit();//
g_tTouchscreenDev.GetInputEvent(event);//
如果获取事件失败打印错误信息并退出程序printf(GetInputEvent
NetinputGetInputEvent,.DeviceInit
NetinputGetInputEvent(PInputEvent
NetinputGetInputEvent(PInputEvent
INPUT_TYPE_NET;gettimeofday(ptInputEvent-tTime,
NULL);strncpy(ptInputEvent-str,
AF_INET;tSocketServerAddr.sin_port
*/tSocketServerAddr.sin_addr.s_addr
*/memset(tSocketServerAddr.sin_zero,
*/g_tNetinputDev.DeviceInit();/*
g_tNetinputDev.GetInputEvent(event);if
*///tSocketServerAddr.sin_addr.s_addr
将命令行参数指定的IP地址转换为网络字节序并设置到地址结构体中
tSocketServerAddr.sin_addr)){printf(invalid
*/memset(tSocketServerAddr.sin_zero,
注释掉的部分是尝试进行TCP风格的连接但由于是UDP套接字这里实际上不会进行连接操作
在input_manager.c中向上提供一个InputInit(void)
TouchscreenRegister(void);TouchscreenRegister();/*
NetInputRegister(void);NetInputRegister();
中注册TouchscreenRegister(void)函数用于注册触摸屏设备到输入管理器
调用输入管理器的注册函数将触摸屏设备注册到输入管理器中RegisterInputDevice(g_tTouchscreenDev);
TouchscreenGetInputEvent,.DeviceInit
TouchscreenDeviceInit,.DeviceExit
中注册NetInputRegister(void)函数用于注册网络设备到输入管理器
{RegisterInputDevice(g_tNetinputDev);
NetinputGetInputEvent,.DeviceInit
RegisterInputDevice(PInputDevice
g_InputDevs的链表头g_InputDevs这个链表中存放设备。
将所有设备放到一个链表中
RegisterInputDevice(PInputDevice
在input_manager.c中向上提供一个IntpuDeviceInit(void)对于每个设备初始化它并且创建线程
中创建*input_recv_thread_func(void
ptInputDev-GetInputEvent(tEvent);if
*/pthread_mutex_lock(g_tMutex);PutInputEventToBuffer(tEvent);/*
*/pthread_cond_signal(g_tConVar);pthread_mutex_unlock(g_tMutex);}}return
,最上层的代码只要调用这个函数就可以得到这些设备的数据得到线程数据则返回数据无数据则休眠
*/pthread_mutex_lock(g_tMutex);
(GetInputEventFromBuffer(tEvent))
将获取的事件复制到传入的指针所指向的变量pthread_mutex_unlock(g_tMutex);
(GetInputEventFromBuffer(tEvent))
设置返回值为-1表示获取事件失败}pthread_mutex_unlock(g_tMutex);
在input_manager.c中编写环形缓冲区也是一个一维数组并不是一个环形的数组用于保存各个输入设备得到的数据
PutInputEventToBuffer(PInputEvent
(!isInputBufferFull()){g_atInputEvents[g_iWrite]
GetInputEventFromBuffer(PInputEvent
(!isInputBufferEmpty()){*ptInputEvent
g_atInputEvents[g_iRead];g_iRead
再次打印并显示GetInputEvent函数的返回值printf(%s
如果返回值不是0表示获取事件时出错printf(GetInputEvent
详细介绍Linux基础项目开发1:量产工具——输入系统三)-CSDN博客
FontBitMap是结构体类型PFontBitMap是指向该结构体的指针类型
因为显示系统和文字系统都需要用到这个区域结构体所以我们直接把它拿出来定义成一个公共的头文件common.h
在font_manager.h定义字体操作结构体用于管理不同字体的操作函数
FontOpr是结构体类型PFontOpr是指向该结构体的指针类型*4.3
在freetype.c中定义一个字体操作结构体包含字体名字、字体初始化、设置字体大小、获取字体位图等函数指针
定义一个字体操作结构体包含字体初始化、设置字体大小、获取字体位图等函数指针
FreeTypeSetFontSize,.GetFontBitMap
(error){printf(FT_Init_FreeType
设置字体大小FT_Set_Pixel_Sizes(g_tFace,
设置字体大小FT_Set_Pixel_Sizes(g_tFace,
设置变换矩阵FT_Set_Transform(g_tFace,
设置字体位图的区域信息ptFontBitMap-tRegion.iLeftUpX
slot-bitmap_left;ptFontBitMap-tRegion.iLeftUpY
slot-bitmap_top;ptFontBitMap-tRegion.iWidth
slot-bitmap.width;ptFontBitMap-tRegion.iHeigh
slot-bitmap.rows;ptFontBitMap-iNextOriginX
ptFontBitMap-iCurOriginY;return
我们可能要用到的字体有多种那么怎么选择用哪个字符呢所以我们要编写一个程序管理多种字符。
在font_manager.c注册字体操作结构体这里示例了注册FreeType字体
FreetypeRegister(void);FreetypeRegister();
g_ptDefaulFontOpr-SetFontSize(iFontSize);
g_ptDefaulFontOpr-GetFontBitMap(dwCode,
ptFontBitMap-tRegion.iLeftUpX;//
ptFontBitMap-tRegion.iLeftUpY;//
如果位图缓冲区中该像素点有数据即需要绘制的点则用指定颜色在屏幕上绘制该像素if
初始化显示设备DisplayInit();SelectDefaultDisplay(fb);InitDefaultDisplay();ptBuffer
(error){printf(SelectAndInitFont
设置字体大小SetFontSize(font_size);//
(error){printf(SelectAndInitFont
绘制字符到缓冲区DrawFontBitMap(tFontBitMap,0xff0000);
刷新显示区域FlushDisplayRegion(tFontBitMap.tRegion,
tFontBitMap.iNextOriginY;i;}return
详细介绍Linux基础项目开发1:量产工具——文字系统四)-CSDN博客
Interface(用户界面)有图像界面(GUI)等我们的UI系统就是构造各类GUI元素比如按钮(目前只实现按钮)
在ui.h定义Button结构体包含按钮的名称、状态、区域、绘制函数和按下处理函数
定义Button结构体包含按钮的名称、状态、区域、绘制函数和按下处理函数
Button是结构体类型PButton是指向Button的指针类型*5.2
设置绘制函数如果未提供则使用默认绘制函数ptButton-OnPressed
在disp_manager.c中将ptRegion这一部分区域绘制成dwColor的颜色
对于每个像素调用PutPixel函数来设置像素的颜色PutPixel(i,
在disp_manager.c中实现函数DrawTextInRegionCentral用于在指定区域内居中显示文本
函数DrawTextInRegionCentral用于在指定区域内居中显示文本
如果计算出的字体大小超过了区域的高度则将字体大小设置为区域的高度if
设置字体大小SetFontSize(iFontSize);//
获取当前字符的字体位图tFontBitMap.iCurOriginX
iOriginX;tFontBitMap.iCurOriginY
(error){printf(SelectAndInitFont
在缓冲区上绘制当前字符的字体位图DrawFontBitMap(tFontBitMap,
tFontBitMap.iNextOriginX;iOriginY
*/DrawTextInRegionCentral(ptButton-name,
*/FlushDisplayRegion(ptButton-tRegion,
*/DrawTextInRegionCentral(ptButton-name,
*/FlushDisplayRegion(ptButton-tRegion,
定义显示缓冲区和错误代码的指针以及按钮和区域的结构体PDispBuff
选择默认的显示操作接口这里假设fb是一个帧缓冲设备SelectDefaultDisplay(fb);//
初始化默认的显示操作接口InitDefaultDisplay();//
选择并初始化字体这里使用的是freetype字体字体大小由命令行参数指定error
(error){printf(SelectAndInitFont
初始化按钮设置按钮的文本和区域以及回调函数InitButton(tButton,
详细介绍Linux基础项目开发1:量产工具——UI系统(五)_linux
指向执行页面动作的函数指针该函数接受一个void指针参数void
指向下一个PageAction结构体的指针用于链表结构struct
将新动作的下一个指针指向当前链表的头ptPageAction-ptNext
MainPage定义一个静态的PageAction结构体变量表示主页面动作
包含页面管理器头文件这个文件中声明了页面动作相关的结构体和函数
使用printf打印文件名、函数名和当前行号用于调试信息printf(%s
调用页面管理器的注册函数将主页面动作添加到页面动作链表中PageRegister(g_tMainPage);
包含页面管理器头文件这个文件中声明了页面动作相关的结构体和函数
注册所有页面动作这通常会在程序启动时执行PagesRegister();//
这里传递了一个NULL参数表示没有额外的参数传递给Run函数Page(main)-Run(NULL);//
详细介绍Linux基础项目开发1:量产工具——页面系统(六)-CSDN博客
包含内存管理、系统类型、文件状态、Unix标准函数、Linux帧缓冲设备、文件控制、标准输入输出、字符串处理、输入输出控制和标准库函数相关的头文件
检查命令行参数的数量如果不等于2程序名和字体文件名则打印使用说明并返回错误码if
选择默认的显示设备这里是帧缓冲设备SelectDefaultDisplay(fb);//
初始化默认的显示设备InitDefaultDisplay();//
初始化输入系统包括输入设备的初始化InputInit();IntpuDeviceInit();//
注册并初始化字体系统FontsRegister();error
(error){printf(SelectAndInitFont
程序开始运行进入main函数首先检查命令行参数的数量。
如果参数数量不等于2一个是程序自身的路径另一个是字体文件的路径则打印使用说明并返回错误码程序结束。
如果命令行参数数量正确程序会进行显示系统的初始化DisplayInit。
这可能包括分配内存、设置显示分辨率等操作。
然后程序会选择默认的显示设备SelectDefaultDisplay在这个例子中是帧缓冲设备frame
buffer并初始化该显示设备InitDefaultDisplay。
帧缓冲设备是一种可以直接在内存中操作像素来绘制图像的设备。
接下来程序会初始化输入系统InputInit和IntpuDeviceInit。
输入设备的初始化。
然后程序会注册并初始化字体系统FontsRegister和SelectAndInitFont。
字体文件的路径从命令行参数中获取。
如果字体选择和初始化失败程序会打印错误信息并返回错误码结束运行。
接着程序会注册页面系统PagesRegister。
页面系统通常用于管理GUI的各个页面如主页、菜单页等。
最后程序会运行主页面Page(main)-Run(NULL)。
这通常意味着显示主页面并等待用户的输入。
在config.h中定义一个结构体用于表示配置文件中的一个条目
ItemCfg是结构体类型PItemCfg是指向该结构体的指针类型
定义一个静态数组用于存储配置文件中的条目最大数量由ITEMCFG_MAX_NUM定义
g_tItemCfgs[ITEMCFG_MAX_NUM];//
*/g_tItemCfgs[g_iItemCfgCount].command[0]
初始化命令字段为空字符串g_tItemCfgs[g_iItemCfgCount].index
g_tItemCfgs[g_iItemCfgCount].name,
g_tItemCfgs[g_iItemCfgCount].bCanBeTouched,
\g_tItemCfgs[g_iItemCfgCount].command);
在config.h中定义一个函数用于根据索引获取配置文件中的条目
在config.h中定义一个函数用于根据名称获取配置文件中的条目
MainPageRun它负责读取配置文件、生成按钮和界面并进入一个无限循环来监听和处理
GetButtonByInputEvent(tInputEvent);
在main_page.c中根据屏幕的分辨率和按钮总数计算每个按钮的大小和位置并居中显示这些按钮。
按钮的宽度和高度根据屏幕分辨率和黄金分割比0.618进行计算以确定其尺寸同时保留了一定的间隔X_GAP
Y_GAP。
代码中利用两层嵌套循环计算并设置每个按钮的位置和区域并对每个按钮对象进行初始化和绘制。
获取当前按钮对象的引用pButton-tRegion.iLeftUpX
设置按钮的左上角x坐标pButton-tRegion.iLeftUpY
设置按钮的左上角y坐标pButton-tRegion.iWidth
设置按钮的宽度并减去预设的间隔pButton-tRegion.iHeigh
遍历所有按钮对象g_tButtons[i].OnDraw(g_tButtons[i],
处理输入事件GetButtonByInputEvent(PInputEvent
的函数其目的是根据提供的输入事件来寻找对应的按钮对象。
输入事件
以及与特定事件类型相关的数据例如触摸事件的坐标或网络事件的字符串数据。
GetButtonByInputEvent(PInputEvent
(isTouchPointInRegion(ptInputEvent-iX,
解析网络事件中的字符串提取按钮名称sscanf(ptInputEvent-str,
函数首先检查触摸点的X坐标是否在区域的左边界和右边界之间。
如果触摸点的X坐标小于区域的左上角X坐标或者大于或等于左上角X坐标加上区域的宽度即右下角X坐标则触摸点不在区域内函数返回0。
接着函数检查触摸点的Y坐标是否在区域的上边界和下边界之间。
如果触摸点的Y坐标小于区域的左上角Y坐标或者大于或等于左上角Y坐标加上区域的高度即右下角Y坐标则触摸点不在区域内函数返回0。
如果触摸点的X和Y坐标都通过了上述检查即触摸点完全位于区域内函数返回1表示触摸点在区域内。
检查触摸点的X坐标是否在区域的左上角X坐标和右下角X坐标之间if
检查触摸点的Y坐标是否在区域的左上角Y坐标和右下角Y坐标之间if
的静态函数其目的是根据提供的名称来查找并返回对应的按钮对象。
函数接受一个字符串指针
使用strcmp函数比较传入的名称与当前按钮的名称是否相同if
的静态函数用于处理按钮的按下事件。
函数接受三个参数一个指向按钮结构体的指针
函数首先初始化按钮的颜色为默认颜色并准备用于存储名称和状态的缓冲区。
然后根据输入事件的类型触摸屏事件或网络事件执行不同的逻辑。
对于触摸屏事件函数检查按钮是否可以被点击如果可以则切换按钮的状态并相应地修改按钮的颜色。
对于网络事件函数从输入事件中解析出名称和状态并根据状态的不同设置按钮的颜色。
如果状态以数字开头则将按钮名称更新为该数字并设置为百分比颜色。
如果事件类型不是触摸屏或网络事件或者状态不符合任何条件函数返回-1。
最后函数绘制按钮的底色在按钮区域中央绘制文字并将更新后的按钮区域刷新到显示缓冲区然后返回0表示成功处理事件。
(GetItemCfgByName(ptButton-name)-bCanBeTouched
*/DrawTextInRegionCentral(strButton,
*/FlushDisplayRegion(ptButton-tRegion,
}详细介绍Linux基础项目开发1:量产工具——业务系统(七)_量产工具开发-CSDN博客
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback