当前位置: 首页 > 编程日记 > 正文

Linux驱动之LCD驱动编写

在Linux驱动之内核自带的S3C2440的LCD驱动分析这篇博客中已经分析了编写LCD驱动的步骤,接下来就按照这个步骤来字尝试字节编写LCD驱动。用的LCD屏幕为tft屏,每个像素点为16bit。对应与红绿蓝分别为565。

1、分配一个fb_info结构

2、设置fb_info结构

3、硬件相关的操作,配置LCD时钟、配置IO端口、配置LCD寄存器。

4、最终注册fbinfo结构到registered_fb数组

要理解LCD的工作原理,需要了解LCD的时钟,在TFT的LCD中有如下的时钟。这个几个时钟数据在配置LCD寄存器时都说需要设置的。

1、VCLK:两个像素之间的时钟,即两个像素隔多长时间才能显示下一个像素

2、HSYNC:水平同步时钟,即第一行像素点显示完成之后隔多长时间才能开始下一行的显示

3、VSYNC:垂直方向的同步时钟,也叫帧同步信号,即一帧数据显示完成之后(一帧数据表示一个屏幕显示完成,即一个显存的数据全部取完),过多长下一帧数据才开始显示

本节需要用到的函数:

void *dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);  //分配DMA缓存区给显存
//返回值为:申请到的DMA缓冲区的虚拟地址,若为NULL,表示分配失败,则需要使用dma_free_writecombine()释放内存,避免内存泄漏
//参数如下: //*dev:指针,这里填0,表示这个申请的缓冲区里没有内容//size:分配的地址大小(字节单位)//*handle:申请到的物理起始地址//gfp:分配出来的内存参数,标志定义在<linux/gfp.h>,常用标志如下://GFP_ATOMIC    用来从中断处理和进程上下文之外的其他代码中分配内存. 从不睡眠.//GFP_KERNEL    内核内存的正常分配. 可能睡眠.//GFP_USER      用来为用户空间页来分配内存; 它可能睡眠.   

分配一段DMA缓存区,分配出来的内存会禁止cache缓存(因为DMA传输不需要CPU)

它和 dma_alloc_coherent ()函数相似,不过 dma_alloc_coherent ()函数是分配出来的内存会禁止cache缓存以及禁止写入缓冲区

dma_free_writecombine(dev,size,cpu_addr,handle);   //释放缓存
//cpu_addr:虚拟地址, 
//handle:物理地址

释放DMA缓冲区, dev和size参数和上面的一样

struct fb_info *framebuffer_alloc(size_t size, struct device *dev);      //申请一个fb_info结构体,
//size:额外的内存,
//*dev:指针, 这里填0,表示这个申请的结构体里没有内容

int register_framebuffer(struct fb_info *fb_info);  //向内核中注册fb_info结构体,若内存不够,注册失败会返回负数int unregister_framebuffer(struct fb_info *fb_info) ;//注销内核中fb_info结构体

本节需要用到的结构体:

fb_info结构体如下:

struct fb_info {... ...struct fb_var_screeninfo var;       //可变的参数struct fb_fix_screeninfo fix;        //固定的参数
       ... ...struct fb_ops *fbops;              //操作函数
       ... ...char __iomem *screen_base;        //显存虚拟起始地址unsigned long screen_size;          //显存虚拟地址长度void *pseudo_palette;                
//假的16色调色板,里面存放了16色的数据,可以通过8bpp数据来找到调色板里面的16色颜色索引值,模拟出16色颜色来,节省内存,不需要的话就指向一个不用的数组即可
       ... ...
};

其中操作函数fb_info-> fbops 结构体写法如下:

static struct fb_ops s3c_lcdfb_ops = {.owner                = THIS_MODULE,.fb_setcolreg    = my_lcdfb_setcolreg,//设置调色板fb_info-> pseudo_palette,自己构造该函数
.fb_fillrect      = cfb_fillrect,     //填充矩形,用/drivers/video/ cfbfillrect.c里的函数即可
.fb_copyarea    = cfb_copyarea,  //复制数据, 用/drivers/video/cfbcopyarea.c里的函数即可
.fb_imageblit    = cfb_imageblit, //绘画图形, 用/drivers/video/imageblit.c里的函数即可
};

固定的参数fb_info-> fix 结构体如下:

struct fb_fix_screeninfo {char id[16];                   //id名字unsigned long smem_start;  //framebuffer物理起始地址                          __u32 smem_len;           //framebuffer长度,字节为单位__u32 type;                 //lcd类型,默认值0即可__u32 type_aux;               //附加类型,为0__u32 visual;                     //画面设置,常用参数如下
// FB_VISUAL_MONO01             0   单色,0:白色,1:黑色
// FB_VISUAL_MONO10             1    单色,1:白色,0:黑色
// FB_VISUAL_TRUECOLOR          2     真彩(TFT:真彩)
// FB_VISUAL_PSEUDOCOLOR     3     伪彩
// FB_VISUAL_DIRECTCOLOR        4     直彩
__u16 xpanstep;                /*如果没有硬件panning就赋值为0 */__u16 ypanstep;                /*如果没有硬件panning就赋值为0 */__u16 ywrapstep;                 /*如果没有硬件ywrap就赋值为0 */__u32 line_length;                 /*一行的字节数 ,例:(RGB565)240*320,那么这里就等于240*16/8 *//*以下成员都可以不需要*/unsigned long mmio_start;        /*内存映射IO的起始地址,用于应用层直接访问寄存器,可以不需要*/                                   __u32 mmio_len;                   /* 内存映射IO的长度,可以不需要*/__u32 accel;                 __u16 reserved[3];        };

可变的参数fb_info-> var 结构体如下:

structfb_var_screeninfo{                                    __u32xres;                    /*可见屏幕一行有多少个像素点*/__u32 yres;                      /*可见屏幕一列有多少个像素点*/__u32 xres_virtual;         /*虚拟屏幕一行有多少个像素点 */       __u32  yres_virtual;       /*虚拟屏幕一列有多少个像素点*/__u32 xoffset;                 /*虚拟到可见屏幕之间的行偏移,若可见和虚拟的分辨率一样,就直接设为0*/__u32 yoffset;                 /*虚拟到可见屏幕之间的列偏移*/__u32  bits_per_pixel;    /*每个像素的位数即BPP,比如:RGB565则填入16*/__u32 grayscale;           /*非0时,指的是灰度,真彩直接填0即可*/struct fb_bitfield red;          //fb缓存的R位域, fb_bitfield结构体成员如下:
//__u32 offset;          区域偏移值,比如RGB565中的R,就在第11位
//__u32 length;                   区域长度,比如RGB565的R,共有5位
//__u32 msb_right;  msb_right ==0,表示数据左边最大, msb_right!=0,表示数据右边最大struct fb_bitfield green;    /*fb缓存的G位域*/struct fb_bitfield blue;       /*fb缓存的B位域*//*以下参数都可以不填,默认为0*/struct fb_bitfield transp;   /*透明度,不需要填0即可*/    __u32nonstd;                    /* != 0表示非标准像素格式*/__u32 activate;                 /*设为0即可*/__u32height;                     /*外设高度(单位mm),一般不需要填*/__u32width;                      /*外设宽度(单位mm),一般不需要填*/__u32 accel_flags;        /*过时的参数,不需要填*//* 除了pixclock本身外,其他的都以像素时钟为 单位*/ __u32pixclock;                   /*像素时钟(皮秒)*/__u32 left_margin;         /*行切换,从同步到绘图之间的延迟*/__u32right_margin;        /*行切换,从绘图到同步之间的延迟*/__u32upper_margin;       /*帧切换,从同步到绘图之间的延迟*/__u32lower_margin;       /*帧切换,从绘图到同步之间的延迟*/__u32hsync_len;              /*水平同步的长度*/__u32 vsync_len;           /*垂直同步的长度*/__u32 sync;__u32 vmode;__u32 rotate;__u32reserved[5];        /*保留*/}

1.写驱动程序:

(驱动设置:参考自带的LCD平台驱动drivers/video/s3c2410fb.c )

(LCD控制寄存器设置:参考之前的LCD裸机驱动:http://www.cnblogs.com/lifexy/p/7144890.html)

1.1 步骤如下:

在驱动init入口函数中:

1)分配一个fb_info结构体

2)设置fb_info

2.1)设置固定的参数fb_info-> fix

2.2) 设置可变的参数fb_info-> var

2.3) 设置操作函数fb_info-> fbops

2.4) 设置fb_info 其它的成员

3)设置硬件相关的操作

3.1)配置LCD引脚

3.2)根据LCD手册设置LCD控制器

3.3)分配显存(framebuffer),把地址告诉LCD控制器和fb_info

4)开启LCD,并注册fb_info: register_framebuffer()

4.1) 直接在init函数中开启LCD(后面讲到电源管理,再来优化)

控制LCDCON5允许PWREN信号,

然后控制LCDCON1输出PWREN信号,

输出GPB0高电平来开背光,

4.2) 注册fb_info

