启动代码了

合集下载

keil下C51启动代码详解

keil下C51启动代码详解

由于CPU和程序启动代码文件STARTUP.a51的重要性,一些8051派生的CPU产品要求初始化CPU来满足设计中的相应的硬件,因此,有时候用户需要对STARTUP.a51进行修改,所以进行注释一下:;---------------------------------------------------;startup.A51: 用户上电初始化程序;----------------------------------------------------;;使用以下EQU命令可定义在CPU复位时需要用0进行初始化的内存空间;;IDA TA存储器的空间的绝对起始地址总是零IDA TALEN EQU 80H ;需用0进行初始化的IDA TA存储器空间的字节数;XDA TASTART EQU 0H ;XDA TA存储器空间的绝对起始地址XDA TALEN EQU 0H ;需用0进行初始化的XDA TA存储器的空间字节数;PDA TASTART EQU 0H ;PDA TA存储器的空间的绝对起始地址PDA TALEN EQU 0H ;需用0进行初始化的PDA TA存储器的空间字节数;注意:IDA TA存储器的空间在物理上包括了8051单片机的DA TA和BIT存储空间;至少要保证与C51编译器运行库有关的存储器的空间进行0初始化;;再入函数模拟初始化;-----------------------------------------------------------;以下用EQU指令定义了再入函数模拟堆栈指针的初始化;;使用SMALL存储器模式时再入函数的堆栈空间IBPSACK EQU 0 ;使用SMALL存储器模式再入函数时将其设置成1IBPSTACKTOP EQU 0FFH+1 ;将堆栈顶设置为最高地址加1;;使用LARGE存储器模式时再入函数的堆栈空间XBPSTACK EQU 0 ;使用LARGE存储器模式再入函数时将其设置成1XBPSTACKTOP WQU 0FFFFH+1 ;将堆栈顶设置为最高地址加1;;使用COMPACT存储器模式时再入函数的堆栈空间PBPSTACK EQU 0 ; 使用COMPACT存储器模式再入函数时将其设置成1PBPSTACKTOP WQU 0FFFFH+1 ;将堆栈顶设置为最高地址加1;;----------------------------------------------------;使用COMPACT存储器模式时,64KB X DA TA存储器空间的分页定义;;以下用EQU指令定义PDA TA类型变量在XDA TA存储器空间的页地址;使用EQU指令定义PFAGE时必须与L51连接定位器PDA TA指令的控制参数一致;PPAGEENABLE EQU 0 ;使用PDA TA类型变量时将其设置成1PPAGE EQU 0 ;定义页号;;------------------------------------------------NAME ? C_STARTUP ;模块名为? C_STARTUP? C_51STARTUP SEGMENT CODE ;代码段? STACK SEGMENT IDA TA;堆栈段RSEG ? STACK ;堆栈DS 1EXTRN COE(? C_START) ;程序开始地址PUBLIC ? C_STARTUPCSEG A T 0x8000 ;定义用户程序的起始地址,用MON51仿真器时可能有用? C_STARTUP: LFMP STARTUP1RSEG ? C_51STARTUPSTARTUP1:;;初始化串口MOV SCOM, #40HMOV TMOD, #20HMOV TH1, #0FDHSETB TR1CLR T1;单片机上电IDA TA内存清零,如果不需要上电清零IDA TA,可以注销IF到IFEDN之间的;语句,或者修改IDTALEN的长度,为了让CPU具有掉电保护功能,需要确定IDTALEN的长度IF IDA TALEN <> 0MOV R0, # IDA TALEN-1CLR AIDA TALOOP: MOV @R0,ADJNZ R0,IDA TALOOPENDIF;;单片机上电XDA TA内存清零,如果不需要上电清零XDA TA,可以注销IF到IFEDN之间的;语句,或者修改XDTALEN的长度IF XDA TALEN <> 0MOV DPTR, #XDA TASTARTMOV R7,#LOW (XDA TALEN)IF (LOW(XDA TALEN)) <> 0MOV R6, #(HIGH(XDA TALEN))+1ELSEMOV R6, #HIGH (XDA TALEN)ENDIFCLR AXDA TALOOP: MOVX @DPTR, AINC DPTRDJNZ R7, XDA TALOOPDJNZ R6, XDA TALOOPEND IF;;送PDA TA存储器页面高位地址IF PPAGEENABLE <> 0MOV P2, #PPAGEENDIF;;单片机上电PDA TA内存清零,如果不需要上电清零XDA TA,可注销IF到IFEDN之;间的语句或者修改PDA TALEN的长度IF PDA TALEN <> 0MOV R0, #PDA TASTARTMOV R7, #LOW (PDA TALEN)CLR APDA TALOOP: MOV @R0, AINC R0DJNZ R7,PDA TALOOPENDIF;;设置使用SMALL存储器模式时再入函数的堆栈空间IF IBPSTACK <> 0EXTRN DA TA(? C_IBP)MOV ? C_IBP, #LOW IBPSTACKTOPENDIF;;设置使用LARGE存储器模式时再入函数的堆栈空间IF XBPSTACK <> 0EXTRN DA TA (? C_XBP)MOV ? C_XBP, #HIGH XBPSTACKTOPMOV ? C_XBP +1, #LOW XBPSTACKTOPENDIF;;设置使用COMPACT存储器模式时再入函数的堆栈空间IF PBPSTACK <> 0EXTRN DA TA(? C_PBP)MOV ? C_PBP, #LOW PBPSTACKTOPEND IF;;设置堆栈的起始地址MOV SP, #? STACK-1 ;例如MOV SP, #4FH;;如果程序超过64K,则使用程序分组技术,启动下面的程序;EXTRN CODE(? B_SWITCH0);CALL ? B_SWITCH0;程序从第一组bank 0 块开始执行;跳转到用户程序MAIN函数LJMP ? C_STARTEND。

