云终端linux系统,让同方安全的云终端运行于Linux系统之上(二)

4、显示驱动

与云终端显示相关的硬件包括多层控制器(MLC)及显示控制器(DPC)。MLC对应的修改的程序是mlc.c、mlc.h、main.c,

DPC对应修改的程序为dpc_config.h、dpc_ioctl.h及main.c。修改主要涉及MLC顶层的初始设置、显示LOGO设置、及系统默认显示分辨率的设置、及与Pollux硬件相关的系统设置。对于DPC部分的修改主要为系统默认显示分辨率的设置及与其相关的控制信号HSYNC_SWIDTH、HSYNC_FRONT_PORCH、HSYNC_BACK_PORCH、HSYNC_ACTIVEHIGH、VSYNC_SWIDTH、VSYNC_FRONT_PORCH、DISPLAY_VID_PRI_VCLK_SOURCE、DPC_DESIRED_CLOCK_HZ等设置。

5、 I2C系统总线

参考系统使用了一条I2C总线,而Pollux系统使用使用了两条系统总线,一条连接到加密芯片、另一条连接到声音的i2S。所以修改驱动为识别及支持两条系统总线。以下为驱动程序。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define

I2C_CHANNEL CONFIG_I2C_LF1000_CHANNEL

#define LF1000_I2C_TIMEOUT 10

#define LF1000_I2C_RATE_HZ 100000

#ifdef CPU_LF1000

#define I2C_SCL0_PORT GPIO_PORT_A

#define I2C_SCL0_PIN 26

#define I2C_SCL0_FN GPIO_ALT1

#define I2C_SDA0_PORT GPIO_PORT_A

#define I2C_SDA0_PIN 27

#define I2C_SDA0_FN GPIO_ALT1

#define I2C_SCL1_PORT GPIO_PORT_A

#define I2C_SCL1_PIN 28

#define I2C_SCL1_FN GPIO_ALT1

#define I2C_SDA1_PORT GPIO_PORT_A

#define I2C_SDA1_PIN 29

#define I2C_SDA1_FN GPIO_ALT1

#endif

enum lf1000_i2c_state {

I2C_SEND_ADDR,

I2C_SEND_DATA,

I2C_SEND_DONE,

};

struct lf1000_i2c {

void __iomem *base;

int irq;

int div;

wait_queue_head_t wait;

int ready;

wait_queue_head_t bus_access;

int busy;

};

static struct lf1000_i2c dev[2] = {

{

.base = NULL,

.irq = -1,

.ready = 0,

.div = 16,

.busy = 0

},

{

.base = NULL,

.irq = -1,

.ready = 0,

.div = 16,

.busy = 0

}

};

static irqreturn_t lf1000_i2c_irq(int irq, void *dev_id)

