Linux下的FrameBuffer驱动框架

news2024/11/17 6:24:58
一、RGB LCD经典显示器件介绍
1、LCD屏幕的重要属性参数
① 分辨率:也就是屏幕上的像素点的个数;
② 像素格式:即单个像素点RGB三种颜色的表达方式,包括RGB888、ARGB8888和RGB565等。
③ LCD屏幕硬件接口这里指的是RGB LCD排线接口如下图所示
R[7:0]、G[7:0]和B[7:0]这24根是数据线,DE、VSYNC、HSYNC和PCLK这四根是控制信号线 。RGB LCD一般有两种驱动模式DE模式和HV模式,这两个模式的区别是DE模式需要用到DE信号线,而HV模式不需要用到DE信号线, 在DE模式下是可以不需要HSYNC信号线的( DE与HSYNC功能相同 ,即使不接HSYNC信号线LCD也可以正常工作。
///
2、LCD的时间参数:( 重要
       如果将LCD显示一帧图像的过程想象成绘画,那么在显示的过程中就是用一根“笔”在不同的像素点画上不同的颜色。 这根笔按照 从左至右、从上到下 的顺序扫描每个像素点,并且在像素画上对应的颜色,当画到最后一个像素点的时候一幅图像就绘制好了。 假设一款LCD屏幕的分辨率为1024*600,如下图所示
       HSYNC是水平同步信号,也叫做行同步信号,当产生此信号的话就表示开始显示新的一行数据; VSYNC信号是垂直同步信号,也叫做帧同步信号,当产生此信号的话就表示开始显示新的一帧图像了。 当显示完一行以后会发出HSYNC信号,此时电子枪就会关闭,然后迅速的移动到屏幕的左边,当HSYNC信号结束以后就可以显示新的一行数据了,电子枪就会重新打开在HSYNC信号结束到电子枪重新打开之间会插入一段延时,这段延时就图 50.1.5中的HBP;当显示完一行以后就会关闭电子枪等待HSYNC信号产生,关闭电子枪到HSYNC信号产生之间会插入一段延时,这段延时就是图 50.1.5中的HFP信号。同理, 当显示完一帧图像以后电子枪也会关闭,然后等到VSYNC信号产生期间也会加入一段延时,这段延时就是图 50.1.5中的VFP;VSYNC信号产生,电子枪移动到左上角,当VSYNC信号结束以后电子枪重新打开,中间也会加入一段延时,这段延时就是图 50.1.5中的VBP
///
3、RGB LCD屏幕的时序( 底层核心
① 行显示的时序
HSYNC:行同步信号,当此信号有效的话就表示开始显示新的一行数据,查阅所使用的LCD数据手册可以知道此信号是低电平有效还是高电平有效, 假设此时是低电平有效
HSPW:有些地方也叫做thp,是HSYNC信号宽度, 也就是HSYNC信号持续时间。HSYNC信号不是一个脉冲,而是需要持续一段时间才是有效的, 单位为CLK
HBP:有些地方叫做thb,前面已经讲过了,术语 叫做行同步信号后肩单位是CLK
HOZNAL:有些地方叫做thd, 显示一行数据所需的时间,假如屏幕分辨率为1024*600,那么HOZVAL就是1024, 单位为CLK
HFP:有些地方叫做thf,前面已经讲过了,术语叫做行 同步信号前肩单位是CLK
    显示一行所需要的时间就是:HSPW + HBP + HOZVAL + HFP。单位:CLK。
② 帧显示的时序
VSYNC帧同步信号,当此信号有效的话就表示开始显示新的一帧数据,查阅所使用的LCD数据手册可以知道此信号是低电平有效还是高电平有效, 假设此时是低电平有效
VSPW:些地方也叫做tvp,是VSYNC信号宽度,也就是 VSYNC信号持续时间单位为1行的时间( 多少个HSYNC
VBP:有些地方叫做tvb,前面已经讲过了,术语叫做 帧同步信号后肩单位为1行的时间
LINE:有些地方叫做tvd, 显示一帧有效数据所需的时间,假如屏幕分辨率为1024*600,那么LINE就是600行的时间。 单位是1行的时间
VFP:有些地方叫做tvf,前面已经讲过了,术语叫做 帧同步信号前肩单位为1行的时间
      显示一帧所需要的时间就是:VSPW+VBP+LINE+VFP个行时间。
显示完整一帧图像的 clk时间 :T = (VSPW+VBP+LINE+VFP) * (HSPW + HBP + HOZVAL + HFP)。
///
//
二、Linux的FrameBuffer驱动框架
1、驱动框架的介绍
        帧缓冲(framebuffer)是Linux为显示设备提供的一个接口, 把显存抽象后的一种设备,他允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。所以在Linux系统中,凡是显示设备都被称为FrameBuffer设备(帧缓冲设备),所以LCD自然而言就是FrameBuffer设备。
         FrameBuffer设备对应的设备文件为/dev/fb*Linux下可支持多个FrameBuffer设备,最多可达32个,分别为/dev/fb0到/dev/fb31,如果没有指定系统所使用的显示设备,通常指向/dev/fb0,在嵌入式系统中支持一个显示设备就够了。在Linux系统中,FrameBuffer设备为标准字符设备,主设备号为29,次设备号则从0到31。分别对应/dev/fb0-/dev/fb31。
        在Linux系统中,FrameBuffer设备也有对应的设备驱动框架,我们把它叫做FrameBuffer驱动框架,所以Linux下编写LCD驱动我们就可以使用FrameBuffer驱动框架。 FrameBuffer驱动架构其实也是基于字符设备驱动来开发的,其内核源码位置在 drivers/video/fbdev/core/fbmem.c中。 其原理大概如下
① 内核源码基于字符设备驱动 在/dev目录下挂载fbxx设备,其 主设备号为29,此设备0~31
② 最多允许同时存在32个显示设备
③ 在字符设备的file_operations中, 实现了open、release、read、write以及memey、ioctl等函数
④ 这些函数其本质是调用了内核链表的一种 结构体对象struct fb_info
⑤ 作为驱动开发者,实际上 我们就是要描述并挂载一个struct fb_info对象,并初始化配置一下外设
2、LCD驱动开发的基本流程( 基于ZYNQ开发板
① 根据实际电路结构,在设备树上创建设备节点,比如:DMA、pclk、gpio、lcd外设驱动等;
② 在设备树上 按照内核的规定格式,描述lcd显示器件,包括lcd的 刷新频率、分辨率、像素格式等参数
③ 在设备树上描述的 LCD设备,需要基于某个CPU总线来扩展
④ 编写 基于platform_device的驱动程序,匹配设备树上的lcd设备节点;
⑤ 使用 函数接口 framebuffer_alloc动态创建一个struct fb_info对象,同时也为自定义结构体动态申请内存空间;
⑥ 先从设备节点上 获取lcd的pclk时钟( devm_clk_get函数 ,并调用 函数 clk_disable_unprepare先禁止时钟输出;
⑦ 从设备树上获取到lcd的属性参数描述信息( timingxx节点),并 返回到结构体struct videomode
⑧ 调用 函数 dma_alloc_wc获取lcd的dma对应的DDR物理缓存地址和虚拟地址;
配置struct fb_ops结构体,指定设备读写操作函数的具体实现,其中, 有些功能函数内核已经提供drivers/video/fbdev/core/cfbfillrect.c)可以直接引用;
⑩ 开始根据LCD的属性, 配置struct fb_info配置内容包括:显存缓存地址、LCD的fb_fix_screeninfo固定参数、LCD的fb_var_screeninfo动态参数;
11 调用函数fb_alloc_cmap来为lcd分配载流数据, 目前无法确定载流输出是啥
12 为显示设备的16色彩调色板动态分配内存空间;
13 设置LCD的pclk时钟KHz数值,并启动;
14 根据实际电路需求,配置vtc外设和dma外设,DMA外设配置有内核提供的架构可以使用;
15 调用函数 register_framebuffer,向内核注册struct fb_info对象;
16、有些驱动到这里,需要启动背光灯,当然也可以独立驱动;
3、涉及到的结构体与函数API
相关结构体
①  struct fb_info    //framebuffer核心描述结构体
struct fb_info {
465      atomic_t count;   /* 原子变量 */
466     int node;
467     int flags;
468     struct mutex lock;       /* 互斥锁,用于 open/release/ioctl 函数 */
469     struct mutex mm_lock;     /* 互斥锁,用于 fb_mmap smem_* */
470      struct fb_var_screeninfo var;    /* 可变参数信息 */
471      struct fb_fix_screeninfo fix;    /*固定参数信息 */
472     struct fb_monspecs monspecs;   
473     struct work_struct queue;    /* 帧缓冲事件队列 */
474     struct fb_pixmap pixmap;     /* 图像硬件映射,与图像显示有关 */
475     struct fb_pixmap sprite;     /* 光标硬件映射,与光标显示有关 */
476      struct fb_cmap cmap;         /* 调色板 */
477     struct list_head modelist;       /* 模式列表*/
478      struct fb_videomode *mode;   /*当前模式,指定LCD的属性参数值*/
479
480 #ifdef CONFIG_FB_BACKLIGHT
481     /* assigned backlight device */
482     /* set before framebuffer registration,
483        remove after unregister */
484     struct backlight_device *bl_dev;
485
486     /* Backlight level curve */
487     struct mutex bl_curve_mutex;
488     u8 bl_curve[FB_BACKLIGHT_LEVELS];
489 #endif
490 #ifdef CONFIG_FB_DEFERRED_IO
491     struct delayed_work deferred_work;
492     struct fb_deferred_io *fbdefio;
493 #endif
494
495     s truct fb_ops *fbops;    /* 提供显存的具体操作实现函数 */
496     struct device *device;       /* 此设备的父设备*/
497     struct device *dev;     /* 当前设备的设备描述节点 */
498     int class_flag;                    /* 私有文件系统参数*/
499 #ifdef CONFIG_FB_TILEBLITTING
500     struct fb_tile_ops *tileops;    /* Tile Blitting */
501 #endif
502     union {
503         char __iomem *screen_base;   /* 显存的虚拟映射地址*/
504         char *screen_buffer;
505     };
506     unsigned long screen_size;   /* 虚拟显存的字节大小 */
507     void *pseudo_palette;        /*16种颜色的虚拟调色板 */
508 #define FBINFO_STATE_RUNNING    0
509 #define FBINFO_STATE_SUSPENDED  1
510     u32 state;          /* Hardware state i.e suspend */
511     void *fbcon_par;                /* fbcon use-only private area */
512      /* 这里可以用与存放用户自定义的数据内存地址 */
513     void *par;
514     /* we need the PCI or similar aperture base/size not
515        smem_start/size as smem_start may just be an object
516        allocated inside the aperture so may not actually overlap */
517     struct apertures_struct {
518         unsigned int count;
519         struct aperture {
520             resource_size_t base;
521             resource_size_t size;
522         } ranges[0];
523     } *apertures;
524
525     bool skip_vt_switch; /* no VT switch on suspend/resume required */
526 };
②  struct videomode  // 独立的 显示设备属性描述结构体, 可以从设备树节点display_timming上自动生成
19 struct videomode {
20      unsigned long pixelclock;    /* 画面额定刷新频率Hz */
21
22      u32 hactive;            /*LCD横轴分辨率*/
23     u32 hfront_porch;    /*HFP的长度*/
24     u32 hback_porch;   /* HBP的长度 */
25     u32 hsync_len;        /* HSYNC的长度 */
26
27      u32 vactive;       /* LCD的竖轴分辨率 */
28     u32 vfront_porch;    /* VFP的HSYNC个数 */
29     u32 vback_porch;    /* VBP的HSYNC个数 */
30     u32 vsync_len;        /* VSYNC的HSYNC个数 */
31
32     enum display_flags flags; /* display flags */
};
③  struct fb_videomode  //向fb_info传递LCD的基本属性数据
777 struct fb_videomode {
778     const char *name;   /* optional */
779     u32 refresh;        /* optional */
780     u32 xres;      /* LCD显示的横轴分辨率 */
781     u32 yres;      /* LCD显示的竖轴分辨率 */
782     u32 pixclock;  /* 显示器的时钟频率 */
783     u32 left_margin;   
784     u32 right_margin;
785     u32 upper_margin;
786     u32 lower_margin;
787     u32 hsync_len;   /* hsync的时钟长度 */
788     u32 vsync_len;  /* vsync的hsync个数 */
789     u32 sync;
790     u32 vmode;
791     u32 flag;
792 };
④ struct fb_ops  //显示设备具体操作函数的实现结构体
256 struct fb_ops {
257     /* open/release and usage marking */
258      struct module *owner;
259      int (*fb_open)(struct fb_info *info, int user);      /* 设备打开执行函数,在用户层open时被执行 */
260      int (*fb_release)(struct fb_info *info, int user);    /* 设备关闭执行函数,在用户层close时被执行 */
261
262     /*  显存非连续性的或无法进行内存映射的显示设备将使用read和write函数
264      */
265     ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
266                size_t count, loff_t *ppos);
267     ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
268                 size_t count, loff_t *ppos);
269
270      /* 用于检查和 备的可变参数 修改显示设  */
272     int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
273
274      /* 修改info结构体内部的共享成员 */
275     int (*fb_set_par)(struct fb_info *info);
276
277      /*  配置颜色寄存器 */
278     int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
279                 unsigned blue, unsigned transp, struct fb_info *info);
280
281      /* 配置显存数据流*/
282     int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
283
284      /*空白显示 */
285     int (*fb_blank)(int blank, struct fb_info *info);
286
287      /* 画笔显示 */
288     int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
289
290      /*矩形绘画 */
291     void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
292      /* 数据拷贝*/
293     void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
294      /* 显示器上显示图片 */
295     void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
296
297      /* 绘制光标*/
298     int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
299
300     /* wait for blit idle, optional */
301     int (*fb_sync)(struct fb_info *info);
302
303     /* perform fb specific ioctl (optional) */
304     int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
305             unsigned long arg);
306
307     /* Handle 32bit compat ioctl (optional) */
308     int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
309             unsigned long arg);
310
311     /* perform fb specific mmap */
312     int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
313
314     /* get capability given var */
315     void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
316                 struct fb_var_screeninfo *var);
317
318     /* teardown any resources to do with this framebuffer */
319     void (*fb_destroy)(struct fb_info *info);
320
321     /* called at KDB enter and leave time to prepare the console */
322     int (*fb_debug_enter)(struct fb_info *info);
323     int (*fb_debug_leave)(struct fb_info *info);
324 };
⑤ struct fb_var_screeninfo  //显示器件的可变参数描述结构体
241 struct fb_var_screeninfo {
242     __u32 xres;          /* 显示器的横轴像素值 */
243     __u32 yres;          /* 显示器的竖轴像素值 */
244     __u32 xres_virtual;     /* 虚拟值 横轴像素起始地址 */
245     __u32 yres_virtual;    /* 虚拟值 竖轴像素起始地址 */
246     __u32 xoffset;           /* 虚拟横轴相对于物理值得偏移量 */     
247     __u32 yoffset;          /* resolution           */
248
249     __u32 bits_per_pixel;        /* 单个像素点的位数 */
250      __u32 grayscale;         /* 0=彩色 1=灰度   */
251                     /* >1 = FOURCC          */
252      struct fb_bitfield red;      /* 红色在像素点中的位域  */
253     struct fb_bitfield green;   
254     struct fb_bitfield blue;
255     struct fb_bitfield transp;  
256
257      __u32 nonstd;            /* 如果!=0则表示非标准的像素格式 */
258
259      __u32 activate;          /* 配置设备启动方式FB_ACTIVATE_XXX*/
260
261     __u32 height;            /*  画面高度,单位:mm    */
262     __u32 width;         
263
264      __u32 accel_flags;       /* 这里配置为FB_ACCEL_NONE*/
265
266      /* 从设备节点上获取的Timing值,除了pixclk以外 */
267     __u32 pixclock;         /* pixel clock in ps (pico seconds) */
268     __u32 left_margin;      /* time from sync to picture    */
269     __u32 right_margin;     /* time from picture to sync    */
270     __u32 upper_margin;     /* time from sync to picture    */
271     __u32 lower_margin;
272     __u32 hsync_len;        /* length of horizontal sync    */
273     __u32 vsync_len;        /* length of vertical sync  */
274     __u32 sync;         /* see FB_SYNC_*        */
275     __u32 vmode;            /* see FB_VMODE_*       */
276     __u32 rotate;           /* angle we rotate counter clockwise */
277     __u32 colorspace;       /* colorspace for FOURCC-based modes */
278     __u32 reserved[4];      /* Reserved for future compatibility */
279 };
⑥ struct fb_fix_screeninfo  //显示器件固定参数结构体
157 struct fb_fix_screeninfo {
158      char id[16];             /* 设备器件的名称 */
159      unsigned long smem_start;   /* 显存物理缓存的起始地址 */
160       
161      __u32 smem_len;          /* 显存的字节大小 */
162      __u32 type;         /* 显存的数据格式FB_TYPE_XXX */
163     __u32 type_aux;          /* 交换已经交换的画面?? */  
164      __u32 visual;            /* 画面显示格式FB_VISUAL_XXX  */
165     __u16 xpanstep;          /*0=没有硬件画笔 */
166     __u16 ypanstep;          /* 0=没有硬件画笔  */
167     __u16 ywrapstep;         /* zero if no hardware ywrap    */
168      __u32 line_length;       /* 显示一行的字节数    */
169     unsigned long mmio_start;    /* IO内存映射的物理起始地址   */
170  
171     __u32 mmio_len;    
172      __u32 accel;             /* FB_ACCEL_NONE=没有硬件加速度器 */
173 
174     __u16 capabilities;     /* see FB_CAP_*         */
175     __u16 reserved[2];       /* 保留的可扩展成员 */
176 };
⑦  struct fb_cmap   //调色板结构体
281 struct fb_cmap {
282     __u32 start;             /* 起始地址*/
283     __u32 len;           /* 长度 */
284     __u16 *red;          /* 红色占用地址   */
285     __u16 *green;
286     __u16 *blue;
287     __u16 *transp;          /* transparency, can be NULL */
288 };
⑧  struct fb_bitfield  //用于表示像素点中,某个颜色的位域
struct fb_bitfield {
189      __u32 offset;            /*  在像素中的位偏移    */
190      __u32 length;            /* 占用的位个数  */
191     __u32 msb_right;        /*  最高有效位有几位 */
193 };  
⑨  struct dma_chan   //描述一个DMA设备
struct dma_chan {
107     int dev_id;     /* DMA的设备ID号 */
108   
109     void __iomem *io;  /* 虚拟内存映射地址 */
110     const char *dev_str;    /* 设备的名字 */
111     int irq;
112     void *irq_dev;
113     unsigned int fifo_addr;    /* DMA缓存区的首地址 */
114     unsigned int mode;      /* DMA的模式 */
115 };
⑩  struct dma_interleaved_template  //DMA的配置结构体
struct dma_interleaved_template {
160      dma_addr_t src_start;    /*源地址的起始地址*/
161     dma_addr_t dst_start;   /*目标地址的起始地址*/
162      enum dma_transfer_direction dir;  /*DMA数据的传输方向
enum dma_transfer_direction {
  89     DMA_MEM_TO_MEM,
  90     DMA_MEM_TO_DEV,
  91     DMA_DEV_TO_MEM,
  92     DMA_DEV_TO_DEV,
  93     DMA_TRANS_NONE,
  94 };
*/
163      bool src_inc;  /* 1=源地址每次自动递增 */
164      bool dst_inc;  /* 1 = 目标地址每次自动递增 */
165      bool src_sgl;    /* 1 =  每次初始后,源地址根据sgl来偏移*/
166      bool dst_sgl;
167      size_t numf;  /* DMA中缓存的帧数 */
168      size_t frame_size;  /* 每帧画面的块数 */
169      struct data_chunk sgl[0];  /*配置非连续性的地址偏移 */
170 };
相关的函数接口
① fb_info * framebuffer_alloc(size_t size, struct device *dev);    //动态分配基于设备节点的struct fb_info结构体, 同时分配更多内存在info->per指针上指定(可以作为自定义驱动变量)
② void framebuffer_release(struct fb_info *info);    //对应释放struct fb_info的内存
③  void clk_disable_unprepare(struct clk *clk);   //用于禁用时钟的输出
④ int of_get_videomode(struct device_node *np, struct videomode *vm, int index);    //从折本树节点上获取对应的设备描述结构体
⑤ void * dma_alloc_wc(struct device *dev, size_t size,dma_addr_t *dma_addr, gfp_t gfp);  //获取显存对应的物理地址并返回映射的虚拟地址
⑥ int fb_videomode_from_videomode(const struct videomode *vm,struct fb_videomode *fbmode);  //将struct videomode 转换为struct fb_videomode
⑦ void fb_videomode_to_var(struct fb_var_screeninfo *var,const struct fb_videomode *mode);  //将struct fb_videomode的值转换为struct fb_var_screeninfo里
⑧ int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);  //动态分配载流数据, 一个颜色映射表??
⑨ int clk_set_rate(struct clk *clk, unsigned long rate);   //配置时钟的频率,单位Hz
⑩ int clk_prepare_enable(struct clk *clk);    //使能启动时钟
11 int dmaengine_terminate_all(struct dma_chan *chan);    //停止DMA的工作
12 struct dma_async_tx_descriptor * dmaengine_prep_interleaved_dma(struct dma_chan *chan, struct dma_interleaved_template *xt,unsigned long flags);    //配置DMA
13 void dma_async_issue_pending(struct dma_chan *chan);  //启动DMA
14 int  register_framebuffer(struct fb_info *fb_info);  //向内核注册struct fb_info
15 int  unregister_framebuffer(struct fb_info *fb_info);  //注销struct fb_info
//
三、FrameBuffer驱动框架的底层源码分析
//

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全网最全的Linux中的内核级加强型火墙图文详解