在驱动exit出口函数中:

1)卸载内核中的fb_info

2) 控制LCDCON1关闭PWREN信号,关背光,iounmap注销地址

3)释放DMA缓存地址dma_free_writecombine()

4)释放注册的fb_info

1.2 具体代码如下:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <asm/io.h>        //含有iomap函数iounmap函数
#include <asm/uaccess.h>//含有copy_from_user函数
#include <linux/device.h>//含有类相关的处理函数
#include <linux/fb.h>      //含有fb_info结构体定义
//#include <asm/dma-mapping.h> //含有dma_free_writecombine宏定义
#include <linux/dma-mapping.h>  //含有dma_free_writecombine宏定义
#include <linux/platform_device.h>//含有平台设备总线模型相关变量
#include <linux/mm.h>
#include <linux/slab.h>//#include <linux/module.h>
//#include <linux/kernel.h>
//#include <linux/errno.h>
//#include <linux/string.h>
//#include <linux/mm.h>
//#include <linux/slab.h>
//#include <linux/delay.h>
//#include <linux/fb.h>
//#include <linux/init.h>
//#include <linux/dma-mapping.h>
//#include <linux/interrupt.h>
//#include <linux/workqueue.h>
//#include <linux/wait.h>
//#include <linux/platform_device.h>
//#include <linux/clk.h>//#include <asm/io.h>
//#include <asm/uaccess.h>
//#include <asm/div64.h>//#include <asm/mach/map.h>
//#include <asm/arch/regs-lcd.h>
//#include <asm/arch/regs-gpio.h>
//#include <asm/arch/fb.h>/*lcd控制寄存器放在一个结构体里面*/
struct lcd_regs {unsigned long    lcdcon1;    unsigned long    lcdcon2;    unsigned long    lcdcon3;    unsigned long    lcdcon4;    unsigned long    lcdcon5;    unsigned long    lcdsaddr1;    unsigned long    lcdsaddr2;    unsigned long    lcdsaddr3;    unsigned long    redlut;    unsigned long    greenlut;    unsigned long    bluelut;    unsigned long    reserved[9];    unsigned long    dithmode;    unsigned long    tpal;    unsigned long    lcdintpnd;    unsigned long    lcdsrcpnd;    unsigned long    lcdintmsk;    unsigned long    lpcsel;
};static struct fb_info *s3c_mylcdfb_info;//fb_info结构体
static volatile unsigned long *gpbcon;//GPB0用于lcd背光的控制
static volatile unsigned long *gpbdat;//GPB0用于lcd背光的控制
static volatile unsigned long *gpccon;
static volatile unsigned long *gpdcon;
static volatile unsigned long *gpgcon;//GPG4用于lcd电源
static volatile struct lcd_regs* lcd_regs;//lcd寄存器
static u32 pseudo_palette[16];            //调色板内存/* from pxafb.c */
static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
{chan &= 0xffff;                //取出16bit的数据chan >>= 16 - bf->length; //
    return chan << bf->offset;
}static int s3c_mylcdfb_setcolreg(unsigned int regno, unsigned int red,unsigned int green, unsigned int blue,unsigned int transp, struct fb_info *info)
{unsigned int val;if (regno > 16)return 1;/* 用red,green,blue三原色构造出val */val  = chan_to_field(red,    &info->var.red);val |= chan_to_field(green, &info->var.green);val |= chan_to_field(blue,    &info->var.blue);//((u32 *)(info->pseudo_palette))[regno] = val;pseudo_palette[regno] = val;return 0;
}static struct fb_ops s3c_mylcdfb_ops = {     //操作函数结构体.owner        = THIS_MODULE,.fb_setcolreg    = s3c_mylcdfb_setcolreg,//待会设置,这个是调色板,如果使用小于16bit的像素需要用到.fb_fillrect    = cfb_fillrect,.fb_copyarea    = cfb_copyarea,.fb_imageblit    = cfb_imageblit,
};static int lcd_drv_init(void)
{/*1、分配一个fb_info*/s3c_mylcdfb_info = framebuffer_alloc(0,NULL);//size为额外分配的大小,这里不需要,所以设为0if(s3c_mylcdfb_info==NULL){printk("unframebuffer_alloc\n");return 1;}/*2、设置*//*2.1 设置固定的参数*/strcpy(s3c_mylcdfb_info->fix.id, "mylcd");//名字//s3c_mylcdfb_info->fix.smem_start = ;//显存的物理起始地址,后面设置s3c_mylcdfb_info->fix.smem_len = 480*272*16/8;//单位为字节,每个像素点占用16bit :565,显存的大小s3c_mylcdfb_info->fix.type = FB_TYPE_PACKED_PIXELS;//LCD类型,填充像素的类型 tft//s3c_mylcdfb_info->fix.type_aux= //附加的LCD类型,不需要设置s3c_mylcdfb_info->fix.visual = FB_VISUAL_TRUECOLOR;//视觉类型,选择真彩色s3c_mylcdfb_info->fix.line_length = 480*16/8; //一行的长度,单位为字节
//    s3c_mylcdfb_info->fix.mmio_start = //控制lcd的寄存器的物理地址
//    s3c_mylcdfb_info->fix.mmio_len = //控制lcd的寄存器的大小/*2.2 设置可变的参数*/s3c_mylcdfb_info->var.xres = 480;//x方向的分辨率s3c_mylcdfb_info->var.yres = 272;//y方向的分辨率s3c_mylcdfb_info->var.xres_virtual = 480;//x方向的虚拟分辨率s3c_mylcdfb_info->var.yres_virtual = 272;//y方向的虚拟分辨率s3c_mylcdfb_info->var.bits_per_pixel = 16;//每个像素的大小,单位为bits3c_mylcdfb_info->var.grayscale = 0;//灰度值
    s3c_mylcdfb_info->var.red.length = 5;//红色像素占用的长度,单位bits3c_mylcdfb_info->var.green.length = 6;//绿色像素占用的长度,单位bits3c_mylcdfb_info->var.blue.length = 5;//蓝色像素占用的长度,单位bit
    s3c_mylcdfb_info->var.red.offset= 11;//红色像素在16bit中的偏移值s3c_mylcdfb_info->var.green.offset= 6;//绿色像素在16bit中的偏移值s3c_mylcdfb_info->var.blue.offset=0;//蓝色像素在16bit中的偏移值
    s3c_mylcdfb_info->var.red.msb_right= 0;//低位在前还是高位在前,一般高位在前,也就是小端模式s3c_mylcdfb_info->var.green.msb_right= 0;s3c_mylcdfb_info->var.blue.msb_right=0;s3c_mylcdfb_info->var.activate = FB_ACTIVATE_NOW;//使用默认参数,显存立刻生效/*2.3 设置操作函数*/s3c_mylcdfb_info->fbops            = &s3c_mylcdfb_ops;/*2.4 其它的一些设置 */s3c_mylcdfb_info->pseudo_palette  = pseudo_palette;//调色板的地址//s3c_mylcdfb_info->screen_base     = ;//显存的虚拟基地址s3c_mylcdfb_info->screen_size       = 480*272*16/8;//单位为字节,每个像素点占用16bit :565,显存的大小/*3、硬件相关的操作 *//*3.1、配置GPIO用于LCD*/gpbcon = ioremap(0x56000010, 8);//将实际的寄存器地址转换为虚拟地址gpccon =  ioremap(0x56000020 , 4);gpdcon = ioremap(0x56000030 , 4);gpgcon = ioremap(0x56000060 , 4);gpbdat = gpbcon + 1;*gpccon  = 0xaaaaaaaa;   /* GPIO管脚用于VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND */*gpdcon  = 0xaaaaaaaa;   /* GPIO管脚用于VD[23:8] */*gpbcon &= ~(3);  /* GPB0设置为输出引脚 */*gpbcon |= 1;*gpbdat &= ~1;     /* 输出低电平关闭LCD背光 */*gpgcon |= (3<<8); /* GPG4用作LCD_PWREN 电源*//*3.2、根据LCD手册设置LCD控制器,比如VCLK的频率等 */lcd_regs = ioremap(0X4D000000 , sizeof(struct lcd_regs));/* *  bit[17:8] : VCLK = HCLK / [(CLKVAL+1) x 2] *                 10M = 100M/[(CLKVAL+1) x 2] *                  CLKVAL = 4* * bit[6:5] :PNRMODE = 11显示模式,选择TFT模式** bit[4:1] :BPPMODE = 1100;像素=16bit 565** bit[0]    :ENVID = 0;先关闭LCD控制器*/lcd_regs->lcdcon1 = (4<<8) | (3<<5) | (0x0c<<1);//
/** [31:24] : VBPD = 帧同步信号发出后,过多长时间开始显示数据,单位为行,理解为1行的时间* 看LCD手册tvb = VBPD + 1 = 2;所以VBPD = 1** [23:14]:LINEVAL + 1= 272;,所以LINEVAL = 271;垂直方向尺寸,多少行** [13:6]:VFPD = 一帧的数据传输完成之后,过多长时间开始下一帧数据的帧同步信号,单位为行,理解为1行的时间* 看LCD手册tvf = VFPD + 1 = 2;所以VFPD = 1** [5:0]:VSPW = 帧同步信号的脉冲宽度,单位为行* 看LCD手册tvp = VSPW + 1 =10;所以VSPW = 9*/lcd_regs->lcdcon2 = (1<<24) | (271<<14) | (1<<6) | (9<<0);/* * [25:19]:HBPD = 行同步信号发出后,经过多少个VCLK,才发送像素的数据,单位为VCLK* 看LCD手册thb = HBPD + 1 = 2;所以HBPD=1* * [18:8]:HOZVAL + 1 = 480,所以 HOZVAL = 479;水平方向尺寸,多少列**[7:0]:HFPD = 一行的像素数据传输完成之后,经过多长时间,才能发送下一个行同步信号,单位为VCLK*看LCD手册thf = HFPD + 1 = 2;所以HFPD = 1;*/lcd_regs->lcdcon3 = (1<<19) | (479<<8) | (1<<0);/** [7:0]:HSPW = 行同步信号的脉冲宽度,单位为VCLK* 看LCD手册thp = HSPW + 1 = 41;所以HSPW = 40**/lcd_regs->lcdcon4 = (40<<0);/** [11] :FRM565 = 1;16位模式的格式 R:G:B = 5:6:5* [10] :INVVCLK = 0;VCLK在哪个边沿取数据 = 0表示下降沿取数据* [9] :INVVLINE  = 1;行同步信号是否需要反转= 1需要反转* [8] :INVVFRAME = 1;帧同步信号是否需要反转= 1需要反转* [7] :INVVD = 0;    数据是否需要反转* [6] :INVVDEN = 0; 数据使能信号是否需要反转* [5] :INVPWREN = 0;电源使能信号是否需要反转* [4] :INVLEND = 0;行结束信号是否需要反转* [3] :PWREN  = 0;电源使能信号,先不使能* [2] :ENLEND = 1;//行结束信号先使能* [1:0] :BSWP 、HWSWP = 0 1;字节内部不需要交换,字节间需要交换*/lcd_regs->lcdcon5= (1<<11) | (3<<8) | (1<<2) | (1<<0);/*3.3、显存和调色板设置 *//**利用dma_alloc_writecombine分配一块连续的显存*/s3c_mylcdfb_info->screen_base = dma_alloc_writecombine(NULL,s3c_mylcdfb_info->screen_size,(&(s3c_mylcdfb_info->fix.smem_start)),GFP_KERNEL);//返回虚拟地址if(s3c_mylcdfb_info->screen_base==NULL)        //如果显存分配失败,直接返回
        {printk("undma_alloc_writecombine\n");return 1;}/**将显存的地址告诉LCD控制器(物理地址)*/lcd_regs->lcdsaddr1 = (s3c_mylcdfb_info->fix.smem_start >> 1) & (~(3<<30));//起始地址lcd_regs->lcdsaddr2 =  ((s3c_mylcdfb_info->fix.smem_start + s3c_mylcdfb_info->screen_size) >> 1) & 0x1fffff;//结束地址lcd_regs->lcdsaddr3  = (480*16/16);  /* 一行的长度(单位: 2字节) */    //s3c_lcd->fix.smem_start = xxx;  /* 显存的物理地址 *//* 启动LCD */lcd_regs->lcdcon1 |= (1<<0); /* 使能LCD控制器 */lcd_regs->lcdcon5 |= (1<<3); /* 使能LCD本身电源 */*gpbdat |= 1;                       /* 输出高电平, 使能背光 */    /*4、注册LCD*/register_framebuffer(s3c_mylcdfb_info);printk("register_framebuffer\n");return 0;
}static void lcd_drv_exit(void)
{unregister_framebuffer(s3c_mylcdfb_info);lcd_regs->lcdcon1 &= ~(1<<0); /* 关闭LCD本身 */*gpbdat &= ~1;                       /* 关闭背光 */dma_free_writecombine(NULL, s3c_mylcdfb_info->fix.smem_len, s3c_mylcdfb_info->screen_base, s3c_mylcdfb_info->fix.smem_start);iounmap(lcd_regs);iounmap(gpbcon);iounmap(gpccon);iounmap(gpdcon);iounmap(gpgcon);framebuffer_release(s3c_mylcdfb_info);
}module_init(lcd_drv_init);
module_exit(lcd_drv_exit);
MODULE_LICENSE("GPL");

