《uCOOS-II原理与ARM应用程序设计》课件第7章_第1页
《uCOOS-II原理与ARM应用程序设计》课件第7章_第2页
《uCOOS-II原理与ARM应用程序设计》课件第7章_第3页
《uCOOS-II原理与ARM应用程序设计》课件第7章_第4页
《uCOOS-II原理与ARM应用程序设计》课件第7章_第5页
已阅读5页,还剩118页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第七章动态内存配置与Bootloader

7.1动态存储OS_MEM.C7.2Bootloader设计7.3本章小结在程序编译链接时分配的存储空间称为静态空间,在程序执行过程中分配的程序空间称为动态空间。例如,使用malloc函数开辟的存储空间就是动态空间。程序中定义的各种变量和数组均是静态空间,与动态空间相比,静态空间地址是固定的。动态空间在程序执行过程中地址是不固定的,因此,多次调用malloc函数后,会造成大量的内存碎片,并且开辟空间所用的时间也不确定。本节将介绍µC/OS-Ⅱ中如何在任务执行过程中请求动态空间,以及如何释放这些动态空间。本节的另一个内容是介绍Bootloader方法,即在《ARM原理与C程序设计》第七章的基础上,进一步介绍基于µC/OS-Ⅱ嵌入式系统的工程目标文件自举启动的方法。有C/C++语言程序设计经验的程序员大都知道,动态分配内存可以有效地节省存储空间。每个函数运算产生的中间结果使用动态内存保存,计算出最终结果后,当从函数返回时把动态内存释放掉,这样一个动态内存空间可用于多个函数共同使用,而互不干扰。动态内存来自堆。当函数内部产生大量中间变量时,使用动态存储方式比使用局部变量更好一些,因为局部变量大多来自栈,变量空间不能太多。7.1动态存储OS_MEM.C动态存储相关的函数有6个,即OSMemCreate、OSMemGet、OSMemPut、OSMemQuery、OSMemNameGet和OSMemNameSet,列于第一章表1-12中。在µC/OS-Ⅱ中使用动态内存的方法为:使用动态内存前需要调用OSMemCreate函数创建它,动态内存以内存分区的形式存在,可以创建多个动态内存分区,每个分区由大小相同的内存块组成,内存块的大小以字节为单位;在使用动态内存时,调用OSMemGet从内存分区中取得一块内存块,通过多次调用OSMemGet获得多个内存块使用,获得的内存块本质上是这个内存块的首地址,可以对它赋各种类型数据;内存块使用完后,必须调用OSMemPut将内存块释放掉,即还回到内存分区中,这个函数必须与OSMemGet配对使用,保证内存分区中内存块的“供需平衡”。可以调用OSMemNameSet为内存分区命名,调用OSMemNameGet获得内存分区的名称,这个名称主要用于调试中。调用OSMemQuery可以查询内存分区的信息。

第7.1.1节的工程ex7_1使用了内存分区相关的函数,以解释这些函数的用法。但是,正如上文所言,内存分区主要用于函数运行过程中会占用大量存储空间的程序中,相比之下,工程ex7_1完全不具备这个特性,只能用来说明这些内存分区函数如何使用。7.1.1内存分区实例

在第六章工程ex6_1的基础上,新建工程ex7_1,保存目录为D:\ZYUCOSII\ex7_1,此时的工程ex7_1与工程ex6_1完全相同,只是工程文件名更名为ex7_1。需要修改的文件有app.h和appfun.c,其中,在文件app.h的末尾添加以下两行语句:

MY_APPOS_MEM*myMem;//Memorypartition

MY_APPINT32UmyBuf[10][30];

即定义内存分区myMem和二维数组myBuf,内存分区建立在全局数组myBuf的基础上。文件appfun.c需要修改AppTaskStart函数和AppTask_2函数,AppTask_2函数在第7.1.2节介绍,在AppTaskStart函数中添加以下语句:

1myMem=OSMemCreate(&myBuf[0][0],10,30*sizeof(INT32U),&err);

2if(err==OS_ERR_NONE)

