当前位置:首页 > 单片机 > 单片机
[导读]先说明一下在加电之前的这个软硬件情况,这个三星公司根据ARM920T软核生产的这个s3c2410集成了64M的sdram和64M的nandflash存储器。Vivi和UCOS都存储在这个nandflash中,因为nandflash断电后不会丢失信息。这个VIVI是

先说明一下在加电之前的这个软硬件情况,这个三星公司根据ARM920T软核生产的这个s3c2410集成了64M的sdram和64M的nandflash存储器。Vivi和UCOS都存储在这个nandflash中,因为nandflash断电后不会丢失信息。这个VIVI是三星公公司为ARM系列芯片书写的bootloader,用于开发阶段,做系统的引导程序。

VIVI存放在flash 0x00000000地址开始的地方,UCOS存放在flash 0x03f30000地址开始的地方。ARM920T开机从flash启动,启动时把flash前4K (即vivi的前4K)COPY到SDRAM(这种启动方式是利用Nandflash启动,COPY前4K到sdram中是硬件自动实现的),vivi的前4K 代码中有用于COPY剩余VIVI的代码。执行完这些代码之后,VIVI就控制了FLASH的读取,串口的控制以及用户shell接口,当然它还有其他一些功能。当用户执行bootucos命令时,VIVI会把ucos相关代码从flash 0x03f30000 COPY到SDRAM0x30008000的地方。当然也可以设置VIVI自动引导ucos执行。当代码copy完毕后,vivi会把PC值改成0x30008000去执行。

我们先说一下为什么我们非要说具体的那个地址那,咱们前面说了,编译好的程序有一个load地址,一个真正运行的地址,0x30008000这个地址就是咱们说的程序的装载地址,这个地址是我们用编译器指定的地址,也就是通过在ads工程里后缀名是scf的文件配置的。在这个文件里我们配置了程序的装载地址和程序运行的地址,我们为什么要指定这两个地址那?我们整个工程的程序是最后链接时一次性固定的绝对地址,也就是说最终链接出来的程序地址和真正运行的地址是一致的。只不过我们一般不会把这些代码直接放到相应的部位去罢了,其中一个原因就是,我们为了在不加电时保存程序会把程序放到非易失的存储设备里去,而我们运行时会把程序copy到运行速度比较快的sdram中去。也就是说,本来这些静态链接的程序的执行地址都是固定的了,我们要在这些程序运行之前要把这些程序放对位置。我们必须知道我们的程序装载到什么地址和真正在什么地址运行。这样我们才能知道那些装载地址和运行地址不一样的程序段应该怎么搬运。至于搬运的工作,你可以自己手工实现,也可以用ADS提供的库函数实现。

跳转到这个0x30008000去执行这个地址处的指令,我们这个工程编译出来后谁是第一条指令那?我们平时写的程序都是从main()函数开始执行,但我们这个嵌入式的开发可不是哦,在分析完启动代码后你就知道了,在执行的所谓的main()函数之前要做很多工作的。

arm映像文件的入口点有两种类型:一种是映像文件运行时的入口点,称为初始入口点(initial entry point),另一种是普通入口点(entry point).
初始入口点是映像文件运行时的入口点,每个映像文件只有一个唯一的初始入口点,它保存在ELF头文件中。假如映像文件是被操作系统加载的,操作系统是通过跳转到该初始入口点处来加载该映像文件。
普通的入口点是在汇编中用ENTRY伪操作定义。他通常用于标志该段代码是通过异常中断处理程序进入的。这样连接器删除无用的段时不会将该段代码删除。一个映像文件中可以定义多个普通入口点。
应该注重的是,初始入口点可以使普通入口点,但也可以不是普通入口点.

