当前位置: 首页 > news >正文

建设银行个人网站官网网站开发w亿玛酷1负责

建设银行个人网站官网,网站开发w亿玛酷1负责,网页开发与设计的内容,市场调研是什么工作1 理论 1.1 基本概念 目前对外设的操作,都是通过寄存器。寄存器的概念,其实就是接口,访问硬件接口,有I/O端口通信和内存映射I/O (Memory-Mapped I/O),I/O端口通信是比较老的那种,都是老的串口并口设备&am…

1 理论

1.1 基本概念

目前对外设的操作,都是通过寄存器。寄存器的概念,其实就是接口,访问硬件接口,有I/O端口通信和内存映射I/O (Memory-Mapped I/O),I/O端口通信是比较老的那种,都是老的串口并口设备,PS/2鼠标在用,感觉现在应该用不到了。以我浅显的比喻,就是一个是API通信,一个是内存映射。

另外说说这个IO操作模型和总线的关系,两者其实没有关系,比如说I2C总线可以使用IO端口也可以使用内存映射,实际上用的应该是内存映射,但是这块现在是被封装在open,read这几个接口之后,所以一般也感觉不到。


1.2 CPU缓冲

书里面讲的有点绕,也可能是翻译的问题,其实本质就是多核的情况下,可能后面的变量先于前面的变量生效。

// CPU1: Producer
void update_data() {data = 42;          // 更新数据mb();               // 确保data的更新在flag设置之前完成flag = 1;           // 设置标志
}
// CPU2: Consumer
void read_data() {while (flag == 0);  // 等待标志被设置int value = data;   // 读取数据// 使用value进行后续操作
}

在CPU1中:

data = 42;:更新数据。
mb();:插入全内存屏障,确保在此之前的所有内存操作(即data的更新)在此之后的操作(即flag的设置)之前完成。
flag = 1;:设置标志,通知CPU2数据已准备好。


在CPU2中:

while (flag == 0);:等待flag被设置。
int value = data;:读取数据,确保读取的是更新后的值。

1.3 申请IO的API

这里会使用request_region,release_region这几个接口。
申请成功后,会在/proc/ioports看到。

soft@7080:~/memo$ cat /proc/ioports 
0000-0000 : PCI Bus 0000:000000-0000 : dma10000-0000 : pic10000-0000 : timer00000-0000 : timer10000-0000 : keyboard0000-0000 : keyboard0000-0000 : rtc00000-0000 : dma page reg0000-0000 : pic20000-0000 : dma20000-0000 : fpu0000-0000 : PNP0C04:000000-0000 : serial0000-0000 : iTCO_wdt0000-0000 : pnp 00:030000-0000 : pnp 00:010000-0000 : pnp 00:010000-0000 : pnp 00:010000-0000 : pnp 00:010000-0000 : pnp 00:010000-0000 : pnp 00:010000-0000 : pnp 00:01
0000-0000 : PCI conf1
0000-0000 : PCI Bus 0000:000000-0000 : pnp 00:030000-0000 : ACPI PM1a_EVT_BLK0000-0000 : ACPI PM1a_CNT_BLK0000-0000 : ACPI PM_TMR0000-0000 : ACPI PM2_CNT_BLK0000-0000 : pnp 00:050000-0000 : ACPI GPE0_BLK0000-0000 : pnp 00:070000-0000 : 0000:00:02.00000-0000 : 0000:00:17.00000-0000 : ahci0000-0000 : 0000:00:17.00000-0000 : ahci0000-0000 : 0000:00:17.00000-0000 : ahci0000-0000 : 0000:00:1f.40000-0000 : i801_smbus


1.4 操作端口

在<asm/io.h>中,使用unsigned inb(unsigned port);void outb(unsigned char byte, unsigned port);unsigned inl(unsigned port);。这里主要的差别是数据的宽度。在底层,8位,16位,32位都必须要做出区别。
用户空间中也可以通过<sys/io.h>的接口操作,但是需要root权限,以及使用ioperm 和 iopl申请权限。

还有接口可以实现直接读取或者写入一串字符:
void insb(unsigned port, void *addr, unsigned long count);
void outsb(unsigned port, void *addr, unsigned long count);

1.5 平台差异

最后是这些IO接口不是所有平台可用,书中列出了这些区别。对我来说,x86,ARM,MIPS这几个平台能用就够了。


2 short代码

书中是和并口设备交互,串口设备如上图。现在实在是找不到这样的设备了。我的重点是后面的USB,所以这次就代码走读为主。代码是short.c,就一个c文件。还是很简单。

module_init(short_init);
module_exit(short_cleanup);

重点就是两个函数,short_init和short_cleanup。

1 short_init