3{

4OSMemNameSet(myMem,"MyMemPart",&err);

5Str_Uart0("Partition\"myMem\"CreateOK!\n\n");

6}这些语句可添加到创建信号量LedSem的语句“LedSem=OSSemCreate(0);”前面。第1行为调用OSMemCreate创建内存分区myMem,包含4个参数:第1个参数为内存分区首地址;第2个参数为内存分区中包含的内存块数量;第3个参数为每个内存块的大小,以字节为单位;第4个参数为函数调用情况的返回信息,如果为OS_ERR_NONE则表示创建内存分区成功。第4行将内存分区命名为“MyMemPart”。

工程ex7_1如图7-1所示,调试窗口如图7-2所示。从图7-2中C-SPY窗口可以看到内存分区的信息。串口调试助手显示的信息如图7-3所示。图7-1工程ex7_1界面图7-2工程ex7_1调试窗口图7-3串口调试助手显示信息窗口7.1.2工程ex7_1注解

文件appfun.c中函数AppTask_2的内容如下:

1voidAppTask_2(void*pdata)

2{

3INT8Uerr;

4INT8Ui;

5

6INT32UtickCur; //Timetick'scurrentval

7INT8U*pmsg; //ablock

69}

70

71OSTimeDlyHMSM(0,0,2,0);

72}

73}

第10行OS_MEM_DATA类型定义位于ucos_ii.h的第493~500行,其中成员OSNFree、OSNUsed和OSNBlks分别用于表示内存分区中空闲的内存块、使用了的内存块和全部内存块数量,都是INT32U型变量成员,用于第57行取得内存块的信息。任务2执行后,第19行取得当前时钟节拍值,如果小于30秒,则调用OSMemGet从内存分区中取得第一块内存块(第22行)。第23行判断是否取得了内存块,如果取得了,则第25行向取得的内存块(实际上是内存分区的第一个内存块)写入字符串,然后第26行输出这个字符串到串口调试助手。第28行调用OSMemPut释放这个内存块。第29~35行重复这个过程,只是向内存块中写入的字符串不同了;同理,第36~42行和第43~49行又重复了这个过程两次。串口调试助手的输出结果参看图7-3。当运行时间大于30秒小于60秒时,第51行为真,则52~69行的代码得到执行,第53~56行从内存分区中取得5个内存块。然后,第57行调用OSMemQuery函数查询内存块的信息,第58行调用OSMemNameGet函数获得内存分区的名称,第59行向串口调试助手输出内存分区的名称。之后,第60~64行输出内存分区的信息,第65~68行调用OSMemPut释放已使用完的5个内存块。任务2延时2秒重复执行(第71行)。

由分析可见,程序员必须清楚内存分区中有多少个内存块及每个内存块的大小,µC/OS-Ⅱ不检测内存分区中内存块的越界。如果使用不当,会造成整个工程程序的瘫痪。读者可参考Labrosse的《嵌入式实时操作系统µC/OS-Ⅱ(第2版)》第12章“内存管理”,了解内存控制块及其管理。一般地,将程序下载到ARM芯片内部的FLASH存储区或下载到ARM外扩的FLASH芯片内,ARM板上电复位后自动从FLASH中读取程序目标代码,完成程序启动的过程通称为Bootloader,或称自举启动,以区别于带有仿真器的程序仿真运行。Bootloader是ARM嵌入式项目开发过程中必须实现的一步,从严格意义上来讲,Bootloader相关的内容与µC/OS-Ⅱ没有关系,但作者还是把这部分内容添加到本书中,以使本书成为一个完整的基于µC/OS-Ⅱ的嵌入式项目开发整体解决方案。7.2Bootloader设计这里需要区分三个概念,即模拟运行、仿真运行及自举运行。模拟运行主要是针对算法的处理,使用一些仿真软件和环境,对算法的实现进行模拟,以了解算法的运算量和优缺点,有时模拟运行也可模拟一些芯片的外设与时序。仿真运行本质上就是程序的执行,仿真运行时,程序通过仿真器下载到目标芯片中,程序是在芯片上运行,因此,仿真运行的程序一定可以完全脱离仿真器运行。例如,工程ex6_1仿真调试时,退出调试环境,串口调试助手仍然接收到UP-Star实验板串口0发送的信息,说明程序还在芯片内部执行。模拟运行的程序一般做不到百分之百地仿真运行。相对于仿真运行来说,自举运行就是程序脱离仿真器而工作的过程,本书第二章至第7.1节的程序均是仿真运行的。