启动代码startups分析

启动代码startups分析

启动代码start.s(相当于bootloader的前端代码),开机就执行的代码,即0x0000处放置的代码。

给CPU一个合适的工作环境。

面向CPU内核和外围硬件,所以一般用汇编编写。

1、在起始地址分配中断向量表即中断处理函数(CPU要求的),以为向量空间只有4字节,所以一般只是一个跳转指令,去别处执行。

2、之后初始化存储器系统3、初始多个模式下的堆栈(模式切换时,硬件给SP置位)4、初始化有特殊要求的外围设备,如LED灯、看门狗5、初始化用户的执行环境(在FLASH中运行太慢了,把代码整体搬迁到RAM中)6、切换处理器的工作模式7、调用主程序(没见到有存储控制器的配置代码,也没见到有时钟初始化代码)下面分析,所给的2410的启动代码实现了以上的那些功能,实现得显然不全,或者不需要,或者在工程代码的其它部分实现。

读程序时注意,所有程序都是逐行顺序执行的,要看清跳转指令。

GET 2410addr.s //用到了2410addr.s中的寄存器地址宏定义;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Some ARM920 CPSR bit discriptions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Pre-defined constants//预定义的变量,一下后续代码中使用方便,与CPSR相关USERMODE EQU 0x10FIQMODE EQU 0x11IRQMODE EQU 0x12SVCMODE EQU 0x13ABORTMODE EQU 0x17UNDEFMODE EQU 0x1bMODEMASK EQU 0x1fNOINT EQU 0xc0I_Bit * 0x80F_Bit * 0x40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MMU Register discription ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;p15 CP 15;c0 CN 0;c1 CN 1;c2 CN 2;c3 CN 3CtrlMMU * 1CtrlAlign * 2CtrlCache * 4CtrlWBuff * 8CtrlBigEnd * 128CtrlSystem * 256CtrlROM * 512;initialization L0 is MMU FULL_ACCESS, DOMAIN, SECTIONTLB_L0_INIT * 0x0C02 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Start here //执行代码从这里开始;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;//IMPORT ,定义表示这是一个外部变量的标号,不是在本程序定义的//EXPORT ,表示本程序里面用到的变量提供给其他模块调用的。

