Linux基础项目开发1:量产工具——显示系统(二)

前言:

前面我们已经对这个项目的基本框架有了一个初步的了解与认识,要实现显示管理器与输入管理器,有输入有输出基本就实现这个项目的大部分功能了,首先我们先来做显示系统,对于上层系统为了让程序更好扩展,我们得添加一个显示管理器,在下面有各种设备,就比如有Framebuflerweb输出。

一、数据结构抽象

        我们添加的一个显示管理器中有Framebuflerweb输出,对于俩个不同的设备我们需要抽象出同一个结构体类型。

1.使用场景

        在上图中我们可以将其分为两层,上层要获得下层某个结构体,通过这个结构体中的函数来操作、绘制、刷新上层的界面。

        所有我们需要定义一个统一的结构体DispOpr

 2.disp_manager.h

  1 #ifndef _DISP_MANAGER_H
  2 #define _DISP_MANAGER_H
  3
  4 typedef struct Region {
  5     int iLeftUpX;                //左上角x坐标
  6     int iLeftUpY;                //左上角y坐标
  7     int iWidth;                  //宽度
  8     int iHeigh;                  //高度
  9 }Region, *PRegion;
 10
 11 typedef struct DispOpr {
 12     char *name;                  //显示模块的名字 
 13     char *GetBuffer(int *pXres, int *pYres, int *pBpp);//分辨率(长和宽)每个像素占据多少位
 14     int FlushRegion(PRegion ptRegion, char *buffer);//刷出某个区域
 15     struct DispOpr *ptNext;      //链表
 16 };
 17
 18 #endif
 19

第1~2行:防止头文件在.c文件中多次定义

第4~9行:定义刷新区域结构体

第11~16行:定义统一管理的结构体

二、Framebuffer编程

1.disp_manager.h

  1 #ifndef _DISP_MANAGER_H
  2 #define _DISP_MANAGER_H
  3
  4 typedef struct Region {
  5     int iLeftUpX;
  6     int iLeftUpY;
  7     int iWidth;
  8     int iHeigh;
  9 }Region, *PRegion;
 10
 11 typedef struct DispOpr {
 12     char *name;
 13     int DeviceInit(void);
 14     int DeviceExit(void);
 15     char *GetBuffer(int *pXres, int *pYres, int *pBpp);
 16     int FlushRegion(PRegion ptRegion, char *buffer);
 17     struct DispOpr *ptNext;
 18 }DispOpr, *PDispOpr;
 19
 20 #endif

第13行:初始化函数定义

第14行:退出函数定义

2.framebuffer.c

  1 #include <sys/mman.h>
  2 #include <sys/types.h>
  3 #include <sys/stat.h>
  4 #include <unistd.h>
  5 #include <linux/fb.h>
  6 #include <fcntl.h>
  7 #include <stdio.h>
  8 #include <string.h>
  9 #include <sys/ioctl.h>
 10
 11 #include "disp_manager.h"
 12
 13 static int fd_fb;                       //framebuffer文件
 14 static struct fb_var_screeninfo var;    /* Current var */
 15 static int screen_size;                 //framebuffer长度
 16 static unsigned char *fb_base;          //framebuffer地址
 17 static unsigned int line_width;
 18 static unsigned int pixel_width;
 19
 20 static int DeviceInit(void)
 21 {
 22     fd_fb = open("/dev/fb0", O_RDWR);
 23     if (fd_fb < 0)
 24     {
 25         printf("can't open /dev/fb0\n");
 26         return -1;
 27     }
 28     if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
 29     {
 30         printf("can't get var\n");
 31         return -1;
 32     }
 33
 34     line_width  = var.xres * var.bits_per_pixel / 8;
 35     pixel_width = var.bits_per_pixel / 8;
 36     screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
 37     fb_base = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
 38     if (fb_base == (unsigned char *)-1)
 39     {
 40         printf("can't mmap\n");
 41         return -1;
 42     }
 43
 44     return 0;
 45 }
 46
 47 static int DeviceExit(void)
 48 {
 49     munmap(fb_base, screen_size);
 50     close(fd_fb);
 51     return 0;
 52 }
 53
 54
 55 /* 可以返回LCD的framebuffer, 以后上层APP可以直接操作LCD, 可以不用FbFlushRegion
 56  * 也可以malloc返回一块无关的buffer, 要使用FbFlushRegion刷到LCD上
 57  */
 58 static int FbGetBuffer(PDispBuff ptDispBuff);
 59
 60 {
 61     ptDispBuff->iXres = var.xres;
 62     ptDispBuff->iYres = var.yres;
 63     ptDispBuff->iBpp  = var.bits_per_pixel;
 64     ptDispBuff->buff  = (char *)fb_base;
 65     return 0;
 66 }
 67
 68 static int FbFlushRegion(PRegion ptRegion, PDispBuff ptDispBuff)
 69 {
 70     return 0;
 71 }
 72
 73
 74 static DispOpr g_tFramebufferOpr = {
 75     .name        = "fb",
 76     .DeviceInit  = FbDeviceInit,
 77     .DeviceExit  = FbDeviceExit,
 78     .GetBuffer   = FbGetBuffer,
 79     .FlushRegion = FbFlushRegion,
 80 };
 81
 82
 83 void FramebufferInit(void)
 84 {
 85     RegisterDisplay(&g_tFramebufferOpr);
 86 }
 87

 20 static int DeviceInit(void)