Bootloader过程可以分为三步,即首先编写对NAND型FLASH的读写操作工程,实现对FLASH的编程,这部分内容将在第7.2.1节介绍;然后,生成Boot表,即要写入到FLASH中的目标代码数据,这部分内容在第7.2.2节介绍;最后一步是关闭UP-Star实验板电源,取下仿真器,重新上电,观察程序运行情况。7.2.1读写FLASH工程

UP-Star实板板上集成了型号为K9F1208C的FLASH芯片,该芯片的读写方法请参考《ARM原理与C程序设计》第7.2节,以下摘录其中第7.2.1节关于K9F1208C的内容。

K9F1208U0C的存储阵列如图7-4所示。图7-4K9F1208U0C存储阵列由图7-4知,一片K9F1208U0C芯片包含4096个存储块,每个存储块分为32个存储页,每个存储页为528字节,其中,512字节用于存储数据,16字节用于存储校验信息。这样,一片K9F1208U0C的存储空间大小为4096×32×(512+16)B=(64+2)MB=66MB,其中,1MB=1024KB,1KB=1024B。用户可用存储空间为64MB,对其完全寻址,至少需要26根地址线。IO0~IO7作为地址输入时,至少占用4个周期,每个周期的地址输入如图7-4所示:第一个周期输入的A0~A7作为列地址;第2至4周期输入的A9~A25作为行地址,即页地址,因此,一片K9F1208U0C有217=128K个存储页面。每个512B的页面由A8分为上、下两部分(Read1命令),每部分为256个字节,可以被8位列地址寻址,即A0~A7寻址。每个存储页最后的16字节(512~527)使用A0~A3寻址,A4~A7忽略,对应于不同的访问命令(Read2命令)。现在,有充分理由相信,NAND型FLASH这种“分而治之”的存储寻址方式比NOR型FLASH的“一统天下”在芯片制造上更容易实现。

K9F1208U0C共有4个存储柱面(Plane),它的4096个存储块分布在不同的存储柱面上,不同的存储柱面可以同时读写。块序号被4整除的存储块,例如块0、4、8、…、4092位于面0上;而块序号除以4余1的存储块,例如,块1、5、9、…、4093位于面1上;块2、6、10、…、4094位于面2上;块3、7、11、…、4095位于面3上,如图7-5所示。每个柱面上有528字节的数据寄存器,位于存储单元阵列和外部I/O口之间,用于缓冲读写的数据。查阅S3C2410A手册可知,NAND型FLASH操作寄存器位于0x4E000000至0x4E000014。由第一章图1-22和图1-26可知,K9F1208U0C的I/O0~I/O7接S3C2410A的DATA0~DATA7,其控制管脚接S3C2410A的NANDFLASH控制器相应管脚。

通过S3C2410A访问K9F1208的一般步骤为:

(1)初始化S3C2410ANAND型FLASH控制器。

(2)读K9F1208的芯片ID号。

(3)整片擦除K9F1208,然后对K9F1208的存储块进行有效性检验,把无效存储块标记。

(4)编程K9F1208芯片,并读取写入的数据进行ECC校验。图7-5存储器配置表

K9F1208仅支持基于块的擦除和基于页的编程,针对FLASH来说,编程是指向其中写入数据。由于S3C2410A具有硬件ECC校验发生器,因此用户不需要编写ECC校验码产生函数。

上述内容是编程K9F1208的基础知识,下面介绍读写K9F1208C的工程ex7_2。