目录 前言 一、Selinux的功能 二、Selinux的状态及管理 三、Selinux的安全上下文 四、SEBOOL 五、SEPORT 六、setrouble 前言 内核级加强型火墙主要是指系统中的selinux功能,该功能开启时,会对系统中的文件和程序产生影响,用户的…

SkyEye:针对飞行模拟器的仿真解决方案

01.飞行模拟器简介 飞行模拟器是一种由人工打造,能够尽可能真实地还原飞机飞行及空中环境的模拟系统,一般用于飞行员培训、飞机设计等工作。飞行模拟器能够模拟如何控制飞机飞行、模拟飞机应用系统的反应,还可模拟一些可能会对飞机系统造成影…

java图片压缩

1背景 查看各种文章,发现thumbnailator的压缩率和压缩效果都不错,thumbnailator又是使用java实现的,所以直接扒源码,找到了里面实现压缩的关键代码,封装成一个压缩工具类,有需要的同学可以参考。thumbnail…

Linux多线程Web服务器(C++实现)

本文实现的是基于Reactor模式epoll(边缘触发)非阻塞socket非阻塞IO线程池的Web服务器,可以处理GET、POST两种请求,完成展示主页、获取图片、获取视频、登录及注册共五种功能。原理图:上图为本文实现的服务器的原理图&a…