第20~45行:初始化函数

 47 static int DeviceExit(void)

第47~52行:退出函数

第58~66行的FbGetBuffer是已经封装好的,详细封装过程后续会讲

第61~62行:设置分辨率

第63行:设置bpp

74 static DispOpr g_tFramebufferOpr

第74~80行:上层代码可以根据这个结构体里的函数来初始化LCD来得到Buffer

        第78行:通过.GetBuffer   = FbGetBuffer来构建好图像和文字

        第79行:通过.FlushRegion = FbFlushRegion来刷新到LCD上

第83~86行:注册结构体g_tFramebufferOpr,详细介绍在三、显示管理

        

三、显示管理

        上层函数想要选择哪个设备进行显示,需要中间加一个函数进行选择,起到承上启下的作用,用来实现显示管理,是操作Framebuffer还是WEB设备,需要进行选择某个模块,好可以提供一些函数,描点等

1.disp_manager.h

  1 #ifndef _DISP_MANAGER_H
  2 #define _DISP_MANAGER_H
  3
  4 #ifndef NULL
  5 #define NULL (void *)0
  6 #endif
  7
  8 typedef struct DispBuff {
  9     int iXres;     //x坐标分辨率
 10     int iYres;     //y坐标分辨率
 11     int iBpp;      //bpp
 12     char *buff;    缓冲区地址
 13 }DispBuff, *PDispBuff;
 14
 15
 16 typedef struct Region {
 17     int iLeftUpX;
 18     int iLeftUpY;
 19     int iWidth;
 20     int iHeigh;
 21 }Region, *PRegion;
 22
 23 typedef struct DispOpr {
 24     char *name;
 25     int (*DeviceInit)(void);
 26     int (*DeviceExit)(void);
 27     int (*GetBuffer)(PDispBuff ptDispBuff);
 28     int (*FlushRegion)(PRegion ptRegion, PDispBuff ptDispBuff);
 29     struct DispOpr *ptNext;
 30 }DispOpr, *PDispOpr;
 31
 32 void RegisterDisplay(PDispOpr ptDispOpr);
 33
 34 void DisplayInit(void);
 35 int SelectDefaultDisplay(char *name);
 36 int InitDefaultDisplay(void);
 37 int PutPixel(int x, int y, unsigned int dwColor);
 38 int FlushDisplayRegion(PRegion ptRegion, PDispBuff ptDispBuff);
 39 PDispBuff GetDisplayBuffer(void);
 40
 41
 42 #endif

第8~13行:进一步封装GetBuffer(int *pXres, int *pYres, int *pBpp)

第27行:将4~9行的PDispBuff保存到GetBuffer

第32行:定义注册函数RegisterDisplay

第34行:调用底层提供的模块

第35行:定义选择模块函数

第36行:选择默认的SelectDefaultDisplay后,我们还需要定义初始化函数

第37行:提供绘制图像函数

第38行:将绘制好的图像刷新到硬件上

第39行:返回取址 