在第二章工程ex2_1的基础上,新建工程ex7_2,此时的工程ex7_2与工程ex2_1完全相同,只是工程文件名改为ex7_2。需要修改的文件有zyMain.c和zyDef2410.h,并且添加一个新文件flashRW.c(这个文件来自《ARM原理与C程序设计》),完成后的工程ex7_2如图7-6所示。图7-6为工程ex7_2的调试图,其中flashDat为要写入FLASH中的数据,flashCp为从FLASH读出的数据,长度均为1000,可以看出写入与读出的数据完全相同,说明读写K9F1208C成功。图7-6工程ex7_2工程ex7_2是芯片级的程序。在文件zyDef2410.h的开头添加如下语句:

1#ifdefMY_APP_GLOBALS

2#defineMY_APP

3#else

4#defineMY_APPextern

5#endif

在文件zyDef2410.h的末尾添加如下语句:

1MY_APPunsignedintflashID;

2MY_APPunsignedcharflashWhat[1200];

3MY_APPunsignedcharflashDat[1000];

4MY_APPunsignedcharflashCp[1000];zyMain.c文件的内容如下:

1/*FileName:zyMain.c

2**Byzhnyong@21

3**@2009-4-4

4**MainSubroutine

5**CopyrightReserved

6*/

7

8#include"zyDef2410.h"

9

10unsignedintFCLK,HCLK,PCLK;第18行读取K9F1208C的ID号,调试时可用Watch窗口观察变量flashID的值为0xEC765A3F。第19~20行初始化要写入的数据,由于每个数组元素为无符号整型,所以只能存储0~255间的数值。第20行取模247,表示初始化数值从0至246。第21~24行擦除了K9F1208的10个块的空间,约160KB的空间大小。第25行将flashDat的值写入FLASH中,写入首地址为0x0。第26行从FLASH中读出1200个值,读出首地址为0x0。第28~32行将读出的值中的有效数据值写入flashCp数组中,于是flashCp数组的内容应该与flashDat的内容完全相同,这一点可从图7-6中看出。文件flashRW.c的内容如下:

1/*FileName:flashRW.h

2**Byzhnyong@21

3**@2009-4-4

4**CopyrightReserved

5*/

6

7#defineMY_APP_GLOBALS

8#include"zyDef2410.h"

9

10//InitNANDControllerReg

11voidinitFlash()文件flashRW.c的内容全部来自《ARM原理与C程序设计》一书,包含了对FLASH的读写操作函数,具体实现细节不再赘述。需要注意的是,仿真工程ex7_2要用配置稍好一些的计算机,如果要用Watch窗口查看读出的大容量数组,建议不要用装有英特尔赛扬处理器的计算机进行仿真。第7.2.3节的工程中将继续使用文件flashRW.c。7.2.2用于自举的工程ex7_3

这里修改一下第六章工程ex6_1startup.s的文件,使之成为能自举的工程。

在工程ex6_1的基础上新建工程ex7_3,保存目录为D:\ZYUCOSII\ex7_3,这时的工程ex7_3与工程ex6_1完全相同,只是工程文件名更改为ex7_3。需要修改的文件只有startup.s,同时要更改ex7_3的配置。下面首先介绍ex7_3配置的更改。在工程ex7_3窗口中点击菜单“Project|Options…”,进入如图7-7所示的窗口。图7-7在OutputConverter中填写输出文件ex7_3.hex

再进入到Linker选项页,在图7-8中点击“Edit…”按钮,在弹出的窗口中设置各页如图7-9所示。图7-8Linker选项页图7-9工程链接配置从图7-9中的“MemoryRegions”可以看出ROM空间为0x1000~0x3FFFF(约256KB),RAM空间为0x40000~0x7FFFF(256KB),这两段空间在UP-Star实验板上没有RAM和SDRAM,所以,在startup.s中需要将位于0x30000000地址处的SDRAM重定位于0x0开始的空间。

如图7-10所示,点击左上角的下拉框可以将工程ex7_3设置为Release编译模式,这时要重新设置工程选项卡(即“Project|Options”菜单弹出的配置窗口)。本章讲述Bootloader使用的是Debug模式下编译链接成的目标文件ex7_3.hex,作为练习,读者可试着把Release模式下编译链接成的目标文件下载到UP-Star实验板上。图7-10编译模式选择