国产GPU芯片迎来突破,算力全球第一,中文编程也有好消息

苦,芯片久矣,终,迎来突破,实在振奋人心!最近,国产GPU芯片传来了好消息,国产自研首款通用芯片,以每秒千万亿次的计算能力,创全球算力记录,芯片领域实现跨越式的…

包体积优化 · 实战论 · 怎么做包体优化? 做好能晋升吗? 能涨多少钱?

“ 【小木箱成长营】包体积优化系列文章: 包体积优化 方法论 揭开包体积优化神秘面纱 包体积优化 工具论 初识包体积优化 BaguTree 包体积优化录播视频课 ”一、引言 Hello,我是小木箱,欢迎来到小木箱成长营系列教程,今天将分…

论文投稿指南——中文核心期刊推荐(农业工程)

【前言】 🚀 想发论文怎么办?手把手教你论文如何投稿!那么,首先要搞懂投稿目标——论文期刊 🎄 在期刊论文的分布中,存在一种普遍现象:即对于某一特定的学科或专业来说,少数期刊所含…

实战10:基于opencv的数字图像处理:边缘检测 (完整代码+详细教程)

给出“离散拉普拉斯算子”一般形式的数学推导 离散值的导数使用差分代替: 所以: 以(x, y)为中心点,在水平和垂直方向上应用拉普拉斯算子,滤波器(对应a=1的情况)为:

Spring Cloud Alibaba学习指南

文章目录背景介绍主要功能主要组件参考文档Spring Cloud Alibaba githubNacos官方文档Nacos运维手册Sentinel官方文档Spring Cloud Alibaba SentinelSeata官方文档Spring Cloud Alibaba 英语文档应用脚手架背景 由于在2018年Netflix公司宣布对其核心组件Hystrix、Ribbon、zuul…

远端连接服务器详解

昨天决定入手了一台腾讯轻量应用服务器,在连接的过程中遇到很多问题,浪费了很多时间,所以在这里对这些问题进行整理分享给大家!!!系统的安装OpenCloudOS是完全中立、全面开放、安全稳定、高性能的操作系统及…

JVM调优之GC日志分析及可视化工具介绍

JVM调优之GC日志分析及可视化工具介绍 文章目录JVM调优之GC日志分析及可视化工具介绍GC日志参数GC日志参数常用垃圾收集器参数GC日志分析日志的含义使用 ParNew Serial Old 的组合进行内存回收使用 Parallel Scavenge Parallel Old 的组合进行内存回收大对象回收分析日志分析…

药品溶出曲线数据库

药物在体外的溶出行为,可以用来预测体内的崩解、溶出和吸收情况,同时药物体外溶出行为能够在一定程度上反映出制剂的质量。而溶出曲线特别是不同溶出介质的多条溶出曲线,可更加全面、灵敏地反映出上述关键要素的变化。当药物溶出曲线中药物品…

