新2440slib.s注释

合集下载

RealviewMDK4.0进行2440开发快速入门

RealviewMDK4.0进行2440开发快速入门

Realview MDK4.0 进行2440开发快速入门----苑臣芒(光芒)RealView MDK在中国推出已经有一段时间了,而且作为未来发展的趋势必将取代ADS1.2,成为工程师广泛应用的开发平台。

但是好多工程师还习惯于用ads环境来调试,编译,我以前也是,但毕竟ads软件已经没有技术支持了,这势必会在以后对开发工作有一定影响,ARM将Keil公司收购之后,正式推出了针对ARM微控制器的开发工具RealView Microcontroller Development Kit (简称RealView MDK 或者MDK),它将ARM开发工具RealView Development Suite(简称RVDS)的编译器RVCT与Keil的工程管理、调试仿真工具集成在一起,是一款非常强大的ARM微控制器开发工具。

所以将ads工程转成rvmdk工程势必会成为开发道路上的难题。

第一步:分析一下ads工程及环境。

这是我的工程文件,看一下ads的设置,首先是target setting选项,选择arm from elf接下来编译器选项总平台都选择arm920t,其余不需要修改。

如图其余几个编译器(c,c++)也相应都设置为arm920t,其他地方不需要动。

接下来就是关键的link选项了,最关键的是ro,这个是程序运行地址,也就是在ram的哪个地址运行,tq2440和mini2440都可以设置为0x30000000,也可以比这个数值稍微大些,看实际需要吧,我们设置为0x30000000.在option标签页中添加程序入口点,这个入口点就是主程序运行的第一条指令的地方,在2440init.s中可以找到是entry,所以这里填写“__ENTRY”接下来看lay out选项卡,设置如下:到这里,设置基本完工了,但还不能生成文件,在arm fromELF中我们选择plain binary,接可以生成与工程名字同名的bin文件了。

2440裸机学习心得上

2440裸机学习心得上

2440裸机学习心得(上)哎,以前总想裸机加系统一齐学,学着学着发现好混乱,D驱动~~然后又重新斋跑2440的裸机。

以下系少少心得,记录下学习过程。

里面有三个地方还没弄好:1、硬盘的文件系统 FAT部分(后面有空补补)2、 NORFLASH中的读写有点问题3、 USB主机中对U盘的UFI命令有什么问题欢迎一起交流。

以下是部分心得:LEDGPXCON中每两位控制一个引脚:00输入,01输出,10特殊功能初始化rGPBCON , rGPBUP , rGPBDAT三个寄存器关于ADS配置的解释:在Target Settings中的Post-linker中选择ARM fromELF,因为我们需要把ELF文件格式转化为下载到flash中所必须的二进制文件。

在Language Settings中的所有语言的Target下的Architecture or Processor,选择ARM920T,因为s3c2440是ARM920T内核。

在ARM Linker中的Output中的RO Base填写0x30000000,因为在开发板上SDRAM是从0x30000000地址开始。

在Layout中的Object/Symbol中填写2440init.o,它是启动文件的目标文件,在Section中填写Init,它是在启动文件中我们所定义的入口代码段的名称。

外部中断我们要打开某一中断的屏蔽,这样才能响应该中断,相对应的寄存器为INTMSK;还要设置外部中断的触发方式,如低电平、高电平、上升沿、下降沿等,相对应的寄存器为EXTINTn。

另外由于EINT4到EINT7共用一个中断向量,EINT8到EINT23也共用一个中断向量,而INTMSK只负责总的中断向量的屏蔽,要具体打开某一具体的中断屏蔽,还需要设置EINTMASK。

有一些中断是共用一个中断向量的,而一个中断向量只能有一个中断执行函数,因此具体是哪个外部中断,还需要EINTPEND或rINTOFFSET来判断使用__irq这个关键词来定义中断处理函数,这样系统会为我们自动保存一些必要的变量,并能够在中断处理函数执行完后正确地返回这种形式:void __irq key();pISR_EINT0=(int)key;定时器使用主要配置:外部时钟源→通过寄存器MPLLCON得到FCLK→再通过寄存器CLKDIVN得到HCLK和PCLK->;再得到定时器的工作频率PWM定时器使用:蜂鸣器=GPB0=TOUT0=定时器0蜂鸣器高电平响,低电平不响关键是设置寄存器TCNTBn和TCMPBn,前者可以确定一个计数周期的时间长度,而后者可以确定方波的占空比定时器中断使用:不需要配置TCMPBn,只需TCNTBn,TCNTBn*1/定时器的工作频率=定时的时间但要记住中断要:void __irq timer0_sever();pISR_TIMER0=(int)timer0_sever;rINTMSK =~BIT_TIMER0;Uart主要配置以下寄存器:UBRDIVn,UCONn,UTRSTATn收发寄存器:UTXHn,URXHn注意几点:1.对于s3c2440来说,接收数据是被动的,发送数据是主动的,因此一般来说,接收数据用中断方式,发送数据用查询方式较好;2.在中断方式下,当接收到数据时,尽管可能该数据无用,但也一定要读取它,否则下次再接收数据时,不会再引起中断,因为接收数据缓存器被上次接收到的数据所霸占,只要没有读取它,它就永远在那里;3.由于UART中断涉及到SUBSRCPND寄存器,因此在中断处理程序中不仅要清SRCPND寄存器,还要清SUBSRCPND 寄存器,它们的顺序一定是先清SUBSRCPND寄存器,再清SRCPND寄存器,否则就会引起一个中断两次响应的问题。

阳初 2440 开发 板说明书

阳初 2440 开发 板说明书