下面列出了修改后的文件startup.s的代码,并在其后作了注解。

1;Filename:startup.s

2;Byzhnyang@21

3;@2009-4-4

4;ForS3C2410A(RunafterReset)

5;CopyrightReserved

6

7;Note:@LittleEndian

8

注意第84行,这里是ROOT,而不是NOROOT,ROOT指示符将该段程序的地址定位于0x0;第89行添加了_iar_program_start标号,这个标志符是EWARM用于指示程序开始的缺省标示符;第90行使用B跳转;第101行注释掉;第157~164行用于点亮第3个LED灯,如果该灯被点亮,说明程序已经完成了芯片初始化。

第166~239行用于将K9F1208中地址0x0~0x100000(1MB)空间内的数据拷贝到内存0x30000000~0x30100000处,即完成代码从FLASH到SDRAM的搬移工作。这些代码比较简单,供感兴趣的读者自己阅读。第241~245行将位于0x30000000~0x32000000处的SDRAM映射到0x0处,即完成了内存的重映射。

第248~272行用于设置各种工作模式的堆栈指针。

第273~278行是点亮第2个LED灯(关闭第3个LED灯),该灯用于指示程序完成重定位和堆栈配置工作。

第280~281行用于跳转到主程序运行。

第283~290行是一个汇编子函数,用于判断NANDFLASH数据有没有准备好。需要补充一点:NANDFLASH的读不如NORFLASH稳定。虽然NANDFLASH读数据时地址具有自动增加功能,但实际使用中不太稳定。一般的做法是每几页(甚至一页)复位一下NAND型FLASH。所以,在文件startup.s中读K9F1208时,每读完一页都复位了该芯片。

完成上述工作后,重新编译链接工程ex7_3,在目录D:\ZYUCOSII\ex7_3\Debug\Exe下得到目标文件ex7_3.hex,可用UltraEdit软件打开阅读。打开ex7_3.map文件,如图7-11所示,intvec段起始地址必须位于0x0处。

接下来的工作是如何将工程ex7_3的目标代码(ex7_3.hex)下载到FLASH芯片K9F1208中。这里介绍两种下载的方法:其一为自己编写下载程序,参见第7.2.3~7.2.4节,这种方法比较繁琐,但有助于提高程序设计水平;其二为借助于H-JTAG等软件,参见第7.2.5节。图7-11工程ex7_3的Map表7.2.3目标代码转化为C头文件flash.h

文件ex7_3.hex的内容如下(由于代码太长,这里仅列出了文件头和尾,中间代码没有列出):

1:10000000210000EA0000A0E10000A0E10000A0E162

2:100010000000A0E10000A0E10000A0E10000A0E1DC

3:1000200000000000000000000000000000000000D0

4:1000300000000000000000000000000000000000C0

5:1000400010111111FC7F0000FC7F00000007000070

6:1000500000070000502E0000502E00000580010017

7:100060000580010000008C00B0000000300000009E8:1000700030000000FFFFFF000300000011800500BA

9:100080002380070004000000F0FF07005304A0E3F2

10:10009000A4119FE5A4219FE5082080E5042080E5C8

11:1000A000001080E54C04A0E33C804FE27E0098E81D

12:1000B000001080E5142080E5043080E5084080E5EC

13:1000C000105080E50C6080E590E04FE2FF1F9EE855

14:1000D00048E4A0E3FF1F8EE864019FE5541CA0E301

15:1000E000001080E55C019FE5CF10A0E3001080E5E3

16:1000F00054019FE50010E0E3001080E54C019FE50E

17:100100004C119FE5001080E55604A0E30010E0E3E9

18:10011000001080E54E04A0E338119FE5001080E553

19:100120003F0000EB0050A0E30000A0E3C015A0E3F720:1001300024819FE5FF90A0E3009088E5380000EB64

21:1001400014819FE50090A0E3009088E50C819FE575

