1 工具介绍

1.1 ADS 命令行命令介绍

1.1.1 armasm

1. 命令:armasm [选项] -o 目标文件 源文件

2. 选项说明

-Errors 错误文件名        ;指定一个错误输出文件

-I 目录[,目录]                 ;指定源文件搜索目录

-PreDefine  预定义宏     ;指定预定义的宏

-NOCache                   ;编译源代码时禁止使用Cache进               优化

-MaxCache <n>              ;编译源代码时使用Cache进             优化

-NOWarn                    ;关闭所有的警告信息

-G                         ;输出调试表

-keep                      ;在目标文件中保存本地符号表

-LIttleend                 ;生成小端(Little-endian) ARM代码

-BIgend                    ;生成大端(Big-endian) ARM代码

-CPU    <target-cpu>       ;设立目标板ARM核类型,如: arm920t.

-16                        ;建立16位的thumb指令.

-32                        ;建立 32位的ARM指令.

3. 编译一个汇编文件

c:/adsloader>armasm -LIttleend -cpu ARM920T -32 bdinit.s

把汇编语言编译成小端, 32位, ARM920T CPU.

1.1.2 armcc, armcpp

1. 命令:armcc [选项] 源文件1 源文件2 ... 源文件n

2. 选项说明

-c                         ;编译但是不连接

-D                         ;指定一个编译时使用的预定义宏常量

-E                         ;仅仅对C源文件做预处理

-g                         ;产生调试信息表

-I                         ;指头文件的搜索路径

-o<file>                   ;指定一个输出的目标文件

-O[0/1/2]                  ;指定源代码的优化级别

-S                         ;输出汇编代码来代替目标文件

-CPU    <target-cpu>       ;设立目标板ARM核类型,如: arm920t.

3.编译一个C程序

c:/adsloader>armcc -c -O1 -cpu ARM920T bdisr.c

编译不连接, 二级优化, ARM920T CPU.

1.1.3 armlink

1. 命令:armlink [选项] 输入文件

2. 选项说明

-partial                   ;合并目标文件

-Output 文件              ;指定输出文件名

-scatter 文件             ;按照指定的文件为可执行文件建立内存映射

-ro-base 地址值           ;只读代码段的起始地址

-rw-base 地址值           ;RW/ZI段的起始地址

3. 把多个目标文件合并成一个目标文件

c:/adsloader>armlink -partial bdmain.o bdport.o bdserial.o bdmmu.o bdisr.o -o

bd.o

4. 把几个目标文件编译一个可执地文件

c:/adsloader>armlink bd.o bdinit.o -scatter bdscf.scf -o bd.axf

1.1.4 fromelf

1. 命令:fromelf [选项] 输入文件

2. 选项说明

-bin     二进制文件名     ;产生的二进制文件

-elf     elf文件名       ;产生一个elf文件

-text    text文件名      ;产生text文件

3. 产生一个可执行的二进制代码

c:/adsloader>fromelf bd.axf -bin -o bd.bin

2 基本原理

2.1 可执行文件组成及内存映射

2.1.1 可执行文件的组成

在ADS下,可执行文件有两种,一种是.axf文件,带有调试信息,可供AXD调试工具使用.另一种是.bin

文件,可执行的二进制代码文件。我们重点是讲描.bin文件的组成。

我们把可执行文件分为两种情况:分别为存放态和运  态。

1. 存放态

存放态是指可执行文件通过fromelf产生后,在存储介质(flash或磁盘)上的分布. 此时可执行文件一

般由两部分组成:分别是代码段和数据段。代码段又分为可执行代码段(.text)和只读数据段(.rodata),

数据段又分为初始化数据段(.data)和未初始化数据段(.bss)。可执行文件的存放态如下:

+-------------+-----------

|   .bss      |

+-------------+-- 数据段

|   .data     |

+-------------+-----------

|   .rodata   |

|_____________| 代码段

|   .text     |

+-------------+-----------

2. 运  态

可执行文件通过装载过程, 搬入到RAM中运             , 这时候可执行文件就变成运         态。在ADS下对可执行代