阳初2440开发板使用说明书2008‐3‐20目录第一章 开发板的介绍 (6)1.1开发板简介 (6)1.1.1硬件资源特性 (6)1.1.2用户光盘资源说明 (7)1.2 Linux特性 (7)1.3开发套件配件清单 (8)第二章 开发板使用说明 (8)2.1 开发板设置及连接 (9)2.1.1 开发板外部接口连接 (9)2.1.2 设置超级终端(主机PC) (9)2.2 开发板BIOS功能及使用说明 (12)2.2.1 开机进入BIOS模式 (13)2.2.2 安装USB驱动 (14)2.2.3 vivi子菜单功能说明 (14)2.3 预装linux系统的功能简介 (14)2.3.1 设置开发板网络 (15)2.3.2 如何中止程序的运行 (15)2.3.3 挂载USB闪存盘(U盘) (16)2.3.4 使用SD卡 (17)2.3.5 如何通过串口与PC互相传送文件 (17)2.3.6 串口2 的测试 (19)2.3.7 使用ftp传递文件 (21)2.3.8 设置并保存系统实时时钟 (26)2.3.9 如何掉电保存数据到Flash (26)2.3.10 使用telnet登陆开发板 (26)2.3.11 如何设置开机自动运行程序 (27)第三章 安装嵌入式系统 (28)3.1安装启动程序 (28)3.1.1在PC上安装JTAG下载线的驱动程序 (29)3.1.2烧写Bootloader (35)3.2串口安装Linux (36)3.2.1分区并格式化闪存 (36)3.2.2下载Bootloader (37)3.2.3下载Linux的内核映象 (39)3.2.4下载文件系统映象 (40)3.2.5启动Linux系统 (41)3.3 tftp安装linux (41)3.3.1 启动TFTP服务器 (41)3.3.2 网络设置 (43)3.3.3 下载内核映象以及文件系统 (45)3.4安装WinCE系统 (47)3.4.1下载WindowsCE启动程序 (47)3.4.2下载WindowsCE映象 (49)3.4.3启动WindowsCE (54)第四章 ADS1.2 集成开发环境的使用 (54)4.1 使用ADS创建LED工程 (54)4.1.1 建立一个工程 (54)4.1.2 编译和链接工程 (58)4.2 下载和运行 (65)第五章 建立linux开发环境 (66)5.1 linux发行版本介绍 (66)5.2 完全图解安装Redhat9.0 (70)5.2.1用grub引导双操作系统 (70)5.2.2使用vmware虚拟机 (74)5.3 配置minicom终端通讯工具 (75)5.4 配置网络文件系统NFS服务 (77)5.5 通过NFS启动系统 (78)5.6 配置PC机Linux的ftp服务 (78)5.7 配置PC机的telnet服务 (79)第六章 嵌入式linux系统架构介绍 (80)6.1 Bootloader,内核镜像,文件系统 (80)6.2 Bootloader介绍 (81)6.3 内核 (82)6.4 文件系统 (82)6.4.1嵌入式系统存储设备及其管理机制分析 (82)6.4.2基于Flash的文件系统 (84)第七章 配置和编译linux (85)7.1 交叉编译环境 (85)7.1.1 交叉编译环境介绍 (85)7.1.2建立交叉编译环境 (86)7.2 bootloader (88)7.2.1编译bootloader (88)7.2.2 使用VIVI命令 (90)7.3 使用缺省配置文件编译内核 (92)7.3.1 解压内核源代码 (92)7.3.2 装载缺省配置文件 (93)7.3.3 编译内核 (96)7.4 定制linux内核 (99)7.4.1 如何配置CPU选项 (99)7.4.2 如何配置USB鼠标和键盘 (100)7.4.3 如何配置优盘的支持 (102)7.4.4 如何配置CS8900 网卡驱动 (103)7.4.5 如何配置声卡驱动 (105)7.4.6 如何配置串口驱动 (106)7.4.7 如何配置RTC实时时钟驱动 (108)7.4.8 如何配置yaffs文件系统的支持 (109)7.4.9 如何配置EXT2/VFAT/ NFS等文件系统 (110)7.5 根文件系统的制作 (112)7.5.1 根文件系统的构成 (112)7.5.2 构建根文件系统 (112)7.5.3 Yaffs根文件系统映像的制作 (114)7.5.4 Qtopia文件系统映象 (116)第八章 为目标板编写linux应用程序 (118)8.1 编辑编译示例程序 (118)8.2 如何把编译好的程序下载到开发板运行 (121)8.2.1 使用优盘 (121)8.2.2 通过串口传送文件到开发板 (123)8.2.3 通过网络文件系统NFS执行 (124)8.2.4 通过ftp下载文件执行 (126)8.3 程序驱动开发实验 (128)8.3.1 编辑编译LED灯驱动程序 (128)8.3.2 用ftp下载LED灯驱动程序 (129)8.3.3 运行LED灯驱动程序 (132)第九章 配置和编译Wince (134)9.1 安装开发环境Platform Builder 4.2 (134)9.2 Wince Image 生成简要说明 (139)9.2.1 解压缩文件 (139)9.2.2 导入CEC文件 (139)9.2.3 Image编译过程 (142)9.3 烧写Wince系统 (146)附录1 linux命令初步 (146)1.1文件列表 (146)1.2目录切换 (146)1.3复制 (147)1.4删除 (147)1.5移动 (147)1.6比较 (147)1.7回显 (147)1.8容量查看 (147)1.9文件内容查看 (147)1.10分页查看 (147)1.11时间日期 (147)1.12查找 (148)1.13搜索 (148)1.14设置环境变量 (148)1.15编辑 (148)1.16压缩与解压 (148)1.17挂接 (148)1.18启动信息显示 (148)1.19改变文件权限 (148)1.20创建节点 (148)1.21进程查看 (149)1.22杀死进程 (149)1.23设置环境变量 (149)1.24启动信息显示 (149)1.25网络设置命令 (149)1.26设置网关 (149)1.27测试网络联通 (150)1.28路由检测 (150)附录2 硬件地址空间分配 (150)2.1 地址空间分配和片选信号定义 (150)2.2 跳线说明 (151)附录3 推荐网站和下载资源 (153)3.1图书 (153)3.2网站 (156)3.2.1大陆资源 (156)3.2.2台湾资源 (157)第一章 开发板的介绍1.1开发板简介1.1.1硬件资源特性阳初2440 开发板由核心板和底板构成,更加方便客户做二次开发使用,在光盘中提供有底板的PCB 图,更利于客户出板。

【总结】S3C2440PLL设置详解总结

【总结】S3C2440PLL设置详解总结

S3C2440 PLL设置详解CPU上电几毫秒后,晶振输出稳定,FCLK=Fin(晶振频率),CPU开始执行指令。

但实际上,FCLK可以高于Fin,为了提高系统时钟,需要用软件来启用PLL。

这就需要设置CLKDIVN,MPLLCON,UPLLCON这3个寄存器。

CLKDIVN寄存器用于设置FCLK,HCLK,PCLK三者的比例,MPLLCON用于设置主频FCLK,UPLLCON用于设置USB时钟UCLK。

S3C2440APLL源有两个,一个是MPLL,另一个是UPLL. MPLL用于CPU用外设,UPLL只用于USB.,包括CPU的FCLK,AHB总线外设的HCLK以及APB总线外设的PCLK。

S3C2440A包含两个锁相环(PLL):MPLL提供给FCLK、HCLK和PCLK,UPLL 专用于USB模块(48MHz)。

时钟控制逻辑可以不使用PLL来减慢时钟,并且可以由软件连接或断开各外设模块的时钟,以降低功耗。

S3C2440A的主时钟源由外部时钟(EXTCLK)或者外部晶振(XTIPll)提供,输入时钟源由模式控制引脚OM3和OM2控制选择,在复位信号的上升沿参考OM3和OM2的引脚将OM[3:2]的状态在内部锁定,如图1所示图1 引导启动时的时钟源选择选择不同输入时钟源时连接方式如图2所示:图2 时钟连接参考通过在片内集成的2个锁相环:MPLL和UPLL,可对输入的Fin=12MHz的晶振频率进行倍频。

S3C2440使用了三个倍频因子MDIV、PDIV和SDIV来设置倍频,通过寄存器MPLLCON和UPLLCON可分别设置各自的倍频因子。

其中MPLLCON寄存器用于设置处理器内核时钟主频FCLK,其输入输出频率间的关系为FCLK=MPLL=(2*m*Fin)/(p*2^s)其中m=(MDIV+8), p=(PDIV+2), s=SDIV。

其中UPLLCON寄存器用于产生48MHz或96MHz,提供USB时钟(UCLK),其输入输出频率间的关系为UCLK=UPLL=(m * Fin) / (p * 2^s)其中m=(MDIV+8), p=(PDIV+2), s=SDIV。

s3c2440的一些解释

s3c2440的一些解释

S3c2440启动是从文件vivi/arch/s3c2440/head.S开始的1. 在这个文件中,做了这样的工作:(1) 关闭看门狗(2) 禁止所有中断(3) 初始化system clock(4) 初始化串口(5) 初始化nand flash相关的控制寄存器(6) 把vivi copy 到 SDRAM上,最后把pc指向ram(7) 设置堆栈(8) call 一个叫做main的函数。