int short_init(void)
{int result;/** first, sort out the base/short_base ambiguity: we'd better* use short_base in the code, for clarity, but allow setting* just "base" at load time. Same for "irq".*/short_base = base;short_irq = irq;/* Get our needed resources. */if (!use_mem) {if (! request_region(short_base, SHORT_NR_PORTS, "short")) {printk(KERN_INFO "short: can't get I/O port address 0x%lx\n",short_base);return -ENODEV;}} else {if (! request_mem_region(short_base, SHORT_NR_PORTS, "short")) {printk(KERN_INFO "short: can't get I/O mem address 0x%lx\n",short_base);return -ENODEV;}/* also, ioremap it */short_base = (unsigned long) ioremap(short_base, SHORT_NR_PORTS);/* Hmm... we should check the return value */}/* Here we register our device - should not fail thereafter */result = register_chrdev(major, "short", &short_fops);if (result < 0) {printk(KERN_INFO "short: can't get major number\n");if (!use_mem) {release_region(short_base, SHORT_NR_PORTS);} else {release_mem_region(short_base, SHORT_NR_PORTS);}return result;}if (major == 0) major = result; /* dynamic */short_buffer = __get_free_pages(GFP_KERNEL,0); /* never fails */  /* FIXME */short_head = short_tail = short_buffer;/** Fill the workqueue structure, used for the bottom half handler.* The cast is there to prevent warnings about the type of the* (unused) argument.*//* this line is in short_init() */INIT_WORK(&short_wq, (void (*)(struct work_struct *)) short_do_tasklet);/** Now we deal with the interrupt: either kernel-based* autodetection, DIY detection or default number*/if (short_irq < 0 && probe == 1)short_kernelprobe();if (short_irq < 0 && probe == 2)short_selfprobe();if (short_irq < 0) /* not yet specified: force the default on */switch(short_base) {case 0x378: short_irq = 7; break;case 0x278: short_irq = 2; break;case 0x3bc: short_irq = 5; break;}/** If shared has been specified, installed the shared handler* instead of the normal one. Do it first, before a -EBUSY will* force short_irq to -1.*/if (short_irq >= 0 && share > 0) {result = request_irq(short_irq, short_sh_interrupt,IRQF_SHARED,"short",short_sh_interrupt);if (result) {printk(KERN_INFO "short: can't get assigned irq %i\n", short_irq);short_irq = -1;}else { /* actually enable it -- assume this *is* a parallel port */outb(0x10, short_base+2);}return 0; /* the rest of the function only installs handlers */}if (short_irq >= 0) {result = request_irq(short_irq, short_interrupt,0, "short", NULL);if (result) {printk(KERN_INFO "short: can't get assigned irq %i\n",short_irq);short_irq = -1;}else { /* actually enable it -- assume this *is* a parallel port */outb(0x10,short_base+2);}}/** Ok, now change the interrupt handler if using top/bottom halves* has been requested*/if (short_irq >= 0 && (wq + tasklet) > 0) {free_irq(short_irq,NULL);result = request_irq(short_irq,tasklet ? short_tl_interrupt :short_wq_interrupt,0, "short-bh", NULL);if (result) {printk(KERN_INFO "short-bh: can't get assigned irq %i\n",short_irq);short_irq = -1;}}return 0;
}

首先是request_region,如果配置了内存映射,就是request_mem_region和ioremap。

之后是注册字符设备,register_chrdev。

内存是用的__get_free_pages。

之后的INIT_WORK看起来是处理中断用的。

之后根据probe状态处理probe,有两种,short_kernelprobe和short_selfprobe。这两个的区别还要再看看。

后面是request_irq,之后outb(0x10,short_base+2);向寄存器写入0x10。

在较早的硬件中(例如并口设备),基地址和中断号通常是预定义的,形成了硬件设计上的约定。例如,地址0x378通常对应 IRQ 7,地址0x278通常对应 IRQ 2。


2 short_cleanup

倒是没啥特别的,就是清理。

void short_cleanup(void)
{if (short_irq >= 0) {outb(0x0, short_base + 2);   /* disable the interrupt */if (!share) free_irq(short_irq, NULL);else free_irq(short_irq, short_sh_interrupt);}/* Make sure we don't leave work queue/tasklet functions running */if (tasklet)tasklet_disable(&short_tasklet);elseflush_scheduled_work();unregister_chrdev(major, "short");if (use_mem) {iounmap((void __iomem *)short_base);//release_mem_region(short_base, SHORT_NR_PORTS);release_mem_region(base, SHORT_NR_PORTS);} else {release_region(short_base,SHORT_NR_PORTS);}if (short_buffer) free_page(short_buffer);
}

free_irq,unregister_chrdev,release_mem_region,release_region,free_page。

http://www.yayakq.cn/news/437810/

相关文章:

  • 门户网站集群建设方案ftp中打开wordpress
  • 推荐一个免费网站宁波人才网
  • 电子商务网站建设需要注意什么毕设做网站的系统概述怎么写
  • 贵州三蒲建设工程有限公司网站今天上午北京发生了什么
  • 大连网站建设渠道建设工程安全监督备案网站
  • 个人买卖网站如何做兰州模板型网站建设
  • 网站建设与制开发网站公司名称
  • 网站做外链的方式行业网站建设教程
  • 好网站建设公司选择哪家好百度的企业网站
  • 做企业网站应该注意什么校内二级网站建设整改方案
  • 新闻摘抄大全小红书seo
  • 上海响应式网站建设公司投资公司取名字大全
  • 网站怎么怎么做关键字北京网站优化效果怎样
  • 网站制作不用备案杭州专业的网站制作成功案例
  • 门户网站的建设公司一般的学校网站怎么做
  • 用jsp实现网站开发的流程c# 网站开发实例教程
  • 网站建设高端勒流有做网站的吗
  • 导购类网站备案网站上传wordpress
  • 哪个旅游网站做的比较好会计培训班初级费用
  • 可以自己做安卓app的网站网站建设基本情况介绍
  • 企业网站建设长沙app软件程序开发
  • 天津网站建设制作品牌公司WordPress 转发文章 配图怎么办
  • 教你学做窗帘的网站校园网站设计与实现
  • 网站优化如何收费wordpress搜索乱码
  • 长春百度网站排名优化轴承 网站建设 企炬
  • ups国际快递网站建设天津网站建设有哪些
  • 请柬网站开发最新新闻摘抄
  • 零基础网站建设教程大型资讯门户网站怎么做排名
  • seo网站优化外包lnmp wordpress 数据库
  • 获取网站访客qq代码泸州市住房和城乡建设厅官方网站