码各段有另一个名称:

|    ...      |

+-------------+-----------

|   .bss      | ZI 段

+-------------+-- 数据段

|    .data      | RW 段

+-------------+-----------

|    .rodata    |

|_____________| 代码段(RO 段)

|    .text      |

+-------------+-----------

|     ...       |

装载前

当可执行文件装载后, 在RAM中的分布如下:

|     ...       |

+-------------+-- ZI段结束地址

|     ZI 段     |

+-------------+-- ZI段起始地址

|    保留区2       |

+-------------+-- RW段结束地址

|     RW 段     |

|-------------+-- RW段起始地址

|   保留区1       |

+-------------+-- RO段结束地址

|     RO 段     |

+-------------+-- RO段起始地址

|     ...       |

装载后

所以装载过程必须完成把执行文件的各个段从存储介质上搬到RAM指定的位置。而这个装载过程由谁来完

成呢?由我们的启动程序来完成.

2.1.2 装载过程

在ADS 中,可以通过两种方式来指定可执行代码各段在RAM中的位置,一个是用armlink来指定,一种是

用 scatter文件来指定.RAM区的起始地址:0x30000000.

1. armlink指定代码段地址

我们通常的代码,只用指定两个段开始地址, RO段的起始地址和RW段的起始地址, ZI段紧接在RW段之

后.示例见该部分的1.1.3.

2. scatter指定代码段地址

我们也可以通过 scatter文件指定可执行文件各段的详细地址. Scatter文件如下:

MYLOADER 0x30000000

;MYLOADER: 为可执行文件的名称, 可自定义

;0x3000000: 起始地址

{

RO 0x30000000

;RO 只读代码段的名称

;0x30000000: 只读代码段的起始地址

{

init.o (Init, +First)

; Init 代码段为可执行文件的第一部分.

* (+RO)     ;所有其它的代码段和只读数据段放在该部分

}

RW +0

;RW: RW 段的名称

;+0: 表示RW 段紧接着RO 段

{

* (+RW)    ;所有RW 段放在该部份

}

ZI  +0

;ZI: ZI 段的名称

;+0: 表示ZI 段紧接着RW 段

{

*(+ZI)     ;所有ZI 段放在该部分

}

}

3. ADS 产生的各代码段宏

|Image$$RO$$Base| /* RO 代码段起始地址 */

|Image$$RO$$Limit| /* RO 代码段结束地址 */

|Image$$RW$$Base| /* RW 代码段起始地址 */

|Image$$RW$$Limit| /* RW 代码段结束地址 */

|Image$$ZI$$Base| /* ZI 代码段起始地址   */

|Image$$ZI$$Limit| /* ZI 代码段结束地址   */

注意:在两个$$之间的名称, 与scatter 中指定的段的名称相同.

4. 装载过程说明

当从NorFlash 启动时, 要把flash 芯片的首地址映射到0x00000000 位置, 系统启动后, 启动程序本身把自己从

flash 中搬到RAM 中运  . 搬移后的各段起始地址, 由以上宏来确定.

当从NandFlash 启动时, S3C2410 会自动把前NandFlash 的前4k 搬到S3C2410 的内部RAM 中,并把内部

RAM 的首地址设为0x00000000 ,CPU 从0x00000000 开始执        . 所以, 在nandFlash 的前4k 程序中,必须包含从

NandFlash 把BootLoader 的其余部分装入RAM 的程序.

2.1.3 启动过程的汇编部分

当系统启动时, ARM CPU 会跳到0x00000000 去执         。一般BootLoader 都包括如下几个部分:

1.  建立中断向量异常表

2. 显示的切换到SVC 且32 指令模式

3. 关闭S3C2410 的内部看门狗

4. 禁止所有的中断

5. 配置系统时钟频率和总线频率

6. 设置内存区的控制寄存器

7. 初始化中断

8. 安装中断向表量

9. 把可执行文件的各个段搬到运           态的各个位置

10. 跳到C 代码部分执