初始入口点必须满足下面两个条件:
1.初始入口点必须位于映像文件的运行时域内。
1.1饱含初始入口点的运行时域不能被覆盖,他的加载地址和运行地址必须是相同的。
可以使用连接选项-entry address来指定映像文件的初始入口点。这时,address指定了映像文件的初始入口点的地址值。对于地址0x0处为rom的嵌入式应用系统,可以使用-entry 0x0来指定映像文件的初始入口点。这样当系统复位后,自动跳转到该入口开始执行。假如映像文件是被一个加载器加载的,该映像文件该映像文件必须包含一个初始化入口点。这种映像文件通常还包含了其他普通入口点,这些普通入口点一般为异常中断处理程序的入口地址。
当用户没有指定-entry address时,连接器根据下面的规则决定映像文件的初始入口点。
假如输入的目标文件中只有一个普通入口点,该普通入口点被连接器当成映像文件的初始入口点。
假如输入的目标文件中没有一个普通入口点,或者其中的普通入口点多于一个,则连接器生成的映像文。

我们编译好的可执行文件时去除了头格式的映像文件,我们讲的本来就是操作系统,所以这个程序不是通过初始入口点执行的第一条指令,应该是通过普通入口点来执行的,通常是中断向量表。也就是程序中用伪指令entry指定的指令段的第一条指令。我们用ADS1.2打开ucos的学习资料的工程中的第十个实验(ucos系统移植实验)。在startup文件夹中有一个startup.s 的汇编程序,这个就是ucos的启动代码了。由ENTRY伪指令指定的第一条指令是b ColdReset,所以第一条指令就是它了。

咱先不管这个第一条指令的问题,我的目的是把我学习的UCOS讲述给你听,但这需要一定的讲述规范,希望我说的你能听懂,愿意看下去,我想这样做:

先从整体描述一下整个过程,然后在分阶段概括这一阶段整个硬件和软件系统干了什么?为什么会有这些顺序?为什么要这么干?在这个过程中可能思维随即发散到任何有关系的知识点。最后我将逐一分析源代码,在分析源代码时遇到的问题,都将解决,当然包括那些精华和美。还可能阐述一下我的理解和方法,以及我对学习的一些认识。我是想按照一定的规范去写这个东东,但是我又不想完全按照一种思路去写,毕竟我是随意书写的。我的整体思路就是针对硬件和软件在整个时间流里都干了什么?为什么要这么干为主要线路。在这个线路中涉及到的所有疑问和知识点都将一一展开阐述。我尽量做到自然,而不是强加给你一些生硬的概念,因为人不喜欢被。被学习,被干活,被记忆。

理解UCOS最好的方式是阅读其源代码,一本很好的参考书是嵌入式实时操作系统ucos-ii,邵贝贝译

声明:在写这个文档时,我还有很多地方没有真正弄明白,所以有些地方可能我也说不清楚,但我会把我的疑问写出来,我什么时候想明白了,我会把它写出来,如果你知道请你告诉我,我会很高兴的。

在说明一下现在的情况:现在ucos的所有代码(包括启动的bootloader)都被vivi copy到0x30008000的内存地址开始的地方了,然后PC值改为0x30008000,取出这个地址放的arm指令就开始执行这条指令了。前面已经分析完整个工程编译出来的可执行程序的第一条指令了。

好了,下面开始说整个班子以及UCOS的整体启动过程,只是大概的说明流程,至于会为什么这样的问题等到具体详解的时候在具体解释。

硬件初始化,主要是让硬件平台处于一个可知的状态,重要的一点就是初始化C语言运行环境。

UCOS初始化

UCOS运行并执行应用程序

哎 ,这样看的话,整个过程还真挺简单的,哈。

下面具体讲解硬件初始化阶段,这个就真的比较麻烦了,但没关系,咱们慢慢说。

从具体代码上看,它主要干了这些活:

关闭看门狗,(一个用于开发阶段的硬件,到代码讲解时具体说明)

屏蔽中断掩码寄存器(现在整个硬件平台的控制权都在UCOS,在初始化的时候,我们不希望被打扰,具体原因我们以后说)

初始化各个模式堆栈空间(堆栈空间很重要哦)

COPY中断向量表(关于为什么要copy,我们在后面说)