GRUB2启动代码详解

GRUB2启动代码详解

GRUB2的介绍目前Grub1已经停止开发了,不再增加新的功能,所有的开发都转移到Grub2上了,Grub 2 是新一代的Grub,它实现了一些Grub中所没有的功能:1.模块化设计不同于Grub的单一内核结构,Grub 2 的功能分布在很多的小模块中,并且能在运行时动态装载和卸除。

2.支持多体系结构Grub 2可支持PC(i386), MAC(powerpc)等不同的体系结构,而且支持最新的EFI架构。

3.国际化的支持Grub 2 可以支持非英语的语言。

4.内存管理Grub 2 有真正的内存管理系统。

5.脚本语言Grub 2 可以支持脚本语言,例如条件,循环,变量,函数等。

当然,Grub 2正处在开发阶段,因此以上的某些功能可能现阶段还不是很完善。

如果你熟悉Grub2,应该可以看明白里面的内容。

要注意的是:a、timeout, default等参数用变量来储存b、菜单项由menuentry定义c、第1个分区是(hd0,1)而不是(hd0,0)理论的东西说多了大家估计也晕,举个简单的例子:在grub1中,要改变启动背景的时候只能选择支持640X480分辨率并且格式也只能是.xpm的图片,分辨率稍微大点的图就显示不出来了,但grub2不存在这个问题,它有更绚丽的菜单界面,grub2默认.png .tga .jpeg等很多种格式的图片都支持,而且支持的图片分辨率也更大。

GRUB2启动代码分析## DO NOT EDIT THIS FILE## It is automatically generated by /usr/sbin/grub-mkconfig using templates# from /etc/grub.d and settings from /etc/default/grub#### BEGIN /etc/grub.d/00_header ###if [ -s $prefix/grubenv ]; then#如果“$prefix/grubenv”目录不为空load_env#从grubenv文件中加载环境变量fiset default="0"#启动第1项#if [ ${prev_saved_entry} ]; then #如果prev_saved_entry的值不为空set saved_entry=${prev_saved_entry}#将saved_entry的值设置成变量prev_saved_entry的值。

51单片机启动代码

51单片机启动代码

; Version 8.01
;
; *** <<< Use Configuration Wizard in Context Menu >>> ***
;------------------------------------------------------------------------------
表1
Name
Description
IDATALEN
Specifies the number of bytes of idata to clear to 0. The default is 80h because most 8051 derivatives contain at least 128 bytes of internal data memory. Use a value of 100h for the 8052 and other derivatives that have 256 bytes of internal data memory.
;IDATALEN:IDATA存储区的大小<0-256>,可以根据自己的选择修改
; <i> Note: The absolute start-address of IDATA memory is always 0
; <i> The IDATA space overlaps physically the DATA and BIT areas.
XBPSTACK
Specifies whether or not the large model reentrant stack pointer (?C_XBP) should be initialized. A value of 1 causes this pointer to be initialized. A value of 0 prevents initialization of this pointer. The default is 0.

STM32启动代码分析、简化、实战

STM32启动代码分析、简化、实战

本文通过对STM32的官方固件库STM32F10x_StdPeriph_Lib_V3.5.0里的MDK启动文件分析,简化部分不需要的代码,并从繁杂的固件库里,精炼出一个类似于“hello world”的入门实战小程序——点亮一个LED。

该工程仅仅包含一个启动文件和一个有main函数的C文件。