2.1.4 启动过程的 C部分

1. 初始化MMU

2.初始化外部端口

3. 中断处理程序表初始化

4.  串口初始化

5. 其它部分初始化(可选)

6. 主程序循环

3 AXD 的使用以及源代码说明

3.1 源代码说明

3.1.1 汇编源代码说明

;===============================================================================

;  引用头文件

;===============================================================================

get bdinit.h

;===============================================================================

; 引用标准变量

;===============================================================================

IMPORT  |Image$$RO$$Base|   ; Base address of RO section

IMPORT  |Image$$RO$$Limit|  ; End address of RO section

IMPORT  |Image$$RW$$Base|   ; Base address of RW section

IMPORT  |Image$$RW$$Limit|  ; End address of RW section

IMPORT  |Image$$ZI$$Base|   ; Base address of ZI section

IMPORT  |Image$$ZI$$Limit|  ; End addresss of ZI section

IMPORT  bdmain    ; The entry function of C program

;===============================================================================

; 宏定义

;===============================================================================

; macro HANDLER

MACRO

$HandlerLabel HANDLER $HandleLabel

$HandlerLabel

sub     sp,sp,#4        ;Decrement sp (to store jump address)

stmfd   sp!,{r0}        ;PUSH the work register to stack

ldr     r0,=$HandleLabel;Load the address of HandleXXX to r0

ldr     r0,[r0]         ;Load the contents(service routine start address) of HandleXXX

str     r0,[sp,#4]      ;Store the contents(ISR) of HandleXXX to stack

ldmfd   sp!,{r0,pc}     ;POP the work register and pc(jump to ISR)

MEND

;===============================================================================

; 汇编语言的入口代码

;===============================================================================

AREA    Init,CODE,READONLY

CODE32

ENTRY

;=====================

; 建立中断向量表

;=====================

----------------------- 页面 19-----------------------

b   reset_handler   ;0x00000000:   Reset (SVC)

b   undef_handler   ;0x00000004:   Undefined instruction (Undef)

b   swi_handler     ;0x00000008:   Software Interrupt (SVC)

b   iabr_handler    ;0x0000000C:   Instruction Abort (Abort)

b   dabr_handler    ;0x00000010:   Data Abort (Abort)

b   no_handler      ;0x00000014:

b   irq_handler     ;0x00000018:   IRQ (IRQ)

b   fiq_handler     ;0x0000001C:   FIQ (FIQ)

LTORG

undef_handler HANDLER HandleUndef

swi_handler   HANDLER HandleSWI

iabr_handler  HANDLER HandlePabort

dabr_handler  HANDLER HandleDabort

no_handler    HANDLER HandleReserved

irq_handler   HANDLER HandleIRQ

fiq_handler   HANDLER HandleFIQ

;=============================

;  复位时运行的主程序

;=============================

reset_handler

;Set the cpu to SVC32 mode

mrs     r0,cpsr

bic     r0,r0,#0x1f

orr     r0,r0,#0xd3

msr     cpsr_cxsf,r0

;Turn off watchdog

ldr    r0,=WTCON

ldr    r1,=0x0

str    r1,[r0]

;Disable all the first level interrupts

ldr    r0,=INTMSK

ldr    r1,=0xffffffff

str    r1,[r0]

;Disable all the second level interrupts

ldr    r0,=INTSUBMSK

ldr    r1,=0x7ff

str    r1,[r0]

;Configure MPLL

ldr    r0,=MPLLCON

ldr    r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)  ;Fin=12MHz,Fout=200MHz

str    r1,[r0]

;Set FCLK:HCLK:PCLK = 1:2:4

ldr    r0, =CLKDIVN

mov     r1, #3

str    r1, [r0]

;Set memory control registers

ldrr0,=SMRDATA

----------------------- 页面 20-----------------------

ldr     r1,=BWSCON

add     r2, r0, #52           ;End address of SMRDATA

0

ldr     r3, [r0], #4

str    r3, [r1], #4

cmp     r2, r0

bne     %B0