2.disp_manager.c

  1 #include <disp_manager.h>
  2 #include <stdio.h>
  2 #include <string.h>
  2
  3 /* 管理底层的LCD、WEB */
  4 static PDispOpr g_DispDevs = NULL;
  5 static PDispOpr g_DispDefault = NULL;
  6 static DispBuff g_tDispBuff;
  7 static int line_width;
  8 static int pixel_width;
  9
 10 int PutPixel(int x, int y, unsigned int dwColor)
 11 {
 12     unsigned char *pen_8 = (*unsigned char*)(g_tDispBuff.buff+y*line_width+x*pixel_width);
 13     unsigned short *pen_16;
 14     unsigned int *pen_32;
 15
 16     unsigned int red, green, blue;
 17
 18     pen_16 = (unsigned short *)pen_8;
 19     pen_32 = (unsigned int *)pen_8;
 20
 21     switch (g_tDispBuff.iBpp)
 22     {
 23         case 8:
 24         {
 25             *pen_8 = dwColor;
 26             break;
 27         }
 28         case 16:
 29         {
 30             /* 565 */
 31             red   = (dwColor >> 16) & 0xff;
 32             green = (dwColor >> 8) & 0xff;
 33             blue  = (dwColor >> 0) & 0xff;
 34             dwColor = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
 35             *pen_16 = dwColor;
 36             break;
 37         }
 38         case 32:
 39         {
 40             *pen_32 = dwColor;
 41             break;
 42         }
 43         default:
 44         {
 45             printf("can't surport %dbpp\n", g_tDispBuff.iBpp);
 45             return -1;
 46             break;
 47         }
 48     }
 48      return 0;
 49 }
 50
 51
 52
 53 void RegisterDisplay(PDispOpr ptDispOpr)
 54 {
 55     ptDispOpr->ptNext = g_DispDevs;
 56     g_DispDevs = ptDispOpr;
 57 }
 58
 59
 60 int SelectDefaultDisplay(char *name)
 61 {
 62     PDispOpr pTmp = g_DispDevs;
 63     while (pTmp)
 64     {
 65         if (strcmp(name, pTmp->name) == 0)
 66         {
 67             g_DispDefault = pTmp;
 68             return 0;
 69         }
 70
 71         pTmp = pTmp->ptNext;
 72     }
 73
 74     return -1;
 75 }
 76
 77 int InitDefaultDisplay(void)
 78 {
 79     int ret;
 80
 81     ret = g_DispDefault->DeviceInit();
 82     if (ret)
 83     {
 84         printf("DeviceInit err\n");
 85         return -1;
 86     }
 87
 88
 89     ret = g_DispDefault->GetBuffer(&g_tDispBuff);
 90     if (ret)
 91     {
 92         printf("GetBuffer err\n");
 93         return -1;
 94     }
 95
 96     line_width  = g_tDispBuff.iXres * g_tDispBuff.iBpp/8;
 97     pixel_width = g_tDispBuff.iBpp/8;
 98
 99     return 0;
100 }
101
102
103 int FlushDisplayRegion(PRegion ptRegion, PDispBuff ptDispBuff)
104 {
105     return g_DispDefault->FlushRegion(ptRegion, ptDispBuff);
106 }
107
108
109 void DisplayInit(void)
110 {
111     void FramebufferInit(void);
112     FramebufferInit();
113 }
114
115 PDispBuff GetDisplayBuffer(void)
116 {
117    return &g_tDispBuff;
118 }

 第4行:将底层的LCD、WEB所实现的结构体放入到链表(指针)中,所以我们需要提供一个函数。void RegisterDisplay(PDispOpr ptDispOpr)

 第5行:存放找到名字的新链表

 第6行:定义一个全局变量 g_tDispBuff之后用来放第89行中GetBuffer中的(int* pxres, int * pYres, int * pBpp)

53 void RegisterDisplay(PDispOpr ptDispOpr)

  第53~57行:构造注册函数,将typedef struct DispOpr这个结构体注册到g_DispDevs链表中

        第55行:传入底层结构体指针ptDispOpr指向链表头g_DispDevs

        第56行:链表头g_DispDevs指向ptDispOpr

109 void DisplayInit(void)

第109~112行:调用底层提供的 FramebufferInit();目前我们只需要调用FramebufferInit()即可,还没有实现WEB的功能

        如果g_DispDevs链表中有好几个模块,那我们应该如何选择呢,现在我们就要设计一个模块选择函数进行模块的选择 

60 int SelectDefaultDisplay(char *name)

第60~75行:模块选择函数

        定义一个临时指针pTmp存放链表头

        while循环里根据名字name找到那一项

        找到的名字放到新链表g_DispDefault中,在第五行中有定义

        第71行,如果这个不对,这找寻下一个是否正确     

        因为上层需要通过中间的显示管理来绘制图像,坐标反馈给底层进行反应,所有需要在中间层加入绘制函数