这个函数是c写的2. main()这个函数在vivi/init/main.c中(1) 程序正常跳转到这里后,首先打印一些进本信息(2) 调用若干个初始化的函数<1> reset_handler() vivi/lib/reset_handler.c中(主要做了clear memory的工作)<2> board_init() (没找到)<3> mem_map_init() vivi/arch/mmu.c中(如果使用nand flash,会在这里使它看起来线性化;清空cache;invalidate I & D tlb)mmu_init vivi/arch/mmu.c中(初始化cache,load页表指针,mmu 使能等等)<4> heap_init 初始化堆 vivi/lib/heap.c(这里好像malloc了一段空间,具体的没看懂)<5> mtd_dev_init vivi/driver/mtd/mtdcore.c中mtd_init() 在vivi/driver/mtd/maps/s3c2440_flash.c 中,这里根据所使用的flash,做相应的cpu控制初始化,分配内存add_command(&flash_cmd) 注册了flash这个用户命令<6> init_priv_data() vivi/lib/priv_data/rw.c中读出boot的基本参数<7> misc() (没找到)init_builtin_cmds() vivi/lib/command.c中(注册用户的基本命令,包括boot, bon, load, help 等等)<8> boot_or_vivi() 就在main.c中,等待用户输入,有输入进入vivi_shell,没有输入,超时后启动linux到这里main就结束喽好像还有一件事没有记下来,就是vivi是怎么启动到linux的。

2440slib.s 解析

2440slib.s 解析

2440slib.s解析;===================================================================== ; File Name : 2440slib.s; Function : S3C2440 (Assembly);===================================================================== ; 禁止中断FIQ/IRQNOINT EQU 0xc0 ; 1100 0000; Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.GBLL THUMBCODE[ {CONFIG} = 16THUMBCODE SETL {TRUE}CODE32|THUMBCODE SETL {FALSE}]MACROMOV_PC_LR[ THUMBCODEbx lr|mov pc,lr]MENDAREA |C$$code|, CODE, READONLY;========================================; Workaround of problem between LCD and Framebuffer;========================================EXPORT SDRAMtestSDRAMtest ; SDRAM测试程序ldr r0,=0x31000000ldr r1,=0x80000mov r2,#0xf000000fLB2 str r2,[r0],#4str r2,[r0],#4subs r1,r1,#4bne LB2mov pc,lr;=================================; 设置CPSR的I位(IRQ)和F位(FIQ);=================================; 置位CPSR_IR,即禁止IRQ中断和FIQ中断EXPORT SET_IFSET_IF; 仅在特权模式下可用此程序.mrs r0,cpsrmov r1,r0orr r1,r1,#NOINTmsr cpsr_cxsf,r1MOV_PC_LR; 写值到CPSR; void WR_IF(int cpsrValue);EXPORT WR_IFWR_IF; 仅在特权模式下可用此程序.msr cpsr_cxsf,r0MOV_PC_LR; 清CPSR_IR,即允许IRQ中断和FIQ中断; void CLR_IF(void);EXPORT CLR_IFCLR_IF; 仅在特权模式下可用此程序.mrs r0,cpsrbic r0,r0,#NOINTmsr cpsr_cxsf,r0MOV_PC_LR在ARM的嵌入式应用中,存储系统是通过协处理器CP15完成的。

JZ2440学习笔记

JZ2440学习笔记

JZ2440学习笔记Chili2015.5前言本人入手JZ2440半个月,以前未接触过linux,但在校接触过许多不跑linux系统的CPU,具有LPC1114,LPC1343,STM32,blackfin等处理器的编程经验,对微处理器的原理以及运行方式具有一定的了解。

靠着这点小经验,以及新学习的知识,自己动手移植了最新的uboot,绝对原创,得益于韦老师的书籍以及开发板,能让我们这个小白可以踏进linux的世界,但本人毕竟在linux方面只是个类似小白的学生,许多不对之处,希望大家不吝指教!说明:阅读本文需要一点的ARM以及S3C2440的基础知识,建议先阅读《嵌入式Linux应用开发完全手册》,此书对对ARM以及JZ2440有很好的介绍和说明,在阅读中有不懂的也可以再去翻看此书,查漏补缺。

JZ2440移植最新u-boot-2015.04-rc4.tar1,配置uboot去官网下载最新uboot源代码u-boot-2015.04-rc4.tar,开发环境采用JZ2440光盘上的vmware 虚拟机ubuntu9.10。

本次采用smdk2410的默认配置来配置uboot,然后启动类似linux一样的menuconfig菜单进行配置,然后make,并烧写进JZ2440看效果,然后根据现象一步步修改。

我们移植uboot的基本原则是:因为我们刚上手,可能什么都不知道,更加不知需要更改什么,这个时候我们就先尽量什么都不改,直接烧写进去看现象,然后根据现象或者提示信息一步步更改,从而移植完成。

配置命令如下:book@book-desktop:~/uboot/u-boot-2015.04-rc4$ tar jxvf u-boot-2015.04-rc4.tar.bz2book@book-desktop:~/uboot/u-boot-2015.04-rc4$ cd u-boot-2015.04-rc4/book@book-desktop:~/uboot/u-boot-2015.04-rc4$ make smdk2410_defconfigbook@book-desktop:~/uboot/u-boot-2015.04-rc4$ make menuconfig3,在uboot根目录执行book@book-desktop:~/uboot/u-boot-2015.04-rc4$ make报错:cc1: error: bad value (armv4) for -march= switchcc1: error: bad value (armv4) for -mtune= switchmake[2]: *** [include/autoconf.mk] Error 1make[1]: *** [silentoldconfig] Error 1make: *** No rule to make target `include/config/auto.conf', needed by `include/config/uboot.release'. Stop.错误并不可怕,学会看错误提示,根据提示进行下一步工作。

学习S3C2440bootloader

学习S3C2440bootloader

按照gooogleman老兄的建议,从优龙2440板子的bootloader学起。

首先先将程序运行起来,step执行,搞清楚每步做了什么,为什么这么做。

将整体的流程学习一遍。

等1个月,2个月,无论多长时间,当自己真正掌握后,再将整体的代码加上注释,做成PDF文档。

分给后来者,去帮助像我现在这样水平的小小鸟。

OK,第一话开始:程序入口点:程序最开始跳到2440init.s文件,执行如下代码:b ResetHandler 跳转到复位异常处理程序。