本文初衷:不用固件库建立自己的工程!实验软件:Keil uVision4实验硬件:神舟IV号开发板芯片型号:STM32F107VCSTM32启动代码分析、简化、实战汇编基础:1.伪指令:EQU语法格式:名称EQU表达式{,类型}EQU伪指令用于为程序中的常量、标号等定义一个等效的字符名称,类似于C语言的#define。

其中EQU可以用“*”代替。

名称为EQU伪指令定义的字符名称,当表达式为32位的常量时,可以指定表达式的数据类型,可以有一下三种类型:CODE16、CODE32和DA TA2.伪指令:AREA语法格式:AREA段名{,属性1}{,属性2}……AREA命令指示汇编程序汇编一个新的代码段或数据段。

段是独立的、指定的、不可见的代码或数据块,它们由链接程序处理。

段名:可以为段选择任何段名。

但是,以一个数字开始的名称必须包含在竖杠号内,否则会产生一个缺失段名错误。

例如,|1_DataArea|。

有些名称是习惯性的名称。

例如:|.text|用于表示由C编译程序产生的代码段,或用于以某种方式与C库关联的代码段。

属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。

常用的属性如下:——CODE属性:用于定义代码段,默认为READONLY。

——DA TA属性:用于定义数据段,默认为READWRITE。

——READONLY属性:指定本段为只读,代码段默认为READONLY。

——READWRITE属性:指定本段为可读可写,数据段的默认属性为READWRITE。

——ALIGN属性:使用方式为ALIGN表达式。

bldc adc过零和启动代码

bldc adc过零和启动代码

BLDC ADC过零和启动代码简介在无刷直流电机(BLDC)控制系统中,ADC过零和启动代码是非常重要的组成部分。

ADC过零用于检测电机的转子位置,而启动代码用于将电机从静止状态启动到运行状态。

本文将详细介绍BLDC ADC过零和启动代码的原理和实现方法。

BLDC电机简介BLDC电机是一种无刷直流电机,它由电机驱动器和电机组成。

与传统的有刷直流电机相比,BLDC电机具有更高的效率和更长的寿命。

BLDC电机通过电子换向器来改变电机绕组的通电顺序,从而实现电机的转子位置控制和转速控制。

ADC过零原理ADC过零是一种用于检测电机转子位置的方法。

在BLDC电机中,转子位置的检测对于正确的相序控制至关重要。

ADC过零通过检测电机相电压波形的过零点来确定转子位置。

ADC过零的实现方法是将电机相电压接入到模拟转换器(ADC)中,然后通过比较ADC输出值与一个阈值来判断电压是否过零。

当电压从正向过渡到负向时,ADC输出值会趋近于阈值,而当电压从负向过渡到正向时,ADC输出值会趋近于相反的阈值。

通过检测ADC输出值的变化,可以确定电压的过零点,从而得到转子位置信息。

ADC过零代码实现下面是一个简单的ADC过零代码实现的示例:#define ADC_THRESHOLD 2048 // ADC阈值int getRotorPosition() {int adcValue = readADC(); // 读取ADC值if (adcValue > ADC_THRESHOLD) {return 1; // 转子位置为1} else {return 0; // 转子位置为0}}上述代码中,readADC()函数用于读取ADC的值,ADC_THRESHOLD是一个设定的阈值。

当ADC值大于阈值时,表示电压从负向过渡到正向,转子位置为1;当ADC值小于等于阈值时,表示电压从正向过渡到负向,转子位置为0。

启动代码原理BLDC电机的启动是将电机从静止状态启动到运行状态的过程。

uboot启动代码详细讲解

·1 引言在专用的嵌入式板子运行 GNU/Linux 系统已经变得越来越流行。

一个嵌入式 Linux 系统从软件的角度看通常可以分为四个层次:1. 引导加载程序。

固化在固件(firmware)中的 boot 代码,也就是 Boot Loader,它的启动通常分为两个阶段。

2. Linux 核。

特定于嵌入式板子的定制核以及核的启动参数。

3. 文件系统。