10 int PutPixel(int x, int y, unsigned int dwColor)

第7~8行:每个像素占据多长多少像素可以先定义好,事先计算好,每一行多少字节,每个像素多少宽度,这个在InitDefaultDisplay()中已经计算好了

第10~49行:设置绘制图像函数

        函数内表示绘制的x、y坐标和绘制图像的颜色       

        第12行:g_tDispBuff.buff是写存的基地址

        第21行:g_tDispBuff.iBpp是每个像素的宽度

   

       想要在上层显示一个像素,首先需要得到一块内存,内存可以调用到底层提供的结构体,里面的g_tDispBuff这个函数,在上层得到一个新的buf,在这块buf里面绘制图像,但是g_tDispBuff不可以放到PutPixel,我们需要再定义一个函数: InitDefaultDisplay(void)

选择默认的SelectDefaultDisplay后,我们还需要初始化

 77 int InitDefaultDisplay(void)

第77~100行:

           第81行: 调用 g_DispDefault 中的DeviceInit()

           第89行: 调用 g_DispDefault  中的GetBuffer(&g_tDispBuff)

           这里我们需要定义一个新的GetBuffer结构体,把它的(int* pxres, int * pYres, int * pBpp)再次进行封装,封装结构体在disp_manager.h中的DispBuff

           第89行:将GetBuffer中的(int* pxres, int * pYres, int * pBpp)放到全局变量 g_tDispBuff

           第96行:line_width表示每一行占据多少个字节

           第97行:pixel_width表示每个像素的宽度

        当我们上层已经通过 PutPixel 已经绘制好图像,那我们就需要把它刷到硬件上,我们需要再提供一个函数FlushDisplayRegion

103 int FlushDisplayRegion(PRegion ptRegion, PDispBuff ptDispBuff)

        第105行:调用底层设备提供的FlushRegion函数

        返回取址 

114 PDispBuff GetDisplayBuffer(void)

献上韦东山老师对以上代码流程的梳理过程:

电子产品量产工具显示系统代码流程

四、测试单元

book@100ask:~/04_disp_unittest/display$ vi Makefile

1.通用Makefile

  1
  2 CROSS_COMPILE ?=
  3 AS      = $(CROSS_COMPILE)as
  4 LD      = $(CROSS_COMPILE)ld
  5 CC      = $(CROSS_COMPILE)gcc
  6 CPP     = $(CC) -E
  7 AR      = $(CROSS_COMPILE)ar
  8 NM      = $(CROSS_COMPILE)nm
  9
 10 STRIP       = $(CROSS_COMPILE)strip
 11 OBJCOPY     = $(CROSS_COMPILE)objcopy
 12 OBJDUMP     = $(CROSS_COMPILE)objdump
 13
 14 export AS LD CC CPP AR NM
 15 export STRIP OBJCOPY OBJDUMP
 16
 17 CFLAGS := -Wall -O2 -g
 18 CFLAGS += -I $(shell pwd)/include
 19
 20 LDFLAGS :=
 21
 22 export CFLAGS LDFLAGS
 23
 24 TOPDIR := $(shell pwd)
 25 export TOPDIR
 26
 27 TARGET := test
 28
 29
 30 obj-y += display/
 31 obj-y += unittest/
 32
 33 all : start_recursive_build $(TARGET)
 34     @echo $(TARGET) has been built!
 35
 36 start_recursive_build:
 37     make -C ./ -f $(TOPDIR)/Makefile.build
 38
 39 $(TARGET) : built-in.o
 40     $(CC) -o $(TARGET) built-in.o $(LDFLAGS)
 41
 42 clean:
 43     rm -f $(shell find -name "*.o")
 44     rm -f $(TARGET)
 45
 46 distclean:
 47     rm -f $(shell find -name "*.o")
 48     rm -f $(shell find -name "*.d")
 49     rm -f $(TARGET)
 50

第27行:编译出test的应用程序

第30行:指定display下的目录

第31行:指定unittest下的目录 

 2.display下的Makefile


  1 EXTRA_CFLAGS  :=
  2 CFLAGS_file.o :=
  3
  4 obj-y += disp_manager.o
  5 obj-y += framebuffer.o

3. unittest下的Makefile

  1 EXTRA_CFLAGS  :=
  2 CFLAGS_file.o :=
  3
  4 obj-y += disp_test.o

4.

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>

#include <disp_manager.h>

#define FONTDATAMAX 4096