;Initialize stacks

bl      InitStacks

;Setup IRQ handler

ldr     r0,=HandleIRQ         ;This routine is needed

ldr     r1,=IsrIRQ

str    r1,[r0]

;Copy RW/ZI section into RAM

ldr     r0, =|Image$$RO$$Limit|;Get pointer to ROM data

ldr     r1, =|Image$$RW$$Base| ;and RAM cop

ldr     r3, =|Image$$ZI$$Base|

cmp     r0, r1                ; Check that they are different

beq     %F2

1

cmp     r1, r3                ; Copy init data

ldrcc   r2, [r0], #4          ;--> LDRCC r2, [r0] + ADD r0, r0, #4

strcc  r2, [r1], #4          ;--> STRCC r2, [r1] + ADD r1, r1, #4

bcc     %B1

2

ldr     r1, =|Image$$ZI$$Limit| ; Top of zero init segment

mov     r2, #0

3

cmp     r3, r1                ; Zero init

strcc  r2, [r3], #4

bcc     %B3

bl bdmain                 ;Jump to the main function

;Dead loop

1

nop

b       %B1

;===============================================================================

;  初始中断处理程序

;===============================================================================

IsrIRQ

sub    sp,sp,#4       ;reserved for PC

stmfd  sp!,{r8-r9}

ldr     r9,=INTOFFSET

ldr     r9,[r9]

ldr     r8,=HandleEINT0

add     r8,r8,r9,lsl #2

ldr     r8,[r8]

----------------------- 页面 21-----------------------

str     r8,[sp,#8]

ldmfd   sp!,{r8-r9,pc}

;===============================================================================

; 初始化各个模式下堆栈

;===============================================================================

InitStacks

mrs     r0,cpsr

bic     r0,r0,#MODEMASK

orr     r1,r0,#UNDEFMODE|NOINT

msr     cpsr_cxsf,r1          ;UndefMode

ldr     sp,=UndefStack

orr     r1,r0,#ABORTMODE|NOINT

msr     cpsr_cxsf,r1          ;AbortMode

ldr     sp,=AbortStack

orr     r1,r0,#IRQMODE|NOINT

msr     cpsr_cxsf,r1          ;IRQMode

ldr     sp,=IRQStack

orr     r1,r0,#FIQMODE|NOINT

msr     cpsr_cxsf,r1          ;FIQMode

ldr     sp,=FIQStack

bic     r0,r0,#MODEMASK|NOINT

orr     r1,r0,#SVCMODE

msr     cpsr_cxsf,r1          ;SVCMode

ldr     sp,=SVCStack

mov     pc,lr                 ;Return the call routine

LTORG

;===============================================================================

; 内存区控制寄存器值表; 你可根据需要修改bdinit.h 文件, 下面代码不用做任何改动

;===============================================================================

SMRDATA DATA

DCD

(0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(

B7_BWSCON<<28))

DCD

((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))   ;GCS0

DCD

((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))   ;GCS1

DCD

((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))   ;GCS2

DCD

((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))   ;GCS3

DCD

((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))   ;GCS4

DCD

((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))   ;GCS5

DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))    ;GCS6

DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))    ;GCS7

----------------------- 页面 22-----------------------

DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)

DCD 0x32            ;SCLK power saving mode, BANKSIZE 128M/128M

DCD 0x30            ;MRSR6 CL=3clk

DCD 0x30            ;MRSR7

ALIGN

;===============================================================================

; 异常及中断向量表空间; 安装异常或中断处理程序在bdisr.c 中,isr_setup()来完成.

;===============================================================================

AREA RamData, DATA, READWRITE

^   _ISR_STARTADDRESS ;表示下面数据区从_ISR_STARTADDRESS指定的位置开始

HandleReset      #   4

HandleUndef      #   4

HandleSWI        #   4

HandlePabort    #   4

HandleDabort    #   4

HandleReserved  #   4

HandleIRQ         #   4

HandleFIQ         #   4

;=============================

; The Interrupt table

;=============================