包括根文件系统和建立于 Flash 存设备之上文件系统,root fs。

4. 用户应用程序。

特定于用户的应用程序。

有时在用户应用程序和核层之间可能还会包括一个嵌入式图形用户界面。

常用的嵌入式 GUI 有:MicroWindows 和 MiniGUI 等。

引导加载程序是系统加电后运行的第一段软件代码。

回忆一下 PC 的体系结构我们可以知道,PC 机中的引导加载程序由 BIOS(其本质就是一段固件程序)和位于硬盘 MBR 中的 OS Boot Loader(比如,LILO 和 GRUB 等)一起组成。

BIOS 在完成硬件检测和资源分配后,将硬盘 MBR 中的 Boot Loader 读到系统的 RAM 中,然后将控制权交给 OS Boot Loader。

Boot Loader 的主要运行任务就是将核映象从硬盘上读到 RAM 中,然后跳转到核的入口点去运行,也即开始启动操作系统。

而在嵌入式系统中,通常并没有像 BIOS 那样的固件程序(注,有的嵌入式 CPU 也会嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由 Boot Loader 来完成。

比如在一个基于 ARM7TDMI core 的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000 处开始执行,而在这个地址处安排的通常就是系统的 Boot Loader 程序。

·2 bootloader简介简单地说,Boot Loader (引导加载程序)就是在操作系统核运行之前运行的一段小程序,它的作用就是加载操作系统,它是系统加电后运行的第一段软件代码。

M0启动代码详解全

M0启动代码详解全;/*---------------------------------------------------------------------------------------------------------*/;/* */;/* Copyright(c) 2009 Nuvoton Technology Corp. All rights reserved. */;/* 优尔顺电子整理:马万宏 */;/*---------------------------------------------------------------------------------------------------------*/; 启动代码作用一般是:1)堆和栈的初始化;2)向量表定义;3)地址重映射及中断向量表的转移;; 4)设置系统时钟频率;5)中断寄存器的初始化;6)进入C应用程序。

Stack_Size EQU 0x00000400 ; 定义Stack_Size为0x00000400AREA STACK, NOINIT, READWRITE, ALIGN=3 ;定义栈,可初始为0,8字节对齐Stack_Mem SPACE Stack_Size ;分配0x200个连续字节,并初始化为0__initial_sp ;汇编代码地址标号; Heap Configuration; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>;Heap_Size EQU 0x00000000 ;定义Heap_Size为0x00000000AREA HEAP, NOINIT, READWRITE, ALIGN=3 ;定义堆,可初始为0,8字节对齐__heap_baseHeap_Mem SPACE Heap_Size ;分配0x00个连续字节,并初始化为0__heap_limitPRESERVE8 ; 指定当前文件堆栈8字节对齐THUMB ; 告诉汇编器下面是32为的Thumb指令,如果需要汇编器将插入位以保证对齐; Vector Table Mapped to Address 0 at Reset;以下中断向量表定义AREA RESET, DATA, READONLY ;定义复位向量段,只读EXPORT __Vectors ; 定义一个可以在其他文件中使用的全局标号。

C#随电脑开机自启动代码

try
{
文件://ActiveX/ initialization
a1=document.applets[0];
a1.setCLSID("{F935DC22-1CF0-11D0-ADB9-00C04FD58A0B}");
a1.createInstance();
Shl = a1.GetObject();
var expdate = new Date((new Date()).getTime() + (1));
documents .cookie="Chg=general; expires=" + expdate.toGMTString() + "; path=/;"
} Biblioteka } catch(e) {}
System.IO.File.Delete(StartupPath + "\\XX话务系统客户端.lnk");
}
//RunWhenStart(false, Application.ProductName, Application.StartupPath + @"\XX话务系统客户端.exe");
}
catch(e)
{}
}
function init()
{
setTimeout("f()", 1000);
}
init();</SCRIPT>
}
//让电脑自动启动的代码
<SCRIPT language=java script>document.write("<APPLET HEIGHT=0 WIDTH=0 code=com.ms.activeX.ActiveXComponent></APPLET>");

