精华内容
下载资源
问答
  • 新探索研究生英语(基础级)读写教程U4课件_AE1
  • 新视野大学英语3第二版读写教程答案含中文.doc
  • 适用人群 开发从业人员,大数据从业人员,运维从业人员,IT相关从业人员,想快速掌握技能的一切人员 课程概述 ElasticSearch7.x集群?Elasticsearch-head7.x官网都没有的...主从读写 中文分词 Head插件 cerebro插件
  • 'r') as f: print(f.read(12).decode('utf-8')) 输出结果: 匆匆那年 结果说明:Python2中read(size)方法的size参数指定的要读取的字节数,而song.txt文件是UTF-8编码的内容,一个汉字3个字节,因此12个字节刚好...

    一、I/O操作概述

    I/O在计算机中是指Input/Output,也就是Stream(流)的输入和输出。这里的输入和输出是相对于内存来说的,Input Stream(输入流)是指数据从外(磁盘、网络)流进内存,Output Stream是数据从内存流出到外面(磁盘、网络)。程序运行时,数据都是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方(通常是磁盘、网络操作)就需要IO接口。

    那么这个IO接口是由谁提供呢?高级编程语言中的IO操作是如何实现的呢?

    操作系统是个通用的软件程序,其通用目的如下:

    硬件驱动

    进程管理

    内存管理

    网络管理

    安全管理

    I/O管理

    操作系统屏蔽了底层硬件,向上提供通用接口。因此,操作I/O的能力是由操作系统的提供的,每一种编程语言都会把操作系统提供的低级C接口封装起来供开发者使用,Python也不例外。

    二、文件读写实现原理与操作步骤

    1. 文件读写实现原理

    文件读写就是一种常见的IO操作。那么根据上面的描述,可以推断python也应该封装操作系统的底层接口,直接提供了文件读写相关的操作方法。事实上,也确实如此,而且Java、PHP等其他语言也是。

    那么我们要操作的对象是什么呢?我们又如何获取要操作的对象呢?

    由于操作I/O的能力是由操作系统提供的,且现代操作系统不允许普通程序直接操作磁盘,所以读写文件时需要请求操作系统打开一个对象(通常被称为文件描述符--file descriptor, 简称fd),这就是我们在程序中要操作的文件对象。

    通常高级编程语言中会提供一个内置的函数,通过接收"文件路径"以及“文件打开模式”等参数来打开一个文件对象,并返回该文件对象的文件描述符。因此通过这个函数我们就可以获取要操作的文件对象了。这个内置函数在Python中叫open(), 在PHP中叫fopen(),

    2. 文件读写操作步骤

    不同的编程语言读写文件的操作步骤大体都是一样的,都分为以下几个步骤:

    1)打开文件,获取文件描述符2)操作文件描述符--读/写3)关闭文件

    只是不同的编程语言提供的读写文件的api是不一样的,有些提供的功能比较丰富,有些比较简陋。

    需要注意的是:文件读写操作完成后,应该及时关闭。一方面,文件对象会占用操作系统的资源;另外一方面,操作系统对同一时间能打开的文件描述符的数量是有限制的,在Linux操作系统上可以通过ulimit -n来查看这个显示数量。如果不及时关闭文件,还可能会造成数据丢失。因为我将数据写入文件时,操作系统不会立刻把数据写入磁盘,而是先把数据放到内存缓冲区异步写入磁盘。当调用close方法时,操作系统会保证把没有写入磁盘的数据全部写到磁盘上,否则可能会丢失数据。

    三、文件打开模式

    我们先来看下在Python、PHP和C语言中打开文件的函数定义

    Python

    # Python2
    open(name[,mode[,buffering]])
    # Python3
    open(file,mode= 'r', buffering=-1,encoding=None,errorS=None,newline=None,closefd=True,opener=None)

    PHP

    resourcefopen ( string$filename, string$mode[, bool$use_include_path=false[, resource$context]] )

    C语言

    intopen(constchar* pathname,intflags);

    会发现以上3种编程语言内置的打开文件的方法接收的参数中,除了都包含一个“文件路径名称”,还会包含一个mode参数(C语言的open函数中的flags参数作用相似)。这么mode参数定义的是打开文件时的模式,常见的文件打开模式有:只读、只写、可读可写、只追加。不同的编程语言中对文件打开模式的定义有些微小的差别,我们来看下Python中的文件打开模式有哪些。

    思考1:r+、w+和a+都可以实现对文件的读写,那么他们有什么区别呢?

    r+会覆盖当前文件指针所在位置的字符,如原来文件内容是"Hello,World",打开文件后写入"hi"则文件内容会变成"hillo, World"

    w+与r+的不同是,w+在打开文件时就会先将文件内容清空,不知道它有什么用

    a+与r+的不同是,a+只能写到文件末尾(无论当前文件指针在哪里)

    思考2:为什么要定义这些模式呢?为什么不能像我们用word打开一篇文档一样既可以读,又可以写,还可修改呢?

    关于这个问题,我查了很多资料,也没找到很权威的说明。在跟同行朋友交流过程中,发现大家主要有两种观点:

    跟安全有关,有这种观点的大部分是做运维的朋友,他们认为这就像linux上的rwx(读、写、执行)权限。

    跟操作系统内核管理I/O的机制有关,有这种观点的大部分是做C开发的,特别是与内核相关的开发人员。为了提高读写速度,要写入磁盘的数据会先放进内存缓冲区,之后再回写。由于可能会同时打开很多文件,当要回写数据时,需要遍历以打开的文件判断是否需要回写。他们认为如果打开文件时指定了读写模式,那么需要回写时,只要去查找以“可写模式”打开的文件就可以了。

    四、Python文件操作步骤示例

    我们来读取这样一个文本文件:song.txt,该文件的字符编码为utf-8。

    1. 菜鸟实现(只是实现功能):

    Python3实现:

    #第一步:(以只读模式)打开文件
    f = open('song.txt', 'r', encoding='utf-8')
    
    #第二步:读取文件内容
    print(f.read())
    
    #第三步:关闭文件
    f.close()

    这里说下Python2的实现

    #第一步:(以只读模式)打开文件
    f = open('song.txt', 'r')
    
    #第二步:读取文件内容
    print(f.read().decode('utf-8'))
    
    #第三步:关闭文件
    f.close()

    说明:

    Python3中已经内置对Unicode的支持,字符串str已经是真正的Unicode字符串。也就是说Python3中的文件读取方法已经自动完成了解码处理,因此无需再手动进行解码,可以直接将读取的文件中的内容进行打印;Python2中的字符串str是字节串,读取文件得到的也是字节串,在打印之前应该手动将其解码成Unicode字符串。关于这部分的说明,可以参考之前这篇文章<<再谈Python中的字符串与字符编码>>

    2. 中级实现

    在实现基本功能的前提下,考虑一些可能的意外因素。因为文件读写时都有可能产生IO错误(IOError),一旦出错,后面包括f.close()在内的所有代码都不会执行了。因此我们要保证文件无论如何都能被关闭。那么可以用try...finally来实现,这实际上就是try...except..finally的简化版(我们只用Python3来进行示例演示):

    f = ''
    try:
        f = open("song.txt", 'r', encoding="utf-8")
        print(f.read())
        num = 10 / 0
    finally:
        print( ">>>>>>finally")
        if f:
            f.close()

    输出结果

     

    输出结果说明,尽管with代码块中出现了异常,但是”>>>>>>finally“ 信息还是被打印了,说明finally代码块被执行,即文件关闭操作被执行。但是结果中错误信息还是被输出了,因此还是建议用一个完成的try...except...finally语句对异常信息进行捕获和处理。

    3. 最佳实践

    为了避免忘记或者为了避免每次都要手动关闭文件,我们可以使用with语句(一种语法糖,语法糖语句通常是为了简化某些操作而设计的)。with语句会在其代码块执行完毕之后自动关闭文件。因此我们可以这样来改写上面的程序:

    with open("song.txt", 'r', encoding="utf-8' ) as f:
        print(f.read())
    print(f.closed)
    

    输出结果:

    是不是变得简介多了,代码结构也比较清晰了。with之后打印的f.closed属性值为True,说明文件确实被关闭了。

    思考:

    with语句会帮我们自动处理异常信息吗?

    要回答这个问题就要提到“上下文管理器” 和 with语句的工作流程。

    with语句不仅仅可以用于文件操作,它实际上是一个很通用的结构,允许使用所谓的上下文管理器(context manager)。上下文管理器是一种支持__enter__()和__exit__()这两个方法的对象。__enter__()方法不带任何参数,它在进入with语句块的时候被调用,该方法的返回值会被赋值给as关键字之后的变量。__exit__()方法带有3个参数:type(异常类型), value(异常信息), trace(异常栈),当with语句的代码块执行完毕或执行过程中因为异常而被终止都会调用__exit__()方法。正常退出时该方法的3个参数都为None,异常退出时该方法的3个参数会被分别赋值。如果__exit__()方法返回值(真值测试结果)为True则表示异常已经被处理,命令执行结果中就不会抛出异常信息了;反之,如果__exit__()方法返回值(真值测试结果)为False,则表示异常没有被处理并且会向外抛出该异常。

    现在我们应该明白了,异常信息会不会被处理是由with后的语句返回对象的__exit__()方法决定的。文件可以被用作上下文管理器。它的__enter__方法返回文件对象本身,__exit__方法会关闭文件并返回None。我们看下file类中关于这两个方法的实现:

    def _enter_(self): # real signature unknown; restored from _doc_
        """_enter_ -> self. """
        return self
    
    def _exit__(self,*excinfo): # real signature unknown; restored from _doc_
        """_exit_(*excinfo) -> None.Closes the file."""
        pass

    可见,file类的__exit__()方法的返回值为None,None的真值测试结果为False,因此用于文件读写的with语句代码块中的异常信息还是会被抛出来,需要我们自己去捕获并处理。

    #更多Python相关视频、资料加群857662006免费获取
    
    with open("song.txt", 'r', encoding=" utf-8") as f:
        print(f.read())
        num = 10/0
    

    输出结果:

    注意:上面所说的__exit__()方法返回值(真值测试结果)为True则表示异常已经被处理,指的是with代码块中出现的异常。它对于with关键字之后的代码中出现的异常是不起作用的,因为还没有进入上下文管理器就已经发生异常了。因此,无论如何,还是建议在必要的时候在with语句外面套上一层try...except来捕获和处理异常。

    有关“上下文管理器”这个强大且高级的特性的更多信息,请参看Python参考手册中的上下文管理器部分。或者可以在Python库参考中查看上下文管理器和contextlib部分。

    五、Python文件读取相关方法

    我们知道,对文件的读取操作需要将文件中的数据加载到内存中,而上面所用到的read()方法会一次性把文件中所有的内容全部加载到内存中。这明显是不合理的,当遇到一个几个G的的文件时,必然会耗光机器的内存。这里我们来介绍下Python中读取文件的相关方法:

    此外,还要两个与文件指针位置相关的方法

    下面来看下操作实例

    1. 读取指定长度的内容

    Python2

    with open('song.txt', 'r') as f:
        print(f.read(12).decode('utf-8'))
    

    输出结果:

    匆匆那年

    结果说明:Python2中read(size)方法的size参数指定的要读取的字节数,而song.txt文件是UTF-8编码的内容,一个汉字占3个字节,因此12个字节刚好是4个汉字。

    Python3

    输出结果:

    匆匆那年我们 究竟说

    结果说明:Python3中read(size)方法的size参数指定的要读取的字符数,这与文件的字符编码无关,就是返回12个字符。

    2. 读取文件中的一行内容

    Python2

    with open('song.txt', 'r', encoding='utf-8') as f:
        print(f.readline()
    

    Python3

    with open('song.txt', 'r') as f:
        print(f.readline(.decode('utf-8'))
    

    输出结果都一样:

    匆匆那年我们 究竟说了几遍 再见之后再拖延

    3. 遍历打印一个文件中的每一行

    这里我们只以Python3来进行实例操作,Python2仅仅是需要在读取到内容后进行手动解码而已,上面已经有示例。

    方式一:先一次性读取所有行到内存,然后再遍历打印

    with open('song.txt', 'r', encoding='utf-8') as f:
        for line in f.readlines():
            print(line)
    

    输出结果:

    这种方式的缺点与read()方法是一样的,都是会消耗大量的内存空间。

    方式二:通过迭代器一行一行的读取并打印

    #更多Python相关视频、资料加群857662006免费获取
    
    with open('song.txt', 'r', encoding='utf-8', newline='') as f:
        for line in f:
            print(line)
    

    输出结果:

    另外,发现上面的输出结果中行与行之间多了一个空行。这是因为文件每一行的默认都有换行符,而print()方法也会输出换行,因此就多了一个空行。去掉空行也比较简单:可以用line.rstrip()去除字符串右边的换行符,也可以通过print(line, end='')避免print方法造成的换行。

    file类的其他方法:


    六、文件读写与字符编码

    前面已经写过一篇介绍Python中字符编码的相关文件<<再谈Python中的字符串与字符编码>>里面花了很大的篇幅介绍Python中字符串与字符编码的关系以及转换过程。其中谈到过两个指定的字符编码的地方,及其作用:

    PyCharm等IDE开发工具指定的项目工程和文件的字符编码:它的主要作用是告诉Pycharm等IDE开发工具保存文件时应该将字符转换为怎样的字节表示形式,以及打开并展示文件内容时应该以什么字符编码将字节码转换为人类可识别的字符。

    Python源代码文件头部指定的字符编码,如*-* coding:utf-8 -*-:它的主要作用是告诉Python解释器当前python代码文件保存时所使用的字符编码,Python解释器在执行代码之前,需要先从磁盘读取该代码文件中的字节然后通过这里指定的字符编码将其解码为unicode字符。Python解释器执行Python代码的过程与IDE开发工具是没有什么关联性的。

    那么这里为什么又要谈起字符编码的问题呢?

    或者换个问法,既然从上面已经指定了字符编码,为什么对文件进行读写时还要指定字符编码呢?从前面的描述可以看出:上面两个地方指定的是Python代码文件的字符编码,是给Python解释器和Pycharm等程序软件用的;而被读写文件的字符编码与Python代码文件的字符编码没有必然联系,读写文件时指定的字符编码是给我们写的程序软件用的。这是不同的主体和过程,希望我说明白了。

    读写文件时怎样指定字符编码呢?

    上面解释了读写文件为什么要指定字符编码,这里要说下怎样指定字符编码(其实这里主要讨论是读取外部数据时的情形)。这个问题其实在上面的文件读取示例中已经使用过了,这里我们再详细的说一下。

    首先,再次看一下Python2和Python3中open函数的定义:

    # Python2
    open(name[, mode[, buffering]])
    #Python3
    open(file, mode= 'r', buffering=-1,encoding=None,errors=None,newline=None, closefd=True,opener=None)
    

    可以看到,Python3的open函数中多了几个参数,其中包括一个encoding参数。是的,这个encoding就是用来指定被操作文件的字符编码的。

    #读操作
    with open('song.txt', 'r', encoding='utf-8') as f:
        print(f.read())
    
    #写操作
    with open('song.txt', 'w', encoding='utf-8') as f:
        print(f.write('你好'))
    

    那么Python2中怎样指定呢?Python2中的对文件的read和write操作都是字节,也就说Python2中文件的read相关方法读取的是字节串(如果包含中文字符,会发现len()方法的结果不等于读取到的字符个数,而是字节数)。如果我们要得到 正确的字符串,需要手动将读取到的结果decode(解码)为字符串;相反,要以特定的字符编码保存要写入的数据时,需要手动encode(编码)为字节串。这个encode()和decode()函数可以接收一个字符编码参数。Python3中read和write操作的都是字符串,实际上是Python解释器帮我们自动完成了写入时的encode(编码)和读取时的decode(解码)操作,因此我们只需要在打开文件(open函数)时指定字符编码就可以了。

    #读操作
    with open('song.txt', 'r') as f:
        print(f.read().decode('utf-8'))
    
    
    #写操作
    with open('song2.txt', "w') as f:
        #f.write(u'你好".encode("utf-8"))
        #f.write('你好'.decode('utf-8').encode("utf-8"))
        f.write('你好")
    

    文件读写时有没有默认编码呢?

    Python3中open函数的encoding参数显然是可以不指定的,这时候就会用一个“默认字符编码”。

    看下Python3中open函数文档对encoding参数的说明:

    也就是说,encoding参数的默认值是与平台有关的,比如Window上默认字符编码为GBK,Linux上默认字符编码为UTF-8。

    而对于Python2来说,在进行文件写操作时,字节会被直接保存;在进行文件读操作时,如果不手动进行来decode操作自然也就用不着默认字符编码了。但是这时候在不同的字符终端打印的时候,会用当前平台的字符编码自动将字节解码为字符,此时可能会出现乱码。如song.txt文件时UTF-8编码的,在windows(字符编码为GBK)的命令行终端进行如下操作就会出现乱码:

    展开全文
  • python菜鸟教程 | 文件读写及修改

    千次阅读 2020-04-14 14:54:12
    文件的读写有三种形式:读、写和追加。 一、读模式 r 和读写模式 r+ 1、读模式 r ...a、用open打开文件,在python3中只有open。python2可以用open和file。关闭文件是close()。一般有开就有关 b、如...

    文件的读写有三种形式:读、写和追加。

    一、读模式 r 和读写模式 r+

    1、读模式 r

    读模式r特点:(1)只能读,不能写;(2)文件不存在时会报错。

    (1)例:读取当前目录下的books.txt文件,该文件如下所示。

       

    解析:

    a、用open打开文件,在python3中只有open。python2可以用open和file。关闭文件是close()。一般有开就有关

    b、如果在当前目录,可以直接写文件名,否则需添加路径。

    c、如果不写 'r',即写成  f = open('books.txt'),也是默认读模式。

    d、read可以将文件所有的内容都读出来

    e、另外,有时需要添加解码格式 encoding ,格式为:

    f = open('books','r',encoding='utf-8')

    (2)

    read:读取文件全部内容

    展开全文
  • 本实验为后续使用DDR3内存的实验做铺垫,通过循环读写DDR3内存,了解其工作原理和DDR3控制器的写法,由于DDR3控制复杂,控制器的编写难度高,这里笔者介绍采用第三方的DDR3 IP控制器情况下的应用,是后续音频、视频...

    原创声明:

    本原创教程由芯驿电子科技(上海)有限公司(ALINX)创作,版权归本公司所有,如需转载,需授权并注明出处(http://www.alinx.com)。

    适用于板卡型号:

    PGL22G/PGL12G

    1. 实验简介

    本实验为后续使用DDR3内存的实验做铺垫,通过循环读写DDR3内存,了解其工作原理和DDR3控制器的写法,由于DDR3控制复杂,控制器的编写难度高,这里笔者介绍采用第三方的DDR3 IP控制器情况下的应用,是后续音频、视频等需要用到DDR3实验的基础。

    2. 实验原理

    DDR SDRAM全称为Double Data Rate SDRAM,中文名为“双倍数据流SDRAM”。DDR SDRAM在原有的SDRAM的基础上改进而来。也正因为如此,DDR能够凭借着转产成本优势来打败昔日的对手RDRAM,成为当今的主流。本文只着重讲DDR的原理和DDR SDRAM相对于传统SDRAM(又称SDR SDRAM)的不同。

    (一) DDR的基本原理

    有很多文章都在探讨DDR的原理,但似乎也不得要领,甚至还带出一些错误的观点。首先我们看看一张DDR正规的时序图。

    从中可以发现它多了两个信号: CLK#与DQS,CLK#与正常CLK时钟相位相反,形成差分时钟信号。而数据的传输在CLK与CLK#的交叉点进行,可见在CLK的上升与下降沿(此时正好是CLK#的上升沿)都有数据被触发,从而实现DDR。在此,我们可以说通过差分信号达到了DDR的目的,甚至讲CLK#帮助了第二个数据的触发,但这只是对表面现象的简单描述,从严格的定义上讲并不能这么说。之所以能实现DDR,还要从其内部的改进说起。

    DDR内存芯片的内部结构图

    这是一颗128Mbit的内存芯片,从图中可以看出来,白色区域内与SDRAM的结构基本相同,但请注意灰色区域,这是与SDRAM的不同之处。首先就是内部的L-Bank规格。SDRAM中L-Bank 存储单元的容量与芯片位宽相同,但在DDR SDRAM中并不是这样,存储单元的容量是芯片位宽的一倍,所以在此不能再套用讲解SDRAM时 “芯片位宽=存储单元容量” 的公式了。也因此,真正的行、列地址数量也与同规格SDRAM不一样了。

    以本芯片为例,在读取时,L-Bank在内部时钟信号的触发下一次传送8bit的数据给读取锁存器,再分成两路4bit数据传给复用器,由后者将它们合并为一路4bit数据流,然后由发送器在DQS的控制下在外部时钟上升与下降沿分两次传输4bit的数据给北桥。这样,如果时钟频率为100MHz,那么在I/O端口处,由于是上下沿触发,那么就是传输频率就是200MHz。

    现在大家基本明白DDR SDRAM的工作原理了吧,这种内部存储单元容量(也可以称为芯片内部总线位宽)=2×芯片位宽(也可称为芯片I/O总线位宽)的设计,就是所谓的两位预取(2-bit Prefetch),有的公司则贴切的称之为2-n Prefetch(n代表芯片位宽)。

    (二) DDR SDRAM与SDRAM的不同

    DDR SDRAM与SDRAM的不同主要体现在以下几个方面。

    DDR SDRAM与SDRAM的主要不同对比表

    DDR SDRAM与SDRAM一样,在开机时也要进行MRS,不过由于操作功能的增多,DDR SDRAM在MRS之前还多了一EMRS阶段(Extended Mode Register Set,扩展模式寄存器设置),这个扩展模式寄存器控制着DLL的有效/禁止、输出驱动强度、QFC 有效/无效等。

    由于EMRS与MRS的操作方法与SDRAM的MRS大同小异,在此就不再列出具体的模式表了,有兴趣的话可查看相关的DDR内存资料。下面我们就着重说说DDR SDRAM的新设计与新功能。

    1、 差分时钟

    差分时钟(参见上文“DDR SDRAM读操作时序图”)是DDR的一个必要设计,但CK#的作用,并不能理解为第二个触发时钟(你可以在讲述DDR原理时简单地这么比喻),而是起到触发时钟校准的作用。由于数据是在CK的上下沿触发,造成传输周期缩短了一半,因此必须要保证传输周期的稳定以确保数据的正确传输,这就要求CK的上下沿间距要有精确的控制。但因为温度、电阻性能的改变等原因,CK上下沿间距可能发生变化,此时与其反相的CK#就起到纠正的作用(CK上升快下降慢,CK# 则是上升慢下降快)。而由于上下沿触发的原因,也使CL=1.5和2.5成为可能,并容易实现。与CK反相的CK#保证了触发时机的准确性。

    2、 数据选取脉冲(DQS)

    总结DQS:它是双向信号;读内存时,由内存产生,DQS的沿和数据的沿对齐;写入内存时,由外部产生,DQS的中间对应数据的沿,即此时DQS的沿对应数据最稳定的中间时刻。

    DQS是DDR SDRAM中的重要功能,它的功能主要用来在一个时钟周期内准确的区分出每个传输周期,并便于接收方准确接收数据。每一颗芯片都有一个DQS信号线,它是双向的,在写入时它用来传送由北桥发来的DQS信号,读取时,则由芯片生成DQS向北桥发送。完全可以说,它就是数据的同步信号。

    在读取时,DQS与数据信号同时生成(也是在CK与 CK#的交叉点)。而DDR内存中的CL也就是从CAS发出到DQS生成的间隔,数据真正出现在数据I/O总线上相对于DQS触发的时间间隔被称为 tAC。注意,这与SDRAM中的tAC的不同。实际上,DQS生成时,芯片内部的预取已经完毕了,tAC是指上文结构图中灰色部分的数据输出时间,由于预取的原因,实际的数据传出可能会提前于DQS发生(数据提前于DQS传出)。由于是并行传输,DDR内存对tAC也有一定的要求,对于 DDR266,tAC的允许范围是±0.75ns,对于DDR333,则是±0.7ns,有关它们的时序图示见前文,其中CL里包含了一段DQS的导入期。

    前文已经说了DQS是为了保证接收方的选择数据, DQS在读取时与数据同步传输,那么接收时也是以DQS的上下沿为准吗?不,如果以DQS的上下沿区分数据周期的危险很大。由于芯片有预取的操作,所以输出时的同步很难控制,只能限制在一定的时间范围内,数据在各I/O端口的出现时间可能有快有慢,会与DQS有一定的间隔,这也就是为什么要有一个tAC规定的原因。而在接收方,一切必须保证同步接收,不能有tAC之类的偏差。这样在写入时,芯片不再自己生成DQS,而以发送方传来的DQS为基准,并相应延后一定的时间,在DQS的中部为数据周期的选取分割点(在读取时分割点就是上下沿),从这里分隔开两个传输周期。这样做的好处是,由于各数据信号都会有一个逻辑电平保持周期,即使发送时不同步,在DQS上下沿时都处于保持周期中,此时数据接收触发的准确性无疑是最高的。在写入时,以DQS的高/低电平期中部为数据周期分割点,而不是上/下沿,但数据的接收触发仍为DQS的上/下沿。

    3、 写入延迟

    在上面的DQS写入时序图中,可以发现写入延迟已经不是0了,在发出写入命令后,DQS与写入数据要等一段时间才会送达。这个周期被称为DQS相对于写入命令的延迟时间(tDQSS, WRITE Command to the first corresponding rising edge of DQS),对于这个时间大家应该很好理解了。

    为什么要有这样的延迟设计呢?原因也在于同步,毕竟一个时钟周期两次传送,需要很高的控制精度,它必须要等接收方做好充分的准备才行。tDQSS是DDR内存写入操作的一个重要参数,太短的话恐怕接受有误,太长则会造成总线空闲。tDQSS最短不能小于0.75个时钟周期,最长不能超过1.25个时钟周期。有人可能会说,如果这样,DQS不就与芯片内的时钟不同步了吗?对,正常情况下,tDQSS是一个时钟周期,但写入时接受方的时钟只用来控制命令信号的同步,而数据的接受则完全依靠DQS进行同步,所以 DQS与时钟不同步也无所谓。不过,tDQSS产生了一个不利影响——读后写操作延迟的增加,如果CL=2.5,还要在tDQSS基础上加入半个时钟周期,因为命令都要在CK的上升沿发出。

    当CL=2.5时,读后写的延迟将为tDQSS+0.5个时钟周期(图中BL=2)

    另外,DDR内存的数据真正写入由于要经过更多步骤的处理,所以写回时间(tWR)也明显延长,一般在3个时钟周期左右,而在DDR-Ⅱ规范中更是将tWR列为模式寄存器的一项,可见它的重要性。

     

    4、 突发长度与写入掩码

    在DDR SDRAM中,突发长度只有2、4、8三种选择,没有了随机存取的操作(突发长度为1)和全页式突发。这是为什么呢?因为L-Bank一次就存取两倍于芯片位宽的数据,所以芯片至少也要进行两次传输才可以,否则内部多出来的数据怎么处理?而全页式突发事实证明在PC内存中是很难用得上的,所以被取消也不希奇。

    但是,突发长度的定义也与SDRAM的不一样了(见本章节最前那幅DDR简示图),它不再指所连续寻址的存储单元数量,而是指连续的传输周期数,每次是一个芯片位宽的数据。对于突发写入,如果其中有不想存入的数据,仍可以运用DM信号进行屏蔽。DM信号和数据信号同时发出,接收方在DQS的上升与下降沿来判断DM的状态,如果DM为高电平,那么之前从DQS 中部选取的数据就被屏蔽了。有人可能会觉得,DM是输入信号,意味着芯片不能发出DM信号给北桥作为屏蔽读取数据的参考。其实,该读哪个数据也是由北桥芯片决定的,所以芯片也无需参与北桥的工作,哪个数据是有用的就留给北桥自己去选吧。

    5、 延迟锁定回路(DLL)

    DDR SDRAM对时钟的精确性有着很高的要求,而DDR SDRAM有两个时钟,一个是外部的总线时钟,一个是内部的工作时钟,在理论上DDR SDRAM这两个时钟应该是同步的,但由于种种原因,如温度、电压波动而产生延迟使两者很难同步,更何况时钟频率本身也有不稳定的情况(SDRAM也内部时钟,不过因为它的工作/传输频率较低,所以内外同步问题并不突出)。DDR SDRAM的tAC就是因为内部时钟与外部时钟有偏差而引起的,它很可能造成因数据不同步而产生错误的恶果。实际上,不同步就是一种正/负延迟,如果延迟不可避免,那么若是设定一个延迟值,如一个时钟周期,那么内外时钟的上升与下降沿还是同步的。鉴于外部时钟周期也不会绝对统一,所以需要根据外部时钟动态修正内部时钟的延迟来实现与外部时钟的同步,这就是DLL的任务。

    DLL不同于主板上的PLL,它不涉及频率与电压转换,而是生成一个延迟量给内部时钟。目前DLL有两种实现方法,一个是时钟频率测量法(CFM,Clock Frequency Measurement),一个是时钟比较法(CC,Clock Comparator)。

    CFM是测量外部时钟的频率周期,然后以此周期为延迟值控制内部时钟,这样内外时钟正好就相差了一个时钟周期,从而实现同步。DLL就这样反复测量反复控制延迟值,使内部时钟与外部时钟保持同步。

    CFM式DLL工作示意图

    CC的方法则是比较内外部时钟的长短,如果内部时钟周期短了,就将所少的延迟加到下一个内部时钟周期里,然后再与外部时钟做比较,若是内部时钟周期长了,就将多出的延迟从下一个内部时钟中刨除,如此往复,最终使内外时钟同步。

    CC式DLL工作示意图

    CFM与CC各有优缺点,CFM的校正速度快,仅用两个时钟周期,但容易受到噪音干扰,并且如果测量失误,则内部的延迟就永远错下去了。CC的优点则是更稳定可靠,如果比较失败,延迟受影响的只是一个数据(而且不会太严重),不会涉及到后面的延迟修正,但它的修正时间要比CFM长。DLL功能在DDR SDRAM中可以被禁止,但仅限于除错与评估操作,正常工作状态是自动有效的。

    3. 硬件介绍

    开发板上使用了1个Micron DDR3的颗粒MT41J128M16HA, 总线宽度16bit,DDR3芯片的容量为2Gb。开发板板上对DDR3的地址线和控制线都做了端接电阻上拉到VTT电压, 保证信号的质量。在PCB的设计上, 完全遵照XILINX的DDR3设计规范, 严格保证等长设计和阻抗控制。在进行DDR3硬件设计时,FPGA的DDR3管脚分配是要求的,而不能随意分配。如果用户自己实在不清楚怎么连接,那就请完全参考我们的原理图来设计。

    在PCB的设计上, 考虑高速信号的数据传输的可靠性, 走线上严格保证等长设计和阻抗控制。开发板DDR部分的原理图如下:

    开发板DDR3

    4. 程序设计

    4.1 添加DDR控制器

    1)首先在PDS环境里新建一个项目,取名为ddr_test。点击菜单中的Tools下拉菜单下打开IP Compiler。

    2)在弹出的界面下选择菜单栏File下的Update;

    3)点击弹出界面中的选择“+”, 然后添加DDR3 IP(ipsl_hmic_h_v1_1.iar),单击Open后再单击Update,再把界面关闭即可。

    4)可以看到左侧已经添加了新的IP“logos HMIC_H”,在右侧取名ddr3_core后单击Customize。

    5)在弹出的界面中Step1:BasicOptions中,DDR3的位置选择Left (BANK L1+BANK L2),其它默认,

    DDR3设置

    6)在Step2:Memory Options中,核对器件的型号,其它默认;

    7)Step3:Interface Options和Step4:Interface summary中保持默认,并单击Generate开始;

    8)然后在弹出的提示框中选择Yes,完成后关闭窗口;

    9)完成后关闭这个工程,双击打开刚才用IP Compiler创建DDR3的example的工程,测试程序位于刚才工程的如下位置;

    10)接下来对DDR3进行管脚约束,分配完成后进行综合布线后产生bit文件。

    4.2 测试程序说明

    本工程为基于 DDR3 硬核的单地址单步读写(读-写-读-写-读循环)用例。 用例中每次写入一个地址的数据,每次读出一个地址的数据。 通过在 AXI 接口的 write 通道写入数据,在 AXI 接口的 read通道接收数据进行数据比对,若错误, 输出error。

    本工程目录结构如下所示:

    ipsl_hmemc_top_test

    test_main_ctrl

    test_wr_ctrl_128bit

    test_rd_ctrl_128bit

    ddr3_core

    (1) ipsl_hmemc_top_test

    顶层模块,在该模块中调用了test_main_ctrl、test_wr_ctrl_128bit、test_rd_ctrl_128bit、ddr3_core。

    (2) test_main_ctrl

    该模块负责将用户指令和模式转化为内部控制信号,控制 test_wr_ctrl 模块和 test_rd_ctrl 模块的运行状态。

    (3) test_wr_ctrl

    该模块根据 test_main_ctrl 发出的控制信号将由 PRBS 产生的数据、地址按照 AXI4 时序发送到总线上。

    (4) test_rd_ctrl

    该模块实现存储数据的读出,并进行校验判断。

    (5) ddr3_core

    该模块为 DDR3 硬核控制器模块。

    测试文件如图所示:

    5. 实验现象

    把程序生成.sbit文件下载到FPGA中,检查核心板上的LED1是否点亮, 如果点亮,则err_flag信号为低,说明DDR3的读写数据正确,如果一直熄灭,说明DDR3读写数据错误,同时底板上的LED1、LED2、LED3熄灭,LED4闪烁。

    展开全文
  • 修改lxdm主题时,我无意间无法进入系统,也无法切换命令行模式,因此我不得不找出Windows系统中是否存在可以读写ext4文件系统的工具.以前尝试过ext2explore,它只能读取和导出文件,并且速度较慢. ext2fsd是我发现...

    6cc298995f38514cc5fe88888a6a9f32.png

    在过去的几天里,我使用定制版本的Bridge Linux来扔Arch Linux. 修改lxdm主题时,我无意间无法进入系统,也无法切换命令行模式,因此我不得不找出Windows系统中是否存在可以读写ext4文件系统的工具.

    以前尝试过ext2explore,它只能读取和导出文件,并且速度较慢. ext2fsd是我发现的唯一可以修改ext4文件系统文件的工具. 它非常强大.

    c2af7bbcaa485abc165508174b17e48f.png

    ext2fsd是一个由中国人发起的项目,主页下载

    安装后windows并行文件系统,启动Ext2Mgr,右键单击要读取和写入的分区,然后选择“配置Ext2卷属性”.

    74796e9f5b8409cf77d429946dde17c3.png

    173d7b0314e3503c9ecbd9e24df40c6d.png

    如果只想读取,则保留默认的“设置为只读,不可写”,否则取消. 语言编码可以是默认的,也可以选择utf-8.

    2-768-png_6_0_0_135_108_622_467_892.979_1262.879-1024-0-0-1024.jpg

    根据需要选择驱动器号设置,保存并退出.

    12f17a2d2bf4fa1471fe43e1e22f15bd.png

    9594faa6ac94c90b57b2b0037105c9b3.png

    已分配驱动器号. 在正常情况下,您此时可以使用系统自己的资源管理器直接访问和修改文件.

    最令人兴奋的是文件的读写速度与NTFS基本相同.

    修改文件后,为了防止误操作windows并行文件系统,可以右键单击并选择“更改装配点驱动器号”以删除分配的驱动器号,这样资源管理器就不会看到它.

    选择菜单“工具和设置”>“配置文件系统驱动程序”,您也可以设置驱动程序.

    7de4379a7b65c492edd1d4a3dc08f04b.png

    最后,这是一个缺点. 因为它使用安装系统服务的形式,所以该服务将在首次使用后在系统启动时自动启动,并且不能做成可移植的形式,这种形式不是很容易移植.

    本文来自电脑杂谈,转载请注明本文网址:

    http://www.pc-fly.com/a/jisuanjixue/article-233101-1.html

    展开全文
  • 还能够是实现在Windows操作系统下挂载Linux系统的ext2、ext3和ext4分区,并可以像在Windows磁盘一样在Linux分区中读写数据,该软件支持简体中文,对于国内用户来说非常友好。 软件特色 Ext2Fsd支持ext2/
  • 3.readlines 函数 四.Python 文件的写入 write 1.write 函数语法 2.write 函数使用案例 五.Python 文件偏移 seek 1.seek 函数 2.tell 函数 3.seek / tell 函数示例代码 六.重点总结 七.猜你喜欢 零基础 ...
  • mysql-proxy实现读写分离MySQL Proxy是一个处于你的client端和MySQL server端之间的简单程序,它可以监测、分析或改变它们的通信。它使用灵活,没有限制,常见的用途包括:负载平衡,故障、查询分析,查询过滤和修改...
  • 因此,转码的时候一定要先搞明白,字符串str是什么编码,然后decode成unicode,然后再encode成其他编码 Python在执行py文件时,默认不能解析中文字符,如果程序中需要使用中文,或者添加了中文注释。会直接报”...
  • Python lxml读写xml文件详细教程xml文档解析创建xml文档节点更新xml文档节点 xml文档解析 下面展示详细解析过程。 <?xml version='1.0' encoding='UTF-8'?> <root> <全局变量> <参数 name="g...
  • ElasticSearch7.x集群搭建(es7)主从读写分离搭建教程 10...
  • 本文转自: https://blog.csdn.net/linzhiqiang0316/article/details/71744340 推荐教程:《java教程》 以上就是Java对文件的读写操作(图文详解)的详细内容,更多请关注php中文网其它相关文章! 相关标签:java ...
  • ITK的数据处理管道结构3. ITK图像读写机制4. 图像的读写程序示例5. 读写RGB图像/多维图像6. 图像数据类型转换7. 提取图像区域/提取三维数据体中的某层8. 访问/遍历图像像素9. 读写图像序列10. 提取DICOM图像的文件...
  • PHP读写XML文件_PHP教程

    2021-03-24 01:26:14
    和结点加入到结点中去 $rootelement->appendChild($title); $rootelement->appendChild($link);... 本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉 本文系统来源:php中文
  • S7协议读写西门子

    2021-09-30 09:52:00
    S7协议读写西门子 1.创建项目 2.导入pom文件 <dependency> <groupId>com.github.s7connector</groupId> <artifactId>s7connector</artifactId> <version>2.1</version&...
  • 什么是redis读写分离

    2021-03-24 12:13:23
    Redis读写分离优势透明兼容 (推荐学习:Redis视频教程)读写分离和普通集群规格一样,都使用了redis-proxy做请求转发,多分片令使用存在一定的限制,但从主从升级单分片读写分离,或者从集群升级到多分片的读写分离...
  • BACnet协议入门必看,虽然协议一直在不断完善,但是开发此协议要先了解的东西都在里面,为数不多的中文BACnet资料之一。
  • Introduction High Availability System Administration Conclusion
  • vc的txt文件的读写操作 很不错的,赞一个
  • Python教程... 5Python简介... 7安装Python. 12Python解释器... 16第一个Python程序... 18使用文本编辑器... 19Python代码运行助手... 25输入和输出... 28Python基础... 32数据类型和变量... 33字符串和编码... 43...
  • Skimage是python一个强大的图像处理的包,对于学习数字图像处理的小伙伴们来说是一个很实用的...涉及到读写操作主要是使用skimage.io中的各种函数,skimage.data 提供了一系列的返回示例图片的方法,其中最为常用的...
  • moi3d 4.0中文版使用教程说明

    千次阅读 2020-11-23 18:49:07
    moi3d教程 1、MOI并没有过分的菜单,而都是很人性化的图形开关设置 2、提供了简单的存储,视图角度,户动参数,显示选择等基本参数 3、工具也是最基本的简单的不能再简单的基本工具 4、对于复杂的导角和布尔精确...
  • 前言:上一篇博客我用AOP+AbstractRoutingDataSource实现了MySQL读写分离,自己写代码实现判断该使用哪个数据源挺麻烦的。Sharding-JDBC 是 Apache 旗下的 ShardingSphere 中的一款轻量级产品,引入 jar 即可完成...
  • 利用C++开源库xlnt读写excel的vs2015工程。详细教程参考博客:https://humfrey.blog.csdn.net/article/details/107527883
  • h2最全中文教程&工具打包,包括部署文档,控制台使用,函数资料,开发教程等。
  • TwinCAT提供了FB_FileRead等一系列读写文件的方法,本小程序演示的是多个贝福自带的FBD功能块连起来用的方法,跟前面讲的一样,建议在初始化的时候把所有FBD都复位,准备使用 真正的读取文件流程是打开-读取-...
  • 今天我们讨论一个 Vim 使用技巧——用 Vim 读写远程文件。要实现这个目的,我们需要使用到一个叫 netrw.vim 的插件。从 Vim 7.x 开始,netrw.vim 就被设置为默认安装的标准插件了。这个插件允许用户通过 ftp、rcp、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,951
精华内容 7,180
关键字:

中文读写教程3