HandleEINT0   #   4

HandleEINT1   #   4

HandleEINT2   #   4

HandleEINT3   #   4

HandleEINT4_7 #   4

HandleEINT8_23 #   4

HandleRSV6       #   4

HandleBATFLT  #   4

HandleTICK    #   4

HandleWDT        #   4

HandleTIMER0  #   4

HandleTIMER1  #   4

HandleTIMER2  #   4

HandleTIMER3  #   4

HandleTIMER4  #   4

HandleUART2   #   4

HandleLCD        #   4

HandleDMA0       #   4

HandleDMA1       #   4

HandleDMA2       #   4

HandleDMA3       #   4

HandleMMC        #   4

HandleSPI0       #   4

HandleUART1      #   4

HandleRSV24      #   4

HandleUSBD       #   4

HandleUSBH       #   4

HandleIIC        #   4

HandleUART0      #   4

HandleSPI1       #   4

----------------------- 页面 23-----------------------

HandleRTC     #   4

HandleADC     #   4

END

3.1.2 C语言源代码说明

void bdmain(void)

{

/* 禁止Cache 和MMU */

cache_disable();

mmu_disable();

/* 端口初始化       */

port_init();

/* 中断处理程序     */

isr_init();

/* 串口初始化      */

serial_init(0, 115200);

/* 输出信息进行主循环 */

serial_printf("is ok!/n");

while(1) {

}

}

通常基本ADS 的测试程序都可以在这个架构上加入自己的代码.

3.2 AXD 的使用

3.2.1 配置仿真器

1. 为仿真器安装Server

一般的仿真器都对应有一个Server 程序,所以在使用在线仿真之前,必须先安装这个Server 程序。我使用

是Dragon-ICE 仿真器, 所以先要安装Dragon-ICE Server 程序。

2. 连接仿真器

把dragon-ICE 仿真器的JTAG 口连接上ARM 板(注意:ARM 板要断电连接), 另一端通过并口连接到PC 上,

有的仿真器是通过USB 口连接到PC 上, 这与仿真器的硬件相关。连接好后, 打开ARM 电源,启动ARM 板。

当ARM 通电启动后,启动Dragon-ICE Server 检测ARM 板,详细步骤及设置参见对应的仿真器手册。我的

dragon-ICE Server 启动, 按”自动检测”可以检测到ARM920T 。

3.2.2 启动AXD 配置开发板

1. 启动AXD

先启动Dragon-ICE Server 程序.

按如下步聚启动AXD:

开始->所有程序->ARM Developer Suite v1.2->AXD Debugger

2. 装载仿真器库文件

从AXD 菜单的Options--> Configure Target...启动”Choose Target” 目标板配置窗口.

在”Choose Target”窗口中,点击”Add”按钮,选择仿真器的库文件. 我的仿真器服务器程序安装在

c:/Dragon-ICE 下,所以选择项c:/Dragon-ICE/dragon-ice.dll 文件

----------------------- 页面 24-----------------------

3. 为AXD 在线仿真配置仿真器

在"Target Environments"中选中Dragon-ICE 中,点击右边的"Configure"按钮.

在”FJB Dragon-ICE Release v1.2”窗口点击"This computer..."按钮,再点击"OK"按钮。

回到”Choose Target”窗口,点击"OK"按钮。完成配置.

回到主界面, 在右边的”Target”窗口会出现ARM920T_0.这表明AXD 已经进入ARM 板的在线仿真状态.

点击菜单"System Views"-->"Controls Monitors".会出现"ARM920T-Register"窗口.此时,会显示当前ARM 板上所

有寄存器的状态。

4. 配置ARM 板

如果ARM 板通电后,没有程序运行并把内存区控制寄存器配置好的说,外部RAM 是不能使用的. 所以必须

通过仿真器来设置这些寄存器. 如果ARM 板已经有启动程序并且已经配置好, 这一步可以省略.

首先把2410cfg.txt 拷贝到c:/下.

回到AXD 主界面,  从菜单”System Views” --> “Command Line Interface” 。会出现一个Command Line

