<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title><![CDATA[缘份天空]]></title>
<link>http://www.zjidea.com/blog/</link>
<description><![CDATA[记录我生活与工作中的点滴]]></description>
<language>zh-cn</language>
<copyright><![CDATA[Copyright 2005 PBlog3 v2.8]]></copyright>
<webMaster><![CDATA[lzq0323@yahoo.com.cn(相逢萍水)]]></webMaster>
<generator>PBlog2 v2.4</generator> 
<image>
	<title>缘份天空</title>
	<url>http://www.zjidea.com/blog/images/logos.gif</url>
	<link>http://www.zjidea.com/blog/</link>
	<description>缘份天空</description>
</image>

			<item>
			<link>http://www.zjidea.com/blog/article/arm/2010-02-11_arm3.htm</link>
			<title><![CDATA[S3C2410启动代码详解(3)]]></title>
			<author>lzq0323@yahoo.com.cn(相逢萍水)</author>
			<category><![CDATA[ARM编程]]></category>
			<pubDate>Thu,11 Feb 2010 11:12:31 +0800</pubDate>
			<guid>http://www.zjidea.com/blog/default.asp?id=468</guid>
		<description><![CDATA[;================================================================================<br/>; ENTRY&nbsp;&nbsp;系统上电后经过一个b ResetHandler就跳转到此处来。在此完成一些相关的软硬件配置工作<br/><br/>1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;屏蔽所有中断，关看门狗。 <br/>2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;根据工作频率设置PLL寄存器 <br/>3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;初始化存储控制相关寄存器 <br/>4.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;初始化各模式下的栈指针 <br/>5.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;设置缺省中断处理函数 <br/>6.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将数据段拷贝到RAM中，将零初始化数据段清零 <br/>7.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;跳转到C 语言Main入口函数中 <br/>;================================================================================<br/>ResetHandler<br/> ldr r0,=WTCON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;watch dog disable 关看门狗<br/> ldr r1,=0x0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/> str r1,[r0]<br/><br/> ldr r0,=INTMSK<br/> ldr r1,=0xffffffff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;all interrupt disable屏蔽所有中断<br/> str r1,[r0]<br/><br/> ldr r0,=INTSUBMSK<br/> ldr r1,=0x3ff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;all sub interrupt disable屏蔽所有子中断<br/> str r1,[r0]<br/><br/> [ {FALSE}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//;是得有些表示了,该点点LED灯了,不过被FALSE掉了. <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; rGPFDAT = (rGPFDAT &amp; ~(0xf&lt;&lt;4)) | ((~data &amp; 0xf)&lt;&lt;4);&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; Led_Display<br/> ldr r0,=GPFCON<br/> ldr r1,=0x5500&nbsp;&nbsp;<br/> str r1,[r0]<br/> ldr r0,=GPFDAT<br/> ldr r1,=0x10<br/> str r1,[r0]<br/> ]<br/> <br/> ;To reduce PLL lock time, adjust the LOCKTIME register. 为了减少PLL的lock time, 调整LOCKTIME寄存器. <br/> ldr r0,=LOCKTIME&nbsp;&nbsp;&nbsp;&nbsp; //LOCKTIME为锁定计数定时器，即设置PLL稳定过渡时间，一般大于150uS<br/> ldr r1,=0xffffff<br/> str r1,[r0]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/><br/>；=================================================================================<br/><br/>上电复位时的时钟行为。晶振在几毫秒内开始振荡。当OSC时钟稳定后，PLL根据默认PLL设置开始生效，但是通常这个时候是不稳定的，因此在软件重新配置PLLCON寄存器之前FCLK直接使用Fin而不是MPLL，即使用户不希望改变PLLCON的默认值，用户也应该执行一边写PLLCON操作。<br/><br/>;这里介绍一下计算公式<br/>;Fpllo=(m*Fin)/(p*2^s)<br/>;m=MDIV+8,p=PDIV+2,s=SDIV<br/>;Fpllo必须大于20Mhz小于66Mhz<br/>;Fpllo*2^s必须小于170Mhz<br/>;如下面的PLLCON设定中的M_DIV P_DIV S_DIV是取自option.h中M_DIV=0x5c=92 P_DIV=0x4&nbsp;&nbsp;S_DIV=0x2<br/><br/>所以Fpllo=(m*Fin)/(p*2^s)=（92+8）*12M/（4+2）*2^2=50M<br/><br/><br/>；==================================================================================&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp; [ PLL_ON_START<br/> ;Configure MPLL<br/> ldr r0,=MPLLCON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//M_DIV=0x5c=92 P_DIV=0x4&nbsp;&nbsp;S_DIV=0x2<br/> ldr r1,=((M_MDIV&lt;&lt;12)+(M_PDIV&lt;&lt;4)+M_SDIV)&nbsp;&nbsp;;Fin=12MHz,Fout=50MHz<br/> str r1,[r0]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;Configure UPLL<br/> ldr r0,=UPLLCON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/> ldr r1,=((U_MDIV&lt;&lt;12)+(U_PDIV&lt;&lt;4)+U_SDIV)&nbsp;&nbsp;;Fin=12MHz,UPLLout=48MHz<br/> str r1,[r0]<br/> ]<br/><br/> ;Check if the boot is caused by the wake-up from POWER_OFF mode.<br/> ldr r1,=GSTATUS2<br/> ldr r0,[r1]<br/> tst r0,#0x2<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;In case of the wake-up from POWER_OFF mode, go to POWER_OFF_WAKEUP handler. <br/> bne WAKEUP_POWER_OFF<br/><br/> EXPORT StartPointAfterPowerOffWakeUp<br/>StartPointAfterPowerOffWakeUp<br/><br/> ；====================================================================================<br/><br/>//设置内存控制器等寄存器的值,因为这些寄存器是连续排列的,所以采用如下办法对这些 ;寄存器进行连续设置.其中用到了SMRDATA的数据,这在代码后面有定义 ;Set memory control registers<br/><br/>；=====================================================================================<br/><br/>ldr r0,=SMRDATA<br/> ldr r1,=BWSCON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;BWSCON Address<br/> add r2, r0, #52&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;End address of SMRDATA，共13个DCD，52个字节<br/>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/> ldr r3, [r0], #4&nbsp;&nbsp;&nbsp;&nbsp;<br/> str r3, [r1], #4&nbsp;&nbsp;&nbsp;&nbsp;<br/> cmp r2, r0&nbsp;&nbsp;<br/> bne %B0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //上面这段小程序将后面定义的数据复制到相关内存控制寄存器<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; ;Initialize stacks<br/> bl InitStacks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//调用堆栈初始化子程序<br/> ；==================================================================================<br/><br/>关于异常中断系统：异常中断矢量表（每个表项占4个字节） 下面是中断向量表 一旦系统运行时有中断发生 即使移植了操作系统 如linux 处理器已经把控制权交给了操作系统 一旦发生中断 处理器还是会跳转到从0x0开始<br/>;中断向量表中某个中断表项（依据中断类型）开始执行;具体中断向量布局请参考s3c44b0 spec 例如 adc中断向量为 0x000000c0下面对应表中第49项位置 向量地址0x0+4*(49-1)=0x000000c0<br/>2410异常中断系统中有两张中断转移表，经过二重转移才跳到中断处理程序。第一张中断向量表由硬件决定，所在区域为ROM（flash），地址空间从0X00开始，其中0X00-0X1C为异常向量入口地址。另一张中断向量表在RAM 中，可以随便改，其位置在程序连接后才定。ARM7的内核实际上只有8个（1个保留）异常向量，对于其他所有众多的中断源，ARM7 的内核是通过IRQ或FRQ 的软件查询中断状态寄存器的位来获得ISR的起始地址。<br/>；===================================================================================<br/>&nbsp;&nbsp; ; Setup IRQ handler&nbsp;&nbsp;//;设置缺省中断处理函数<br/> ldr r0,=HandleIRQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //;This routine is needed;//使用ldr伪指令装载HandleIRQ的地址到r0中<br/> ldr r1,=IsrIRQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//If there isn&#39;t &#39;subs pc,lr,#4&#39; at 0x18, 0x1c;//使用ldr伪指令装载IsrIRQ的地址到r1中<br/> str r1,[r0]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//把r1的值写到r0指向的存储地址中，把IsrIRQ这个函数的地址写入到HandleIRQ存储单元里面<br/><br/> <br/><br/>；======================================================================================<br/><br/> ;Copy and paste RW data/zero initialized data<br/><br/>//以下程序段将加载哉中的数据段RW拷贝到运行域的ram中 将ZI段中的零初始化数据段清零 <br/><br/>//跳入C语言的main函数执行到这步结束bootloader初步引导结束&nbsp;&nbsp;&nbsp;&nbsp;<br/><br/>程序先把 ROM 里|Image$$RO$$Limt|开始的 RW 初始数据拷贝到 RAM 里面|Image$$RW$$Base|开始的地址，当RAM这边的目标地址到达|Image$$ZI$$Base|后就表示RW区的结束和ZI区的开始，接下去就对这片ZI区进行清零操作，直到遇到结束地址|Image$$ZI$$Limit|。<br/><br/>；======================================================================================<br/> ldr r0, =|Image$$RO$$Limit|&nbsp;&nbsp;&nbsp;&nbsp; //Get pointer to ROM data，rom中的RW数据源的起始地址<br/> ldr r1, =|Image$$RW$$Base|&nbsp;&nbsp; //and RAM copyRW区在RAM里的执行区起始地址<br/> ldr r3, =|Image$$ZI$$Base|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//ZI区在RAM里面的起始地址<br/> <br/> ;Zero init base =&gt; top of initialised data检查装载地址和执行地址是否相同<br/> cmp r0, r1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; Check that they are different<br/> beq %F2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;//若相等则跳转到2,相同，则不拷贝该区间，初始化零数据区<br/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/> cmp r1, r3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; Copy init data;//如果r0不等于r1，r1和r3比较，Copy init data,不相同，将装载区拷贝到执行区<br/> ldrcc r2, [r0], #4&nbsp;&nbsp;&nbsp;&nbsp;;--&gt; LDRCC r2, [r0] + ADD r0, r0, #4&nbsp;&nbsp; 当无符号数r1&lt;r3时，读取r0地址处的内容&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/> strcc r2, [r1], #4&nbsp;&nbsp;&nbsp;&nbsp;;--&gt; STRCC r2, [r1] + ADD r1, r1, #4<br/> bcc %B1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;//若相等则跳转到1,相同，则不拷贝该区间，初始化零数据区<br/><br/>2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/> ldr r1, =|Image$$ZI$$Limit|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; Top of zero init segment，ZI区在RAM里面的结束地址后面的一个地址<br/> mov r2, #0<br/>3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/> cmp r3, r1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; Zero init<br/> strcc r2, [r3], #4&nbsp;&nbsp;&nbsp;&nbsp; //当ZI区的起始地址未达等于结束地址时，继续清0<br/> bcc %B3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;//当无符号数r3&lt;r1时,跳转到3处，这样做就完成了zi区的初始化清0<br/><br/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;[ :LNOT:THUMBCODE<br/>&nbsp;&nbsp;&nbsp;&nbsp; bl Main&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;Don&#39;t use main() because ......跳到Main()主函数，注意大小写<br/>&nbsp;&nbsp;&nbsp;&nbsp; b .&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;]<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;[ THUMBCODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;for start-up code for Thumb mode<br/>&nbsp;&nbsp;&nbsp;&nbsp; o&#114;r lr,pc,#1<br/>&nbsp;&nbsp;&nbsp;&nbsp; bx lr<br/>&nbsp;&nbsp;&nbsp;&nbsp; CODE16<br/>&nbsp;&nbsp;&nbsp;&nbsp; bl Main&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;Don&#39;t use main() because ......<br/>&nbsp;&nbsp;&nbsp;&nbsp; b .<br/>&nbsp;&nbsp;&nbsp;&nbsp; CODE32<br/>&nbsp;&nbsp;&nbsp;&nbsp;]<br/><br/><br/>;function initializing stacks<br/>InitStacks<br/> ;Don&#39;t use DRAM,such as stmfd,ldmfd......<br/> ;SVCstack is initialized before<br/> ;Under toolkit ver 2.5, &#39;msr cpsr,r1&#39; can be used instead of &#39;msr cpsr_cxsf,r1&#39;<br/> mrs r0,cpsr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;//读取CPSR的值，R0=CPSR,CPSR为当前程序状态寄存器<br/> bic r0,r0,#MODEMASK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;//R0=R0&amp;(~MODEMASK),MODEMASK=0X1F,也就是低五位清0<br/> o&#114;r r1,r0,#UNDEFMODE|NOINT&nbsp;&nbsp;;//R1=R0|(MODEMASK|NONINT),R1为未定义模式，也就是低八位为11X11011<br/> msr cpsr_cxsf,r1&nbsp;&nbsp;;UndefMode&nbsp;&nbsp; ;//写把R1的值写到状态寄存器cpsr_cxsf（也就是CPSR）,UndefMode<br/> ldr sp,=UndefStack&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;//设置未定义模式下的堆栈指针<br/> <br/> o&#114;r r1,r0,#ABORTMODE|NOINT<br/> msr cpsr_cxsf,r1&nbsp;&nbsp;;AbortMode<br/> ldr sp,=AbortStack<br/><br/> o&#114;r r1,r0,#IRQMODE|NOINT<br/> msr cpsr_cxsf,r1&nbsp;&nbsp;;IRQMode<br/> ldr sp,=IRQStack<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/> o&#114;r r1,r0,#FIQMODE|NOINT<br/> msr cpsr_cxsf,r1&nbsp;&nbsp;;FIQMode<br/> ldr sp,=FIQStack<br/><br/> bic r0,r0,#MODEMASK|NOINT<br/> o&#114;r r1,r0,#SVCMODE<br/> msr cpsr_cxsf,r1&nbsp;&nbsp;;SVCMode<br/> ldr sp,=SVCStack<br/> <br/> //USER mode has not be initialized.注意：不要切换到User模式进行User模式的堆栈设置，因为进入User模式后就<br/><br/>//不能再操作CPSR回到别的模式了，可能会对接下去的程序执行造成影响<br/> <br/> mov pc,lr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //堆栈初始化完成返回<br/> ;The LR register won&#39;t be valid if the current mode is not SVC mode.<br/><br/><br/> ;以下是上面提到的对存储寄存器初始化的数据map，共13个DCD<br/><br/> LTORG<br/><br/>SMRDATA DATA<br/>; Memory configuration should be optimized for best performance <br/>; The following parameter is not optimized.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>; Memory access cycle parameter strategy<br/>; 1) The memory settings is&nbsp;&nbsp;safe parameters even at HCLK=75Mhz.<br/>; 2) SDRAM refresh period is for HCLK=75Mhz. <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DCD (0+(B1_BWSCON&lt;&lt;4)+(B2_BWSCON&lt;&lt;8)+(B3_BWSCON&lt;&lt;12)+(B4_BWSCON&lt;&lt;16)+(B5_BWSCON&lt;&lt;20)+(B6_BWSCON&lt;&lt;24)+(B7_BWSCON&lt;&lt;28))&nbsp;&nbsp;//BAN1,6,7为32位数据完，其他除0外为16<br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD ((B0_Tacs&lt;&lt;13)+(B0_Tcos&lt;&lt;11)+(B0_Tacc&lt;&lt;8)+(B0_Tcoh&lt;&lt;6)+(B0_Tah&lt;&lt;4)+(B0_Tacp&lt;&lt;2)+(B0_PMC))&nbsp;&nbsp; ;GCS0；BANK0的相关访问模式及各访问周期设置， 各位定义可参考memcfg.inc文件<br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD ((B1_Tacs&lt;&lt;13)+(B1_Tcos&lt;&lt;11)+(B1_Tacc&lt;&lt;8)+(B1_Tcoh&lt;&lt;6)+(B1_Tah&lt;&lt;4)+(B1_Tacp&lt;&lt;2)+(B1_PMC))&nbsp;&nbsp; ;GCS1 <br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD ((B2_Tacs&lt;&lt;13)+(B2_Tcos&lt;&lt;11)+(B2_Tacc&lt;&lt;8)+(B2_Tcoh&lt;&lt;6)+(B2_Tah&lt;&lt;4)+(B2_Tacp&lt;&lt;2)+(B2_PMC))&nbsp;&nbsp; ;GCS2<br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD ((B3_Tacs&lt;&lt;13)+(B3_Tcos&lt;&lt;11)+(B3_Tacc&lt;&lt;8)+(B3_Tcoh&lt;&lt;6)+(B3_Tah&lt;&lt;4)+(B3_Tacp&lt;&lt;2)+(B3_PMC))&nbsp;&nbsp; ;GCS3<br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD ((B4_Tacs&lt;&lt;13)+(B4_Tcos&lt;&lt;11)+(B4_Tacc&lt;&lt;8)+(B4_Tcoh&lt;&lt;6)+(B4_Tah&lt;&lt;4)+(B4_Tacp&lt;&lt;2)+(B4_PMC))&nbsp;&nbsp; ;GCS4<br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD ((B5_Tacs&lt;&lt;13)+(B5_Tcos&lt;&lt;11)+(B5_Tacc&lt;&lt;8)+(B5_Tcoh&lt;&lt;6)+(B5_Tah&lt;&lt;4)+(B5_Tacp&lt;&lt;2)+(B5_PMC))&nbsp;&nbsp; ;GCS5<br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD ((B6_MT&lt;&lt;15)+(B6_Trcd&lt;&lt;2)+(B6_SCAN))&nbsp;&nbsp;&nbsp;&nbsp;;GCS6<br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD ((B7_MT&lt;&lt;15)+(B7_Trcd&lt;&lt;2)+(B7_SCAN))&nbsp;&nbsp;&nbsp;&nbsp;;GCS7<br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD ((REFEN&lt;&lt;23)+(TREFMD&lt;&lt;22)+(Trp&lt;&lt;20)+(Trc&lt;&lt;18)+(Tchr&lt;&lt;16)+REFCNT)&nbsp;&nbsp;&nbsp;&nbsp;//;设置刷新周期<br/><br/> <br/><br/> DCD 0x32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; ;SCLK power&nbsp;&nbsp;saving mode, ARM&nbsp;&nbsp;core burst disable, BANKSIZE 128M/128M <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD 0x30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;MRSR6 CL=3clk CL：CAS latency<br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD 0x30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;MRSR7<br/>;&nbsp;&nbsp;&nbsp;&nbsp; DCD 0x20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;MRSR6 CL=2clk<br/>;&nbsp;&nbsp;&nbsp;&nbsp; DCD 0x20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;MRSR7<br/><br/>&nbsp;&nbsp;<br/><br/>//下面是对ram区域map的定义;这里定义了处理器工作于各模式的堆栈区在ram中map.<br/><br/> ALIGN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//字对齐<br/>&nbsp;&nbsp;&nbsp;&nbsp; AREA RamData, DATA, READWRITE<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^&nbsp;&nbsp; _ISR_STARTADDRESS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //^=map<br/>HandleReset&nbsp;&nbsp;#&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //#=field<br/>HandleUndef&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleSWI&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandlePabort&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleDabort&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleReserved&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleIRQ&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleFIQ&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/><br/>;Don&#39;t use the label &#39;IntVectorTable&#39;,<br/>;The value of IntVectorTable is different with the address you think it may be.<br/>;IntVectorTable<br/>HandleEINT0&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleEINT1&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleEINT2&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleEINT3&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleEINT4_7 #&nbsp;&nbsp; 4<br/>HandleEINT8_23 #&nbsp;&nbsp; 4<br/>HandleRSV6 #&nbsp;&nbsp; 4<br/>HandleBATFLT&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleTICK&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleWDT #&nbsp;&nbsp; 4<br/>HandleTIMER0&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleTIMER1&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleTIMER2&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleTIMER3&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleTIMER4&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleUART2&nbsp;&nbsp; #&nbsp;&nbsp; 4<br/>HandleLCD&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleDMA0 #&nbsp;&nbsp; 4<br/>HandleDMA1 #&nbsp;&nbsp; 4<br/>HandleDMA2 #&nbsp;&nbsp; 4<br/>HandleDMA3 #&nbsp;&nbsp; 4<br/>HandleMMC #&nbsp;&nbsp; 4<br/>HandleSPI0 #&nbsp;&nbsp; 4<br/>HandleUART1 #&nbsp;&nbsp; 4<br/>HandleRSV24 #&nbsp;&nbsp; 4<br/>HandleUSBD #&nbsp;&nbsp; 4<br/>HandleUSBH #&nbsp;&nbsp; 4<br/>HandleIIC&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleUART0&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleSPI1&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleRTC&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/>HandleADC&nbsp;&nbsp;#&nbsp;&nbsp; 4<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;END<br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.zjidea.com/blog/article/arm/2010-02-11-arm2.htm</link>
			<title><![CDATA[S3C2410启动代码详解(2)]]></title>
			<author>lzq0323@yahoo.com.cn(相逢萍水)</author>
			<category><![CDATA[ARM编程]]></category>
			<pubDate>Thu,11 Feb 2010 11:11:09 +0800</pubDate>
			<guid>http://www.zjidea.com/blog/default.asp?id=467</guid>
		<description><![CDATA[;========================================================================================<br/><br/>//在这里用IMPORT伪指令(和c语言的extren一样)引入|Image$$RO$$Base|,|Image$$RO$$Limit|...<br/><br/>//这些变量是通过ADS的工程设置里面设定的RO Base和RW Base设定的,最终由编译脚本和连接程序导入程序. <br/><br/>//那为什么要引入这玩意呢,最简单的用处是可以根据它们拷贝自已 ，从把RW和ZI变量从加载域中复制到运行域中<br/><br/>//一个arm由RO,RW,ZI三个断组成 其中RO为代码段，RW是已经初始化的全局变量，ZI是未初始化的全局变量（对于GNU工具 对应的概念是TEXT ,DATA,BSS）。<br/><br/><br/><br/><br/>;========================================================================================<br/>IMPORT&nbsp;&nbsp;|Image$$RO$$Base|&nbsp;&nbsp;&nbsp;&nbsp;; ROM code(也就是代码)的开始地址 <br/>IMPORT&nbsp;&nbsp;|Image$$RO$$Limit|&nbsp;&nbsp;&nbsp;&nbsp;; ROM code的结束地址 (也就是RW在加载域中的起始地址) <br/>IMPORT&nbsp;&nbsp;|Image$$RW$$Base|&nbsp;&nbsp; ; 在运行域中要初始化的RAM的开始地址 <br/>IMPORT&nbsp;&nbsp;|Image$$ZI$$Base|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; area(需要清零的RAM区域)的开始地址 <br/>IMPORT&nbsp;&nbsp;|Image$$ZI$$Limit|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; area的结束地址 <br/><br/>;这里引入一些在其它文件中实现在函数,包括为我们所熟知的main函数<br/>IMPORT&nbsp;&nbsp;Main&nbsp;&nbsp;&nbsp;&nbsp;; The main entry of mon program <br/>;从这里开始就是正真的代码入口了! <br/>AREA&nbsp;&nbsp;&nbsp;&nbsp;Init,CODE,READONLY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;这表明下面的是一个名为Init的代码段 <br/>ENTRY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;定义程序的入口(调试用) 其中关键字ENTRY是指定编译器保留这段代码，因为<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 编译器可能会认为这是一段亢余代码而加以优化。链接的时候要确保这段代码<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 被链接在0地址处，并且作为整个程序的入口 <br/>;1)The code, which converts to Big-endian, should be in little endian code. <br/>;2)The following little endian code will be compiled in Big-Endian mode. <br/>;&nbsp;&nbsp;The code byte o&#114;der should be changed as the memory bus width. <br/>;3)The pseudo instruction,DCD can not be used here because the linker generates error. <br/>ASSERT :DEF:ENDIAN_CHANGE <br/>[ ENDIAN_CHANGE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;下面是大小端的一个判断,在Option.inc里已经设为FALSE <br/>&nbsp;&nbsp;&nbsp;&nbsp; ASSERT&nbsp;&nbsp;:DEF:ENTRY_BUS_WIDTH <br/>&nbsp;&nbsp;&nbsp;&nbsp; [ ENTRY_BUS_WIDTH=32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//‘[’=IF<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b ChangeBigEndian&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;DCD 0xea000007 <br/>&nbsp;&nbsp;&nbsp;&nbsp; ] <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; [ ENTRY_BUS_WIDTH=16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;andeq r14,r7,r0,lsl #20&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;DCD 0x0007ea00 <br/>&nbsp;&nbsp;&nbsp;&nbsp; ] <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; [ ENTRY_BUS_WIDTH=8 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;streq r0,[r0,-r10,ror #1]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;DCD 0x070000ea <br/>&nbsp;&nbsp;&nbsp;&nbsp; ] <br/>| <br/>&nbsp;&nbsp;&nbsp;&nbsp; b ResetHandler ;因为设成FALSE，所以系统复位后就来到这了,转跳到复位程序入口 <br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;] <br/><br/>//=====================================================================================<br/><br/>;ARM要求中断向量表必须放置在仿地址开始，连续8X4字节的空间内.每当一个中断发生以后，ARM处理器便强制把PC指针置为向量表中对应中断类型的地址值。因为每个中断只占据向量表中1个字的存储空间，只能放置一条ARM指令，使程序跳转到存储器的其他地方，再执行中断处理 <br/><br/>//=====================================================================================<br/>b HandlerUndef&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;转跳到Undefined mode程序入口 <br/>b HandlerSWI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;转跳到SWI 中断程序入口 <br/>b HandlerPabort&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;转跳到PAbort(指令异常)程序入口 <br/>b HandlerDabort&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;转跳到DAbort(数据异常)程序入口 <br/>b .&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;保留 <br/>b HandlerIRQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;转跳到IRQ 中断程序入口 <br/>b HandlerFIQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;转跳到FIQ 中断程序入口 <br/><br/>;@0x20 不知道是什么意思,地址？<br/>b EnterPWDN ; Must be @0x20.<br/><br/>;================================================================================== <br/>;下面是改变大小端的程序,这里采用直接定义机器码的方式,至说为什么这么做就得问三星了 <br/>;反正我们程序里这段代码也不会去执行,不用去管它 <br/>;================================================================================== <br/>ChangeBigEndian&nbsp;&nbsp;&nbsp;&nbsp;//通过设置CP15中的C1的位7来设置存储格式为大端模式。<br/>;@0x24 <br/>[ ENTRY_BUS_WIDTH=32 <br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD 0xee110f10 ;0xee110f10 =&gt; mrc p15,0,r0,c1,c0,0 <br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD 0xe3800080 ;0xe3800080 =&gt; o&#114;r r0,r0,#0x80;&nbsp;&nbsp;//Big-endian <br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD 0xee010f10 ;0xee010f10 =&gt; mcr p15,0,r0,c1,c0,0 <br/>] <br/>[ ENTRY_BUS_WIDTH=16 <br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD 0x0f10ee11 <br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD 0x0080e380 <br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD 0x0f10ee01 <br/>] <br/>[ ENTRY_BUS_WIDTH=8 <br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD 0x100f11ee <br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD 0x800080e3 <br/>&nbsp;&nbsp;&nbsp;&nbsp; DCD 0x100f01ee <br/>&nbsp;&nbsp;&nbsp;&nbsp;] <br/>DCD 0xffffffff&nbsp;&nbsp;;swinv 0xffffff is similar with NOP and run well in both endian mode. <br/>DCD 0xffffffff <br/>DCD 0xffffffff <br/>DCD 0xffffffff <br/>DCD 0xffffffff <br/>b ResetHandler <br/><br/>;Function for entering power down mode，下面这段程序为进入掉电模式及从掉电模式中唤醒的相关设置和处理<br/>; 1. SDRAM should be in self-refresh mode. SDRAm应该设置为自刷新的模式<br/>; 2. All interrupt should be maksked for SDRAM/DRAM self-refresh. 所有中断必须屏蔽 for SDRAM/DRAM self-ref<br/>; 3. LCD controller should be disabled for SDRAM/DRAM self-refresh. LCD 控制器关闭<br/>; 4. The I-cache may have to be turned on.&nbsp;&nbsp; <br/>; 5. The location of the following code may have not to be changed.<br/><br/>//;void EnterPWDN(int CLKCON);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //PWDN：powerdown<br/>EnterPWDN&nbsp;&nbsp; <br/> mov r2,r0&nbsp;&nbsp;;r2=rCLKCON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //rCLKCONr [3;2]位为电源模式标置位。若[3]为1，表示转为了掉电模式<br/> tst r0,#0x8&nbsp;&nbsp;;POWER_OFF mode?&nbsp;&nbsp; //按位与判断，若[3]为1则跳转到ENTER_POWER_OFF<br/> bne ENTER_POWER_OFF<br/><br/>ENTER_STOP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//进入停止模式相关处理<br/> ldr r0,=REFRESH&nbsp;&nbsp;<br/> ldr r3,[r0]&nbsp;&nbsp;;r3=rREFRESH <br/> mov r1, r3<br/> o&#114;r r1, r1, #BIT_SELFREFRESH<br/> str r1, [r0]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;Enable SDRAM self-refresh<br/><br/> mov r1,#16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;wait until self-refresh is issued. may not be needed.等待自刷新生效<br/>0 subs r1,r1,#1<br/> bne %B0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //表示不相等则往回跳转到标号为0的位置，在此为上一句。<br/><br/> ldr r0,=CLKCON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;enter STOP mode.<br/> str r2,[r0]&nbsp;&nbsp;&nbsp;&nbsp;<br/><br/> mov r1,#32<br/>0 subs r1,r1,#1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;1) wait until the STOP mode is in effect.<br/> bne %B0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;2) o&#114; wait here until the CPU&amp;Peripherals will be turned-off<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;&nbsp;&nbsp; Entering POWER_OFF mode, only the reset by wake-up is available.<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //进入掉电 模式后，仅唤醒中断有效<br/><br/> ldr r0,=REFRESH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;exit from SDRAM self refresh mode.<br/> str r3,[r0]<br/> <br/> MOV_PC_LR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//开始处定义的返回跳转宏<br/><br/>ENTER_POWER_OFF <br/> ;NOTE.注意在rGSTATUS3寄存器中应该保存掉电模式唤醒的返回地址，rGSTATUS3，4可在掉电下保存信息<br/> ;1) rGSTATUS3 should have the return address after wake-up from POWER_OFF mode.<br/> <br/> ldr r0,=REFRESH&nbsp;&nbsp;<br/> ldr r1,[r0]&nbsp;&nbsp;;r1=rREFRESH <br/> o&#114;r r1, r1, #BIT_SELFREFRESH<br/> str r1, [r0]&nbsp;&nbsp;;Enable SDRAM self-refresh<br/><br/> mov r1,#16&nbsp;&nbsp;&nbsp;&nbsp; ;Wait until self-refresh is issued,which may not be needed.<br/>0 subs r1,r1,#1<br/> bne %B0<br/><br/> ldr&nbsp;&nbsp;r1,=MISCCR<br/> ldr r0,[r1]<br/> o&#114;r r0,r0,#(7&lt;&lt;17)&nbsp;&nbsp;;Make sure that SCLK0:SCLK-&gt;0, SCLK1:SCLK-&gt;0, SCKE=L during boot-up <br/> str r0,[r1]<br/><br/> ldr r0,=CLKCON<br/> str r2,[r0]&nbsp;&nbsp;&nbsp;&nbsp;<br/><br/> b .&nbsp;&nbsp; ;CPU will die here.<br/><br/><br/> ；=================================================================================<br/><br/>从掉电模式唤醒的过程<br/><br/>1、&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 某个唤醒源生效将产生一个内部复位信号。复位时间由一个内部16位计数器决定，此计数器的时钟是tRST=(65535/XTAL_frequency)。<br/><br/>2、&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查询GSTATUS[2]位看从掉电模式唤醒是否产生了一个POWER-UP。<br/><br/>3、&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过将MISCCR[19:17]设置为000b，释放SDRAM信号保护。<br/><br/>4、&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 配置SDRAM控制器。<br/><br/>5、&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 等待SDRAM自我刷新完毕。大部分SDRAM需要refresh cycle of all SDRAM row。<br/><br/>6、&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GSTATUS3，4的信息可以被用户使用，因为GSTATUS3，4的值已经在掉电模式下被保存了。<br/><br/>7、&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于EINT[3:0],检查SRCPND寄存器；对于EINT[15:4],检查EINTPND寄存器；对于RTC报警唤醒，检查RTC时间，因为在唤醒时SRCPND寄存器的RTC位不被置位；如果在掉电模式期间有nBATT-FLT assertion，SRCPND寄存器的相关位被置位。<br/><br/>；==================================================================================<br/><br/>WAKEUP_POWER_OFF<br/> ;Release SCLKn after wake-up from the POWER_OFF mode.<br/><br/> ldr&nbsp;&nbsp;r1,=MISCCR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //MISCCR寄存器用来设置一些USB等相关的时钟周期等<br/> ldr r0,[r1]<br/> bic r0,r0,#(7&lt;&lt;17)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//SCLK0:0-&gt;SCLK, SCLK1:0-&gt;SCLK, SCKE:L-&gt;H<br/><br/> str r0,[r1]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //通过将MISCCR[19:17]设置为000b，释放SDRAM信号保护。<br/><br/><br/> ;Set memory control registers配置内存控制寄存器。<br/> ldr r0,=SMRDATA&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //在程序的后面 LTORG SMRDATA DATA中定义了<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//一个数据缓冲池就是用来配置相关的内存控制寄存器的<br/> ldr r1,=BWSCON&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;BWSCON Address<br/> add r2, r0, #52&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;End address of SMRDATA<br/>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/> ldr r3, [r0], #4&nbsp;&nbsp;&nbsp;&nbsp;<br/> str r3, [r1], #4&nbsp;&nbsp;&nbsp;&nbsp;<br/> cmp r2, r0&nbsp;&nbsp;<br/> bne %B0<br/><br/> mov r1,#256<br/>0 subs r1,r1,#1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;1) wait until the SelfRefresh is released.<br/> bne %B0&nbsp;&nbsp;<br/> <br/> ldr r1,=GSTATUS3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;; GSTATUS3 has the start address just after POWER_OFF wake-up<br/> ldr r0,[r1]<br/> mov pc,r0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//从掉电模式下唤醒后，将保存在GSTATUS3 返回地址传给PC<br/><br/>如上所说,这里采用HANDLER宏去建立Hander***和Handle***之间的联系 <br/><br/>LTORG&nbsp;&nbsp; ;声明文字池,因为我们用了ldr伪指令 <br/>HandlerFIQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HANDLER HandleFIQ <br/>HandlerIRQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HANDLER HandleIRQ <br/>HandlerUndef&nbsp;&nbsp;&nbsp;&nbsp;HANDLER HandleUndef <br/>HandlerSWI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HANDLER HandleSWI <br/>HandlerDabort&nbsp;&nbsp; HANDLER HandleDabort <br/>HandlerPabort&nbsp;&nbsp; HANDLER HandlePabort <br/><br/>;=================================================================================== <br/>;呵呵,来了来了.好戏来了,这一段程序就是用来进行第二次查表的过程了. <br/>;如果说第一次查表是由硬件来完成的,那这一次查表就是由软件来实现的了. <br/>;为什么要查两次表?? <br/>;没有办法,ARM把所有的中断都归纳成一个IRQ中断异常和一个FIRQ中断异常 <br/>;第一次查表主要是查出是什么异常,可我们总要知道是这个中断异常中的什么中断呀! <br/>;没办法了,再查一次表呗! <br/>;=================================================================================== <br/>IsrIRQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//第二次中断查表，因为ARM把所有的中断都归为一个IRQ异常，通过此处查表可知道具体中断<br/>sub sp,sp,#4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;给PC寄存器保留 <br/>stmfd sp!,{r8-r9}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;把r8-r9压入栈 <br/><br/>ldr r9,=INTOFFSET&nbsp;&nbsp;&nbsp;&nbsp; ;把INTOFFSET的地址装入r9 <br/>ldr r9,[r9]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;把INTOFFSET的值装入r9 <br/>ldr r8,=HandleEINT0&nbsp;&nbsp;&nbsp;&nbsp;;这就是我们第二个中断向量表的入口的,先装入r8 <br/>;=================================================================================== <br/>;哈哈,这查表方法够好了吧,r8(入口)+index*4(别望了一条指令是4 bytes的喔), <br/>;这不就是我们要找的那一项了吗.找到了表项,下一步做什么?肯定先装入了! <br/>;==================================================================================&nbsp;&nbsp;<br/>add r8,r8,r9,lsl #2&nbsp;&nbsp;<br/>ldr r8,[r8]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;装入中断服务程序的入口 <br/>str r8,[sp,#8]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;把入口也入栈,准备用旧招 <br/>ldmfd sp!,{r8-r9,pc}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;施招,弹出栈,哈哈,顺便把r8弹出到PC,O了,跳转成功!<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.zjidea.com/blog/article/arm/2010-02-11_arm1.htm</link>
			<title><![CDATA[S3C2410启动代码详解(1)]]></title>
			<author>lzq0323@yahoo.com.cn(相逢萍水)</author>
			<category><![CDATA[ARM编程]]></category>
			<pubDate>Thu,11 Feb 2010 11:03:15 +0800</pubDate>
			<guid>http://www.zjidea.com/blog/default.asp?id=466</guid>
		<description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;最近开始学习ARM，不过也无从下手的感觉，索性网上找些资料先看看，了解点基础知识，下面是网上找到的S3C2410启动代码详解，转过来以备后用。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;花了好几天的时间研究S3C2410r的启动代码，终于看完！在参考了一些资料后，加上自己的理解，留下点笔记。有些地方可能不正确，有待改正：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 通常,启动代码是指CPU复位后到进入C语言的main函数之前需要执行的那段汇编代码.这是由于C语言程序的运行需要具备一定的条件,比如:分配好外部数据空闿堆栈空间和中断入口等筿另外汇编代码可以更直接的对硬件进行操使效率更高. 通常启动代码是放圿410init.s汇编文件；特殊功能寄存器定义在2410addr.s；Memory Bank 配置在mencfg.s；还有系统的选项等在option.s文件；2410init.s不仅包括复位后执行的代码,还包括CPU进入掉电模式,产生中断等和处理器直接相关的,用汇编实现的代码.<br/><br/>;=========================================<br/>; NAME: 2410INIT.S<br/>; DESC: C start up codes<br/>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Configure memory, ISR ,stacks<br/>; Initialize C-variables<br/>; HISTORY:<br/>; 2002.02.25:kwtark: ver 0.0<br/>; 2002.03.20:purnnamu: Add some functions for testing STOP,POWER_OFF mode<br/>; 2003.05.19:jcs:Configure UPLL in init.s not usbmain.c<br/>;=========================================<br/><br/>&nbsp;&nbsp;//首先，启动代码定义了一些常量 ,相当于C中的INCLUDE<br/><br/> GET option.inc<br/> GET memcfg.inc<br/> GET 2410addr.inc<br/><br/> <br/><br/>BIT_SELFREFRESH EQU (1&lt;&lt;22) //自刷新常量<br/><br/>//;;处理器模式常量 <br/>USERMODE&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;0x10<br/>FIQMODE&nbsp;&nbsp;&nbsp;&nbsp; EQU&nbsp;&nbsp;0x11<br/>IRQMODE&nbsp;&nbsp;&nbsp;&nbsp; EQU&nbsp;&nbsp;0x12<br/>SVCMODE&nbsp;&nbsp;&nbsp;&nbsp; EQU&nbsp;&nbsp;0x13<br/>ABORTMODE&nbsp;&nbsp; EQU&nbsp;&nbsp;0x17<br/>UNDEFMODE&nbsp;&nbsp; EQU&nbsp;&nbsp;0x1b<br/>MODEMASK&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;0x1f&nbsp;&nbsp;//系统模式<br/>NOINT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EQU&nbsp;&nbsp;0xc0&nbsp;&nbsp;//屏蔽所有的中断，即置位I，F位<br/><br/>//;The location of stacks 定义处理器各模式下堆栈地址常量 <br/>UserStack&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~ <br/>SVCStack&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU (_STACK_BASEADDRESS-0x2800)&nbsp;&nbsp;;0x33ff5800 ~<br/>UndefStack&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU (_STACK_BASEADDRESS-0x2400)&nbsp;&nbsp;;0x33ff5c00 ~<br/>AbortStack&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EQU (_STACK_BASEADDRESS-0x2000)&nbsp;&nbsp;;0x33ff6000 ~<br/>IRQStack&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EQU (_STACK_BASEADDRESS-0x1000)&nbsp;&nbsp;;0x33ff7000 ~<br/>FIQStack&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EQU (_STACK_BASEADDRESS-0x0)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;0x33ff8000 ~ <br/><br/>;check if tasm.exe is used.<br/>;arm处理器有两种工作状态 1.arm:32位 这种工作状态下执行字对准的arm指令 2.Thumb:16位 这种工作状态执行半字对准的Thumb指令<br/>;因为处理器分为16位 32位两种工作状态程序的编译器也是分16位和32两种编译方式 所以下面的程序用于根据处理器工作状态确定编译器编译方式<br/>;code16伪指令指示汇编编译器后面的指令为16位的thumb指令<br/>;code32伪指令指示汇编编译器后面的指令为32位的arm指令<br/>;这段是为了统一目前的处理器工作状态和软件编译方式（16位编译环境使用tasm.exe编译）<br/>GBLL THUMBCODE ;设置一个全局逻辑变量<br/>[ {CONFIG} = 16 ;if config==16 这里表示你的目前处于领先地16位编译方式，{CONFIG}为汇编器内置变量<br/>THUMBCODE SETL {TRUE} ;设置THUMBCODE 为 true<br/>CODE32 ;转入32位编译模式<br/>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;else<br/>THUMBCODE SETL {FALSE} ;设置THUMBCODE 为 false<br/>] <br/><br/>[ THUMBCODE&nbsp;&nbsp;&nbsp;&nbsp; ;if THUMBCODE==TRUE<br/>CODE32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;for start-up code for Thumb mode;转入32位编译方式<br/>]<br/><br/>;注意下面这段程序是个宏定义 很多人对这段程序不理解 我再次强调这是一个宏定义 所以大家要注意了下面包含的HandlerXXX HANDLER HandleXXX将都被下面这段程序展开。<br/><br/>;这段程序用于把中断服务程序的首地址装载到pc中，有人称之为“加载程序”。其大致作用是把宏的第一个参数$HandlerLabel 转变为一个标号，然后让程序跳转到第二个参数 $HandleLabel (第二个参数应该为一个地址)对应的值的地址去。可以分析出，sp和r0在执行前后都没有变化，程序就实现了跳转<br/><br/>;本初始化程序定义了一个数据区（在文件最后），34个字空间，存放相应中断服务程序的首地址。每个字空间都有一个标号，以Handle***命名。<br/><br/>;在向量中断模式下使用“加载程序”来执行中断服务程序。<br/><br/>;这里就必须讲一下向量中断模式和非向量中断模式的概念<br/><br/>;向量中断模式是当cpu读取位于0x18处的IRQ中断指令的时候，系统自动读取对应于该中断源确定地址上的指令取代0x18处的指令，通过跳转指令系统就直接跳转到对应地址<br/><br/>;函数中 节省了中断处理时间提高了中断处理速度标 例如 ADC中断的向量地址为0xC0,则在0xC0处放如下代码：ldr PC,=HandlerADC 当ADC中断产生的时候系统会<br/><br/>;自动跳转到HandlerADC函数中<br/><br/>;非向量中断模式处理方式是一种传统的中断处理方法，当系统产生中断的时候，系统将interrupt pending寄存器中对应标志位置位 然后跳转到位于0x18处的统一中断<br/><br/>;函数中 该函数通过读取interrupt pending寄存器中对应标志位 来判断中断源 并根据优先级关系再跳到对应中断源的处理代码中 <br/><br/>MACRO <br/>$HandlerLabel HANDLER $HandleLabel&nbsp;&nbsp;&nbsp;&nbsp;//<br/>$HandlerLabel <br/>sub sp,sp,#4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;减少sp(预留一个字，用于存放转跳地址) <br/>stmfd sp!,{r0}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;把工作寄存器压入栈(lr does not push because it return to o&#114;iginal address) <br/>ldr&nbsp;&nbsp;&nbsp;&nbsp; r0,=$HandleLabel&nbsp;&nbsp;&nbsp;&nbsp;;将HandleXXX的址址放入r0 <br/>ldr&nbsp;&nbsp;&nbsp;&nbsp; r0,[r0]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;把HandleXXX所指向的内容(也就是中断程序的入口)放入r0 <br/>str&nbsp;&nbsp;&nbsp;&nbsp; r0,[sp,#4]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;把中断服务程序(ISR)压入栈，保存在高一个地址预留的空间中，但SP没变。 <br/>ldmfd&nbsp;&nbsp; sp!,{r0,pc}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;用出栈的方式恢复r0的原值和为pc设定新值(也就完成了到ISR的转跳) ;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ADS仅支持FD（满递减）型堆栈，故只能用stmfd和ldmfd<br/>MEND<br/><br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.zjidea.com/blog/article/diary/2010-02-10_new_year.htm</link>
			<title><![CDATA[2010新年快乐！]]></title>
			<author>lzq0323@yahoo.com.cn(相逢萍水)</author>
			<category><![CDATA[心情坐标]]></category>
			<pubDate>Wed,10 Feb 2010 12:27:26 +0800</pubDate>
			<guid>http://www.zjidea.com/blog/default.asp?id=465</guid>
		<description><![CDATA[<br/><img src="http://www.zjidea.com/blog/attachments/month_1002/h2010210122523.jpg" border="0" alt=""/><br/><br/><br/>一年一年过的可真叫快，转眼间2010年新年即将到来,我在这祝福所有的朋友在新的一年里工作顺利，家庭和睦，虎年行大运<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.zjidea.com/blog/article/arm/2010-01-09_arm.htm</link>
			<title><![CDATA[ARM指令中特殊符号的含义]]></title>
			<author>lzq0323@yahoo.com.cn(相逢萍水)</author>
			<category><![CDATA[ARM编程]]></category>
			<pubDate>Tue,09 Feb 2010 11:20:19 +0800</pubDate>
			<guid>http://www.zjidea.com/blog/default.asp?id=469</guid>
		<description><![CDATA[ARM中常用的一些代表指令的符号<br/><br/>特殊符号&nbsp;&nbsp; 对应指令&nbsp;&nbsp;&nbsp;&nbsp; 含义 <br/>&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;分配一片连续的字节存储单元并用指定的数据初始化<br/>&nbsp;&nbsp;&nbsp;&nbsp;&amp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 分配一片连续的字存储单元并用指定的数据初始化<br/>&nbsp;&nbsp;&nbsp;&nbsp;%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SPACE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;分配一片连续的存储单元<br/>&nbsp;&nbsp;&nbsp;&nbsp;^&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MAP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;定义一个结构化内存表的首地址<br/>&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FILED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 定义一个结构化内存表的数据域（经常和MAP一使&nbsp;&nbsp;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;用，一个定义起始地址，一个定义长度）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EQU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为程序中的常量、标号等定义一个等效的字符名称，<br/><br/>&nbsp;&nbsp;!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 地址更新，结果写回到Rn中，Rn不允许是R15<br/>&nbsp;&nbsp; [&nbsp;&nbsp;|&nbsp;&nbsp;]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 相当于IF&nbsp;&nbsp;ELSE&nbsp;&nbsp;ENDIF<br/><br/> <br/><br/>其他：<br/><br/>LDM中{∧}为可选后缀，当指令为LDM且寄存器列表中包含R15，选用该后缀时表示：除了正常的数据传送之外，还将SPSR复制到CPSR。同时，该后缀还表示传入或传出的是用户模式下的寄存器，而不是当前模式下的寄存器。 <br/><br/>TST R1，＃％1&nbsp;&nbsp; // 用于测试在寄存器R1中是否设置了最低位(％表示二进制数）<br/><br/>n <br/> $：如果在串变量前有一个$则在汇编时编译器将用该串变量的数值取代该串变量，如： <br/>GBLS&nbsp;&nbsp;&nbsp;&nbsp;STR1<br/><br/>GBLS&nbsp;&nbsp;&nbsp;&nbsp;STR2<br/><br/>STR1&nbsp;&nbsp;&nbsp;&nbsp;SETS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;“pen.”<br/><br/>STR2&nbsp;&nbsp;&nbsp;&nbsp;SETS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;“This is a $STR1&#34;<br/><br/>编译后的结果是STR2的值为This is a pen.<br/><br/>如果$后是数字变量（与串变量区分），在汇编时编译器将该数字变量的数值转换成十六进制的串，然后用该十六进制的串取代$后的数字变量。<br/><br/>如果$后是逻辑变量，在汇编时编译器将该逻辑变量替换成它的取值（T或者F）。<br/><br/>如果程序中需要$，则用$$来表示，编译器将不进行变量替换。<br/><br/>注意：在两个竖线“|”之间的$并不表示进行变量替换，但如果“|”是在双引号内，则将进行变量替换。<br/><br/> <br/><br/>B .&nbsp;&nbsp;&nbsp;&nbsp;//表示程序进入死循环。&#39;.&#39;为location counter，可在源文件中指示当前地址。该符号可以被引用或赋值。<br/><br/> <br/><br/>ARM汇编程序中的符号 <br/>在ARM汇编语言中，符号（symbols）可以代表地址（addresse）、变量（variables）和数字常量（numeric constants）。当符号代表地址时，又称为标号（lable）。当标号以数字开头时，其作用范围为当前段（当前段没有使用ROUT伪操作时），这种标号又称为局部标号（lacal lable）。符号变量包括变量、数字常量、标号和局部标号。 <br/>1、变量 <br/>在程序中，变量的值在汇编处理过程中可能会发生改变。在ARM汇编中变量有数字变量、逻辑变量和串变量3种类型。变量的类型在程序中是不可以改变的。 <br/>数字变量的取值范围为数字常量和数字表达式所能表示的数值；逻辑变量的取值范围为{true}和{flash}；串变量的取值范围为串表达式可以表达的范围。 <br/>在ARM汇编语言中，使用GBLA、GBLL及GBLS声明全局变量；使用LCLA、LCLL及LCLS声明局部变量；使用SETA、SETL及SETS为这些变量赋值。<br/>2、数字常量 <br/>数字常量是32位的整数。在ARM汇编语言中，使用EQU来定义数字常量。数字常量一经定义就不可修改。 进行大小比较时，认为数字常量都是无符号数。<br/>3、汇编时变量的替换 <br/>如果在串变量前有一个$字符，在汇编时编译器将用改串的数值来取代该串变量。 <br/>对于数字变量来说，如果该变量前面有一个$字符，在汇编时编译器将该数字变量的数值转换成十六进制的串，然后用该十六进制的串取代$字符后的数字变量。<br/>对于逻辑变量来说，如果该逻辑变量前面有一个$字符，在汇编时编译器将该逻辑变量替换成它的取值（T或者F）<br/>如果程序中需要字符$，则用$$来表示，编译器将不进行变量替换，而是将$$当作$.<br/>通常情况下，包含在两个竖线（|）之间的$并不表示进行变量替换。但是如果竖线（|）是在双引号内，则将进行变量替换。<br/>使用“.”来表示变量名称的结束。<br/>4、标号 <br/>标号是表示程序中的指令或者数据地址的符号。根据标号的生成方式可分为3种： <br/>基于PC的标号。基于PC的标号是位于目标指令前或者程序中数据定义伪操作前的标号。这种标号在汇编时将被处理成PC值加上（或减去）一个数字常量。常用于表示跳转指令的目标地址，或者代码段中所嵌入的少量数据。 <br/>基于寄存器的标号。基于寄存器的标号常用MAP和FIELD未定义操作，也可以该用EQU伪定义。这种标号在汇编时将被处理成寄存器的值加上（或减去）一个数据常量。常用于访问数据段中的数据。 <br/>绝对地址。绝对地址是一个32位数据。它可以寻址2^32 -1，即直接可以寻址整个内存空间。 <br/>5、局部标号 <br/>局部标号主要在局部范围内使用。它由两部组成：开头是一个0-99直接的数字，后面紧接一个通常表示该局部变量作用范围的符号。 <br/>局部变量的作用范围通常为当前段，也可以用伪操作ROUT来定义局部变量的作用范围。<br/>局部变量定义的语法格式如下：<br/>N{routname}，其中，N为0~99之间的数字。routname为符号，通常为该变量作用范围的名称（用ROUT伪操作定义的）。<br/>局部变量引用的语法格式如下：<br/>%{F|B}{A|T}N{routname}<br/>其中，N为局部变量的数字号。<br/>routname 为当前作用范围的名称（用ROUT伪操作定义的）<br/>%表示引用操作<br/>F指示编译器只向前搜索<br/>B指示编译器只向后搜索<br/>A指示编译器搜索宏的所有嵌套层次<br/>T指示编译器搜索宏的当前层次<br/>如果F和B都没有指定，编译器先向前搜索，再向后搜索<br/>如果A和T都没有指定，编译器搜索所有从当前层次到宏的最高层次，比当前层次低的层次不再搜索。<br/>如果指定了routname，编译器向前搜索最近的ROUT伪操作，若routname与该ROUT伪操作定义的名称不匹配，编译器报告错误，汇编失败。<br/>ARM汇编语言中的表达式<br/>表达式是由符号、数值、单目或多目操作符以及括号组成的。<br/>1、字符串表达式<br/>字符串表达式由字符串、字符串变量、操作符以及括号组成。字符串的最大长度为512字节，最小长度为0.下面介绍字符串表达式的组成元素。<br/>字符串：由包含在双引号内的一系列的字符组成。字符串的长度受到ARM汇编语言语句长度的限制。当在字符串中包含美元符号$或者引号＂时，用$$表示一个$，用＂＂表示一个＂。<br/>字符串变量：用伪操作GBLS或者LCLS声明，用SETS赋值。<br/>操作符：<br/>（1）LEN：返回字符串的长度<br/>：LEN：A<br/>其中，A为字符串变量<br/>（2）CHR：可以将0~255之间的整数作为含一个ASCII字符的字符串。当有些ASCII字符不方便放在字符串中时，可以使用CHR将其放在字符串表达式中。<br/>：CHR：A<br/>其中，A为某一字符的ASCII值<br/>（3）STR：将一个数字量或者逻辑表达式转换成串。对于32位的数字量而言，STR将其转换成8个十六进制数组成的串；对于逻辑表达式而言，STR将其转换成字符串T或者F<br/>：STR：A<br/>其中，A为数字量或者逻辑表达式<br/>（4）LEFT：返回一个字符串最左端一定长度的子串<br/>A：LEFT：B<br/>其中，A为源字符串，B为数字量，表示LEFT将返回的字符个数<br/>（5）RIGHT：返回一个字符串最右端一定长度的子串<br/>A：RIGHT：B<br/>其中，A为源字符串，B为数字量，表示RIGHT将返回的字符个数<br/>（6）CC：用于连接两个字符串。<br/>A：CC：B<br/>其中，A为第1个源字符串。B为第2个源字符串。CC操作符将字符串B连接在字符串A的后面。<br/>2、数字表达式<br/>数字表达式由数字常量、数字变量、操作符和括号组成<br/>数字变量用伪操作GBLA或者LCLA声明，用SETA赋值，它代表一个32位的数字量。<br/>操作符：<br/>（1）NOT：按位取反<br/>：NOT：A<br/>其中，A为一个32位数字量<br/>（2）+、—、×、/及MOD算术操作符<br/>A+B，A-B，A×B，A/B<br/>A：MOD：B表示A除以B的余数<br/>（3）ROL，ROR，SHL，SHR移位<br/>A：ROL：B将整数A循环左移B位<br/>A：SHL：B将整数A左移B位<br/>（4）AND、OR及EOR按位逻辑操作符<br/>A：AND：B将数字表达式A和B按位作逻辑与操作<br/>3、基于寄存器和基于PC的表达式<br/>基于寄存器的表达式表示了某个寄存器的值加上（或者减去）一个数字表达式<br/>基于PC的表达式表示了PC寄存器的值加上（或减去）一个数字表达式。基于PC的表达式通常由程序中的标号与一个数字表达式组成。相关的操作符：<br/>（1）BASE：返回基于寄存器的表达式中的寄存器编号。<br/>：BASE：A&nbsp;&nbsp;&nbsp;&nbsp;A为基于寄存器的表达式<br/>（2）INDEX：返回基于寄存器的表达式相对于其基址寄存器的偏移量。<br/>：INDEX：A&nbsp;&nbsp; A为基于寄存器的表达式<br/>（3）＋、﹣：正负号，可以放在数字表达式或者基于PC的表达式前面。<br/>+A（﹣A）&nbsp;&nbsp; A为基于PC的表达式或者数字表达式<br/>4、逻辑表达式<br/>由逻辑量、逻辑操作符、关系操作符以及括号组成，取值范围为{FLASE}和{TRUE}<br/>关系操作符：用于表示两个同类表达式之间的关系。关系操作符和它的两个操作数组成一个逻辑表达式，其取值为{FALSE}或{TRUE}<br/>如A=B 表示A等于B<br/>A/=B，A&lt;&gt;B表示A不等于B<br/>逻辑操作符：进行两个逻辑表达式之间的基本逻辑操作。操作的结果为{FLASE}或{TRUE}<br/>：LNOT：A 逻辑表达式A的值取反<br/>A：LAND：B逻辑表达式A和B逻辑与<br/>5、其他的一些操作符<br/>（1）？：返回定义符号A的代码行所生成的可执行代码的字节数<br/>？A<br/>其中，A为一个符号<br/>（2）DEF：判断某个符号是否已定义<br/>：DEF：A<br/>如果符号A已经定义，上述结果为{TRUE}，否则为{FLASE}<br/>（3）SB_OFFSET_19_12<br/>：SB_OFFSET_19_12：label 其中，label为一个标号<br/>返回（label-SB）的bits[19:12]<br/>（4）SB_OFFSET_11_0<br/>：SB_OFFSET_11_0：label<br/> <br/>]]></description>
		</item>
		
			<item>
			<link>http://www.zjidea.com/blog/article/program/2010-01-29-Discuz.htm</link>
			<title><![CDATA[修改Discuz 注册文件防注册机]]></title>
			<author>lzq0323@yahoo.com.cn(相逢萍水)</author>
			<category><![CDATA[Web编程]]></category>
			<pubDate>Fri,29 Jan 2010 15:39:26 +0800</pubDate>
			<guid>http://www.zjidea.com/blog/default.asp?id=464</guid>
		<description><![CDATA[论坛最讨厌的就是有注册机来注册，然后发表一大堆垃圾广告，相信广大站长们都各有妙招来对付。前段日子我也架设了一论坛，方便江西老乡们交流，可没想到垃圾贴N多，注册的成员也是乱七八糟的，郁闷之下，改为邀请码注册，虽然是封杀了广告贴，但好多老乡也跟着不能注册了，邀请码不方便得到，论坛人气大大下降。<br/><br/>思来想去，想了一个相对比较好的方法，注册还是需要邀请码，另外单独做一张网页，把邀请码全部从数据库里读出来，想注册的就用一个，这样注册就没多大问题了。当然，如果是人为的来注册发贴，那有可能就防不住了，这方法只能防住注册机来注册，我想，这样应该能减少90%的垃圾广告了吧！<br/><br/>废话不多说，想看效果的到论坛（<a target="_blank" href="http://www.jx0572.com" rel="external">http://www.jx0572.com</a>），下面开始具体操作！<br/><br/><br/><strong>第一步：新建显示邀请码的网页，并传到论坛根目录下（文件名：invit_code.php）</strong><br/><br/><br/>代码如下：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.zjidea.com/blog/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>&lt;!DOCTYPE html PUBLIC &#34;-//W3C//DTD XHTML 1.0 Transitional//EN&#34; &#34;<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" target="_blank" rel="external">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</a>&#34;&gt;<br/>&lt;html xmlns=&#34;<a href="http://www.w3.org/1999/xhtml" target="_blank" rel="external">http://www.w3.org/1999/xhtml</a>&#34;&gt;<br/>&lt;head&gt;<br/>&lt;title&gt;自助获取邀请码&lt;/title&gt;<br/>&lt;meta http-equiv=&#34;Content-Type&#34; content=&#34;text/html; charset=utf-8&#34; /&gt;<br/><br/>&lt;style type=&#34;text/css&#34;&gt;<br/>&lt;!--<br/>body,td,th {<br/>&#160;&#160;&#160;&#160;font-size: 13px;<br/>&#160;&#160;&#160;&#160;line-height: 30px;<br/>}<br/>body {<br/>&#160;&#160;&#160;&#160;margin-top: 0px;<br/>&#160;&#160;&#160;&#160;margin-left: 0px;<br/>&#160;&#160;&#160;&#160;margin-right: 0px;<br/>&#160;&#160;&#160;&#160;margin-bottom: 0px;<br/>}<br/><br/>--&gt;<br/>&lt;/style&gt;<br/>&lt;/head&gt;<br/>&lt;body&gt;<br/>&lt;br /&gt;<br/>&lt;table width=&#34;600&#34; border=&#34;0&#34;&nbsp;&nbsp;align=&#34;center&#34; cellpadding=&#34;0&#34; cellspacing=&#34;0&#34;&gt;<br/>&nbsp;&nbsp;&lt;tr&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&gt;&lt;/td&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;td align=&#34;center&#34;&gt;&lt;font color=&#34;#FF0000&#34;&gt;无邀请码时，请联系QQ：10101840   &lt;a href=&#34;<a href="http://wpa.qq.com/msgrd?V=1" target="_blank" rel="external">http://wpa.qq.com/msgrd?V=1</a>&amp;Uin=10101840&amp;Site=[XXX论坛]&amp;Menu=yes&#34; target=&#34;_blank&#34;&gt;&lt;img src=&#34;<a href="http://wpa.qq.com/pa?p=1:10101840:1" target="_blank" rel="external">http://wpa.qq.com/pa?p=1:10101840:1</a>&#34; border=&#34;0&#34;&gt;&lt;/a&gt;&lt;/font&gt;&lt;/td&gt;<br/>&nbsp;&nbsp;&lt;/tr&gt;<br/>&lt;/table&gt;<br/>&lt;br/&gt;<br/>&lt;table width=&#34;250&#34; border=&#34;0&#34; align=&#34;center&#34; cellpadding=&#34;0&#34; cellspacing=&#34;1&#34; bgcolor=&#34;#E3E3E3&#34;&gt;<br/>&nbsp;&nbsp;&lt;tr&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;td height=&#34;25&#34; align=&#34;center&#34; bgcolor=&#34;#F7F7F7&#34;&gt;邀请码&lt;font color=&#34;#FF0000&#34;&gt;( 随意复制一条即可 )&lt;/font&gt;&lt;/td&gt;<br/>&nbsp;&nbsp;&lt;/tr&gt;<br/>&nbsp;&nbsp;&lt;tr&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;td bgcolor=&#34;#FFFFFF&#34;&gt;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&lt;?php <br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$dbh = mysql_connect(&#39;localhost&#39;,&#39;UserName&#39;,&#39;password&#39;); <br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;mysql_sel&#101;ct_db(&#39;dataname&#39;); <br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$query = &#34;Sel&#101;ct `invitecode`,`status` FROM `cdb_invites` wh&#101;re `status` = 1 o&#114; `status` = 3 &#34;; <br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$res = mysql_query($query, $dbh); <br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$err = mysql_error(); <br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if($err){ <br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;echo &#34;数据库连接出错，请检查！&#34;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$number = 1;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;while($row = mysql_fetch_row($res)){<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;echo &#34;&lt;font color=#FF0000&gt;邀请码&#34;.$number.&#34;: &lt;/font&gt;&#34;.$row[0];<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;echo &#34;&lt;br/&gt;&#34;;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$number = $number +1;<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;mysql_free_result($res);<br/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;?&gt;<br/>&#160;&#160;&#160;&#160;&lt;/script&gt;&lt;/td&gt;<br/>&nbsp;&nbsp;&lt;/tr&gt;<br/>&lt;/table&gt;<br/><br/>&lt;p&gt; &lt;/p&gt;<br/>&lt;/body&gt;<br/>&lt;/html&gt;<br/></div></div><br/>请自己行修改上面文件中的部分代码以适用于你的网站，主要修改如下：<br/><br/>$dbh = mysql_connect(&#39;localhost&#39;,&#39;UserName&#39;,&#39;password&#39;); <br/>mysql_sel&#101;ct_db(&#39;dataname&#39;); <br/><br/>localhost：你数据库的地址，如果和你的网站在同一主机，就用localhost，否则请填你SQL数据库的IP地址。<br/>UserName：SQL数据库登陆的用户名<br/>password：SQL数据库登陆的密码<br/>dataname：SQL数据库的表名<br/><br/><strong>下面的QQ及论坛名请修改：</strong><br/>&lt;font color=&#34;#FF0000&#34;&gt;无邀请码时，请联系QQ：10101840   &lt;a href=&#34;<a href="http://wpa.qq.com/msgrd?V=1" target="_blank" rel="external">http://wpa.qq.com/msgrd?V=1</a>&amp;Uin=10101840&amp;Site=[XXX论坛]&amp;Menu=yes&#34; target=&#34;_blank&#34;&gt;&lt;img src=&#34;<a href="http://wpa.qq.com/pa?p=1:10101840:1" target="_blank" rel="external">http://wpa.qq.com/pa?p=1:10101840:1</a>&#34; border=&#34;0&#34;&gt;&lt;/a&gt;&lt;/font&gt;<br/><br/><br/><strong>第二步：修改注册窗口</strong><br/>修改注册窗口的目的是为了让在注册的网友可以找到邀请码<br/><br/>在论坛源码的templates\default文件下，打开register.htm文件，搜索代码&lt;label&gt;&lt;em&gt;{lang invite_code}:&lt;/em&gt;&lt;input type=&#34;text&#34; name=&#34;invitecode&#34; autocomplete=&#34;off&#34; size=&#34;25&#34; maxlength=&#34;16&#34; value=&#34;$invitecode&#34; id=&#34;invitecode&#34; onBlur=&#34;checkinvitecode()&#34; tabindex=&#34;1&#34; class=&#34;txt&#34; /&gt;&lt;!--{if $regstatus == 2}--&gt; *&lt;!--{/if}--&gt;&lt;/label&gt;，大概在85行左右，在其后面添加如下代码：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.zjidea.com/blog/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">&lt;label&gt;&lt;em&gt; &lt;/em&gt;{lang invit_addr}&lt;/label&gt;</div></div><br/><br/><span style="color:Red">至于为什么要用{lang invit_addr}而不是直接写上文字，我其实也不清楚，第一次修改Discuz文件，对其框架结构也不熟，一开始我是直接写上文字的，但全部以失败告终，经过N次实验之后才知道代码里不能有中文字符！</span><br/><br/>然后保存文件并上传到目录templates\default下，覆盖原文件。<br/><br/><strong>第三步：修改变量文件</strong><br/>修改这文件是因为在第二步添加的代码里用到了‘invit_addr’<br/><br/>在论坛源码的templates\default文件下，打开templates.lang.php文件，在&#39;discuz_lang&#39; =&gt; &#39;templates&#39;,下面一行加入下面文字：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.zjidea.com/blog/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>&#39;invit_addr&#39; =&gt; &#39;&lt;a href=&#34;invit_code.php&#34; target=&#34;_blank&#34;&gt;&lt;font color=&#34;#FF0000&#34;&gt; &gt;&gt;点击获得 邀请码&lt;/font&gt;&lt;/a&gt;&#39;,<br/></div></div><br/><br/>保存并上传文件到templates\default目录，覆盖原文件。<br/><br/><strong>第四步：设置注册方式</strong><br/><br/>以管理员帐号登陆后台，在‘全局’--‘注册与访问’里将注册方式改为‘只开放邀请注册’<br/><br/><br/><strong>第五步：添加邀请码</strong><br/><br/>在个人中心里购买邀请码，这样你访问invit_code.php看看是不是有邀请码了。<br/><br/>这样全部搞定！<br/><br/>如果你不会修改文件，并且你也没有修改过论坛代码，你可以用下面的文件直接覆盖就OK了！<br/><br/><br/><br/><img src="http://www.zjidea.com/blog/images/download.gif" alt="下载文件" style="margin:0px 2px -4px 0px"/> <a href="http://www.zjidea.com/blog/attachments/month_1001/1201012915396.rar" target="_blank">点击下载此文件</a><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.zjidea.com/blog/article/computer/2010-01-28_SaveAspdf.htm</link>
			<title><![CDATA[把word 2007 的docx 转化成 pdf]]></title>
			<author>lzq0323@yahoo.com.cn(相逢萍水)</author>
			<category><![CDATA[电脑诊所]]></category>
			<pubDate>Thu,28 Jan 2010 08:25:58 +0800</pubDate>
			<guid>http://www.zjidea.com/blog/default.asp?id=463</guid>
		<description><![CDATA[是不是还在为Office 2007的文件格式转化成pdf文件而苦恼呢？其实你完全不用如此，你只要到Microsoft网站上下载个插件，装上之后，在office中可以把文件发布为pdf格式了。<br/><br/>插件下载页面：<a target="_blank" href="http://www.microsoft.com/downloads/details.aspx" rel="external">http://www.microsoft.com/downloads/details.aspx</a><br/>点击下载按钮下载，不大的文件，几分钟就能下好，下完后安装即可。<br/><br/>安装结束后，打开你的word，然后点击开始中的&#34;另存为\PDF”菜单命令&#34;，然后点击“发布”即可。注意，不会有进度条，所以不要以为软件不动了就是死了或者怎么样，也许你文件大一点会需要一点时间，发布后的效果还是跟在office中看到的效果一样的。]]></description>
		</item>
		
			<item>
			<link>http://www.zjidea.com/blog/article/diary/2010-01-01_newyear.htm</link>
			<title><![CDATA[话别2009，迎接2010]]></title>
			<author>lzq0323@yahoo.com.cn(相逢萍水)</author>
			<category><![CDATA[心情坐标]]></category>
			<pubDate>Sun,10 Jan 2010 08:35:06 +0800</pubDate>
			<guid>http://www.zjidea.com/blog/default.asp?id=462</guid>
		<description><![CDATA[2010年到了，在这先祝福所有的朋友在新的一年里工作顺利，家庭美满，身体倍棒，吃嘛嘛香！<br/><br/>对于2009，最大的事件就是买好了房子，虽然不大，但也算是自己的窝，可以不用担心被人赶出家门了。<br/><br/>另外，2009年，生活和工作都没有多大变化，说好听点应该算是稳定吧，不好听点，生活太平淡，工作没起色，没啥盼头！<br/><br/>不过2009的最后一天，发生了一件让我比较郁闷的事。同学的QQ被盗了，然后让我帮她买5张充值卡，我竟然就买了，不过在最后关头，我同学发短信来提醒说她QQ被盗了，不然充值密码就发给那盗QQ的人了，真是惊险啊！这种事竟然会发生在我的身上，一向以谨慎自居的我，也上当了，也许是和她比较熟，她也经常在网上买东西，因此就没有太多怀疑，直接买下！<br/><br/>提醒大家以后碰到让你帮忙付钱的事，请多留下心眼，先打电话确认后再行动，不然到时就有苦果子吃了！<br/><br/><br/>2010年，新的一年，希望有新发展，有新的成就，有新的机遇！<br/><br/>今天已经有件喜事发生，老婆怀孕了。希望从今天开始，我的喜事连连，我的家庭和事业都会有新的开始<br/><br/>期待2010年的好事！！]]></description>
		</item>
		
			<item>
			<link>http://www.zjidea.com/blog/article/diary/2009-12-21-name_design.htm</link>
			<title><![CDATA[艺术签名设计]]></title>
			<author>lzq0323@yahoo.com.cn(相逢萍水)</author>
			<category><![CDATA[心情坐标]]></category>
			<pubDate>Mon,21 Dec 2009 12:39:29 +0800</pubDate>
			<guid>http://www.zjidea.com/blog/default.asp?id=461</guid>
		<description><![CDATA[练了这么多年，自己的名字总是写不好，拿不出手啊！<br/><br/>于是想在网上找个帮忙设计下自己的签名，可找来找去，基本上是要自己输入手机号来获取，这不就是要自己付费嘛，本来就没几个钱，还是忍下吧，继续寻找免费的。。。<br/><br/>功夫不负有心人，终于让我找到了一下，哈哈~~~~<br/><br/>如果各位看官也想给自己来个签名设计，请留下您的大名与邮箱，我定会发送于你！<br/><br/>请看下面的例子：<br/><br/><img src="http://www.zjidea.com/blog/attachments/month_0912/82009122112350.jpg" border="0" alt=""/><br/><br/>另外还附带有名字解析，不过纯属娱乐，请勿当真！<br/><br/><img src="http://www.zjidea.com/blog/attachments/month_0912/a20091221123836.jpg" border="0" alt=""/><br/><br/>]]></description>
		</item>
		
			<item>
			<link>http://www.zjidea.com/blog/article/diary/my_dead_hard_disk.htm</link>
			<title><![CDATA[悼念我那逝去的硬盘]]></title>
			<author>lzq0323@yahoo.com.cn(相逢萍水)</author>
			<category><![CDATA[心情坐标]]></category>
			<pubDate>Wed,16 Dec 2009 12:09:48 +0800</pubDate>
			<guid>http://www.zjidea.com/blog/default.asp?id=460</guid>
		<description><![CDATA[上星期六写了个程序，让做硬件的工程师来测试，没想到他测试的时候一不小心短路，整个房间跳电，我的本本也直接关机，然后再也开不起来了 <img src="http://www.zjidea.com/blog/images/smilies/Face_11.gif" border="0" style="margin:0px 0px -2px 0px" alt=""/>，经检测是硬盘坏了，只等着换一个新硬盘！只是有一件事让我想不通，通过USB也能让硬盘给挂了。测试硬件的板子短路，然后把USB写入器也给烧了，再直接进入电脑，我想也就USB端口烧坏，最多再加个主板也跟着烧，但万万没想到是硬盘烧坏了！气啊！！<br/><br/>这电脑是去年4月份的时候买的，各种资料也就从那时开始慢慢积累，到现在也有不少了，现在硬盘一坏，数据也就拷贝不出来了，郁闷啊！不过值得幸运的是，原来所写的程序上个月刚过做过备份，而从备份后也没有新的程序写，只是有的程序简单的修改了些，现在只能把修改过的程序再重新修改一次了！<br/><br/>至于个人资料，上次备份的时候已经把所有相片全部拷贝回家，剩下的财务记录，QQ聊天记录，以及平时搜集的各种资料也就全部Over <img src="http://www.zjidea.com/blog/images/smilies/Face_10.gif" border="0" style="margin:0px 0px -2px 0px" alt=""/>！！<br/><br/>教训是惨痛的，以后要学会经常备份数据，万一哪天又有什么不测风云，也不至于一命乌乎！<br/><br/>各位看官，现在赶紧备份次数据吧！说不定下哪天就轮到你了！ <img src="http://www.zjidea.com/blog/images/smilies/Face_03.gif" border="0" style="margin:0px 0px -2px 0px" alt=""/><br/><br/>That&#39;s go,do it now！<br/><br/>]]></description>
		</item>
		
</channel>
</rss>