22:10015000FF6005E2006088E500819FE5A564A0E1FD

23:10016000FF6006E2006088E5F0809FE5A568A0E1F9

24:10017000FF6006E2006088E5E0809FE5A56CA0E1F5

25:10018000016006E2006088E5250000EBD0209FE5D5

26:100190000030A0E30040D2E50140C1E4013083E239

27:1001A000800F53E3FAFFFF1A0040D2E5013083E2EB

28:1001B000840F53E3FBFFFF1A190000EB805F85E219

29:1001C000010080E2800E50E3D8FFFF1AC005A0E3D3

30:1001D000100F0DEE101F1DEE0000A0E1DBF021E37B

31:1001E00080D09FE5D7F021E37CD09FE5D1F021E3DB

32:1001F00078D09FE5D2F021E374D09FE5D3F021E3DE33:1002000070D09FE538009FE5541CA0E3001080E506

34:1002100030009FE5AF10A0E3001080E558009FE597

35:1002200010FF2FE154809FE5009098E5019009E2CE

36:10023000000059E3FBFFFF0A0EF0A0E1187C00006C

37:100240003075000020000056240000560800004AC7

38:100250000C00004CF0FF0700779700000400004EF0

39:100260000800004E0C00004E00230400002404008F

40:10027000002204000021040000200400A4720000F9

41:040280001000004E1C

42:10100000F8402DE90060B0E10140B0E10250B0E1EC

43:101010000070A0E3C4019FE50000D0E5010050E3AB

44:101020000200003A1200A0E30000C5E51E0000EA3D

45:101030000000D6E5010050E30500000A1000003A68

46:10104000030050E30200000A0100003A040050E3EC

47:101050000B00001AC50F00EB0070B0E10400B0E116

48:10106000200300EBFF0010E2100050E30700003AFD

49:101070000700B0E1C10F00EB0B00A0E30000C5E5E5

50:10108000090000EA0100A0E30000C5E5060000EA4F

51:101090000410B0E12C0096E2030300EB0700B0E17E

52:1010A000B60F00EB0000A0E30000C5E5F140BDE88D

53:1010B0001EFF2FE100502DE9681200EBEB0100EB61

54:1010C000130200EB660200EBC20100EBF50300EB3C

55:1010D0001A0400EB3F0400EB2D0200EB460200EB8C

56:1010E000C20600EB721200EB101300EB0140BDE8EA

57:1010F0001EFF2FE110402DE90040A0E34C039FE5C758:101100000000D0E5010050E33000001A970F00EB1B

59:101110000040B0E1C4009FE50000D0E5010050E3CD

60:101120000400003AB4009FE50000D0E5010050E261

61:10113000A8109FE50000C1E5A0009FE50000D0E5F4

1685:1076B00020546D72000000004170705461736B5F64

1686:1076C000310000004170705461736B5F3200000044

1687:1076D0004170705461736B5F330000004F532D5441

1688:1076E0006D724C6F636B00004F532D546D72536974

1689:1076F000670000000010B0E101C0B013FFFEFFEA18

1690:107700004C65645F53656D005461736B5F310000BD1691:107710005461736B5F3200005461736B5F33000020

1692:10772000686A6C747A4C0000785634121EFF2FE1A0

1693:107730001EFF2FE1010001000A0010003C0058026A

1694:10774000010001001C001400020005001000FE00F2

1695:1077500001000100050010002400B4000100040035

1696:1077600001000400180010000100040001000100E5

1697:1077700001008000010016001000010080000100DF

1698:107780000100FF006000640001001E010100100004

1699:10779000100008000A003400400308004000271AC7

1700:0400000500000000F7

1701:00000001FF该Hex文件每行的含义请参考《ARM原理与C程序设计》第267页。从上述代码可以看出,第1~41行的数据要写入到FLASH芯片的地址0x0~0x283处,而第42~1699行的数据要写入到FLASH芯片的地址0x1000~0x779F处,按字节(地址)写入。

