首页 基于s3c2410的jflash源代码说明

基于s3c2410的jflash源代码说明

举报
开通vip

基于s3c2410的jflash源代码说明 Jflash-s3c2410(linux 版本)源码分析 最近在远峰公司买了 arm9 的板子,S3C2410,ARM920T,没有 Nor flash,Nand Flash 是 64M, SDRAM 是 K9f1208,本人对 linux 的热情大于 windows,所以想在 linux 下做开发,可是远峰公司只 给我 YFSJF.exe 文件,而且没有源代码,每次在 linux 下编译好了后还得切换到 windows 下烧录,很 是麻烦,于是在网上找了很多 Jflash 类似的程序,不过不同的烧录针对不同...

基于s3c2410的jflash源代码说明
Jflash-s3c2410(linux 版本)源码分析 最近在远峰公司买了 arm9 的板子,S3C2410,ARM920T,没有 Nor flash,Nand Flash 是 64M, SDRAM 是 K9f1208,本人对 linux 的热情大于 windows,所以想在 linux 下做开发,可是远峰公司只 给我 YFSJF.exe 文件,而且没有源代码,每次在 linux 下编译好了后还得切换到 windows 下烧录,很 是麻烦,于是在网上找了很多 Jflash 类似的程序,不过不同的烧录针对不同的硬件平台,Jflash 是跟 硬件紧密结合的,比如有的针对 Nor Flash,有的针对 Nand Flash 的,不同内核有不同的 Jflash,而且 相同的内核也有不同的版本,因为 Jtag 的原理图不同,就只能有相对应的 Jflash,程序中的定义要与 pc 机并口与 Jtag 接口的对应相一致。 在进入源码分析之前要介绍一些预备的知识,有助于理解源代码,毕竟这个程序和硬件联系很紧 密的。首先介绍一下对 PC 并口做一些简要的介绍 一、PC 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 配备并行口介绍 本文主要介绍计算机的标准配备并行端口即 25 针的母接头端口的应用,在此基础上可以运用相 同的原理使用其它模式的并行端口。并行端口共有 25 支脚,但不是每支脚均被使用到。这些脚被区 图 1 分为 3 种主要的功能,分别是用于数据的传送、检查打印机的状态及控制打印机,其接口如下所示: 注:18~ 脚为 GND 在 PC 机中,标准并行口使用 3 个 8 位 对这些寄存器,也就是所说的数据、 25 号 的端口寄存器,PC 就是通过 状态、控制寄存器的读写访问并口的信号的。本文中使用一些通用的叫法,8 个数据位分别为 D0~ D7,5 个状态位为 S3~S7,4 个控制为 C0~C3。其中字母 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 示了端口寄存器,数字则表示该信号在 寄存器中的位。 数据寄存器 据端口或称数据寄存器(D0~D7)保存了写入数据输出端口的一字节信息。数据端口可以写入数 数据寄存器(即数据输出端口)可擦写、基地址 数 据,也可以读出数据(即可擦写);写进去的当然是我们希望从数据端口引脚输出的数据,不过读进 来的也只是我们上次写进去的数据,或是原来保留在里面的数据,并不是从端口引脚输入 PC 的数据。 数据端口引脚是 PIN2~PIN9,其定义如下: bit 引 在连接器处倒相 脚 信号 信号源 是否 0 Pin2 D ATA0 PC 否 1 Pin3 DATA1 PC 否 2 Pin4 DATA2 PC 否 3 Pin5 DATA3 PC 否 4 Pin6 DATA4 PC 否 5 Pin7 DATA5 PC 否 6 Pin8 DATA6 PC 否 7 Pin9 DATA7 PC 否 图 2 如果我们把这 8 支脚当成一般的数字输出的脚位看待,上述 8 支脚就相当于是 8 个数字输出的位置一 态寄存器 状态端口或称状态寄存器保存的是 5 个输入(S3~S7)的逻辑状态。S0~S2 位不出现在并口连接 器中 入端口)基地址+1 般,我们就可以把它们当成是 8 个可以自由控制的输出点。当我们通过数据端口传送数据时,就是改 变这 8 支脚的电平状态;而接受方也按照相同的编码原则解释,就可以获得传送的数据。 状 。除了 S0 以外,状态寄存器是只读的,读出数据信息是状态端口引脚上的逻辑状态。S0 是支持 EPP 传输并口的超时标志信息,可以用软件 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 清零。在许多并口中,状态输入接有上拉电阻。状态 端口引脚是 Pin10~Pin13、Pin15,其定义如下: 状态寄存器(即状态输 bit 引脚 是否在连接器处倒相 信号名 信号源 0 T ime-Out 1 未使用 2 未使用 3 Pin 5 nError(nFault) 外设 否 1 4 Pin13 Select 外设 否 5 Pin12 P aperEnd 外设 否 6 Pin10 nAck 外设 否 7 Pin11 Busy 外设 是 图 3 上表中所谓的(基地址+1)指的是:如果我们 PT 地址是 378H,在加上 1 就是 379H;这个 地址 的 L 是专门用来传递打印机的状态的。和数据地址比较起来不一样的是,这里地址并非在连接器的脚 位上均有对应点。在这个状态的显示上只有 5 个脚位有对应,位 S0~S2 是没有的--最起码是无法 让计算机有对应的值可读取。 如果打印机接到并口上,那么打印机的状态将会通过这几支脚传送到 PC,程序只要去基地址 +1 的位置读取数值即可知道现在打印机所处的状态。由于这几支脚可以让打印机传送状态给 PC, 制寄存器 制端口或称控制寄存器保存了 C0~C3 的 4 位的控制信息。C4~C7 不出现在并口连接器中。一般 地址+2 那么我们可以把这几支脚位拿来当作数字输入的通道;我们可以让这几支脚位的状态发生电位的改 变,而利用程序去读取这些脚位的数值,即可实现数据的输入。 控 控 来说,这些位被用来输出,然而大多数 SPP 中,控制位为集电极开路/漏极开路模式,也就是说,它 们同样可以用作输入。要从控制位上读取外部逻辑信号,首先将向相应的输出写入“1”,然后读取控 制寄存器的值即可。但是,为了提高交换速度,大多数支持 EPP 和 ECP 接口中,控制位工作在不能 用作输入的推拉模式下。在一些多模式接口中,控制位采用的是改进型的推拉模式,可以用作输入。 控制端口引脚是 Pin1、Pin14、Pin16 和 Pin17,其定义如下: 控制寄存器(即控制输出端口)基 bit 是否在连接器处倒相引脚 信号名 信号源 0 Pin1 nStrobe PC 是 1 Pin14 nAutoLF PC 是 2 Pin16 nInit PC 否 3 Pin17 nS n electI PC 是 4 IRQ 5 未使用 6 未使用 7 未使用 图 4 上表中所谓的(基地址+2)指的是:如果我们的 LPT 地址是 378H,在加上 1 就是 37AH;这个 地址 寄存器和状态寄存器。根据图 1 可知用 到了 、Jflash 源代码分析 具体的配置,我们针对的是 s3c2410, Nand Flash 64M、无 Nor Flash,s3c2410, 的文件: 是专门用来控制打印机动作的。 如同数据的送出,我们的程序只要将我们的信息送往(基地址 +2)的地址去,就可以实现数据输出,接受端在相应引脚就可以接受到相应的逻辑电位状态。当控 制端口的信号源为高电平时,这些引脚可以作为输入引脚,如同状态端口引脚一样。 在上述定义表 格中,所谓“是否在连接器处倒相”是指并口硬件将连接器与相应寄存器位之间的 4 个信号进行了倒 相处理。具体说来,S7、C0、C1、C3 信号的逻辑状态在连接器处是与相应寄存器位反相的。当你对 这些位进行写操作时,必须牢记写入的值应该与你想在连接器处设置的值相反;当要对这些位进行读 操作时,也必须记住所读取的值与连接器处的值相反。 计算机的标准配备并行端口除以上介绍的数 据端口引脚 Pin2~Pin9、状态端口引脚 Pin15、Pin10~Pin13、控制端口引脚 Pin1、Pin14、pin16、Pin17 外,连接器上的 其它引脚 Pin18~Pin25 是归地引脚 GND。 在与 Jtag 相连接是控制寄存器是没有用到,只用到了数据 Pin2、Pin3、Pin8、Pin11 分别对应数据寄存器的 DATA0、DATA1、DATA6 和状态寄存器的位 7 即信号名 Busy。 二 源代码分析总是要针对 默认是从 Nand Flash 启动.下面的分析都是基于上面的配置,不同的配置可以做相应的修改,以满足不 同的硬件环境。 在 Jflash 中有如下 Def.h Jtag.c Jtag.h K9sxx08.c K9sxx08.h Pin2410.c Pin2410.h ppt 关于艾滋病ppt课件精益管理ppt下载地图下载ppt可编辑假如ppt教学课件下载triz基础知识ppt .c Ppt.h Sjf.c Sjf.h c 中,那 2410 的一般的使用方法是: otloader.bin /t=5 在 Sjf.c 中有这样的函数 void 取得目标文件的大小这里是 函数中调用了另一个函数 int GetValidPpt(void),该函数 unsigned long port ) if (ioperm (port, 3, 1)) { ioperm (0x80, 1, 1)) { urn 1; 函数目的取得在 Ppt.h 中定义的端口的控制权 hen 2 then 3 er if needed for multiple ports) po 数是取得或关闭对端口的控制权,port sm/unistd.h 中定义的,它是个系统调用。 护模式下,不能直接对端口进行存取,需先通过系统调用 ioperm 取得对端 口的控 erm (port, 3, 1)目的是取得对三个端口的控制权,是并口的数据寄存器端口,状态寄存器端口, 控制寄 调用了个(ioperm (0x80, 1, 1),它的目的是取得对 0x80 端口的控制权,因为在函数 int G 如果一致,说明该端口是可用 的,否 我用的是 Nand Flash K9f1208 和 K9s1208 参数基本是一样的,两者可以通用。主函数在 Sjf. 我们先从这里开始。 在 linux 下用 Jflash-s3c ./Jflash-s3c2410 bo OpenImageFile(char *filename); 它用来 bootloader.bin 文件的大小,放在全局变量 U32 imageSize;中、在函数 void ErrorBanner(void)中只是介 绍一些 Jflash 的使用说明,没有必要关注。 当执行到函数 void OpenPpt(void)时,在该 中 Ppt.c 文件中定义的,在 int GetValidPpt(void)函数中调用了 int io_access_on( unsigned long port )函数, 这个函数如下: int io_access_on( { perror ("ioperm()"); return 0; } if ( perror ("ioperm()"); return 0; } ret } 该 #define LPT1 0x378 // the search order is LPT1 t #define LPT2 0x278 // first valid address found is used (re-ord #define LPT3 0x3bc // hardware base address for parallel port ioperm(unsigned long rt , unsigned long num,bool on_off)这个函 是指的端口的基地址,num 是连续的端口数目,on_off 表明是获得控制权(on_off=1),还是释放控 制权(on_off=0)。 该函数是在 include/a #define __NR_ioperm 101 因为 linux 程序运行在保 制权。Linux 的 ioperm 系统调用允许本地读/写访问系统的 I/O 端口,ioperm 由于 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 问题可允许 非特权用户获得对系统 I/O 端口的读和写访问。当特权进程使用时,ioperm 系统调用也会不正确地限制权 限。 iop 存器端口。 在该函数中还 etValidPpt(void)中调用了_outp(),_inp(),它们其实是宏指令,在对端口进行存取后需要延迟 1~2 毫秒才能完成,而这些宏指令中会利用对端口 0x80 输出数据来达到延迟时间的目的,在对端口 0x80 输出数据时,并不影响系统,故先要取得对端口 0x80 得到控制权。 取得控制权后,向端口写入个数据 0x55,在从该端口读出该数据 则通过函数 void io_access_off( unsigned long port )释放对端口 0x80 和并口的控制权。 接下来调用函数 void SetPptCompMode(void) //configure the parallel port at the compatibility mode. ISnERRORINT | ECR_DISDMA | ECR_ 源文件中这个函数是设置并口的兼容模式,下面先看看并口的模式 下的并口模式: 靠 种模式 在主板中 BIOS 设置为 EPP 或 ECP 模式,故在软件 中就没 函数中执行 void JTAG_ReadId(void),在解释这个函数之前,先简要介绍一下 JTAG 技术。 主要包括 4 个部分(见图 5) { //_outp(validPpt+ECP_ECR,ECR_STANDARD | ECR_D DISSVCINT); } 在 由于双向并口是各制造商独自设计没有一个统一的规范。逐渐形成了如 1、原始并口 SPP 单向 8 位+双向 4 位 2、简单双向 PS/2 双向 8 位 3、增强并口 EPP 高速双向 4、扩展并口 ECP 高速双向可 5、多模式口 ECP+EPP 可工作于多 在该函数中的语句是被注释了的,因为一般 有必要在设置了,如果你没有在主板 BIOS 中设置,那就的去掉注释了,但现在主板默认是 EPP 或 ECP 模式的。 接下来回到主 JTAG 图 5 JTAG 结构示意 (1)测试访问端口 TAP(Test Access Port):JT :TDI(Test data in),TDO(Test data 。逻辑测试单元有自己的时钟(TCK)和复位 以让你将测试指令和数据送入设备,将测试结果读出。测试器通过 TCK 和 TMS 控 制 T 下,产生控制信号。其中一类是选链信号, 的长度一般等于指令长度,指令通过 TDI 逐位移入指令寄存器, AG 定义了 4 个基本端口 out),TMS(Test model select),TCK(Test clock );分别实现测试数据的输入与输出,测试模式的选择 以及提供测试时钟。此外,JTAG 还定义了一个可选端口 TRST,用于实现测试复位,在具体的电路中可能 没有用到 TRST,如图 1中,就没有设计 TRST(Test reset). 测试访问端口由五个专门引脚(四个输入和一个输出) 组成 (TRST # ) 引脚,因此它独立于其他设备。既使其他设备处于复位状态或无电状态,逻辑测试单元可以读或 写自己的寄存器。 逻辑测试单元可 AP 控制器的操作。指令和数据由 TDI 串行输送到 TDO。 (2)TAP 控制器:TAP 控制器的作用是在 TMS﹑TCK 和 TRST 的作用 即在测试数据寄存器组和指令寄存器之间进行选择的信号;另一类是扫描控制信号,控制着测试数据寄存 器与指令寄存器进入相应的状态。 (3)指令寄存器及译码逻辑:指令寄存器 在译码逻辑的作用下,产生译码信号。其产生的译码信号,主要有针对边界扫描单元的控制信号,以及在 多条测试数据寄存器中进行选择的选链信号。可以根据特殊的需要,定义新的译码信号。 (4)测试数据寄存器组:JTAG 可以有很多测试数据寄存器,它们都具有扫描功能,称为扫描链。边界扫描 AG 引脚的定义: JTAG 接口主要包括四个引脚:TMS、TCK、TDI 和 TDO 及一个可选配的引脚 TRST,用于驱动电路模块 和控制 存器提供测试参考。在TCK的同步作用下通过TDI和TDO 引脚串 TAP 控制器即将进入的工作 状态。 在指令寄存器中 的具体 器的串行数据输出端。TAP控制器的当前状态以及保持在指令寄存器中 的具体 通过器件移动过程中有效。该引脚在其它时间处于三态状态。 异步初始化信号。 TAG测试访问端口(TAP)控制器 此状态机有16个状态,如图7。测试访问状态机的目的是选择指令寄 链只不过是其中一条特殊的扫描链而已。用户可以定义新的扫描链及相应的指令。 JT 执行规定的操作。各引脚的功能如下: ·TCK:JTAG 测试时钟,为TAP控制器和寄 行移入或移出数据及指令。同时,TCK为TAP控制器状态机提供时钟. ·TMS :TAP 控制器的模式输入信号。TCK 的上升沿时刻 TMS 的状态确定 通常 TMS 引脚具有内部上拉电阻,以保证该引脚在没有驱动时处于逻辑 1状态。 ·TDI:JTAG 指令和数据寄存器的串行数据输入端。TAP 控制器的当前状态以及保存 指令决定对于一个特定的操作由 TDI 装入哪个寄存器。在 TCK 的上升沿时刻,TDI 引脚状态被采 样,结果送到 JTAG 寄存器组。 ·TDO: JTAG指令和数据寄存 指令决定对于一个特定的操作哪个寄存器的内容送到TDO输出。对于任何已知的操作,在TDI和 TDO之间只能有一个寄存器( 指令或数据)处于有效连接状态。TDO在TCK的下降沿改变状态,并且只 在 数据 ·TRST:测试复位输入信号,低电平有效,为TAP控制器提供 J TAP 控制器是一个有限状态机, 存器或数据寄存器,使其连接到TDI 和TDO 之间。状态机的初始状态是测试逻辑复位状 (test-logic-reset) 图6测试单元的结构 图 7 TMS 为输入,在时钟 TCK 的驱动下进行状态转换,TAP 控制器的 16 种状态转换图 指令/ 数据寄存器 逻辑测试单元有一个指令寄存器和三个数据寄存器,三个数据寄存器为:旁路寄存器(BYPASS) ,识 别码寄存器( IDCODE) ,边界扫描寄存器(BOUND) 。指令决定使用哪个寄存器。指令寄存器为 4 位,指令由 TDI 引脚串行输入。1 位旁路寄存器(BYPASS) 为 TDI - TDO 提供了一个最短的串行通路。在板级测试期 间,你可以通过这条通路绕开不需测试的设备。这可以提高测试速度。32 位识别寄存器( IDCODE) 提供了 设备的制造商、版本号等信息。边界扫描寄存器(BOUND) 保持引脚的状态或引脚需要的数据。边界扫描寄 存器为一个串行的移位寄存器,每个单元分配给芯片的相应引脚, 每一个独立的单元称为 BSC (Boundary -Scan Cell) ———边界扫描单元。 指令简介 指令用于控制 JTAG 口的操作,它包括基本指令和扩展指令。JTAG 接口标准要求芯片支持的基本指令为: EXTEST , INTEST , SAMPLE/ PRELOAD ,BYPASS , IDCODE , HIGHZ。芯片厂商可以根据实际需要选择或添 加扩展指令。S3c2410 使用的是 arm920t 支持的指令有 10 条: EXTEST 0000 SAN_N 0010 INTEST 1100 IDCODE 1110 BYPASS 1111 CLAMP 0101 HIGHZ 0111 CLAMPZ 1001 SAMPLE/PRELOAD 0011 RESTART 0100 在这些指令中,在时钟的上升沿对 TDI 和 TMS 进行采样,所有的输出 TDO 都是在时钟的下降沿进行的。在 程序中只用到了 EXTEST、IDCODE、SAMPLE/PRELOAD、BYPASS 指令,上面三星的 s3c2410 使用的是 arm920t 核心,指令使用的是 4 位编码,但不一定所有的都是 4 位编码,如 Intel StrongARM SA110 处理器 JTAG 指令长度是 5位,这个得查芯片手册,见后面的程序分析。 编程原理 通过 JTAG 口对 Flash 编程的实质就是首先将 EXTEST 指令串行移入目标系统板上的 JTAG 器件的指令寄存 器,然后控制JTAG器件的TCK和 TMS引脚使其进入Shift-DR 状态,再将数据串行移入到JTAG器件的边界 扫描寄存器,最后控制 JTAG 器件的 TCK 和 TMS 引脚使其进入 Update-DR 状态将 BSR 的内容写入 Flash。 指令装载完成后,只要不更改指令,就不需要再进行指令移位了,此时只需要进行数据移位,所以数据移位 是编程的主要操作。 下面接着分析在 Jtag.c 中由 void JTAG_ReadId(void)调用的函数 void JTAG_Reset(void),它的目的 是用 JTAG 单元从任何未知状态回到 Test-Logic-Reset 状态,当让 TMS 保持连续至少 5 个周期的高电平 时,JTAG 单元会从任何状态回到 Test-Logic-Reset 状态,在本程序中 void JTAG_Reset(void)函数使 TMS 保持了 6个周期的高电平,当然能使 JTAG 单元会从任何状态回到 Test-Logic-Reset 状态,后面延迟很关 键,不同台式机 cpu 的频率不一样,所以延迟的时间是不一样。 复位进入 Test-Logic-Reset 状态后,接下来程序中频繁的调用了宏 JTAG_SET()和 JTAG_DELAY(),对 于 JTAG_SET()就是向并口输出,JTAG_DELAY()就是个延迟,必须要有延迟,否则可能不会成功,因为并口 是低速设备,有比较长的时间延迟。 TDI_H 代表TDI位高电平、TDI_L代表TDI为低电平,其它的定义类似,有图7知道当处于Test-Logic-Reset 状态时 TMS 为 0,在时钟上升沿到来时,转移到 Run-Test/Idel,在由 Test-Logic-Reset 状态转移到其他 任何状态时,都要经过 Run-Test/Idel 状态,所以这里用了 4个周期使其由 Test-Logic-Reset 状态转移 到稳定的 Run-Test/Idel 状态,void JTAG_ReadId(void)就是先要把 IDCODE 移入 JTAG,然后读取 ID. 此时已经处于 Run-Test/Idel 状态,由图 7当 TMS=1 时在时钟上升沿转移到 Select-DR Scan Status, 为什么是时钟上升沿转移,因为在 JTAG 内部使用的 D边沿触发器,而且是上升沿触发的。当 TMS=1,下个 周期转移到 Select-IR Scan Status,TMS=0 时再转移到 Capture-IR Status,最后在 TMS=0 转移到 Shift-IR Status。然后移入 IDCODE=1110, 注意移入的顺序,因为是右移先移入的是低位。下一步就是使其转移到 到 Update_IR 状态,此时把 ID 写入到边界扫描寄存器,再将状态转移到 Shift-DR 状态,此时从 TDO 移位 输出 ID. 从并口读取 ID 时使用到了在 Jtag.h 中定义的宏 #define JTAG_GET_TDO() ( (InputPpt()&(1<<7)) ? LOW:HIGH ) 它将读到的信号取反,因为在 Jtag.h 中有这样的定义: // Pin Connections // TCK :DATA[0] (2) // TDI :DATA[1] (3) // TMS :DATA[2] (4) // TDO :STATUS[7] (11) TDO 和并口状态寄存器的位 7 相连,如图 3,在该位使用了反相器,故读到的数据应取反后才能和 TDO 的 输出相同。 ID 是 32 位,在循环中读取了 31 位,在循环体外读取一位并同时将状态转移到 Exit1_DR,因为在 JTAG 中 使用个数据缓冲器,本次读到的是上次的输出信息。最后再将状态返回到 Run-Test/Idel 并把得到二进制 字符数据转换成 ID。 返回后再调用 void S2410_InitCell(void)函数初始化边界扫描单元,在解释这个函数之前先介绍一 下边界扫描。 边界扫描测试是通过在芯片的每个 I/ O 脚附加一个边界扫描单元(BSC ,boundary scan cell) 以及 一些附加的测试控制逻辑实现的,BSC 主要是由寄存器组成的。每个 I/ O 管脚都有一个 BSC ,每个 BSC 有 两个数据通道:一个是测试数据通道,测试数据输入TDI ( test data input ) 、测试数据输出TDO(test data output) ;另一个是正常数据通道,正常数据输入 NDI ( normal data input ) 、正常数据输出 NDO(normal data output) 边界扫描链由若干具有相同结构的扫描单元组成,其基本结构与控制见图 8。边界扫描单元的控制信号 包括两类:一类是由 TAP 控制器产生的时序控制信号,另一类是由指令译码器产生的译码 图 8 扫描链及扫描单元结构与控制 扫描链的时序,大致可分为 3 个阶段。 (1)捕获阶段: 扫描单元从并行的数据输入,捕获数据到 S 触发器; (2)移位阶段:扫描单元将 S 触发器中的值,串行移位到下一级扫描单元的 S 触发器中,并将其前一级扫描 单元 S 触发器中的值移入; (3)更新阶段:所有扫描单元并行地将其 S 触发器中的值,打入到 U 触发器中。为实现这 3 个阶段,需要 TAP 控制器产生的 3 个控制信号。此外,还需要一个指令译码信号,控制是否将 U 触发器中的值传入核心 逻辑。 图 9 带有 JTAG 接口的芯片内部结构图 现在分析函数 void S2410_InitCell(void)其目的是初始化边界扫描寄存器,它的数目叫边界扫描单元的 长度。S3c2410 边界扫描单元的长度为 426,不同的型号有不同的长度,这个是在 bsdl 文件中有定义。 可以把边界扫描单元,即边界扫描链看着一个数组,在 Pin2410.c 有这样的定义 char outCellValue[S2410_MAX_CELL_INDEX+2]; char inCellValue[S2410_MAX_CELL_INDEX+2]; 比如处理器的每一个引脚都有一个边界扫描单元,每一个引脚都是边界扫描链中的索引,s3c2410 的引脚 272,而扫描链的初始化即对处理器的引脚的赋值,且扫描链的长度 426,当然还有对外围电路的测试单元, 而且即使在程序中没有使用到的边界扫描单元也必须初始化。 在函数中初始化了边界扫描单元。在 Pin2410.h 中有这样的定义 #define S2410_MAX_CELL_INDEX 426 //0~426 #define DATA_CON (99) #define DATA0_IN (100) #define DATA0_OUT (98) #define DATA1_IN (97) #define nFCE (172) #define nFWE (170) #define nFRE (171) #define nOE (147) #define NCON0 (229) #define nWAIT (167) 后面括号中的数字是边界扫描中的索引,也是对应处理器的引脚,这个是在 bsdl 文件中定义的,同一中 型号的处理器是一样。具体怎样的对应关系,可以参看 bsd 文件的描述,下面简要介绍一下这个 bsd 文件 BSDL(boundary scan description language)语言硬件描述语言(VHDL )的一个子集,是对边界 扫描器件的边界扫描特性的描述,主要用来沟通边界扫描器件厂商、用户与测试工具之间的联系,其应用 包括:厂商将 BSDL 描述作为边界扫描器件的一部分提供给用户;BSDL 描述为自动测试图形生成(A T P G ) 工具测试特定的电路板提供相关信息;在 BSDL 的支持下生成由 IEEE1149.1 标准定义的测试逻辑。现在, B S D L 语言已经正式成为 IEEE1149.1 标准文件的附件。BSDL 本身不是一种通用的硬件描述语言,但它 可与软件工具结合起来用于测试生成、结果分析和故障诊断。每一边界扫描器件都附有特定的 BSDL 描述 文件,下面举例说明。 这是 SA1100 的 bsd 文件,对边界扫描单元长度的定义: attribute BOUNDARY_LENGTH of SA1100 : entity is 279 attribute INSTRUCTION_LENGTH of SA1100:entity is 5;指令长度(INSTRUCTION_LENGTH)属性定义 了所有操作码的长度必须为6位。 attribute INSTRUCTION_OPCODE of SA1100 : entity is "EXTEST (00000)," & "SAMPLE (00001)," & "CLAMP (00100)," & "HIGHZ (00101)," & "IDCODE (00110)," & "BYPASS (11111)" ; attribute INSTRUCTION_CAPTURE of SA1100 : entity is "00001" ; 上面是对 JTAG 指令的描述 attribute BOUNDARY_LENGTH of SA1100 : entity is 279 ; -- (ref B.8.14) attribute BOUNDARY_REGISTER of SA1100 : entity is ------------------------------------------------------------------------------ -- scan cell cntr disable disable -- cell type port function safe cell value state ------------------------------------------------------------------------------ "278 (BC_4, BATTF, INPUT, x), " & "277 (BC_4, VDDFA, INPUT, x), " & "276 (BC_4, *, internal,x), " & "275 (BC_2, *, control, 0), " & "274 (BC_1, SFRMC, OUTPUT3, x, 275, 0, Z ), " & "67 (BC_1, WE, OUTPUT3, x, 68, 1, Z ), " & "66 (BC_1, OE, OUTPUT3, x, 68, 1, Z ), " & "65 (BC_1, RAS(3), OUTPUT3, x, 68, 1, Z ), " & "64 (BC_1, RAS(2), OUTPUT3, x, 68, 1, Z ), " & 对边界扫描寄存器单元(BSC)属性的描述由单元号与4 个或7 个圆括号内的数据子段组成,这些 BSC 的排列顺序可以是任意的,但每个单元都必须被定义。单元号从0 到278(BOUNDARY_LENGTH-1)进 行编号,0 单元是最靠近T D O 的单元。 如果有兴趣可以看看这个bsd文件,这个在程序中要用到宏定义要和bsd文件中定义相一致 #define S2410_MAX_CELL_INDEX 426 //0~426 #define DATA_CON (99) #define DATA0_IN (100) #define DATA0_OUT (98) 上面的定义要跟bsd文件中定义的一样,否则程序就不能正常运行。 char outCellValue[S2410_MAX_CELL_INDEX+2];存放的扫描单元输出的值,JTAG_RunTestldleState()调 用使其转移到Run-Test/Idel状态,函数void JTAG_ShiftIRState(char *wrIR)的作用是把wrIR指向的指 令移入指令寄存器shift-IR,移入后仍然使其处于Run-Test/Idle状态,对于Sample_Preload指令:对“连 线”进行采样,进而进行输出观测;在此处即对426个边界扫描寄存器进行采样,注意输出TDO是使用并口 的状态寄存器,其硬件连接有个反向器,然后输出的数据保存到char inCellValue[]数组中,然后用它初 始化数组outCellValue. 在主函数中最后调的函数void K9Sxx08_Menu(void),在此函数void K9Sxx08_JtagInit(void)中首先 将指令EXTEST(0000),此指令选择了测试模式中一条扫描链(扫描链有多条1,2,3,6……),默认选择是 扫描链3,该程序使用的默认扫描链,如果要修改请参看DDI0151C_920T_TRM文件,EXTEST指令用一条已选 的扫描链将TDI和TDO连接起来, 这样就可以对某个引脚进行赋值了。后面调用函数void S2410_SetPin(int index, char value),其目的 给处理器与Nand Flash相连的控制引脚进行赋值。在Nand Flash手册中有这样的定义如下 图10 K9f1208引脚定义 void K9Sxx08_JtagInit(void) { JTAG_RunTestldleState(); JTAG_ShiftIRState(EXTEST); S2410_SetPin(DATA_CON,HIGH); //D[7:0]=input S2410_SetPin(nOE,HIGH); S2410_SetPin(nFRE,HIGH); S2410_SetPin(nFWE,HIGH); S2410_SetPin(nFCE,HIGH); S2410_SetPin(CLE,LOW); S2410_SetPin(ALE,LOW); } 初始化为地址锁存允许,命令锁存允许,读写都是不允许的,写保护是硬件连接到VDD的,始终都不允许 写保护的。 在调用函数进行初始化Nand Flash static void NF_Init(void) { NF_Reset(); //NF_nFCE_L(); NF_CMD(READ_1_1); //NF_nFCE_H(); } 下面是k9f1208 flash操作命令 图11 当然不同Flash有不同的命令,这个要具体阅读flash的芯片手册 在调用static void NF_Reset(void)目的是使Nand Flash复位,需要注意的是在向flash读写时都有 时间延迟,应做好相应的延迟,具体延迟的大小应查找相应的手册。 在static void NF_Init(void)中调用了static void NF_CMD(U8 cmd)函数,该函数是通过Nand Flash 此地I/O0~I/O7写入,先写入控制命令,此次写入D[7:0]允许,芯片允许,写使能,地址锁存使能,这些 参数都是在使用手册上的model selection中定义的,然后写入命令,此后禁止写信号以免再次写入数据 将以前的命令覆盖。最后禁止芯片,禁止数据端口。 NF_nFCE_L()是使ce引脚输入0即使能芯片,NF_nFCE_H()则相反。 static U16 NF_CheckId(void) { U16 id; NF_nFCE_L(); NF_CMD(0x90); NF_ADDR(0x0); Delay(1); //wait tWB(100ns) id=NF_RDDATA()<<8; // Maker code 0xEC id|=NF_RDDATA(); // Devide code 0x76 NF_nFCE_H(); printf("The Nand flash id is %ld\n",id); return id; } 查看flash手册如下: 图12 ID 读取时序 当先将Read ID 命令写入到I/O口,再将地址00写入到IO后,下两个时钟周期分别自动将ID送到IO输出, 每次8位。static U8 NF_RDDATA(void)函数在两个时钟周期中分别读取0XECH,和0x76h,在此函数中调用 了static void NF_ADDR(U8 addr)函数,目的是将addr写入到IO。对应的控制状态有2410_SetPin函数实 现如下: S2410_SetPin(DATA_CON ,LOW); //D[7:0]=output S2410_SetPin(nFCE,LOW); S2410_SetPin(nFRE,HIGH); S2410_SetPin(nFWE,LOW); S2410_SetPin(ALE,HIGH); S2410_SetPin(CLE,LOW); 应于下图中的第5行相一致。 图13 模式选择K9f1208 这时到了程序最关键的地方了,通过调用函数void K9Sxx08_Program(void)对Nand Flash进行读写和擦除。 在讲对flash进行擦除之前,先了解一下Nand Flash NAND Flash 的数据是以bit 的方式保存在memory cell,一般来说,一个cell 中只能存储一个bit。这些 cell 以8 个或者16 个为单位,连成bit line,形成所谓的byte(x8)/word(x16),这就是NAND Device 的 位宽。这些Line 会再组成Page,(Nand Flash 有多种结构,我使用的Nand Flash 是K9F1208,下面内容针 对三星的K9F1208U0M),每页528Byte,每32 个page 形成一个Block, Sizeof(block)=16kByte 。1 block=16kbyte,512Mbit=64Mbyte,Numberof(block)=1024 1block=32page, 1page=528byte=512byte(Main Area)+16byte(Spare Area) Nand flash 以页为单位读写数据,而以块为单位擦除数据。按照这样的组织方式可以形成所谓的三类地 址: --Block Address -- Page Address --Column Address 对于NAND Flash 来讲,地址和命令只能在I/O[7:0]上传递,数据宽度是8 位。 512byte需要9bit来表示,对于528byte系列的NAND,这512byte被分成1st half和2nd half,各自的访问由 地址指针命令来选择,A[7:0]就是所谓的column address。32 个page 需要5bit 来表示,占用A[13:9], 即该page 在块内的相对地址。Block的地址是由A14 以上的bit 来表示,例如512Mb 的NAND,共4096block, 因此,需要12 个bit 来表示,即A[25:14],如果是1Gbit 的528byte/page的NAND Flash,则block address 用A[26:24]表示。而page address就是blcok address|page address in block NAND Flash 的地址表示 为: Block Address|Page Address in block|halfpage pointer|Column Address 地址传送顺序是Column Address,Page Address,Block Address。 由于地址只能在I/O[7:0]上传递,因此,必须采用移位的方式 进行。 例如,对于512Mbit x8 的NAND flash,地址范围是0~0x3FF_FFFF,只要是这个范围内的数值表示 的地址都是有效的。以NAND_ADDR 为例: 第1 步是传递column address,就是NAND_ADDR[7:0],不需移 位即可传递到I/O[7:0]上,而halfpage pointer 即bit8 是由操作指令决定的,即指令决定在哪个halfpage 上进行读写。而真正的bit8 的值是don't care 的。 第2 步就是将NAND_ADDR 右移9 位,将NAND_ADDR[16:9] 传到I/O[7:0]上 第3 步将NAND_ADDR[24:17]放到I/O 上 第4 步需要将NAND_ADDR[25]放到I/O 上 因此, 整个地址传递过程需要4 步才能完成,即4-step addressing。 如果NAND Flash 的容量是256Mbit 以下, 那么,block adress 最高位只到bit24,因此寻址 只需要3 步。 下面,就x16 的NAND flash 器件稍微进行一下说明。 由于一个page 的main area 的容量为256word,仍 相当于512byte。但是,这个时候没有所谓 的1st halfpage 和2nd halfpage 之分了,所以,bit8就变得 没有意义了,也就是这个时候 bit8 完全不用管,地址传递仍然和x8 器件相同。除了,这一点之外,x16 的NAND使用方法和 x8 的使用方法完全相同。 一页为 528 字节,512 字节存放代码和数据,其余的 16 字节用于 ECC 校验,文件系统信息,块损坏 的记录。 下面分析这个最关键的函数,读写的原理都一样,故不再分析写页的函数。 static int NF_WritePage(U32 block,U32 page,U8 *buffer,U8 *spareBuf) { int i; U32 blockPage=(block<<5)+page; U8 *bufPt=buffer; NF_nFCE_L(); NF_CMD(0x0); NF_CMD(0x80); // Write 1st command NF_ADDR(0); // Column 0 NF_ADDR(blockPage&0xff); // NF_ADDR((blockPage>>8)&0xff); // Block & page num. NF_ADDR((blockPage>>16)&0x01); // for(i=0;i<512;i++) { NF_WRDATA(*bufPt++); // Write one page to NFM from buffer } if(spareBuf!=NULL) { for(i=0;i<16;i++) { NF_WRDATA(spareBuf[i]); // Write spare array(ECC and Mark) } } NF_CMD(0x10); // Write 2nd command Delay(1); //tWB = 100ns. NF_WAITRB(); //wait tPROG 200~500us; NF_CMD(0x70); // Read status command Delay(1); //twhr=60ns if (NF_RDDATA()&0x1) // Page write error { NF_nFCE_H(); printf("[PROGRAM_ERROR:block#=%d]\n",block); NF_MarkBadBlock(block); return 0; } else { NF_nFCE_H(); #if (WRITEVERIFY==1) //return NF_VerifyPage(block,page,pPage); #else return 1; #endif } } 上面已经介绍了 Nand Flash 是页进行读写的,以块进行擦写的。下面是写时序图 图 14 K9f1208 写时序图 先写入对 flash 写命令 0x80,再分别一次写入行地址此处一般都是从 A0~A7 开始,写入 A9~A16,A8 是 有指令决定的。不用关心再写入 A17~A24,最后 A25,对于 k9f1208 A26~A31 写入的必须是 0 NF_CMD(0x0); NF_CMD(0x80); // Write 1st command NF_ADDR(0); // Column 0 NF_ADDR(blockPage&0xff); // NF_ADDR((blockPage>>8)&0xff); // Block & page num. NF_ADDR((blockPage>>16)&0x01); // 最后一句和 NF_ADDR((blockPage>>16)&0xff)效果是一样的。接着写入数据,此时的数据是保存在缓 冲寄存器中,等输入命令 10h 后,将缓冲寄存器中的值写入 flash。 本函数后写入读取状态命令 70h,此后一个周期从 IO 口位 0 输出状态,若为 0 表示写成功,否则失 败 下面分析最后一个函数块擦除
本文档为【基于s3c2410的jflash源代码说明】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_229287
暂无简介~
格式:pdf
大小:372KB
软件:PDF阅读器
页数:20
分类:生产制造
上传时间:2011-11-02
浏览量:29