ResetHandlerldr r0,=WTCON ;watch dog disableldr r1,=0x0str r1,[r0](将看门狗定时器清零,查看datasheet,WTCON的第0位是看门狗定时器复位输出信号开关。

为0,则程序关闭了S3C2440A的看门狗复位功能。

)ldr r0,=INTMSKldr r1,=0xffffffff ;all interrupt disablestr r1,[r0](将中断屏蔽寄存器全部置1,将对应的中断全部关闭。

)ldr r0,=INTSUBMSKldr r1,=0x7fff ;all sub interrupt disable `str r1,[r0](将子中断屏蔽寄存器全不置1,将子中断屏蔽寄存器对应的中断全部关闭。

)ldr r0,=LOCKTIMEldr r1,=0xffffffstr r1,[r0](LOCKTIME是锁定时间计数寄存器,分别设定了UPLL 对于UCLK 的锁定时间计数值和MPLL对于FCLK、HCLK、PCLK的锁定时间计数值。

具体查看datasheet第7章时钟部分。

) [ PLL_ON_START; Added for confirm clock divide. for 2440.; Setting value Fclk:Hclk:Pclkldr r0,=CLKDIVNldr r1,=CLKDIV_V AL ; 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4, 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6.str r1,[r0](这里先明确一下,在ADS下的bootloader代码常看到[|]他们其实就相当于c语言里面的IfdefElseEndif)(CLKDIVN是时钟分频器控制寄存器,设置的值为CLKDIV_V AL宏。

S3C2440启动代码注解

S3C2440启动代码注解

;/*****************************************************************************/ ;/*S3C2440A.S:Startup file for Samsung S3C440A*/ ;/*This file is part of the uVision/ARM development tools.*/ ;/*Copyright(c)2005-2006Keil Software.All rights reserved.*/ ;/*This software may only be used under the terms of a valid,current,*/ ;/*end user licence from KEIL for a compatible version of KEIL software*/ ;/*development tools.Nothing else gives you the right to use this software.*/ ;/*****************************************************************************/;elementary avocationA AND水友(rework:2008.09.15)/****************************************************************************;/欢迎各位大峡更详细的注解和改错;;(越详细越好!目标每行注解)参与的水友如下:【虚处理(子程序)是用一个无限循环实现的,它是可修改的..//(11942295)翻译】【galaxy9229发表于www.21ic2008-9-2516:51ARM程序分析与设计】参考:【龙啸九天】【飘零天堂】【METAL MAX】/****************************************************************************/ ;***启动代码(执行复位后)***;Standard definitions of Mode bits and Interrupt(I&F)flags in PSRs//;向量中断模式/非向量中断模式在PSRs设置(猜的);系统的工作模式设定Mode_USR EQU0x10;定义用户模式标志代码;//用户模式的CPSR 代码Mode_FIQ EQU0x11;定义快速中断模式标志代码;//快中断模式的CPSR代码Mode_IRQ EQU0x12;定义普通中断模式标志代码;//中断模式的CPSR 代码Mode_SVC EQU0x13;定义管理模式标志代码;//管理模式的CPSR代码Mode_ABT EQU0x17;定义中止模式标志代码;//中止模式的CPSR代码Mode_UND EQU0x1B;定义未定义模式标志代码;//未定义模式的CPSR代码Mode_SYS EQU0x1F;定义系统模式(特权模式)标志代码;//系统(特权)模式的CPSR代码I_Bit EQU0x80;//普通中断开关(0×80:打开;0×00:关闭)F_Bit EQU0x40;//快速中断开关(0×40:打开;0×00:关闭);//栈配置();系统的栈空间设定UND_Stack_Size EQU0x00000000;未定义SVC_Stack_Size EQU0x00000008;管理模式端栈长度ABT_Stack_Size EQU0x00000000;中止模式端栈长度FIQ_Stack_Size EQU0x00000000;快速中断模式端栈长度IRQ_Stack_Size EQU0x00000080;普通中断模式模式端栈长度USR_Stack_Size EQU0x00000400;用户模端栈长度;//ISR_Stack_Size EQU(UND_Stack_Size+SVC_Stack_Size+ABT_Stack_Size+ FIQ_Stack_Size+IRQ_Stack_Size);所有的堆栈大小进行相加,得到总堆栈大小/****************************************************************************** ****************;//arm的汇编程序由段组成,段是相对独立的指令或数据单位,每个段由AREA伪指令定义,并定义段的属性:;//READWRITE(读写)READONLY(只读)******************************************************************************* ***************/AREA STACK,NOINIT,READWRITE,ALIGN=3;开辟端栈段,段名(STACK)定义为可读可写,不初始化内存单元或将内存写0,字节对齐Stack_Mem SPACE USR_Stack_Size;//申请栈内存空间__initial_sp SPACE ISR_Stack_SizeStack_Top EQU Stack_Mem+ISR_Stack_Size;//定义堆栈开始地址(最大地址,堆栈向下访问);//堆配置;//堆大小(单位字节)//Heap_Size EQU0x00000000;系统的堆空间设定//定义堆空间大小(配合最后的动态内存申请使用)AREA HEAP,NOINIT,READWRITE,ALIGN=3;//段名(HEAP)声明堆代码段(不初始化内存,可读写,字节对齐)Heap_Mem SPACE Heap_Size;//申请堆的内存空间;时钟管理定义CLK_BASE EQU0x4C000000;时钟基地址LOCKTIME_OFS EQU0x00;PLL锁定时间计数器对应基地址的偏移值MPLLCON_OFS EQU0x04;MPLL控制对应基地址的偏移值//认为MPLL分出三种模式:FCLK、HCLK、PCLKUPLLCON_OFS EQU0X08;UPLL控制对应基地址的偏移值//用于USB设备CLKCON_OFS EQU0x0C;时钟生成控制对应基地址的偏移值CLKSLOW_OFS EQU0x10;慢时钟控制对应基地址的偏移值CLKDIVN_OFS EQU0X14;时钟除法器控制对应基地址的偏移值CAMDIVN_OFS EQU0X18;摄象时钟除法器控制对应基地址的偏移值//UPLL提供CLOCK_SETUP EQU1;时钟设置LOCKTIME_Val EQU0x0FFF0FFF;PLL锁定时间计数器值MPLLCON_Val EQU0x00043011;MPLL控制值UPLLCON_Val EQU0x00038021;UPLL控制值CLKCON_Val EQU0x001FFFF0;时钟生成控制值CLKSLOW_Val EQU0x00000004;慢时钟控制值CLKDIVN_Val EQU0x0000000F;时钟除法器控制值CAMDIVN_Val EQU0x00000000;摄象时钟除法器控制值;Interrupt definitions;中断定义INTOFFSET EQU0X4A000014;中断请求源偏移地址;//中断向量表;//中断向量地址<0x20-0x3fffff78>;//中断向量表地址必须字对齐;//</e>IntVT_SETUP EQU1;中断向量设置IntVTAddress EQU0x33ffff20;中断向量地址;-----------------------存储器设定------------------------------------IRAM_BASE EQU0x40000000;//内存基地址;//看门狗定义WT_BASE EQU0x53000000;看门狗基地址WTCON_OFS EQU0x00;看门狗控制对应基地址的偏移值WTDAT_OFS EQU0x04;看门狗数据对应基地址的偏移值WTCNT_OFS EQU0x08;看门狗记数对应基地址的偏移值WT_SETUP EQU1;看门狗设置WTCON_Val EQU0x00000000;看门狗控制WTDAT_Val EQU0x00008000;看门狗数据;存储控制器设定MC_BASE EQU0x48000000;存储控制器基地址MC_SETUP EQU0;存储控制器设定BWSCON_Val EQU0x22000000;总线宽度和等待控制BANKCON0_Val EQU0x00000700;Boot ROM控制BANKCON1_Val EQU0x00000700;BANK1控制BANKCON2_Val EQU0x00000700;BANK2控制BANKCON3_Val EQU0x00000700;BANK3控制BANKCON4_Val EQU0x00000700;BANK4控制BANKCON5_Val EQU0x00000700;BANK5控制BANKCON6_Val EQU0x00018005;BANK6控制BANKCON7_Val EQU0x00018005;BANK7控制REFRESH_Val EQU0x008404F3;DRAM/SDRAM刷新控制BANKSIZE_Val EQU0x00000032;存储器大小控制MRSRB6_Val EQU0x00000020;SDRAM的模式设置寄存器控制MRSRB7_Val EQU0x00000020;SDRAM的模式设置寄存器控制;存储控制器设定结束;I/O口设定PIO_BASE EQU0x56000000;端口基地址PCONA_OFS EQU0x00;端口A控制对应基地址的偏移值PCONB_OFS EQU0x10;端口B控制对应基地址的偏移值PCONC_OFS EQU0x20;端口C控制对应基地址的偏移值PCOND_OFS EQU0x30;端口D控制对应基地址的偏移值PCONE_OFS EQU0x40;端口E控制对应基地址的偏移值PCONF_OFS EQU0x50;端口F控制对应基地址的偏移值PCONG_OFS EQU0x60;端口G控制对应基地址的偏移值PCONH_OFS EQU0x70;端口H控制对应基地址的偏移值PCONJ_OFS EQU0xD0;端口J控制对应基地址的偏移值PUPB_OFS EQU0x18;端口B上拉控制对应基地址的偏移值PUPC_OFS EQU0x28;端口C上拉控制对应基地址的偏移值PUPD_OFS EQU0x38;端口D上拉控制对应基地址的偏移值PUPE_OFS EQU0x48;端口E上拉控制对应基地址的偏移值PUPF_OFS EQU0x58;端口F上拉控制对应基地址的偏移值PUPG_OFS EQU0x68;端口G上拉控制对应基地址的偏移值PUPH_OFS EQU0x78;端口H上拉控制对应基地址的偏移值PUPJ_OFS EQU0xD8;端口J上拉控制对应基地址的偏移值;--------端口配置--------------PIO_SETUP EQU0;端口APIOA_SETUP EQU0PCONA_Val EQU0x000003FF;端口BPIOB_SETUP EQU0PCONB_Val EQU0x00000000;PUPB_Val EQU0x00000000;端口B上拉开启;端口CPIOC_SETUP EQU1PCONC_Val EQU0x00001401;PUPC_Val EQU0x00000000;端口C上拉开启;端口DPIOD_SETUP EQU0PCOND_Val EQU0x00000000;PUPD_Val EQU0x00000000;端口D上拉开启;端口EPIOE_SETUP EQU0PCONE_Val EQU0x00000000;PUPE_Val EQU0x00000000;端口E上拉开启;端口FPIOF_SETUP EQU0PCONF_Val EQU0x00000000;PUPF_Val EQU0x00000000;端口F上拉开启;端口GPIOG_SETUP EQU0PCONG_Val EQU0x00000000;PUPG_Val EQU0x00000000;端口G上拉开启;端口HPIOH_SETUP EQU0PCONH_Val EQU0x000007FFPUPH_Val EQU0x00000000;端口H上拉开启;端口JPIOJ_SETUP EQU0PCONJ_Val EQU0x00000000;PUPJ_Val EQU0x00000000;端口J上拉开启;汇编程序数据8字节对齐PRESERVE8;c和汇编有8位对齐的要求,这个伪指令可以满足此要求;//存储区设定和程序入口点;//启动代码必须连接到第一个地址才能运行。

S3C2440重要资料

S3C2440重要资料

S3C2440与SDRAM的地址连线分析S3C2440有27根地址线ADDR[26:0],8根片选信号ngcs0-ngcs7,对应bank0-ba nk7,当访问bankx的地址空间,ngcsx引脚为低电平,选中外设。

2^27=2^7 * 2^10 * 2^10 = 128Mbyte8*128Mbyte = 1Gbyte所以S3C2440总的寻址空间是1Gbyte。

市面上很少有32位宽度的单片SDRAM,一般选择2片16位SDRAM扩展得到32位SDRAM.选择的SDARM是HY57V561620F,4Mbit * 4bank *16,共32Mbyte。

首先了解下SDRAM的寻址原理。

SDRAM内部是一个存储阵列。

可以把它想象成一个表格。

和表格的检索原理一样,先指定行,再指定列,就可以准确找到所需要的存储单元。

这个表格称为逻辑B ANK。

目前的SDRAM基本都是4个BANK。

寻址的流程就是先指定BANK地址,再指定行地址,最后指定列地址。

这就是SDRAM的寻址原理。

存储阵列示意图如下:查看HY57V561620F的资料,这个SDRAM有13根行地址线 RA0-RA129根列地址线CA0-CA82根BANK选择线 BA0-BA1SDRAM的地址引脚是复用的,在读写SDRAM存储单元时,操作过程是将读写的地址分两次输入到芯片中,每一次都由同一组地址线输入。

两次送到芯片上去的地址分别称为行地址和列地址。

它们被锁存到芯片内部的行地址锁存器和列地址锁存器。

/RAS是行地址锁存信号,该信号将行地址锁存在芯片内部的行地址锁存器中;/CAS是列地址锁存信号,该信号将列地址锁存在芯片内部的列地址锁存器中。

地址连线如下图:SDRAM的A0接S3C2440的ADDR2,很多初学者都对这里又疑问。

A0为什么不接ADDR0?要理解这种接法,首先要清楚在CPU的寻址空间中,字节(8位)是表示存储容量的唯一单位。

用2片HY57V561620F扩展成32位SDRAM,可以认为每个存储单元是4个字节。

S3C2440启动代码2440init.s彻底解析

S3C2440启动代码2440init.s彻底解析

S3C2440启动代码2440init.s彻底解析2440可以选择nand启动和nor启动,这两者之间的关系通过⼀个按键来选择这个OM0有何⽞机,在数据⼿册中有这么⼀段可以看到,只要将OM1接地,那么通过OM0选择1或选择0就可以选择NAND启动或者16位宽RAM启动了(当然,还得设置⼀些东西,下⾯就说),Nanaflash启动经历的过程相当于⾸先,2440⾃动从nand⾥⾯读取4K的代码,这4K代码将nand⾥⾯的数据拷贝到ram中,然后跳转到ram中执⾏代码,为什么是4K,因为2440.s的启动代码需要包含⼏个⽂件2440addr.inc包含2440内部寄存器地址Memcfg.inc包含2440各个bank的内存配置数据Option.inc包含2440的各种时钟配置代码Nand.c包含nanaflash的读写函数好了,分析开始;REFRESH寄存器[22]bit : 0- auto refresh; 1 - self refreshBIT_SELFREFRESH EQU (1<<22) ;⽤于节电模式中,SDRAM⾃动刷新;处理器模式常量: CPSR寄存器的后5位决定⽬前处理器模式 M[4:0]USERMODE EQU 0x10FIQMODE EQU 0x11IRQMODE EQU 0x12SVCMODE EQU 0x13ABORTMODE EQU 0x17UNDEFMODE EQU 0x1bMODEMASK EQU 0x1f ;M[4:0]//模式计算掩码NOINT EQU 0xc0 //除去模式之后的剩余值CPSR的说明;定义处理器各模式下堆栈地址常量UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~ _STACK_BASEADDRESS定义在option.inc中SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~剩下的请查看以下代码;汇编不能使⽤include包含头⽂件,所有⽤Get;汇编也不认识*.h ⽂件,所有只能⽤*.incGET option.inc ;定义芯⽚相关的配置GET memcfg.inc ;定义存储器配置GET 2440addr.inc ;定义了寄存器符号;REFRESH寄存器[22]bit : 0- auto refresh; 1 - self refreshBIT_SELFREFRESH EQU (1<<22) ;⽤于节电模式中,SDRAM⾃动刷新;处理器模式常量: CPSR寄存器的后5位决定⽬前处理器模式 M[4:0]USERMODE EQU 0x10FIQMODE EQU 0x11IRQMODE EQU 0x12SVCMODE EQU 0x13ABORTMODE EQU 0x17UNDEFMODE EQU 0x1bMODEMASK EQU 0x1f ;M[4:0]NOINT EQU 0xc0;定义处理器各模式下堆栈地址常量UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~ _STACK_BASEADDRESS定义在option.inc中SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~;arm处理器有两种⼯作状态 1.arm:32位这种⼯作状态下执⾏字对准的arm指令 2.Thumb:16位这种⼯作状;态执⾏半字对准的Thumb指令;因为处理器分为16位 32位两种⼯作状态程序的编译器也是分16位和32两种编译⽅式所以下⾯的程序⽤;于根据处理器⼯作状态确定编译器编译⽅式;code16伪指令指⽰汇编编译器后⾯的指令为16位的thumb指令;code32伪指令指⽰汇编编译器后⾯的指令为32位的arm指令;;Arm上电时处于ARM状态,故⽆论指令为ARM集或Thumb集,都先强制成ARM集,待init.s初始化完成后;再根据⽤户的编译配置转换成相应的指令模式。

S3C2440_bootloader及USB下载文档

S3C2440_bootloader及USB下载文档

MDK下向S3C2440 nand flash烧写例程的实现1.工作任务(1)向S3C2440 nand flash烧写例程由于S3C2440没有nor flash而只有nand flash,例程下载到nand flash时,它的前4K会自动转移到称做“进阶石”的SRAM中,然后在SRAM中运行该4K的程序。

如果例程刚好小于4K,则下载到nand flash时,程序可以正确运行,然而一般例程都会大于4K,这时仅仅将程序下载到nand flash中是不行的,这是因为程序是不能在nand flash中运行的,必须利用这4K的“进阶石”将程序从nand flash搬移到外部的SDRAM中,然后将PC指针指向SDRAM中程序所放置的起始位置。

(2)Bootloader的编写要实现上述的功能,必须编写一个小于4K的Bootloader引导程序。

Bootloader中应包含异常向量表、中断向量表、时钟初始化、SDRAM初始化以及相应的端口初始化等部分,另外还应包含将程序从nand flash搬移到SDRAM的功能。

搬移功能主要通过操作nand flash 的相关寄存器和一些读写命令来实现。

(3)USB下载虽然实现了bootloader,可以将程序从nand flash搬移到SDRAM,并且把PC指向了SDRAM中程序的首地址,但程序并不能正确运行。

这是因为下载到nand flash中的可执行文件中包含绝对地址,尽管搬移到了SDRAM,但当运行到绝对地址时,程序就会跑飞,从而不能正确的运行程序。

有一个办法是,先将程序基于SDRAM的地址编译好,然后下到nand flash中,再通过bootloader将程序搬移回SDRAM的相应位置,这样所有的地址都是相对于SDRAM的,程序就可以正确运行。

但是在MDK下,这种方法实现不了,MDK编译生成的.AXF文件中带有地址信息。

使用分散加载文件生成的映像文件是基于某一地址,则必须下载到flash的相应地址,如果要将基于SDRAM某一地址编译生成的.AXF文件下载到nand flash的不同地址,MDK则会提示下载失败,找不到烧写算法。

2440init.s分析

2440init.s分析

2440init.s分析板子上电后就会从这里开始执行,主要完成基本初始化,还有判断是从nor还是nand启动,再实现把程序搬到SDRAM当中,在搬运成功后再跳到main函数里面执行。

我们现在开始来看看它的具体代码吧!GET和INCLUDE的功能是相同的,功能都是引进一些编译过的文件。

GET option.incGET memcfg.incGET 2440addr.inc定义SDRAM工作在Reflesh模式下,SDRAM有两种刷新模式:selfreflesh,autoreflesh。

后者是在其使用过程当中设置的。

BIT_SELFREFRESH EQU (1<<22)下面是对arm处理器模式寄存器对应的常数进行赋值,arm处理器有一个CPSR 寄存器,它的后五位决定了处理器处于哪个模式下。

可以看出常数的定义都不会超过后5位的。

USERMODE EQU 0x10FIQMODE EQU 0x11IRQMODE EQU 0x12SVCMODE EQU 0x13ABORTMODE EQU 0x17UNDEFMODE EQU 0x1bMODEMASK EQU 0x1fNOINT EQU 0xc0各个异常模式的堆栈UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~这一段是统一arm的工作状态和对应的软件编译方式(16位编译环境使用tasm.exe编译)。

arm9开发板2440 非操作系统代码SD卡读写注释

arm9开发板2440 非操作系统代码SD卡读写注释

Uart_Printf("\nSDI Card Write and Read Test\n");
if(!SD_card_init())
return;
TR_Buf_new(); //发送数据缓冲区初始化(其中也完成了接收缓冲区清0的工作),且发送,接收数据缓冲区都放在内存中
Tx_buffer=(unsigned int *)0x31000000;
j=0;
for(i=0;i<2048;i++) //128[word]*16[blk]=8192[byte]
*(Tx_buffer+i)=i+j;
Flush_Rx_buf(); //接收数据缓冲区清0
/*rSDIBSIZE SDI模块大小寄存器 0x200=0b 0010 0000 0000=512
[11:0] 模块数(0~4095),当流模式时不考虑 */
rSDIBSIZE=0x200; // 512byte(128word)
/* rSDIDTIMER SDI数据/忙定时器寄存器
}
}
void View_Tx_buf(void)
{
}
int SD_card_init(void)
{
//-- SD controller & card initialize
int i;
/* Important notice for MMC test condition */
CMD0();
Uart_Printf("In idle\n");
//-- Check MMC card OCR OCR(Operating Conditions Register) 32位的操作条件寄存器存储了VDD电压范围

S3C2440之中断操作(MDK4.22)

S3C2440之中断操作(MDK4.22)

S3C2440之中断操作(MDK4.22)
背景知识:2440 中断控制器接收60 个中断源。

中断被分为多种类别,此处为32 类别,正好用32 位。

图上可以很好的表示整个中断的流程。

有些中断源对应一个中断类别,比如
串口中断发送,接收最后都对应到串口中断。

submask 屏蔽子类别,未屏蔽的会引起srcpnd 相应位置位,如果mask 未屏蔽的话,就会紧接着判断优先级,最后导致intpnd 置位,然后产生了IRQ,而FIQ 不需要优先级判断,会直接产生,由intmod 设置。

注意的是:进入ISR 后,清除中断的顺序很重要,首先是srcpnd 接着是intpnd,如果还需要清除eintpnd 的话,要最先清除。

实验过程:
编译工具--MDK4.22
硬件图
首先需要配置GPF0/1/2/4 的脚为EINT0/1/2/4。

由于用到了外部4-7 中断,需要开启EINTMASK 寄存器相应位。

设置优先
级寄存器,设置INTMSK 寄存器。

在2440A.s 中已经设置了I F 位开启,可以接收中断了。

在中断初始化代码里,需要将中断函数的地址安装到中断向量表中。

程序如下:
MDK4.22 的启动代码设置
配置了堆,栈,以及中断向量表的地址为0x33ffff20 处。

配置了B 口和F 口,B 口试LED 的灯显示,F 口是连接按键的外部中断。

按一个键会亮一个LED。

int.c 代码。

2440 bootloader

2440 bootloader

第24卷 第15期2008年8月甘肃科技Gansu Science and T echnolo gyV ol.24 N o.15A ug. 2008基于S3C2440的Bootloader的设计与实现于云松,由德凯,孙其芳(沈阳化工学院,辽宁沈阳110000)摘 要:Boot loader(引导加载程序)是嵌入式系统开发的一个重要环节,它把操作系统和硬件平台衔接起来,对嵌入式系统的后继软件开发十分重要。

U-boot是一个功能十分强大的Boot loader,本文深入研究了U-boot的运行原理,在基于以三星公司S3C2440微处理器为核心的开发板为背景,分析、探讨并且实现了基于U-boo t的系统引导加载程序的构建。

关键词:嵌入式系统;Bo otloader;S3C2440;u-boo t中图分类号:T P3681 引言Boo tloader(引导加载程序)就是在操作系统内核运行之前运行的一段小程序。

通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境[2]。

嵌入式系统中的Boo tlo ader是嵌入式系统开发的难点之一,同时是系统运行的一个前提条件,没有这段和硬件紧密相关的代码,多么精悍的内核也不能发挥作用[3]。

Bo otloader是严重地依赖于硬件而实现的,特别是在嵌入式系统中,不同体系结构的处理器需要不同的Bootloader,即使是基于同一种处理器构建的不同开发板,通常也需要进行Boo tlo ader 移植工作。

因此,在嵌入式系统中建立一个通用的Boo tloader几乎是不可能的,所以本文是实现针对以S3C2440微处理器为核心的特定目标板的Bo ot loader的开发。

Boo tloader的启动流程一般分为两个阶段stage1和stage2:Boo tloader的stage1通常包括以下步骤:1)硬件设备初始化。

对于2440.s的一点点共同理解(一)

对于2440.s的一点点共同理解(一)

对于2440.s的⼀点点共同理解(⼀)在2440init.s中有中断处理函数,有⼀张中断向量表,定义了32个中断,8种模式,⼀直不得其解,不是很清楚C程序是如何调⽤底层的中断处理程序,如何使⽤这张异常中断向量表,其中涉及到中断⼊⼝地址,堆栈指针SP,程序计数器PC的操作等等,如在⽹上收集到⼀⽚较简单阐述其过程的⽂章,受益匪浅,真是如⿊夜之⼈,见着点点星光,对于作者,鄙⼈不胜感激。

中断向量b HandlerIRQ ;handler for IRQ interrupt很⾃然,因为所有的单⽚机都是那样,中断向量⼀般放在开头,⽤过单⽚机的⼈都会很熟悉,那就不多说了。

异常服务程序这⾥不⽤中断(interrupt)⽽⽤异常(exception),毕竟中断只是异常的⼀种情况,下⾯主要分析的是“中断异常”说⽩了,就是我们平时单⽚机⾥⾯⽤的中断所有由器件引起的中断,例如TIMER中断,UART中断,外部中断等等,都有⼀个统⼀的⼊⼝,那就是中断异常 IRQ ! 然后从IRQ的服务函数⾥⾯分辨出,当前究竟是什么中断,再跳转到相应的中断服务程序。

这样看来,ARM⽐单⽚机要复杂⼀些了,不过原理是不变的。

上⾯说的就是思路,跟着这个思路来接着分析。

HandlerIRQ很明显是⼀个标号,我们找到了HandlerIRQ HANDLER HandleIRQ这⾥是⼀个宏定义,我们再找到这个宏,看他是怎么定义的:MACRO$HandlerLabel HANDLER $HandleLabel$HandlerLabelsub sp,sp,#4 ;decrement sp(to store jump address)stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original address)ldr r0,=$HandleLabel ;load the address of HandleXXX to r0ldr r0,[r0] ;load the contents(service routine start address) ofHandleXXXstr r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stackldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)MEND⽤ HandlerIRQ 将这个宏展开之后得到的结果实际是这样的HandlerIRQsub sp,sp,#4 ;decrement sp(to store jump address)stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original address)ldr r0,=HandleIRQ ;load the address of HandleXXX to r0ldr r0,[r0] ;load the contents(service routine start address) of HandleXXXstr r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stackldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)⾄于具体的跳转原理下⾯再说,好了,这样的话就容易看的多了,很明显, HandlerIRQ 还是⼀个标号,IRQ异常向量就是跳转到这⾥执⾏的,这⾥粗略看⼀下,应该是保存现场,然后跳转到真正的处理函数,那么很容易发现了这么⼀句 ldrr0,=HandleIRQ ,没错,我们⼜找到了⼀个标号 HandleIRQ ,看来真正的处理函数应该是这个 HandleIRQ ,继续寻找AREA RamData, DATA, READWRITE^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00HandleReset # 4HandleUndef # 4HandleSWI # 4HandlePabort # 4HandleDabort # 4HandleReserved # 4HandleIRQ # 4最后我们发现在这⾥找到了 HandleIRQ ,^ 其实就是 MAP ,这段程序的意思是,从 _ISR_STARTADDRESS 开始,预留⼀个变量,每个变量⼀个标号,预留的空间为 4个字节,也就是 32BIT,其实这⾥放的是真正的C写的处理函数的地址,说⽩了,就是函数指针 - - 这样做的话就很灵活了接着,我们需要安装IRQ处理句柄,说⽩了,就是设置处理函数的地址,让PC指针可以正确的跳转。

s3c2440对nandflash的操作

s3c2440对nandflash的操作

s3c2440对nandflash的操作nandflah在对大容量的数据存储中发挥着重要的作用。

相对于norflah,它具有一些优势,但它的一个劣势是很容易产生坏块,因此在使用nandflah时,往往要利用校验算法发现坏块并标注出来,以便以后不再使用该坏块。

nandflah没有地址或数据总线,如果是8位nandflah,那么它只有8个IO口,这8个IO口用于传输命令、地址和数据。

nandflah主要以page(页)为单位进行读写,以block(块)为单位进行擦除。

每一页中又分为main区和pare区,main区用于正常数据的存储,pare区用于存储一些附加信息,如块好坏的标记、块的逻辑地址、页内数据的ECC校验和等。

三星公司是最主要的nandflah供应商,因此在它所开发的各类处理器中,实现对nandflah的支持就不足为奇了。

3c2440不仅具有nandflah的接口,而且还可以利用某些机制实现直接从nandflah启动并运行程序。

本文只介绍如何对nandflah实现读、写、擦除等基本操作,不涉及nandflah启动程序的问题。

在这里,我们使用的nandflah为K9F2G08U0A,它是8位的nandflah。

不同型号的nandflah的操作会有所不同,但硬件引脚基本相同,这给产品的开发带来了便利。

因为不同型号的PCB板是一样的,只要更新一下软件就可以使用不同容量大小的nandflah。

K9F2G08U0A的一页为(2K+64)字节(加号前面的2K表示的是main区容量,加号后面的64表示的是pare区容量),它的一块为64页,而整个设备包括了2048个块。

这样算下来一共有2112M位容量,如果只算main区容量则有256M字节(即256M某8位)。

要实现用8个IO口来要访问这么大的容量,K9F2G08U0A规定了用5个周期来实现。

第一个周期访问的地址为A0~A7;第二个周期访问的地址为A8~A11,它作用在IO0~IO3上,而此时IO4~IO7必须为低电平;第三个周期访问的地址为A12~A19;第四个周期访问的地址为A20~A27;第五个周期访问的地址为A28,它作用在IO0上,而此时IO1~IO7必须为低电平。

2440分析思路

2440分析思路

程序流程:1、首先预处理(宏定义、头文件包含、伪指令)2、程序入口,ENTRY,ResetEntry3、ENDIAN_CHANGE为{FALSE},跳转到ResetHandler4、关闭看门狗定时器、屏蔽所有中断、子中断、调整频率(LOCKTIME值设为0xffffffff)5、PLL_ON_START为{TRUE},则执行以下指令。

没有则跳过步骤55.1CLKDIV_VAL值为5,使Fclk:Hclk:Pclk=1:4:85.2Fclk与Hclk之比不为1,执行一些指令。

(为1执行不同的指令)5.3配置UPLL、配置MPLL。

必须先配置UPLL,然后配置MPLL。

之间必须相隔7个NOP指令的时间6、6.1 如果在休眠模式下,被唤醒。

则跳转到WAKEUP_SLEEP处理中断。

WAKEUP_SLEEP中断处理6.1.1 设置MISCCR寄存器,使得SCLK0=SCLK,SCLK1=SCLK,同时Self refresh retaindisable6.1.2 设置寄存器BWSCON、BANKCON0、BANKCON1、BANKCON2、BANKCON3、BANKCON4、BANKCON5、BANKCON6、BANKCON7、REFRESH、BANKSIZE、MRSRB6、MRSRB76.1.3 内存配置完毕后,等待256条指令循环,然后跳转到StartPointAfterSleepWakeUp,即步骤76.2 如果没有从休眠模式唤醒,则跳过WAKEUP_SLEEP,直接执行StartPointAfterSleepWakeUp处程序,即步骤76.2.1 同样是配置内存控制器7、配置管脚端口F。

将GPF管脚设置为iput、上拉使能。

7.1 如果EINT0按键按下,则执行如下7.1.1 初始化堆栈几种模式下SP所指向的地址。

初始化模式有:UNDEFMODE、ABORTMODE、IRQMODE、FIQMODE、SVCMODE。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
R1_iA EQU (1<<31)
R1_nF EQU (1<<30)
;void MMU_EnableICache(void)
EXPORT MMU_EnableICache
MMU_EnableICache
mrc p15,0,r0,c1,c0,0
orr r0,r0,#R1_I
;//W-bit[3]:禁止/使能写入缓冲,1使能
;//P-bit[4]:控制PROG32控制信号
;// 0 异常中断处理程序进入32地址的模式
;// 1 异常中断处理程序进入26地址的模式 不支持26位时返回1
;//D-bit[5]:对于向前兼容的26位地址的ARM处理器
;=====================================================================
;Interrupt, FIQ/IRQ disable
NOINT EQU 0xc0 ; 1100 0000
;Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.
2440slib.s注释--(转载)转载区之ARM 2009-10-06 23:46:02 阅读313 评论1 字号:大中小 订阅
;=====================================================================
; File Name : 2440slib.s
mcr p15,0,r0,c1,c0,0
MOV_PC_LR
;void MMU_DisableICache(void)
EXPORT MMU_DisableICache
MMU_DisableICache
mrc p15,0,r0,c1,c0,0
bic r0,r0,#R1_I
MOV_PC_LR
;//置位IRQ和FIQ控制位,禁止中断
;void WR_IF(int cpsrValue);
EXPORT WR_IF
WR_IF
;This function works only if the processor is in previliged mode.
mrc p15,0,r0,c1,c0,0
orr r0,r0,#R1_A
mcr p15,0,r0,c1,c0,0
MOV_PC_LR
;void MMU_DisableAlignFault(void)
EXPORT MMU_DisableAlignFault
MMU_DisableAlignFault
;//1、在使能MMU之前,要在内存中建立好页表,同时CP15中的各相关寄存器必须完成初始化。
mcr p15,0,r0,c1,c0,0
MOV_PC_LR
;//禁止/使能指令Cache
;void MMU_EnableDCache(void)
EXPORT MMU_EnableDCache
MMU_EnableDCache
mrc p15,0,r0,c1,c0,0
GBLL THUMBCODE
[ {CONFIG} = 16
THUMBCODE SETL {TRUE}
CODE32
|
THUMBCODE SETL {FALSE}
]
MACRO
MOV_PC_LR
[ THUMBCODE
msr cpsr_cxsf,r0
MOV_PC_LR
;//写CPSR
;void CLR_IF(void);
EXPORT CLR_IF
CLR_IF
;This function works only if the processor is in previliged mode.
mrs r0,cpsr
bic r0,r0,#NOINT
msr cpsr_cxsf,r0
MOV_PC_LR
;//清零IRQ和FIQ控制位,使能中断
;====================================
; MMU Cache/TLB/etc on/off functions //TLB--页表缓冲
;========================================
EXPORT SDRAMtest
SDRAMtest
ldr r0,=0x31000000 ;//#表示立即数寻址,但是LDR立即数是有限制的,
ldr Байду номын сангаас1,=0x80000 ;//只有部分可以,=是伪指令,表示先把这个数存
;// 1 选择big-endian
;//S-bit[8]:用于系统保护
;//R-bit[9]:用于ROM保护
;//F-bit[10]:由生产商定义
;//Z-bit[11]:对于支持跳转预测的ARM系统
;// 1 使能跳转预测功能
;// 0 禁止跳转预测功能
mrc p15,0,r0,c1,c0,0
bic r0,r0,#R1_M
mcr p15,0,r0,c1,c0,0
MOV_PC_LR
;//使能/禁止MMU
;//注意:使能/禁止MMU时
;//====================================================================================================
bx lr
|
mov pc,lr
]
MEND
AREA |C$$code|, CODE, READONLY
;========================================
;Workaround of problem between LCD and Framebuffer
mov r2,#0xf000000f ;//在某个空间然后再给,如果可以直接寻址就自动
;//设置,编译器自己搞定
LB2 str r2,[r0],#4
str r2,[r0],#4
bic r0,r0,#R1_C
mcr p15,0,r0,c1,c0,0
MOV_PC_LR
;//禁止/使能数据Cache
;void MMU_EnableAlignFault(void)
EXPORT MMU_EnableAlignFault
MMU_EnableAlignFault
;// 1 对于一些根据跳转地址的位[0]进行状态切换的指令,忽略[0],不进行状态切换,保持和以前的ARM版本兼容
;//=====================================================
R1_I EQU (1<<12) ;//Cache分开时,1 使能指令Cache,0 禁止使能Cache
orr r0,r0,#R1_C
mcr p15,0,r0,c1,c0,0
MOV_PC_LR
;void MMU_DisableDCache(void)
EXPORT MMU_DisableDCache
MMU_DisableDCache
mrc p15,0,r0,c1,c0,0
MMU_EnableMMU
mrc p15,0,r0,c1,c0,0
orr r0,r0,#R1_M
mcr p15,0,r0,c1,c0,0
MOV_PC_LR
;void MMU_DisableMMU(void)
EXPORT MMU_DisableMMU
MMU_DisableMMU
; Function : S3C2440 (Assembly)
; Date : March 09, 2002
; Revision : Programming start (February 26,2002) -> SOP
; Revision : 03.11.2003 ver 0.0 Attatched for 2440
R1_C EQU (1<<2) ;//禁止/使能数据Cache或整个Cache,1使能 不含Cache返回0,不能禁止Cache返回1
R1_A EQU (1<<1) ;//是否支持内存访问时地址对齐检查系统,1使能
R1_M EQU (1) ;//禁止/使能MMU 1使能
;====================================
;//=============CP15协处理器MMU的C1功能================
;//M-bit[0]:禁止/使能MMU 1使能
;//A-bit[1]:是否支持内存访问时地址对齐检查系统,1使能
;//C-bit[2]:禁止/使能数据Cache或整个Cache,1使能 不含Cache返回0,不能禁止Cache返回1
;//RR-bit[14]:Cache的淘汰算法
;// 0 选择常规的淘汰算法,
;// 1 选择预测性的淘汰算法,如round-robin淘汰算法
;//L4-bit[15]:对于ARM版本5以上的处理器,用于兼容以前的ARM版本的功能
;// 0 保持当前ARM的正常的功能
mrc p15,0,r0,c1,c0,0
bic r0,r0,#R1_A
mcr p15,0,r0,c1,c0,0
MOV_PC_LR
;//使能/禁止存储器对齐功能
相关文档
最新文档