{

struct platform_device *pdev = dev_id;

int ch = pdev->id;

u32 tmp = ioread32(dev[ch].base+IRQ_PEND);

if(!(tmp &

(1<

return IRQ_NONE;

tmp |=

(1<

iowrite32(tmp, dev[ch].base+IRQ_PEND);

dev[ch].ready = 1;

wake_up_interruptible(&dev[ch].wait);

return IRQ_HANDLED;

}

static int lf1000_i2c_wait(struct i2c_adapter *adap)

{

struct platform_device *pdev =

to_platform_device(adap->dev.parent);

int ch =

pdev->id;

int ret =

wait_event_interruptible_timeout(dev[ch].wait,

(dev[ch].ready),

LF1000_I2C_TIMEOUT);

if(unlikely(ret < 0))

printk(KERN_INFO "i2c:

interrupted\n");

else if(unlikely(!(dev[ch].ready)))

return -ETIMEDOUT;

dev[ch].ready = 0;

return 0;

}

static int i2c_bus_available(struct i2c_adapter *adap)

{

unsigned long flags;

int ret;

struct platform_device *pdev =

to_platform_device(adap->dev.parent);

int ch =

pdev->id;

spin_lock_irqsave(&dev[ch].bus_access,

flags);

ret = !(dev[ch].busy);

spin_unlock_irqrestore(&dev[ch].bus_access,

flags);

return ret;

}

static void start_stop_condition(struct i2c_adapter *adap)

{

struct platform_device *pdev =

to_platform_device(adap->dev.parent);

int ch =

pdev->id;

u32 tmp = ioread32(dev[ch].base+IRQ_PEND);

tmp |=

(1<

iowrite32(tmp, dev[ch].base+IRQ_PEND);

}

static void lf1000_i2c_clock(char en, struct i2c_adapter

*adap)

{

struct platform_device *pdev =

to_platform_device(adap->dev.parent);

int ch =

pdev->id;

u32 tmp = ioread32(dev[ch].base+I2C_CLKENB);

en ? BIT_SET(tmp, 3) :BIT_CLR(tmp, 3);

iowrite32(tmp, dev[ch].base+I2C_CLKENB);

}

static void lf1000_i2c_hwinit(struct i2c_adapter *adap)

{

struct platform_device *pdev =

to_platform_device(adap->dev.parent);

int ch =

pdev->id;

iowrite32(0, dev[ch].base+ICCR);

#ifdef CPU_MF2530F

iowrite32(0, dev.base+BURST_CTRL);

#endif

iowrite32((1<

dev[ch].base+ICCR);

iowrite32((1<

dev[ch].base+QCNT_MAX);

iowrite32(0x1010, dev[ch].base+ICSR);

start_stop_condition(adap); }

static int xfer_write(struct i2c_adapter *adap, unsigned char *buf,

int length)

{

u32 tmp;

int ret;

enum lf1000_i2c_state state =

I2C_SEND_ADDR;

struct platform_device *pdev =

to_platform_device(adap->dev.parent);

int ch =

pdev->id;

tmp = (ioread32(dev[ch].base+ICSR)

& 0x10F0);

tmp |=

((1<

(1<

iowrite32(tmp, dev[ch].base+ICSR);

start_stop_condition(adap);

while(1) {

switch(state) {

case

I2C_SEND_ADDR:

ret =

lf1000_i2c_wait(adap);

if(ret !=

0)

goto

done_write;

tmp =

ioread32(dev[ch].base+ICSR);

if(tmp

& (1<

{

printk(KERN_INFO

"i2c: no ACK in xfer_write\n");

ret

= -EFAULT;

goto

done_write;

}

state =

I2C_SEND_DATA;

break;

case

I2C_SEND_DATA:

iowrite32(*buf++,

dev[ch].base+IDSR);

start_stop_condition(adap);

ret =

lf1000_i2c_wait(adap);

if(ret !=

0)

goto

done_write;

if(--length

<= 0)

state

= I2C_SEND_DONE;

break;

case

I2C_SEND_DONE:

ret =

0;

goto

done_write;

}

}

done_write:

tmp = (ioread32(dev[ch].base+ICSR)

& 0x1F0F);

tmp |=

((1<

iowrite32(tmp, dev[ch].base+ICSR);

start_stop_condition(adap);

iowrite32(0, dev[ch].base+ICSR);

return 0;

}

static int xfer_read(struct i2c_adapter *adap, unsigned char *buf,

int length)

{

u32 tmp;

int ret;

enum lf1000_i2c_state state =

I2C_SEND_ADDR;

struct platform_device *pdev =

to_platform_device(adap->dev.parent);

int ch =

pdev->id;

tmp = (ioread32(dev[ch].base+ICSR)

& 0x1F0F);

tmp |=

((1<

(1<

iowrite32(tmp, dev[ch].base+ICSR);

start_stop_condition(adap);

while(1) {

switch(state) {

case

I2C_SEND_ADDR:

ret =

lf1000_i2c_wait(adap);

if(ret !=

0)

goto

done_read;

tmp =

ioread32(dev[ch].base+ICSR);

if(tmp

& (1<

{

printk(KERN_INFO

"i2c: no ACK in xfer_read\n");

ret

= -EFAULT;

goto

done_read;

}

state =

I2C_SEND_DATA;

break;

case

I2C_SEND_DATA:

*buf++ =

ioread32(dev[ch].base+IDSR);

start_stop_condition(adap);

ret =

lf1000_i2c_wait(adap);

if(ret !=

0)

goto

done_read;

if(--length

<= 0)

state

= I2C_SEND_DONE;

break;

case

I2C_SEND_DONE:

ret =

0;

goto

done_read;

}

}

done_read:

tmp = ioread32(dev[ch].base+ICSR);

tmp &= ~(0x1F0F);

tmp |=

((1<

iowrite32(tmp, dev[ch].base+ICSR);

start_stop_condition(adap);

iowrite32(0, dev[ch].base+ICSR);

return ret;

}

static int lf1000_xfer(struct i2c_adapter *adap, struct i2c_msg

*pmsg, int num)

{

int i, ret;

unsigned long flags;

struct platform_device *pdev =

to_platform_device(adap->dev.parent);

int ch =

pdev->id;

spin_lock_irqsave(&dev[ch].bus_access,

flags);

while(dev[ch].busy) {

spin_unlock_irqrestore(&dev[ch].bus_access,

flags);

if(wait_event_interruptible(dev[ch].bus_access,

i2c_bus_available(adap))) {

dev[ch].busy

= 0;

spin_unlock_irqrestore(&dev[ch].bus_access,

flags);

return

-ERESTARTSYS;

}

spin_lock_irqsave(&dev[ch].bus_access,

flags);

}

dev[ch].busy = 1;

spin_unlock_irqrestore(&dev[ch].bus_access,

flags);

lf1000_i2c_clock(1,adap);

for(i = 0; i < num; i++)

{

lf1000_i2c_hwinit(adap);

iowrite32(pmsg->addr

| ((pmsg->flags & I2C_M_RD) ? 1 :

0),

dev[ch].base+IDSR);

if(pmsg->len

&& pmsg->buf)

{

if(pmsg->flags

& I2C_M_RD)

ret

= xfer_read(adap, pmsg->buf,

pmsg->len);

else

ret

= xfer_write(adap, pmsg->buf,

pmsg->len);

if(ret !=

0)

goto

xfer_done;

}

pmsg++;

}

ret = i;

xfer_done:

lf1000_i2c_clock(0,adap);

spin_lock_irqsave(&dev[ch].bus_access,

flags);

dev[ch].busy = 0;

spin_unlock_irqrestore(&dev[ch].bus_access,

flags);

return ret;

}

static u32 lf1000_func(struct i2c_adapter *adapter)

{

return

I2C_FUNC_I2C;

}

static struct i2c_algorithm lf1000_algorithm = {

.master_xfer = lf1000_xfer,

.functionality = lf1000_func,

};

static int lf1000_i2c_probe(struct platform_device *pdev)

{

struct resource *res;

struct i2c_adapter *adapter;

int ret = 0;

unsigned int pclk_hz;

int ch =

pdev->id;

res = platform_get_resource(pdev,

IORESOURCE_MEM, I2C_CHANNEL);

if(!res) {

printk(KERN_ERR "i2c: failed to

get resource\n");

return -ENXIO;

}

if(!request_mem_region(res->start,

(res->end - res->start) + 1,

"lf1000_i2c")) {

printk(KERN_ERR "i2c: failed to

request_mem_region\n");

return -EBUSY;

}

dev[ch].base =

ioremap(res->start, (res->end -

res->start) + 1);

if(dev[ch].base == NULL) {

printk(KERN_ERR "i2c: failed to

ioremap\n");

ret = -ENOMEM;

goto fail_remap;

}

adapter = kzalloc(sizeof(struct i2c_adapter),

GFP_KERNEL);

if(adapter == NULL) {

printk(KERN_ERR "i2c: failed to

allocate interface\n");

ret = -ENOMEM;

goto fail_adapter;

}

sprintf(adapter->name,

"LF1000");

adapter->algo =

&lf1000_algorithm;

adapter->class =

I2C_CLASS_HWMON;

adapter->dev.parent =

&pdev->dev;

platform_set_drvdata(pdev, adapter);

dev[ch].irq = platform_get_irq(pdev,

I2C_CHANNEL);

if(dev[ch].irq < 0) {

printk(KERN_ERR "i2c: failed to

get an IRQ\n");

ret = dev[ch].irq;

goto fail_irq;

}

ret = request_irq(dev[ch].irq,

lf1000_i2c_irq,

SA_INTERRUPT|SA_SAMPLE_RANDOM,

"i2c", pdev);

if(ret) {

printk(KERN_ERR "i2c:

requesting IRQ failed\n" );

goto fail_irq;

}

init_waitqueue_head(&dev[ch].wait);

init_waitqueue_head(&dev[ch].bus_access);

pclk_hz =

get_pll_freq(PCLK_PLL)/BCLK_DIV/2;

dev[ch].div = lf1000_CalcDivider(pclk_hz/256,

LF1000_I2C_RATE_HZ);

if(dev[ch].div < 0) {

printk(KERN_ALERT "i2c: failed

to get divider, using 16\n");

dev[ch].div = 16;

}

else if(dev[ch].div > 16) {

printk(KERN_ALERT "i2c: divider

too high, using 16\n");

dev[ch].div = 16;

}

if (pclk_hz/256/dev[ch].div <

LF1000_I2C_RATE_HZ)

dev[ch].div--;

else if (pclk_hz/256/dev[ch].div >

1000*1000 )

printk("i2c: 2IC bus frequency too high\n");

printk("I2C bus %d frequency set to %d KHz,

address at %x IRQ %d\n", ch,

pclk_hz/256/dev[ch].div/1000, res->start,

dev[ch].irq);

if(ch == 0 ) {

#ifdef I2C_SCL0_PORT

gpio_configure_pin(I2C_SCL0_PORT, I2C_SCL0_PIN,

I2C_SCL0_FN, 1, 0, 0);

#endif

#ifdef I2C_SDA0_PORT

gpio_configure_pin(I2C_SDA0_PORT, I2C_SDA0_PIN,

I2C_SDA0_FN, 1, 0, 0);

#endif

}

else if (ch == 1) {

#ifdef I2C_SCL1_PORT

gpio_configure_pin(I2C_SCL1_PORT, I2C_SCL1_PIN,

I2C_SCL1_FN, 1, 0, 0);

#endif

#ifdef I2C_SDA1_PORT

gpio_configure_pin(I2C_SDA1_PORT, I2C_SDA1_PIN,

I2C_SDA1_FN, 1, 0, 0);

#endif

}

lf1000_i2c_hwinit(adapter);

lf1000_i2c_clock(1,adapter);

ret = i2c_add_adapter(adapter);

if(ret != 0) {

printk(KERN_ERR "i2c: failed to

add adapter\n");

goto fail_register;

}

printk("I2C adapter %s registered\n",

adapter->dev.bus_id);

return 0;

fail_register:

lf1000_i2c_clock(0,adapter);

platform_set_drvdata(pdev, NULL);

kfree(adapter);

fail_irq:

free_irq(dev[ch].irq, NULL);

dev[ch].irq = -1;

fail_adapter:

iounmap(dev[ch].base);

fail_remap:

release_mem_region(res->start,

(res->end - res->start) + 1);

return ret;

}

static int lf1000_i2c_remove(struct platform_device *pdev)

{

struct i2c_adapter *adapter =

platform_get_drvdata(pdev);

struct resource *res;

int ret;

int ch = pdev->id;

if(adapter != NULL) {

lf1000_i2c_clock(0,adapter);

ret =

i2c_del_adapter(adapter);

platform_set_drvdata(pdev,

NULL);

res =

platform_get_resource(pdev, IORESOURCE_MEM, 0);

iounmap(dev[ch].base);

release_mem_region(res->start,

(res->end - res->start) + 1);

return ret;

}

return 0;

}

#ifdef CONFIG_PM

static int lf1000_i2c_suspend(struct platform_device *pdev,

pm_message_t mesg)

{

struct i2c_adapter *adap =

i2c_get_adapter(pdev->id);

lf1000_i2c_clock(0, adap);

return 0;

}

static int lf1000_i2c_resume(struct platform_device *pdev)

{

struct i2c_adapter *adap =

i2c_get_adapter(pdev->id);

lf1000_i2c_clock(1, adap);

return 0;

}

#else

#define lf1000_i2c_suspend NULL

#define lf1000_i2c_resume NULL

#endif

static struct platform_driver lf1000_i2c_driver = {

.probe = lf1000_i2c_probe,

.remove = lf1000_i2c_remove,

.suspend = lf1000_i2c_suspend,

.resume = lf1000_i2c_resume,

.driver = {

.name = "lf1000-i2c",

.owner =

THIS_MODULE,

},

};

static int __init lf1000_i2c_init(void)

{

return

platform_driver_register(&lf1000_i2c_driver);

}

static void __exit lf1000_i2c_exit(void)

{

return

platform_driver_unregister(&lf1000_i2c_driver);

}

module_init(lf1000_i2c_init);

module_exit(lf1000_i2c_exit);

MODULE_AUTHOR("Andrey Yurovsky");

MODULE_DESCRIPTION("I2C driver for LF1000");

MODULE_LICENSE("GPL");

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

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

相关文章

4列变成5列 datatable_云南美食界“5巨头”,谁才是NO.1?你家乡的那道菜也在列...

每个城市都有自己盛产的食材&#xff0c;最终也被制作成几代都传延至今的美食&#xff0c;这便是美食的传承。今天小编就来说说云南美食&#xff0c;下面这云南美食界“5巨头”&#xff0c;谁才是你心里的NO.1&#xff1f;你家乡的那道菜也在列哦~云南大理&#xff1a;白族泥鳅…

linux+基因组字符替换,liftover基因组版本直接的coordinate转换

下载地址:http://hgdownload.cse.ucsc.edu/admin/exe/使用方法:【从hg38转到hg19】因为主流的基因组版本还是hg19&#xff0c;但是时代在进步&#xff0c;已经有很多信息都是以hg38的形式公布出来的了。比如&#xff0c;我下载了pfam.df这个protein domain注释文件&#xff0c;…

elinput内容过长显示悬浮框_excel中一直被忽视的名称框,用好了也能提高效率

在excel左上角功能区下方&#xff0c;有一个名称框(下图红框中的部分)。大部分朋友应该没注意过这个地方有什么作用&#xff0c;或者仅仅知道名称框中会显示单元格的位置&#xff0c;因此在操作中这项功能无法表现出其真正的效果。本文就为大家介绍一下关于名称框的一些实用功能…

linux 漏洞 poc,CVE-2017-11176: 一步一步linux内核漏洞利用 (二)(PoC)

使第二次循环中的fget()返回NULL到目前为止&#xff0c;在用户态下满足了触发漏洞的三个条件之一。TODO:使netlink_attachskb()返回1[DONE]exp线程解除阻塞使第二次fget()调用返回NULL在本节中&#xff0c;将尝试使第二次fget()调用返回NULL。这会使得在第二个循环期间跳到“退…

同步轨道进入过程_“收官之星”定点成功!北斗三号卫星全部进入长管模式

◎ 徐新芳 科技日报记者 付毅飞6月30日14时15分&#xff0c;北斗三号全球卫星导航系统最后一颗组网卫星成功定点于距离地面约36000公里的地球同步轨道&#xff0c;顺利进入长期运行管理模式。卫星有效载荷已完成开通&#xff0c;经过遥测数据判读&#xff0c;星载基准频率合成器…

将当前的head推送到远程_Git 通俗易懂系列 三、远程仓库和标签

远程仓库git remote :列出每个远程库的简短名字。如&#xff1a;origin。git remote -v &#xff1a;显示对应的克隆地址&#xff0c;如&#xff1a;originhttp://gitlab.xxx.corp/xxx.git 添加远程库&#xff1a;git remote add pb git://github.com/xxx.gitpb 指代对应的仓库…

linux中cv调用摄像头,ubuntu中opencv调用摄像头

ubuntu中opencv调用摄像头ubuntu中opencv调用摄像头文章目录一、Ubuntu中安装opencv二、关于Linux如何开启摄像头1.安装VMvareTools&#xff0c;这个是真的强&#xff0c;解决了很多常遇到的问题&#xff0c;比如Linux和Windows无法交互粘贴复制的问题。2.要保证Linux这边能开启…

为什么只有奇次谐波_关于开关电源谐波失真,这有一份测量分析方法经验分享!...

无论是从保护电力系统的安全还是从保护用电设备和人身的安全来看&#xff0c;严格控制并限定电流谐波含量&#xff0c;以减少谐波污染造成的危害已成为人们的共识。总谐波失真THD与功率因数 PF 的关系市面上很多的 LED 驱动电源&#xff0c;其输入电路采用简单的桥式整流器和电…

c语言程序设计平时作业代刷,C语言程序设计——小学生口算刷题系统

程序函数关系图函数功能及全局变量介绍代码中已有详细注释的地方不再进行解释。全局变量Cut( )函数此函数用于分割界面&#xff0c;使界面更为美观。Start( )函数此函数集成了开始菜单&#xff0c;年级的输入&#xff0c;为了营造一个快乐而刺激的刷题体验&#xff0c;程序与用…

机器人出魔切还是三相_工业机器人常见故障和修理方法

机械手常见故障和修理方法 1.先动口再动手对于有故障的电气设备&#xff0c;不应急于动手&#xff0c;应先询问产生故障的前后经过及故障现象。对于生疏的设备&#xff0c;还应先熟悉电路原理和结构特点&#xff0c;遵守相应规则。拆卸前要充分熟悉每个电气部件的功能、位置、连…

字符串转内存c语言,【一起学C】C语言面试题必考:字符串操作函数,内存操作函数实现...

本帖最后由 奉聪 于 2017-1-25 14:54 编辑*******前言*******我数一下&#xff0c;我发了几个帖子&#xff0c;1、2、3&#xff1f;哈哈哈&#xff0c;没几个哈&#xff0c;感谢吾爱&#xff0c;让我学到了很多&#xff0c;乐于分享&#xff0c;共同进步&#xff01;最近也是在…

matlab 图像显著性检测ft_全局对比度的图像显著性检测算法

点击上方蓝字关注我们星标或者置顶【OpenCV学堂】干货与教程第一时间送达&#xff01;显著性检测概念显著性就是可以快速引起你注意的对象或者物体&#xff0c;在图像或者视频中显著性检测的结果往往是图像或者视频中对象&#xff0c;在神经学科中显著性检测被描述为注意力机制…

在c51语言的程序中 注释一般采用,【判断题】在 C51 语言的程序中,注释一般采用 /* */ 和 // 来实现。 (3.0分)...

当ab&#xff1c;0时&#xff0c;化简a2b的结果是()A&#xff0e;&#xff0d;abB&#xff0e;a&#xff0d;bC&#xff0e;&#xff0d;a&#xff0d;bD&#xff0e;ab(&#xff0d;5)2的化简结果为()A&#xff0e;25B&#xff0e;5C&#xff0e;&#xff0d;5D&#xff0e;&a…

修改所有列_哪些数据库是行存储?哪些是列存储?有什么区别?

大多数数据库系统存储一组数据记录&#xff0c;这些记录由表中的列和行组成。字段是列和行的交集&#xff1a;某种类型的单个值。属于同一列的字段通常具有相同的数据类型。例如&#xff0c;如果我们定义了一个包含用户数据的表&#xff0c;那么所有的用户名都将是相同的类型&a…

函数指针定积分C语言,急!!!利用函数指针变量编写一个求定积分的通用函数,...

急&#xff01;&#xff01;&#xff01;利用函数指针变量编写一个求定积分的通用函数&#xff0c;答案:4 信息版本&#xff1a;手机版解决时间 2021-05-05 09:17已解决2021-05-05 02:15用它分别求5个函数的定积分:每次需要求定积分的函数是不一样的。可以编写一个求定积分的通…

cordova 更改app版本_【ios马甲包cps联运】App上架难 马甲包不知道该怎么做?

专业app代上架&#xff01;解决全网IOS上包难诸多问题 ,提供多类别马甲包功能包定制服务&#xff01;(直播.财务.社交.生活.游戏.电商)另外提供app加速审核及好评优化服务.长期出售白包功能包!总的来说&#xff0c;App Store 的上架流程&#xff0c;主要分为 7 大步骤:1、创建证…

须使用visual c 内联汇编语言开发,在VisualC 中使用内联汇编

在VisualC 中使用内联汇编2008-04-09 04:08:57来源&#xff1a;互联网 阅读 ()一、内联汇编的优缺点因为在Visual C 中使用内联汇编不需要额外的编译器和联接器&#xff0c;且可以处理Visual C 中不能处理的一些事情&#xff0c;而且可以使用在C/C 中的变量&#xff0c;所以非常…

dockerfile 修改文件权限_网易技术实践|Docker文件系统实战

在本文中&#xff0c;我们来实战构建一个Docker镜像&#xff0c;然后实例化容器&#xff0c;在Docker的生命周期中详细分析一下Docker的文件存储情况和DockerFile优化策略。在开始实战之前&#xff0c;我们先介绍一个概念&#xff0c;联合文件系统&#xff08;Union File Syste…

stm32c语言写数码管定时器,使用TIM1产生1秒定时控制数码管显示0-9(STM32_10)

一、项目配置1、新建项目文件夹"TimSeg"&#xff1b;2、通过Keil5创建新项目&#xff0c;保存在所创建的文件夹中(设项目名为pTimSeg)&#xff0c;选择MCU芯片为"STM32F103ZE"(本程序使用的硬件为&#xff1a;STM32-PZ6806L开发板)3、在"TimSeg"…

pandas自动创建文件夹_pandas快速入门

pandas有两类数据对象&#xff1a;dataframe和series。Series是一个带标签的一维数组&#xff0c;通常索引在左&#xff0c;值在右。dataframe是一个带标签的二维数组&#xff0c;可以理解成series的字典&#xff0c;共用索引标签。重点记录dataframe的相关用法&#xff1a;一.…