2.重新编译内核,去掉默认的LCD

make menuconfig ,进入menu菜单重新设置内核参数:

进入Device Drivers-> Graphics support:
<M> S3C2410 LCD framebuffer support          //将自带的LCD驱动设为模块, 不编进内核中

然后make uImage 编译内核

make modules 编译模块

为什么要编译模块?

因为LCD驱动相关的文件也没有编进内核,而fb_ops里的成员fb_fillrect(), fb_copyarea(), fb_imageblit()用的都是drivers/video下面的3个文件,所以需要这3个的.ko模块,如下图所示:

3.挂载驱动

将编译好的LCD驱动模块 和drivers/video里的3个.ko模块 放入nfs文件系统目录中

然后烧写内核, 先装载3个/drivers/video下编译好的模块,再来装载LCD驱动模块

挂载LCD驱动后, 如下图,可以通过  ls -l /dev/fb*   命令查看已挂载的LCD设备节点:

4.测试运行

测试有两种:

(echo和cat命令详解入口地址: http://www.cnblogs.com/lifexy/p/7601122.html)

echo hello> /dev/tty1     // LCD上便显示hello字段

cat Makefile>/dev/tty1    // LCD上便显示Makeflie文件的内容

4.1使用上节的键盘驱动在LCD终端打印命令行

vi  /etc/inittab         //修改inittab, inittab:配置文件,用于启动init进程时,读取inittab添加->tty1::askfirst:-/bin/sh   //将sh进程(命令行)输出到tty1里,也就是使LCD输出信息

然后重启,insmod装载3个/drivers/video下编译好的模块,再来insmod装载LCD驱动模块,tty1设备便有了,就能看到提示信息:

如下图,我们insmod上一节的键盘驱动后,按下enter键,便能在LCD终端上操作linux了

(上一节的键盘驱动详解入口地址: http://www.cnblogs.com/lifexy/p/7553861.html)

从上图可以看到按下enter键,它就启动了一个进程号772的-sh进程,如下图发现这个-sh的描述符都指向了tty1:

以上内容转载自16.Linux-LCD驱动(详解)

转载于:https://www.cnblogs.com/andyfly/p/9548835.html

相关文章:

《C++primer》第二章--变量和基本内置类型

基本内置类型 如何选择类型的几点建议 当明确知晓数值不能为负数时&#xff0c;选用无符号类型使用int进行整数运算。因为short一般表示的范围比较小&#xff0c;而long一般和int有相同的范围。如果表示的范围超过了int就使用long long算术运算时尽量不要使用char和bool&…

【入门】等差素数组

题目描述 如果两个素数之和的一半仍然是一个素数&#xff0c;则这三个素数可以组成一个等差素数组&#xff0c;如&#xff08;37&#xff09;/25&#xff0c;则&#xff08;3&#xff0c;5&#xff0c;7&#xff09;为一个等差素数组&#xff0c;编程求100以内的所有等差素数组…

flutter和webapp_Flutter全平台!迁移现有Flutter项目到WEB端

写在前面Flutter 是 Google推出并开源的移动应用开发框架&#xff0c;主打跨平台、高保真、高性能。开发者可以通过 Dart语言开发 App&#xff0c;一套代码同时运行在 iOS 、Android、web和桌面端。Flutter_web是Flutter代码兼容web的实现&#xff0c;可以将使用Dart编写的现有…

使用正则表达式构造定制的HTML5输入框

为什么80%的码农都做不了架构师&#xff1f;>>> 正则表达式&#xff08;点此在线编辑测试&#xff09;是一个功能强大的灵活而简洁的匹配文本字符串的工具&#xff0c;比如匹配特定的字符、单词等。正则表达式通过一个语言规则来书写&#xff0c;通过正则表达式处理…

idea dubbo jar error:cvc-complex-type.2.4.c: 通配符的匹配很全面, 但无法找到元素 'dubbo:application' 的声明...

声明&#xff1a; 出现这个错误的情形是&#xff0c;在idea开发环境里面运行是没有问题的&#xff0c;使用哦idea自带的打包工具生成jar之后&#xff0c;运行jar的时候报的这个错误&#xff0c;如果不是这个情况&#xff0c;这篇文章可能不适用。 主要的原因是spring.schemas、…

lwip可以用于发udp_LWIPUDP一对多

最近在STM32F767的开发板上移植了LWIP UDP的代码&#xff0c;开发板的资料里面有介绍LWIP移植的文档&#xff0c;介绍了几种网络通信方式&#xff0c;如TCP server&#xff0c;TCP client&#xff0c;UDP&#xff0c;按照文档里面的介绍也很容易实现。这里我选择的是基于ucos2操…

奇淫怪巧之给Delphi的PrintDialog增加一个页码选定范围打印的Edit

在Delphi中使用PrintDialog打印对话框的时候&#xff0c;这个控件有三个选项&#xff0c;就是PrintRang那个属性的三个选项&#xff0c;其中有一个选项三&#xff0c;让我们自定义选择页码范围来打印。但是比较蛋疼的是&#xff0c;这个地方选中了之后啥子效果都没有。无法制定…

进程管理(图文)

进程的图文形象表示 阮一峰–进程与线程的一个简单解释 多进程实质 现在&#xff0c;多核CPU已经非常普及了&#xff0c;但是&#xff0c;即使过去的单核CPU&#xff0c;也可以执行多任务。由于CPU执行代码都是顺序执行的&#xff0c;那么&#xff0c;单核CPU是怎么执行多任…

拿到WP官方主题Twenty Ten就是一顿nofollow伺候

2019独角兽企业重金招聘Python工程师标准>>> 今天2012-07-03&#xff0c;我的个人cn域名申请下来了&#xff0c;于是网站搬迁&#xff0c;暂时没有选择一个好的WordPress主题&#xff0c;只有用默认的Twenty Ten&#xff0c;不过这个主题对SEO方面还有一些欠缺&…

Qt分析:Qt中的两种定时器

QTimer类的定时器 QTimer类定时器是QObject类定时器的扩展版或者说升级版&#xff0c;因为它可以提供更多的功能。比如说&#xff0c;它支持单次触发和多次触发。 使用QTimer类定时器的步骤&#xff1a; &#xff08;1&#xff09;创建一个QTimer定时器实例&#xff1a;QTimer …

uestc 1012 饭卡

饭卡(card) Time Limit: 1000 ms Memory Limit: 65535 kB Solved: 253 Tried: 2169 Submit Status Best Solution Back Description 电子科大本部食堂的饭卡有一种很诡异的设计&#xff0c;即在购买之前判断余额。如果购买一个商品之前&#xff0c;卡上的剩余金额大于或等…

wps临时文件不自动删除_win10系统下wps残留文件无法删除如何解决

一位用户反馈自己在win10系统电脑中卸载金山WPS办公软件时&#xff0c;发现根本无法将wps残留的文件夹删除&#xff0c;在删除的时候提示“操作无法完成&#xff0c;因为其中的文件夹或文件已在另一程序打开 请关闭该文件夹文件重试”&#xff0c;这该怎么办呢&#xff1f;接下…

WEB登录H3C模拟器

思路&#xff1a;先将路由器与本地网卡绑定&#xff0c;然后将本地网卡与路由器接口ip设置在同一网段&#xff0c;在路由器上建立本地用户&#xff0c;最后登录就OK了。 1、查看本机网卡的序列号&#xff0c;在CMD里输入systeminfo&#xff0c;输出的最下…

ArcMap 通过DEM获取高程值

第一种方法&#xff1a;Extract values to Points工具&#xff0c;这个网上的资料比较多&#xff0c;就不介绍了。 第二种方法&#xff1a;Interpolate Shape工具 直接用Arc Toolbox->3D Analyst Tools->功能性表面->Interpolate Shape工具就行&#xff0c;可以将DEM的…

Linux进程描述符task_struct结构体简析

进程是处于执行期的程序以及它所管理的资源&#xff08;如打开的文件、挂起的信号、进程状态、地址空间等等&#xff09;的总称 Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程&#xff0c;这个结构体包含了一个进程所需的所有信息。它定义在include/linux/…

hdu 1312 Red and Black 解题报告

题目链接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1312 第二条深搜&#xff0c;题目并不难&#xff0c;但是做了我好久好久&#xff0c;由于一个细节&#xff0c;让我赌上了一个晚上的时间。 题目大意&#xff1a;从图中的标记开始&#xff0c;向四个相邻的方向…

easyexcel怎么设置表头宽度_easyexcel 自动设置列宽

com.alibabaeasyexcel2.1.4导出controller层代码RequestMapping("/download")public void download(HttpServletResponse response) throws IOException {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8…

php ImageMagick扩展

linux下安装php ImageMagick扩展模块下载ImageMagick源码包&#xff1a;#wget ftp://ftp.u-aizu.ac.jp/pub/graphics/p_w_picpath/ImageMagick/p_w_picpathmagick.org/ImageMagick.tar.gz 编译安装&#xff1a;#tar -zxvf ImageMagick.tar.gz #cd ImageMagick-xxxx-0#./confi…

调用浏览器的打印方法打印页面内容

2018-08-30 直接调用浏览器的打印方法 1、打印按钮 <a href"#" target"_self" οnclick"printme()">打印</a> 2、js //打印function printme() {$.messager.confirm(确认, 确认打印&#xff1f;, function (r) {if (r) {document.bo…

jsp中九大内置对象

内置组件 JSP共有以下9种基本内置组件&#xff08;可与ASP的6种内部组件相对应&#xff09;&#xff1a;1.request对象 客户端的请求信息被封装在request对象中&#xff0c;通过它才能了解到客户的需求&#xff0c;然后做出响应。它是HttpServletRequest类的实例。序号 方 法 说…

python数组越界_python 整数越界问题详解

python 内部自带大整数运算能力&#xff0c;整数运算不会溢出&#xff0c;只要内存足够&#xff0c;就oK下面的例子演示了两个32位整数加法的情况(通过位运算实现)&#xff0c;为了模拟溢出的效果&#xff0c;必须人工的进行位运算&#xff0c;~运算符除了求反&#xff0c;还是…

Linux虚拟机连不上网

问题&#xff1a;我们在使用Linux虚拟机的时候经常会出现各种各样的问题&#xff0c;其中的一个问题就是Linux虚拟机连不上网&#xff0c;这是我最近经常遇到的问题&#xff0c;下面提供一种方法解决这个问题 Linux网络设置 打开虚拟机依次单击【System】–>【Preferences】…

企业如何利用新闻类软文营销策划

新闻软文营销对企业的推广有哪些优势呢? 一、首先让客户有机会直接在门户网上相关频道看到关于企业产品的新闻&#xff0c;产生直接的点击或者评论&#xff0c;带来直接客户。 二、当潜在客户运用百度等搜索引擎搜索企业的公司名或者产品的关键词&#xff0c;那么就会在一个页…

WPF XAML 资源样式模板属性存放位置

WPF XAML 资源样式模板属性存放位置 原文:WPF XAML 资源样式模板属性存放位置WPF的XAML 资源申明 类似HTML。 整体来说分3种1.行类资源样式属性 1.1 行内属性 <Button Content"按钮" Foreground"White" FontSize"30"></Button>1.2 行…

SQL Server 数据库备份

SQL Server 数据库备份 原文 http://www.cnblogs.com/ynbt/archive/2013/04/04/2999642.html 备份数据库是指对数据库或事务日志进行复制&#xff0c;当系统、磁盘或数据库文件损坏时&#xff0c;可以使用备份文件进行恢复&#xff0c;防止数据丢失。 SQL Server数据库备份支持…

Linux下修改PATH环境变量

Linux下有很多环境变量&#xff0c;PATH就是其中的一种 PATH 可执行文件的搜索路径。ls命令也是一个程序,执行它不需要提供完整的路径名/bin/ls,然 而通常我们执行当前目录下的程序a.out却需要提供完整的路径名./a.out,这是因为PATH 环 境变量的值里面包含了ls命令所在的目…

vscode 终端 进入node_安装了Node.js 从VScode 使用node -v 和 npm -v等命令却无效

前言最近写TypeScript需要安装、配置Node.js环境&#xff0c;楼主是使用的安装包所以环境变量都是自动就配好了(如果是下载的zip压缩包解压后要自己配置到系统环境变量中)。打开系统终端敲入命令 node -v 和 npm -v 也都有显示对应的软件包版本号&#xff0c;但是在VScode(Vis…

display:inline-block的妙用!!列表布局!!

如下图&#xff1a;像这种列表布局我们一般用 float:left; 设置宽度和高度就OK了。 但是&#xff0c;如果高度不同或者文字字数不同呢&#xff0c;再用float:left;布局就全乱了。如下图&#xff1a; 现在&#xff0c;我们可以利用display:inline-block;完美的解决这个问题。如下…

gitlab解决一些问题

一.修改gitlab端口&#xff1a; 打开/etc/gitlab/gitlab.rb文件&#xff0c;修改以下几点&#xff1a; external_url "http://192.168.58.62:9999"unicorn[listen] localhostunicorn[port] 9999 然后 #gitlab-ctl stop #gitlab-ctl reconfugure #gitlab-ctl start …

Linux下控制环境变量

查看环境变量 查看某一环境变量&#xff1a;比如我们需要查看HOME这个环境变量&#xff0c;我们可以在shell下直接输入echo $HOME 我们可以把所有的环境变量和环境变量的值都打印出来 打印环境变量 libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,…