笔者使用《ARM原理与C程序设计》第七章的工程Hex2H(使用C#语言,VisualStudio2008平台),并稍作修改,生成一个新的可执行文件Hex2H.exe(详细方法不再赘述),用这个可执行文件将ex7_3.hex转化为C语言的头文件flash.h。文件flash.h的内容如下:对比文件flash.h和ex7_3.hex,可以看出这两个文件的关系,即文件flash.h中的数组FlashDat包含了ex7_3.hex中的第1~41行的数据,这些数据写入FLASH的首地址为0x0;文件flash.h中的数组FlashDat2包含了ex7_3.hex中第42~1699行的数据,这些数据写入FLASH的首地址为0x1000。根据这种对应关系,读者可用自己熟悉的语言编写实现工程Hex2H功能的程序,生成的文件flash.h用于第7.2.4节工程ex7_4中。7.2.4Bootloader工程ex7_4

这里将新建一个工程ex7_4,用于将第7.2.3节的flash.h文件中的数据写入到芯片K9F1208中。在工程ex7_2的基础上新建工程ex7_4,保存目录为D:\ZYUCOSII\ex7_4,这时的工程ex7_4与工程ex7_2完全相同(注意,这是一个芯片级的程序)。需要做的修改为:将flash.h拷贝到D:\ZYUCOSII\ex7_4\user目录下,然后将该文件添加到工程ex7_4中,并修改文件zyMain.c。工程ex7_4如图7-12所示。图7-12工程ex7_4其中,文件zyMain.c的内容如下:

1/*FileName:zyMain.c

2**Byzhnyong@21

3**@2009-4-4

4**MainSubroutine

5**CopyrightReserved

6*/

7

8#include"zyDef2410.h"

9#include"flash.h"

10

11unsignedintFCLK,HCLK,PCLK;

12unsignedintval;13

14voidmain(void)

15{

16inti,n=0;

17//initializeNANDController

18initFlash();

19readFlashID();

20//for(i=0;i<1000;i++)

21//flashDat[i]=(i+89)%247;

22for(i=0;i<64;i++)//Erase16K*64

23{

24flashErase(i<<14);

25}

26flashWr(0x0,iDatN,FlashDat);

27flashWr(0x1000,iDatN2,FlashDat2);

28flashRd(0x429C,1000,flashWhat);

29//Flashdata,except16Bper528

30for(i=0;i<668;i++)

31{

32n=i/512;

33flashCp[i]=flashWhat[i+n*16];

34}

35//AboveisNandFlashoperator

36

37//Clock=192MHz?

38val=MPLLCON;上述代码第26行将FlashDat数组写入到K9F1208芯片的地址0x0开始的空间内;第27行将FlashDat2数组写入到K9F1208芯片的地址0x1000开始的空间内。

工程ex7_4是仿真执行的,即仿真运行工程ex7_4,就可以把工程ex7_3生成的ex7_3.hex(flash.h)写入到K9F1208中。现在,回顾一下已做的工作:第一步,在第7.2.1节介绍了读写K9F1208的方法,并给出一个演示工程ex7_2;第二步,在第7.2.2节中修改第六章工程ex6_1成为新的工程ex7_3,这步所做的修改目的是为了使工程ex7_3具有自举特性,即其文件startup.s能完成上电Bootloader功能;第三步,在第7.2.3节将工程ex7_3(Debug模式)生成的ex7_3.hex文件转换为C语言的头文件flash.h;第四步,即本节工程ex7_4将flash.h文件写入到K9F1208的适当位置,当flash.h写入成功后,可以看到三个LED灯滚动闪烁。这些工作都正确无误地完成后,可以关闭UP-Star实验板电源,把J-LINK仿真器取下来(也可以不取);然后,打开串口调试助手,设置波特率为115200bps;最后,再给UP-Star实验板上电,此时串口调试助手会显示如第六章图6-2所示的界面。如果按下JOYSTICK按键,串口调试助手将显示按键的信息,同时LED灯闪烁。至此,Bootloader工作完成了。7.2.5H-JTAG下载方式

上面的方法过于繁琐了,向FLASH中写入程序有大量现成的方案可以选取

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论