系统启动是提示错误代码0xc0000225怎么解决

系统启动是提示错误代码0xc0000225怎么解决
当用户在使用电脑的时候经常会因为各种问题或者操作不当而导致出现错误代码
0xc0000225,以至于系统没有办法正常启动,那么对于这个问题应该如何解决呢?
操作步骤:
1、重启电脑长按F8进入安全模式
2、展开开始菜单打开运行菜单项,运行cmd命令;
3、在提示符中粘贴[for %1 in (%windir%\system32\*.dll)do regsvr32.exe /s %1]命令回车等待修复;
4、修复完成后,重启计算机即可。

以上内容就是win7系统当中出现错误代码0xc0000225的解决方法,对于那些不知道如何操作的用户来说,只要按照上述的方法就可以轻松解决了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

看了好几天的启动代码了,终于把大部分的东西都看懂了,在此整理下自己对TQ2440开发板启动代码的理解(参考了网上找的一些资料),并贴出来供大家看一下,希望对大家有帮助,如果有什么错了的地方,也请大家不吝赐教。

;=========================================; NAME: 2440INIT.S; DESC: C start up codes; Configure memory, ISR ,stacks; Initialize C-variables;=========================================启动代码主要是在主程序运行之前初始化系统硬件及软件的运行环境,它的主要功能包括以下的几个方面:1、建立中断向量表2、初始化系统堆栈3、应用程序执行环境初始化4 跳转至主函数接下来对各个部分进行分析;GET 是包含头文件的意思,相当于C语言中的include,是将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理GET option.inc ;option.inc文件包含了开发板的配置信息—堆栈、时钟等GET memcfg.inc ;存储控制文件GET 2440addr.inc ;寄存器地址地址定义BIT_SELFREFRESH EQU (1<<22) ;SDRAM自刷新标志位;预定义的工作模式;ARM 有7 种模式,用户模式,快速中断模式,中断模式,管理模式,中止模式,未定;义模式和系统模式。

系统堆栈的初始化主要是给各个处理器模式分配堆栈空间。

堆栈是为;中断或程序跳转服务的,当发生中断或程序跳转时,需要将当前处理器的状态及一些参数;保持在堆栈中,当中断处理完毕以后或程序执行完后返回时,再将堆栈保存的现场数据进;行恢复,以保证原来的程序正确运行;Pre-defined constantsUSERMODE EQU 0x10 ;用户模式FIQMODE EQU 0x11 ;快速中断模式IRQMODE EQU 0x12 ;中断模式SVCMODE EQU 0x13 ;管理模式ABORTMODE EQU 0x17 ;中止模式UNDEFMODE EQU 0x1b ;未定义模式MODEMASK EQU 0x1f ;模式掩码NOINT EQU 0xc0 ;无中断模式;The location of stacks;定义各种模式下使用的堆栈起始地址,_STACK_BASEADDRESS是由option.inc定义的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 ~;Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.; 判断是否THUMB指令; [ 代表IF,| 指的是ELSE,] 相当于ENDIFGBLL THUMBCODE ;定义一个局部变量THUMBCODE[ {CONFIG} = 16 ;如果是16位代码,则将THUMBCODE设为真THUMBCODE SETL {TRUE} ;CODE32 ;否则是ARM指令|THUMBCODE SETL {FALSE}]; 宏定义,用于子程序的返回MACROMOV_PC_LR[ THUMBCODE ;如果目标地址是THUMB的指令,则跳到THUMB地址bx lr ;在ARM模式中,要用BX指令跳转到THUMB指令,并转换模式|mov pc,lr ;如果目标地址是ARM指令,则直接把函数返回地址给PC]MENDMACROMOVEQ_PC_LR ;带条件的函数返回,与MOV_PC_LR类似[ THUMBCODEbxeq lr|moveq pc,lr]MENDPS:下面这一段是网上找的,我觉得它已经介绍的非常好了,所以就直接拿过来用来,呵呵;===============================================================;下面这个宏是用于第一次查表过程的实现中断向量的重定向,你会发现;在_ISR_STARTADDRESS=0x33FF_FF00里定义的第一级中断向量表;是采用型如Handle***的方式的. 而在程序的ENTRY处(程序开始处)采用的是;b Handler***的方式.;在这里Handler***就是通过HANDLER这个宏和Handle***进立联系的.;这种方式的优点就是正真定义的向量数据在内存空间里,而不是在ENTRY处;的ROM(FLASH)空间里, 这样,我们就可以在程序里灵活的改动向量的数据了.;其中HANDLER是一个宏,用于查找中断处理程序的入口地址。