Interface 的调试命令  窗口,并显示如下提示符:

Debug >

输入obey c:/2410cfg.txt 装载所有配置命令.

Debug >obey c:/2410cfg.txt

5. 2410cfg.txt 文件说明

sreg psr, 0x00000013

;设置当前CPSR 的值, 把CPU 的模式切换到SVC 模式和32 位指令集,                   关闭IRQ 和FIQ 。

smem 0x53000000,0,32

;设置看门狗控制寄存器WTCON

;禁止看门狗定时器

smem 0x4C000004,((0x74<<12)+(0x3<<4)+0x1),32

;设置主频率设置寄存器MPLLCON

; 目前CPU 的工作频率FCLK 是124.00MHz

smem 0x4C000014,0x3,32

;设置时钟分频寄存器CLKDIVN

;设置FCLK/HCLK/PCLK 的频率比例1:2:4

smem 0x48000000,((2<<28)+(2<<24)+(1<<20)+(1<<16)+(1<<12)+(1<<8)+(1<<4)+0),32

;设置内存总线控制BWSCON

;SDRAM BANK 6&7 is 32 位

;其它BANK is 16 位

smem 0x48000004,((3<<13)+(3<<11)+(7<<8)+(3<<6)+(3<<4)+(3<<2)+3),32

;设置寄存器区0 控制寄存器:BANKCON0

smem 0x4800001c,((3<<15)+(1<<2)+1),32

;设置寄存器区6 控制寄存器: BANKCON6(SDRAM)

作者介绍:本文由尚观科技老师和同学生(刘勇,孙贺,聂强,聂大鹏 ,牛须乐,孙磊)共同创作

;RAS to CAS 延时3 时钟周期

;列地址是9 位

smem 0x48000020,((3<<15)+(1<<2)+1),32

;设置寄存器区7 控制寄存器: BANKCON7(SDRAM)

;RAS to CAS 延时 3 时钟周期

;列地址是9 位

smem 0x48000024,((1<<23)+(3<<18)+(2<<16)+1113),32

;set 外部RAM 刷新寄存器:REFRESH

;允许自刷新

;HCLK=FCLK/2, 60MHz,刷新计算器是1113

smem 0x48000028,0x31,32

----------------------- 页面 25-----------------------

;设置寄存器的大小

;禁止burst 操作

;允许SDRAM power down 模式

;SCLK 在访问期间仍在活动状态

;SDRAM 模式寄存器设置

smem 0x4800002c,0x30,32

smem 0x48000030,0x30,32

3.2.3 使用AXD在线仿真调试程序

1. 装载可执行的文件

AXD 只支持.axf 格式的可执行文件.

启动AXD, 在菜单的File 中,选择Load Image..., 选择c:/adsbloadter/prj/prj_Data/DebugRel/prj .axf 加载执

image. 就可以执行并调试了. AXD 提供了非常方便的调试手段, 包括在线单步,  自由设置断点等.

作者介绍:本文由尚观科技老师和同学生(刘勇,孙贺,聂强,聂大鹏 ,牛须乐,孙磊)共同创作

转自:http://www.uplinux.com/shizi/wenxian/33.html