static const unsigned char fontdata_8x16[FONTDATAMAX] = {
    //字符编码,由于太多就不展示了
    .........
}

void lcd_put_ascii(int x, int y, unsigned char c)
{
	unsigned char *dots = (unsigned char *)&fontdata_8x16[c*16];
	int i, b;
	unsigned char byte;

	for (i = 0; i < 16; i++)
	{
		byte = dots[i];
		for (b = 7; b >= 0; b--)
		{
			if (byte & (1<<b))
			{
				/* show */
				PutPixel(x+7-b, y+i, 0xffffff); /* 白 */
			}
			else
			{
				/* hide */
				PutPixel(x+7-b, y+i, 0); /* 黑 */
			}
		}
	}
}

int main(int argc, char **argv)
{
	Region region;                 //定义刷新区域的大小
	PDispBuff ptBuffer;
		
	DisplayInit();                 //调用DisplayInit()

	SelectDefaultDisplay("fb");    //选择默认的设备,传入一个名字为fd的设备

	InitDefaultDisplay();          //初始化这个默认的设备

	lcd_put_ascii(100, 100, 'A');  //在屏幕100,100的位置显示一个字母A

	region.iLeftUpX = 100;
	region.iLeftUpY = 100;
	region.iWidth   = 8;
	region.iHeigh   = 16;

	ptBuffer = GetDisplayBuffer();
	FlushDisplayRegion(&region, ptBuffer);//将这块区域刷到这个硬件中
	
	return 0;	
}


五、上板测试:

将原有的qt程序停止

[root@100ask:~]# systemctl stop myir

最终效果:在开发板上打印出字符A

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/197868.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python分享之字符串格式化 (%操作符)

在许多编程语言中都包含有格式化字符串的功能&#xff0c;比如C和Fortran语言中的格式化输入输出。Python中内置有对字符串进行格式化的操作%。 模板 格式化字符串时&#xff0c;Python使用一个字符串作为模板。模板中有格式符&#xff0c;这些格式符为真实值预留位置&#xff…

【Android Jetpack】Hilt 依赖注入框架

文章目录 依赖注入DaggerHiltKoin添加依赖项Hilt常用注解的含义HiltAndroidAppAndroidEntryPointInjectModuleInstallInProvidesEntryPoint Hilt组件生命周期和作用域如何使用 Hilt 进行依赖注入 依赖注入 依赖注入是一种软件设计模式&#xff0c;它允许客户端从外部源获取其依…

计算机丢失vcomp140.dll是什么意思,如何解决与修复(附教程)

vcomp140.dll缺失的5种解决方法以及vcomp140.dll缺失原因 引言&#xff1a; 在日常使用电脑的过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“vcomp140.dll缺失”。这个错误提示通常出现在运行某些程序或游戏时&#xff0c;给使用者带来了困扰。本文…

【蓝桥杯 LCA 差分】 砍树

题目分析&#xff1a; 这道题还是比较裸的一道书上差分的题目了 对于每一对标记点(x,y) 他们之间的路径就是 x − > L C A ( x , y ) − > y x->LCA(x,y)->y x−>LCA(x,y)−>y 这条路径上的每一条边都要经过。 那么对于一条边&#xff0c;什么时候砍掉这条…

【推荐系统】MMOE笔记 20231126

paper阅读 任务差异带来的固有冲突实际上会损害至少某些任务的预测&#xff0c;特别是当模型参数在所有任务之间广泛共享时。&#xff08;在说ESMM&#xff09; 共享底层参数可以减少过拟合风险&#xff0c;但是会遇到任务差异引起的优化冲突&#xff0c;因为所有任务都需要在…

Django二转Day02

http #1 http 是什么#2 http特点#3 请求协议详情 -请求首行---》请求方式&#xff0c;请求地址&#xff0c;请求协议版本 -请求头---》key:value形式 -referer&#xff1a;上一次访问的地址 -user-agenet&#xff1a;客户端类型 -name&#x…

JSP迭代标签之 forEach循环标签 基本使用讲解

好 之前我们讲完了 我们的条件动作标签 那么 我们来继续说 迭代标签 所谓迭代就是 将某个主体循环多次 也可以循环 集合 对象 map 这个标签叫 forEach items 就是 我们要循环的数据 注意 这里 操作的也是域对象中的值 begin 开始说 例如 i 0;i<x;i begin 就是开始数 当前…

1.Spring源码解析-ClassPathXmlApplicationContext