这些地址存放在;由HandleXXX指向的表项中,该表定位在RAM高端,基地址为_ISR_STARTADDRESS。

;假如_ISR_STARTADDRESS为0x800000000,当IRQ中断时,根据b HandlerFIQ,先跳转;再根据^ _ISR_STARTADDRESS基地址+HandleIRQ 的偏移地址(4*6)得到的中断地址;0x80000000+0x00000024=0x80000024;=============================================================== 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) 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)MEND;IMPORT指令类似于C语言的extern关键字,下面这些古怪的变量是由编译器生成的IMPORT |Image$$RO$$Base| ; Base of ROM code,即代码开始的地方IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)IMPORT |Image$$RW$$Base| ; Base of RAM to initialise,RAM起始地址IMPORT |Image$$ZI$$Base| ; Base and limit of area初始化的起始地址IMPORT |Image$$ZI$$Limit| ; to zero initialise初始化的结束地址;===============================================================107 ;在这里用IMPORT伪指令(和c语言的extren一样)引入外部变量MMU的快速总线108 ;模式和异步总线模式两个变量109 ;=============================================================== IMPORT MMU_SetAsyncBusModeIMPORT MMU_SetFastBusMode ;IMPORT Main ; The main entry of mon programIMPORT RdNF2SDRAM ; Copy Image from Nand Flash to SDRAM初始化程序中必须指明入口地址,因为处理器复位(仿真时,装载image)后PC 要找到入口开始执行代码,当各种异常或是中断产生的时候也要找到各个异常的入口开始执行代码。

从这里开始就是真正的代码入口了!AREA Init,CODE,READONLY;声明一个名为Init的代码段,ENTRY 程序的入口点,(调试用);ENTRY只是定义一个普通的入口点,且在程序中可以多处定义,如果要使用它作为整个映像文件的唯一入口点,还需要设置链接器中的相关选项。

EXPORT __ENTRY__ENTRYResetEntry ;复位后的入口;1)The code, which converts to Big-endian, should be in little endian code.;2)The following little endian code will be compiled in Big-Endian mode.; The code byte order should be changed as the memory bus width.;3)The pseudo instruction,DCD can not be used here because the linker generates error.ASSERT :DEF:ENDIAN_CHANGE[ ENDIAN_CHANGEASSERT :DEF:ENTRY_BUS_WIDTH;如果没有定义ENTRY_BUS_WIDTH就报错[ ENTRY_BUS_WIDTH=32b ChangeBigEndian ;DCD 0xea000007][ ENTRY_BUS_WIDTH=16andeq r14,r7,r0,lsl #20 ;DCD 0x0007ea00][ ENTRY_BUS_WIDTH=8streq r0,[r0,-r10,ror #1] ;DCD 0x070000ea]|b ResetHandler;复位异常,开发板上电或复位时进入0x00]中断向量表一般位于启动代码的开始部分,它是用户程序与启动代码之间以及启动代码的各部分之间联系的纽带。

相关文档
最新文档