ARM9 2410移植之系统启动bootloader 的编写(ADS)相关推荐

  1. 【转】ARM9 2410移植之ARM中断原理, 中断嵌套的误区,中断号的怎么来的

    from:https://www.crifan.com/switch_arm9_2410_transplant_arm_interrupt_principle_the_error_interrupt_ ...

  2. ARM9 2410移植之Nand flash 驱动的编写与移植

    1 Nand flash 工作原理 S3C2410 板的Nand Flash 支持由两部分组成:Nand Flash 控制器(集成在S3C2410 CPU)和Nand Flash 存储 芯片(K9F1 ...

  3. [转]ARM9 2410移植之Nand flash 驱动的编写与移植

    1 Nand flash 工作原理 S3C2410 板的Nand Flash 支持由两部分组成:Nand Flash 控制器(集成在S3C2410 CPU)和Nand Flash 存储 芯片(K9F1 ...

  4. ARM9 2410移植之ARM中断原理, 中断嵌套的误区,中断号的怎么来的

    几天前一个学生问我ARM中断嵌套的问题,我才发现原在我心中理所当然的事对学生来说理解实属不易.      ARM有七种模式,我们这里只讨论SVC.IRQ和FIQ模式.      我们可以假设ARM核心 ...

  5. grub2引导linux内核,一种基于grub2的linux系统启动bootloader的制作方法与流程

    技术领域 本发明涉及服务器应用技术领域,具体涉及一种基于grub2的linux系统启动bootloader的制作方法. 背景技术: 当前linux系统的内核版本已经升级至4.0以上,最新的linux系 ...

  6. STM32CbueMX之 USB下载更新固件Download Firmware Update(DFU)之一BootLoader程序编写

    声明: STM32CbueMX之 USB下载更新固件Download Firmware Update(DFU)之一BootLoader程序编写https://blog.csdn.net/sudaroo ...

  7. stm32f4 CubeMX生成IAR工程 移植ST官方 Bootloader 教程

    目录 一.前言 二.CubeMX生成 IAR 工程 1.CubeMX生成工程 2.官方的IAP例程 三.移植bootloader 1.移植相关代码 2.flash_if.h文件修改 3.准备App程序 ...

  8. ARM9nbsp;2410移植之ARM中断原理,…

    作者:李柏章 几天前一个学生问我ARM中断嵌套的问题,我才发现原在我心中理所当然的事对学生来说理解实属不易. ARM有七种模式,我们这里只讨论SVC.IRQ和FIQ模式. 我们可以假设ARM核心有两根 ...

  9. Uboot中start.S源码的指令级的详尽解析

    Uboot中start.S源码的指令级的详尽解析 版本:v1.9 Crifan Li 摘要 本文对Uboot中的Start.S的源码的几乎每一行,都进行了详细的解析 本文提供多种格式供: 在线阅读 H ...

最新文章

  1. 解析C语言中的sizeof
  2. java内部类 缺点_Java中的内部类及其优势
  3. AI修复100年前晚清影像喜提热搜,这两大算法立功了
  4. 二叉树两个结点的最低公共父结点 【微软面试100题 第七十五题】
  5. AcWing 1402. 星空之夜 1月28
  6. 4chan 爬虫_类似4chan网站
  7. 用VS开发PHP扩展
  8. arcgis的numpy模块_01. Numpy模块
  9. 安全防御——防病毒网关
  10. python树莓派_树莓派python
  11. 凉州馆中与诸判官夜集
  12. 免驱无线网卡插到电脑上突然驱动变成瑞昱网卡了无法正常联网
  13. 遗传算法优化LSTM网络结构(实现自动根据适应度函数:即准确率来全局搜索最佳网络结构):主要被优化参数:网络层数,每层的神经元个数,全连接的层数,全连接层的神经元个数。代码有详细注解
  14. Appweb+ESP学习笔记
  15. 鼠标悬停帮助图标显示文字提示框代码
  16. Blueprint介绍和使用
  17. [纵横网络靶场社区]组态软件分析
  18. Netty高级进阶之Netty解码器
  19. Axure9中点击变颜色、形状等样式操作
  20. phonegap(cordova) 自定义插件代码篇(三)----支付宝支付工具整合

热门文章

  1. 妈妈再也不用担心我的学习了:“婷婷心选”直播首秀有感
  2. 大学十年(一个程序员的路程)林锐
  3. java图片马赛克_java实现图片缩放、旋转和马赛克化
  4. 架设传奇,问道,怎么选服务器
  5. Docker结合.Net Core初步使用
  6. Word Embedding 和Skip-Gram模型 的实践
  7. doc2html asp,用asp实现网页调用doc附Response.ContentType 详细列表
  8. 大数问题,为什么是1e9+7?
  9. 炉石兄弟 Hearthbuddy 新手教程
  10. 电网储能电池的Matlab代码