电脑磁盘重新分配空间的简单步骤(无损数据空间转移)

目录 一、前言 遇到问题 解决方式 二、磁盘现状与实现目标 磁盘现状 实现目标 三、操作步骤 (一)关闭电脑磁盘加密 (二)下载安装分区助手 (三)分配空间教程 注意事项 磁盘空间移动成功 一、前…

芯片设计五部曲之二 | 图灵艺术家——数字IC

《芯片设计五部曲》:模拟IC、数字IC、存储芯片、算法仿真和总结篇(排名不分先后 上一集我们已经说了,模拟IC,更像是一种魔法。 我们深度解释了这种魔法的本质,以及如何在模拟芯片设计的不同阶段,根据常见的…

千万别乱用!Lombok不是万能的

背景 在使用Lombok构建无参构造器的时候,同事同时使用了Data和Builder,造成了编译不通过的问题! Data使用说明 Lombok的Data注解可以为我们生成无参构造方法和类中所有属性的Getter和Setter方法。这样在我们开发的过程中,我们就…

seaborn的调色板、刻度、边框、标签、数据集等的一些解释

文章目录前言数据集构建整体风格设置调色板x轴的刻度值设置sns.lineplot实例前言 seaborn是对matplotlib进一步封装的库,可以用更少的代码,画出更好看的图。 官网:https://seaborn.pydata.org/index.html 下面记录一下seaborn的基础用法 数…

【日常业务开发】策略+工厂模式优化 if...else判断逻辑

【日常业务开发】策略工厂模式优化 if...else判断逻辑场景策略工厂模式优化利用Spring自动注入的特点处理继承InitializingBean静态工厂方法调用处理注解CommandLineRunnerApplicationContextAware处理/ApplicationListener\<ContextRefreshedEvent>场景 业务中经常有支…

一行代码写一个谷歌插件 —— Javascript

回顾 前期 【提高代码可读性】—— 手握多个代码优化技巧、细数哪些惊艳一时的策略_0.活在风浪里的博客-CSDN博客代码优化对象策略https://blog.csdn.net/m0_57904695/article/details/128318224?spm1001.2014.3001.5501 目录 技巧一&#xff1a;谷歌插件 第一步: 第二步…

Tomcat的安装和使用

作者&#xff1a;~小明学编程 文章专栏&#xff1a;JavaEE 格言&#xff1a;热爱编程的&#xff0c;终将被编程所厚爱。 目录 下载Tomcat tomcat文件介绍 启动Tomcat 简单的部署静态页面 HTTP 服务器&#xff0c;就是在 TCP 服务器的基础上&#xff0c;加上了一些额外的功能…

计算机网络 - 概述

文章目录前言一、计算机网络概述1.1、计算机网络在信息时代的作用1.2、Intnet概述网络、互连网&#xff08;互联网&#xff09;和因特网因特网发展阶段因特网的组成1.3、计算机网络的定义和分类定义分类1.4、报文交换方式电路交换分组交换报文交换三种交换方式对比1.5、性能指标…