初始化c库环境

然后跳转到主应用程序(即我们平时说的main()函数)

下面这些代码是用汇编写的代码,其中分号后面的是注释。

下面就以具体代码为例,详细讲解启动代码。

每个代码块做一个说明,对于特别重要的代码,我在代码后面做详细注释。注释写在//后面,如果此处有很重要知识点的话,单独起一段进行说明。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;

;;; Copyright (c) 2004-2007 threewater@up-tech.com, All rights reserved.

;;;

;;; Startup Code for

;;; S3C2410 : Startup.s

;;;; by threewater 2005.2.22

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

GET 2410addr.s //引入2410addr.s文件里的内容,作用像是c语言里的#include一样。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; Some ARM920 CPSR bit discriptions

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Pre-defined constants

USERMODE EQU 0x10

FIQMODE EQU 0x11

IRQMODE EQU 0x12

SVCMODE EQU 0x13

ABORTMODE EQU 0x17

UNDEFMODE EQU 0x1b

MODEMASK EQU 0x1f

NOINT EQU 0xc0

I_Bit * 0x80

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

程序员入门进阶 我 们在刚写程序的时候,第一个都是 hello world。

关键字: C语言 main函数

最近项目开发需要用到ucos,之前有听说过,但没用过,之前一直从事的与Linux相关的开发工作,基于应用的学习,所以本文偏向于应用的认知,只具备以下的认知即可进行开发啦,OS,其实都差不多。    本文只是个人学习uco...

关键字: ucos

  引言   汽车的普及为人们的生活带来了方便,同时也给人们提出了一大难题——汽车防盗。本设计是为了解决以往汽车防盗产品的缺点和不足而开发的集成传感、报警和远程图

关键字: 数据采集 操作系统 s3c2410 汽车防盗系统

  引言   巡航控制系统(CCS)是20世纪60年代发展起来的,又称为恒速行驶系统。巡航控制系统工作时,ECU根据各种传感器输送来的信号判断汽车的运行状况,通过执行元件自动调节节气门的

关键字: ARM 三星 Linux ecu s3c2410 电子控制系统

  在过去一百年里(l906-2005),全球地表平均温度升高了0.74摄氏度,未来20年,每十年全球温度将会升高0.2摄氏度。气候变暖已成为不容忽视的、直接影响全球生产和生活问题。  

关键字: can总线 s3c2410

  在此设计的基于 GPRS 的远程安防监控系统,是采用的是摄像机传送视频信号经压缩编码后,通过内部总线传送到内置的 Web 服务器。用户在监控端可以直接通过浏览器观看 Web服务器上的摄像机视

关键字: GPRS s3c2410 安防监控

C语言标准在一开始(C90标准 5.1.2条),就规定了程序的执行环境。对于没有操作系统的环境来说,C程序的入口函数是什么都可以(也就是说的在单片机的C程序里,或者在操作系统的底层代码的C入口处,不需要是main函数)。

关键字: C语言 main函数 基础教程 基础知识

网上介绍LINUX下的一般驱动程序开发示例浩如烟海,或是因为简单,关于DMA驱动的介绍却寥寥无几;近期zhaoyang因工作需要,花了几日时间开发了某设备在S3C2410处理器Linux下DMA通信的驱动程序,有感于刚接...

关键字: Linux s3c2410 dma驱动

1引言目前 , 在嵌入式系统里基于ARM核的嵌入式处理器已经成为市场主流。随着ARM技术的广泛应用 , 建立面向ARM构架的嵌入式操作系统也就成为当前研究的热点。S3C2410是SAMSUNG公司基于ARM920T处理器...

关键字: s3c2410 移植 标准linux

一、S3C2410支持4种供电模式(1)NORMAL MODE耗电最大、可以通过关闭具体控制器的时钟来节电(2)SLOW MODE在此模式下可以没有内部PLL,耗电情况依赖于外部时钟的频率(3)IDLE MODEFCLK...

关键字: s3c2410 电源管理
关闭
关闭