此类是读取spring的xml配置文件并解析。也是源码入口之一。 我们调试即将开始。 传递给父类设置值 经调试我们得到是给AbstractApplicationContext设置默认的应用上下文父级的值&#xff0c;很明显是空 给父类AbstractRefreshableConfigApplicationContext设置属性 刷新容器…

AMESim|学习记录

此文记录AMESim学习过程中的各种情况。 目录 01 王佳. AUV 浮力调节系统设计及控制策略研究[D]. 天津大学, 2017.01 王佳. AUV 浮力调节系统设计及控制策略研究[D]. 天津大学, 2017. 01 王佳. AUV 浮力调节系统设计及控制策略研究[D]. 天津大学, 2017. 开始步入正文 01 王佳.…

Open AI宫斗始末:董事会开除CEO再复职,这场闹剧终于结束了!

老哥们&#xff0c;作为一名在科技圈吃瓜前线的程序员&#xff0c;这几天open ai的瓜都吃到了吗&#xff1f;反转反转再反转&#xff0c;堪称职场版的《甄嬛传》&#xff01; 惊呆了&#xff0c;CEO被解雇又回归…… 在梳理open ai时间线之前&#xff0c;给大家先介绍一下这个…

C++基础 -9- 函数的默认参数

函数默认格式(图片代码段呈现) #include "iostream"using namespace std;void rlxy(int a100) {cout << a << endl; }int main() {rlxy();rlxy(99); }函数默认参数注意事项 函数的默认参数从左开始推导 错误写法 正确写法

029 - STM32学习笔记 - ADC(三) 独立模式单通道DMA采集

029 - STM32学习笔记 - 单通道DMA采集&#xff08;三&#xff09; 单通道ADC采集在上节中学习完了&#xff0c;这节在上节的内容基础上&#xff0c;学习单通道DMA采集。程序代码以上节的为基础&#xff0c;需要删除NVIC配置函数、中段服务子程序、R_ADC_Mode_Config()函数中使能…

UE 事件分发机制 day9

观察者模式原理 观察者模式通常有观察者与被观察者&#xff0c;当被观察者状态发生改变时&#xff0c;它会通知所有的被观察者对象&#xff0c;使他们能够及时做出响应&#xff0c;所以也被称作“发布-订阅模式”。总得来说就是你关注了一个主播&#xff0c;主播的状态改变会通…

西南科技大学C++程序设计实验二(类与对象一)

C++最大的特点就是面向对象,掌握它的几种基本性质还是好理解的,可以看我C++专栏的期末速成,希望对你们学习C++有帮助。 一、实验目的 1.理解简单类的定义、说明与使用 2.理解类中不同属性数据成员的访问特点 3.理解构造函数、析构函数的作用 重点:掌握类的定义与实现,…

成为AI产品经理——模型评估指标

目录 一、模型评估分类 1.在线评估 2.离线评估 二、离线模型评估 1.特征评估 ① 特征自身稳定性 ② 特征来源稳定性 ③ 特征成本 2.模型评估 ① 统计性评估 覆盖度 最大值、最小值 分布形态 ② 模型性能指标 分类问题 回归问题 ③ 模型的稳定性 模型评估指标分…

Java高级技术(反射:获取类)

一&#xff0c;认识反射 二&#xff0c; 反射第一步 三&#xff0c;案例

数据库的增删查改(CRUD)基础版

CRUD: create增加、retrieve查询、update更新、delete删除 注意一点&#xff1a;MySQL对大小写是不敏感的 目录 新增&#xff08;create&#xff09; 全列插入 指定列插入 多行插入 查询&#xff08;Retrieve&#xff09; 列查询 全列查询 指定列查询 表达式查询 …

【问题解决!】OSError: [WinError 1455] 页面文件太小,无法完成操作。Error loading “c:\Anaconda3\lib

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 问题描述问题原因二、解决方法 问题描述 在使用pytorch跑深度学习的时候报错OSError: [WinError 1455] 页面文件太小&#xff0c;无法完成操作。Error loading “c…

vivado产生报告阅读分析27

1、设计 QoR 汇总 命令行选项 -qor_summary 可用于为流程中每个步骤生成 QoR 汇总信息。该选项只能从 Tcl 控制台使用。该选项可按两种格式生成&#xff1a; 基于文本的报告或 JSON 格式。 要生成基于文本的格式 &#xff0c; 请运行以下命令 &#xff1a; report_des…