u-boot 启动过程 —— 基于S3C2410

发布者:GoldenSunrise最新更新时间:2016-07-26 来源: eefocus关键字:u-boot  启动过程  S3C2410 手机看文章 扫描二维码
随时随地手机看文章
本文以流行的Samsung公司的S3C2410,openmoko平台和u-boot-1.3.2(2008.5 发布)为例,介绍如何在ZIX嵌入式开发环境下探索u-boot启动过程。

虽然u-boot已经广泛应用,由于其相对的复杂性使用户在了解其内部机理和进行u-boot的移植工作时还是会碰到困难。u-boot已有一些分析文档,但多数和真正的代码不能同步或者版本老旧,难以将概念和现实的代码匹配——即硬件板上跑的代码在文档资料中却看不到,更无法紧密的跟踪。本文涉及的代码基于在s3c2410硬件运行的成熟u-boot-1.3.2代码,版本较新,提供的特性非常丰富,而且在forum.linuxbj.com可以自由浏览下载。此u-boot代表了业界的较高水平,可以直接构建新版的嵌入式产品设计,有较高的应用价值。

u-boot总的启动流程如下
->reset
-> 设置CPU模式
-> 关闭看门狗/中断
-> 设置处理器时钟/片上总线
-> 初始化调试串口
-> MMU/外部总线/SDRAM等初始化
-> rom代码/数据搬移到ram
-> 初始化函数调用栈
-> 初始化外围设备/参数
-> 启动完毕,进入main_loop循环

嵌入式系统离不开bootloader初始化硬件以及引导操作系统。
现在,专用的嵌入式板子运行嵌入式Linux系统已经变得非常流行,u-boot是一种非常适合此类系统的bootloader。

u-boot主要提供以下功能:

  • 设置目标板硬件参数并初始化;
  • 为操作系统传递必要信息;
  • 执行交互式的底层操作;
  • 智能化装载操作系统;
  • 引导和运行的固件程序;
  • 支持大容量存储和USB接口

 

利用ZIX开发环境,能够通过比较直观的方式观察u-boot内部,而且可以将代码调试和分析同时进行,是一种了解、移植u-boot的强大工具。

使用arm工具链编译u-boot源代码,得到可以烧录的u-boot.bin文件。 
在ZIX开发环境里,可以将u-boot.bin载入s3c2410板运行,并利用gdb调试。

gdb能通过JTAG接口访问硬件,也可以通过TCP/IP访问虚拟硬件。 建立好调试连接,即可通过gdb操纵u-boot启动过程,下面可以跟随代码的执行顺序,了解从上点开始,究竟哪些操作被执行。

s3c2410复位之后,pc指针会指向0x0地址。在u-boot代码中,该0x0地址是一个向量表,
第一条指令跳转branch到复位代码start_code。 位于cpu/arm920t/start.S汇编语言文件第53行:

DE>.globl _start  _start: DE> DE>b start_code DE> 
DE>    DE>ldr pc, _undefined_instruction 
DE>    DE>ldr pc, _software_interrupt 
DE>    DE>ldr pc, _prefetch_abort 
DE>    DE>ldr pc, _data_abort 
DE>    DE>ldr pc, _not_used 
DE>    DE>ldr pc, _irq 
DE>    DE>ldr pc, _fiq

复位指令跳转之后来到第154行,开始执行arm920t处理器的基本初始化。
首先修改当前程序状态寄存器CPSR,使处理器进入Supervisor|32 bit ARM模式,
并关闭ARM9TDMI中断和快速中断,这是通过设置CPSR相应掩码实现的:

DE>start_code: 
DE>DE>    DE>DE>/* 
DE>DE>    DE>DE> * set the cpu to SVC32 mode 
DE>DE>    DE>DE> */  
DE>DE>    DE>DE>mrs r0,cpsr 
DE>DE>    DE>DE>bic r0,r0,#0x1f 
DE>DE>    DE>DE>orr r0,r0,#0xd3 
DE>DE>    DE>DE>msr cpsr,r0 DE> 

紧接着,将S3C2410特有的WTCON寄存器清零,此举仅为关闭看门狗,代码位置是234行

DE>    DE>DE>ldr r0, =pWTCON 
DE>DE>    DE>DE>mov r1, #0x0 
DE>DE>    DE>DE>str r1, [r0] DE>

然后在241行,将S3C2410中断控制器INTMSK寄存器置为全1,
INTSUBMSK置为0x7ff,禁止全部中断源。S3C2410手册358页起对此有详细描述:

DE>    DE>DE>mov r1, #0xffffffff  
DE>DE>    DE>DE>ldr r0, =INTMSK 
DE>DE>    DE>DE>str r1, [r0]  
# if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442) || \  
DE>DE>  DE>DE>defined(CONFIG_S3C2443)  
DE>DE>    DE>DE>ldr r1, =INTSUBMSK_val  
DE>DE>    DE>DE>ldr r0, =INTSUBMSK  
DE>DE>    DE>DE>str r1, [r0]  
# endif DE> 

接下来在259行,访问arm920t控制寄存器CP15,并置位最高两位〔31,30〕。
此两位置为0b11后,处理器时钟被设置为异步模式,允许处理器异步访问总线:

DE>    DE>DE>mrc p15, 0, r1, c1, c0, 0 
DE>DE>    DE>DE>orr r1, r1, #0xc0000000 
DE>DE>    DE>DE>mcr p15, 0, r1, c1, c0, 0 DE>

至此arm920t相关的配置完成,后面开始设定S3C2410时钟合成参数。
通过设置UPLL,MPLL和CLKDIVN三个寄存器(在S3C2410手册237页起讲述),
得到需要的处理器工作频率,分别在308行

DE>    DE>DE>ldr r0, =UPLLCON  
DE>DE>    DE>DE>ldr r1, =UPLLCON_val 
DE>DE>    DE>DE>str r1, [r0] DE>

321行

DE>    DE>DE>ldr r1, =MPLLCON_val  
DE>DE>    DE>DE>str r1, [r0, #-4]DE>DE>    DE>DE>/* MPLLCON */DE>DE>

DE>DE>    DE>DE>/* FCLK:HCLK:PCLK = 1:2:4 */ 
DE>DE>    DE>DE>ldr r0, =CLKDIVN 
DE>DE>    DE>DE>mov r1, #CLKDIVN_val 
DE>DE>    DE>DE>str r1, [r0] DE>

S3C2410的UART0得到初始化,以便于尽早通过UART0打印信息。
此段代码从332行开始,其中涉及到的寄存器读者可参考S3C2410手册293页起:

DE>    DE>DE>/* enable uart */
DE>DE>    DE>DE>ldr r0, =0x4c00000c /* clkcon */ 
DE>DE>    DE>DE>ldr r1, =0x7fff0 /* all clocks on */ 
DE>DE>    DE>DE>str r1, [r0] DE>DE>
DE>DE>    DE>DE>/* gpio UART0 init */ 
DE>DE>    DE>DE>ldr r0, =0x56000070 
DE>DE>    DE>DE>mov r1, #0xaa 
DE>DE>    DE>DE>str r1, [r0] DE>DE>
DE>DE>    DE>DE>/* init uart */ 
DE>DE>    DE>DE>ldr r0, =0x50000000 
DE>DE>    DE>DE>mov r1, #0x03 
DE>DE>    DE>DE>str r1, [r0] 
DE>DE>    DE>DE>ldr r1, =0x245 
DE>DE>    DE>DE>str r1, [r0, #0x04] 
DE>DE>    DE>DE>mov r1, #0x01 
DE>DE>    DE>DE>str r1, [r0, #0x08] 
DE>DE>    DE>DE>mov r1, #0x00 
DE>DE>    DE>DE>str r1, [r0, #0x0c] 
DE>DE>    DE>DE>mov r1, #0x1a 
DE>DE>    DE>DE>str r1, [r0, #0x28] DE>

完成UART0设置之后,根据不同的编译时选项和运行时参数,代码会在360行进入相应的分支,分别是

  1. nand启动,代码执行lowlevel_init,主要是清除cpu cache,以及关闭mmu和i-cache,
    并且根据板极硬件配置初始化外部存储器总线和GPIO,最后把代码从nand flash中拷贝到ram中并继续执行。
  2. 从nor启动,与第1种情况相比,仅仅把代码拷贝部分简化,将DATA段从flash中拷贝到ram中,其余相同
  3. 从ram启动,因为u-boot已经处于配置好的ram中,
    所以会跳过所有cache,mmu,sdram,nand和nor相关代码,跳转到done_relocate执行

下面以最复杂的nand启动情况为例分析。首先会跳转到572行执行cpu_init_crit,
通过操作CP15完成flush处理器arm920t的cache和tlb,并关闭mmu和i-cache:

DE>cpu_init_crit:
DE>DE>    DE>DE>/*
DE>DE>    DE>DE> * flush v4 I/D caches 
DE>DE>     DE>DE>*/  
DE>DE>    DE>DE>mov r0, #0 
DE>DE>    DE>DE>mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ 
DE>DE>    DE>DE>mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ DE>DE>  
DE>DE>    DE>DE>/*
DE>DE>    DE>DE> * disable MMU stuff and caches
DE>DE>    DE>DE> */ 
DE>DE>    DE>DE>mrc p15, 0, r0, c1, c0, 0 
DE>DE>    DE>DE>bic r0, r0, #0x00002300DE>DE>     DE>DE>@ clear bits 13, 9:8 (--V- --RS) 
DE>DE>    DE>DE>bic r0, r0, #0x00000087 DE>DE>    DE>DE>@ clear bits 7, 2:0 (B--- -CAM) 
DE>DE>    DE>DE>orr r0, r0, #0x00000002 DE>DE>    DE>DE>@ set bit 2 (A) Align 
DE>DE>    DE>DE>orr r0, r0, #0x00001000 DE>DE>    DE>DE>@ set bit 12 (I) I-Cache 
DE>DE>    DE>DE>mcr p15, 0, r0, c1, c0, 0 DE>

然后跳转到board/neo1973/common/lowlevel_init.S文件的139行执行,
进行总线数据宽度、时序、SDRAM控制、GPIO等配置,配置完毕后会返回start.S继续执行。
因为该代码是与板相关,故放在board目录里面。由于代码较多,只粘贴开始部分:

DE>    DE>DE>/* memory control configuration */  
DE>DE>    DE>DE>/* make r0 relative the current location so that it */  
DE>DE>    DE>DE>/* reads SMRDATA out of FLASH rather than memory ! */ 
DE>DE>    DE>DE>adr r0, SMRDATA  
DE>DE>    DE>DE>ldr r1, =BWSCON /* Bus Width Status Controller */ 
DE>DE>    DE>DE>add r2, r0, #13*4 DE>

完成板级设置后,在cpu/arm920t/start.S的373行判断代码自身的执行位置。如果从stepping stone内执行,
并且u-boot配置为nand boot模式,则跳转到nand_load拷贝代码:

DE>    DE>DE>ldr r1, =BWSCON /* Z = CPU booted from NAND */ 
DE>DE>    DE>DE>ldr r1, [r1] 
DE>DE>    DE>DE>tst r1, #6 /* BWSCON[2:1] = OM[1:0] */ 
DE>DE>    DE>DE>teqeq r0, #0 /* Z &= running at address 0 */ 
DE>DE>    DE>DE>beq nand_load DE>

417行是nand_load代码,首先会跳转到614行执行may_resume
以检测系统是从待机模式唤醒还是上电启动。如果唤醒,则会根据之前保存的现场进行相应处理,
本文不做更多叙述;如果是启动,则会返回nand_load继续执行。在nand_load里初始化s3c2410的nand controller,
涉及存储器映射和寄存器NFCONF等,参见S3C2410手册215页起。同样,仅粘贴开始部分的代码: 

DE>    DE>DE>mov r1, #S3C2410_NAND_BASE 
DE>DE>    DE>DE>ldr r2, =0xf842 @ initial value enable tacls=3,rph0=6,rph1=0 
DE>DE>    DE>DE>str r2, [r1, #oNFCONF] 
DE>DE>    DE>DE>ldr r2, [r1, #oNFCONF] 
DE>DE>    DE>DE>bic r2, r2, #0x800 @ enable chip 
DE>

451行继续根据配置设定栈指针,为后面调用C函数执行拷贝作准备:

DE>    DE>DE>ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ 
DE>DE>    DE>DE>sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ 
DE>DE>    DE>DE>sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ 
#ifdef CONFIG_USE_IRQ 
DE>DE>    DE>DE>sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) 
#endif 
DE>DE>    DE>DE>sub sp, r0, #12 /* leave 3 words for abort-stack */ 
DE>

然后在460行,将SDRAM中的目标地址存入r0,0x0地址存入r1,u-boot长度存入r2,
跳入cpu/arm920t/s3c24x0/nand_read.c文件第154行执行nand_read_ll函数,该函数接受前面3个寄存器中的值作为参数,并将返回值放回r0:

DE>    DE>DE>ldr r0, _TEXT_BASE 
DE>DE>    DE>DE>mov r1, #0x0 
DE>DE>    DE>DE>mov r2, #CFG_UBOOT_SIZE 
DE>DE>    DE>DE>bl nand_read_ll DE>

在nand_read_ll函数中实现了nand flash访问代码,并且支持自动跳过坏块的特性,函数循环执行nand页面读取并存入SDRAM,直到u-boot全部拷贝完,并返回0,该C代码留给读者自己阅读。nand_read_ll返回0后,会跳转到ok_nand_read,并482行对拷贝的头4K字节进行校验:

DE>    @ verify 
    mov r0, #0 
    @ldr r1, =0x33f00000 
    ldr r1, _TEXT_BASE 
    mov r2, #0x400 DE>DE>    DE>DE>@ 4 bytes * 1024 = 4K-bytes 
go_next: 
DE>DE>    DE>DE>ldr r3, [r0], #4 
DE>DE>    DE>DE>ldr r4, [r1], #4 
DE>DE>    DE>DE>teq r3, r4 
DE>DE>    DE>DE>bne notmatch 
DE>DE>    DE>DE>subs r2, r2, #4 
DE>DE>    DE>DE>beq done_nand_read 
DE>DE>    DE>DE>bne go_next DE>

校验通过后代码506行,在地址为_booted_from_nand的SDRAM位置保存1,以便告诉上层软件本次启动是从nand引导:

DE>done_nand_read: 
DE>DE>    DE>DE>ldr r0, _booted_from_nand 
DE>DE>    DE>DE>mov r1, #1 
DE>DE>    DE>DE>strb r1, [r0] DE>

然后在518行,将中断向量表拷贝到0x0: 

DE>    DE>DE>mov r0, #0 
DE>DE>    DE>DE>ldr r1, _TEXT_BASE 
DE>DE>    DE>DE>mov r2, #0x40 
irqvec_cpy_next: 
DE>DE>    DE>DE>ldr r3, [r1], #4 
DE>DE>    DE>DE>str r3, [r0], #4 
DE>DE>    DE>DE>subs r2, r2, #4 
DE>DE>    DE>DE>bne irqvec_cpy_next DE>

532行,设置栈指针: 

DE>    DE>DE>ldr r0, _TEXT_BASEDE>DE>    DE>DE>/* upper 128 KiB: relocated uboot */ 
DE>DE>    DE>DE>sub r0, r0, #CFG_MALLOC_LENDE>DE>    DE>DE>/* malloc area */ 
DE>DE>    DE>DE>sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ 
#ifdef CONFIG_USE_IRQ 
DE>DE>    DE>DE>sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) 
#endif 
DE>DE>    DE>DE>sub sp, r0, #12DE>DE>    DE>DE>/* leave 3 words for abort-stack */ DE>

541行,清除bss段并跳转到真正的C函数start_armboot,进入更高级的硬件初始化代码,汇编初始化部分也全部完成使命: 

DE>    DE>DE>ldr r0, _bss_start /* find start of bss segment */ 
DE>DE>    DE>DE>ldr r1, _bss_end /* stop here */ 
DE>DE>    DE>DE>mov r2, #0x00000000 /* clear */ DE>DE> 
clbss_l:
DE>DE>    DE>DE>str r2, [r0] /* clear loop... */ 
DE>DE>    DE>DE>add r0, r0, #4 
DE>DE>    DE>DE>cmp r0, r1 
DE>DE>    DE>DE>ble clbss_l DE>DE> 
DE>DE>    DE>DE>ldr pc, _start_armboot DE>

start_armboot函数位于lib_arm/board.c文件第277行,首先初始化globel_data类型的变量gd。该变量是一个结构,其成员大多是板子的一些基本设置,如序列号、ip地址、mac地址等(欲知结构的原型可参考include/asm-arm/globel_data.h和include/asm-arm/u-boot.h): 

DE>         DE>DE>gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
DE>DE>         DE>DE>/* compiler optimization barrier needed for GCC >= 3.4 */
         __asm__ __volatile__("": : :"memory");

DE>DE>         DE>DE>memset ((void*)gd, 0, sizeof (gd_t));
         gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
DE>DE>         DE>DE>memset (gd->bd, 0, sizeof (bd_t)); DE>

然后在一个for循环中从init_sequence地址开始,逐个调用初始化C函数至NULL为止。这些routine函数按调用顺序分别是

  1. cpu_init() ——在common/main.c文件,执行初始化中断栈操作
  2. board_init() ——在board/neo1973/gta01/gta01.c文件中,执行板级初始化,主要是更新GPIO和PLL设置
  3. interrupt_init() ——在/cpu/arm920t/s3c24x0/interrupts.c文件中,执行时钟中断初始化
  4. env_init() ——在common/env_nand.c文件中,设置缺省环境变量
  5. init_baudrate() ——在lib_arm/board.c文件中,将环境变量中的baudrate存入bd_info结构bd
  6. serial_init() ——在common/serial.c文件中,调用驱动中真正的init()初始化串口
  7. console_init_f() ——在common/console.c文件中,更新global_data结构gd的have_console标记为1
  8. display_banner() ——在lib_arm/board.c文件中,打印u-boot banner,输出版本、运行地址等信息。比如在控制台看到的
  9. init_func_i2c() ——在lib_arm/board.c文件中,初始化i2c总线
  10. dram_init() ——在board/neo1973/gta01/gta01.c文件中,填充bd->bi_dram[0]的start和size成员,用来描述u-boot可用的ram
  11. display_dram_config() ——在board/neo1973/gta01/gta01.c文件中,打印当前ram配置。在控制台能够看到相应的 DRAM:  128 MB

利用gdb可以清晰的看到调用过程:

DE>         DE>DE>for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { 
DE>DE>         DE>DE>         DE>DE>if ((*init_fnc_ptr)() != 0) { 
DE>DE>         DE>DE>         DE>DE>         DE>DE>hang (); 
DE>DE>         DE>DE>         DE>DE>} 
DE>DE>         DE>DE>} DE>

接着是一些可选外设的初始化,如显示屏、nor、nand、dataflash、网卡等,此过程执行后全部初始化工作完成。下面仅粘贴nor代码:

DE>#ifndef CFG_NO_FLASH 
DE>DE>         DE>DE>/* configure available FLASH banks */ 
DE>DE>         DE>DE>size = flash_init (); 
DE>DE>         DE>DE>display_flash_config (size); 
#endif /* CFG_NO_FLASH */ DE>

之后在457行进入无限循环,调用common/main.c文件的278行main_loop()函数,u-boot完成启动过程。main_loop提供一个交互式命令行,可通过串口或usb控制台操作,也可以进一步引导操作系统:

DE>         DE>DE>for (;;) { 
DE>DE>         DE>DE>         DE>DE>main_loop (); 
DE>DE>         DE>DE>} DE>
关键字:u-boot  启动过程  S3C2410 引用地址:u-boot 启动过程 —— 基于S3C2410

上一篇:关于s3c2410从NAND Flash启动的问题--bootrom 4KB限制
下一篇:解决2.95.3 arm-linux-gcc编译错误问题

推荐阅读最新更新时间:2024-03-16 15:01

基于S3C2410的Linux驱动程序开发
1. 开发环境的建立在嵌入式系统中,由于目标机资源有限,因此通常是在主机上编译好驱动程序以及应用程序,然后通过串口、以太网、仿真器或其他通信手段与目标机通信。为了方便进行Linux设备驱动的开发和调试,首先必须建立良好的开发环境,包括交叉编译环境的建立、minicom的设置以及nfs网络文件系统的建立。 (1) 交叉编译环境由于我采用的是ARM9 S3C2410处理器,因此必须在主机上建立针对目标板处理器的GNU工具链,这个过程相当复杂繁琐,开发者可以采用编译好的针对ARM处理器的交叉工具链arm-linux-gcc,只需对其进行安装即可。首先,在/usr/local下建立目录arm,接着把压缩包arm-linux-gc
[单片机]
入门 | S3C2440启动过程分析
S3C2440启动过程算是一个难点,不太容易理解,而对于S3C2440启动过程的理解,影响了后面裸机代码执行流程的分析,从而看出S3C2440启动过程的重要性。 S3C2440启动方式和启动方式选择 在S3C2440的datasheet《S3C2440A_UserManual_Rev13.pdf》中搜索map,可以在第5章中搜索到下图。 从此图中,可以得知 OM = 01,10,Not using NAND flash for boot ROM OM = 00,Using NAND flash for boot ROM 而OM 又是什么呢? 从S3C2440的datasheet《S3C2440A_UserManua
[单片机]
入门 | S3C2440<font color='red'>启动</font><font color='red'>过程</font>分析
移植嵌入式Linux到ARM处理器S3C2410:BootLoader
BootLoader指系统启动后,在操作系统内核运行之前运行的一段小程序。通过BootLoader,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。通常,BootLoader是严重地依赖于硬件而实现的,特别是在嵌入式世界。因此,在嵌入式世界里建立一个通用的 BootLoader 几乎是不可能的。尽管如此,我们仍然可以对BootLoader归纳出一些通用的概念来,以指导用户特定的BootLoader设计与实现。   BootLoader 的实现依赖于CPU的体系结构,因此大多数 BootLoader 都分为stage1 和stage2 两大部分。依赖
[单片机]
移植嵌入式Linux到ARM处理器<font color='red'>S3C2410</font>:BootLoader
SDRAM-MEMORY CONTROLLER
重点分析s3c2410复位后的内存映射,及其应用。 一、基本配置 EDUKIT-III采用核心子板加扩展板的设计方式,我学习ARM9,所以采用s3c2410的核心子板。核心子板资源如下: MCU : S3C2410A SDRAM : 两片HY57V561620CT-H NOR FLASH: AM29LV160DB-90EC 扩展板资源: NAND FLASH: K9F5608UOC 二、nand flash boot分析 S3C2410支持从nor/nand flash、eeprom等rom类型的介质启动。现在我想做的是从外部nand flash启动,首先看datasheet第
[单片机]
基于S3C2410的TFT-LCD驱动电路设计
随着电子技术的迅猛发展,具有耗电少、亮度高、体积小等特点的液晶显示器被广泛应用于嵌入式系统中。S3C2410是三星公司开发的一款以ARM920T为核心的16/32位嵌入式处理器。它主要面向手持设备以及高性价比、低功耗的应用。LTS350Q1-PE1是三星电子公司生产的一款非晶硅有源矩阵TFT-LCD,它具有功耗低、亮度高和体积小等特点,目前在嵌入式设备中应用非常广泛。 基于S3C2410,采用LTS350Q1-PE1作为显示设备可以构成一个基于嵌入式平台的液晶显示系统,如图1所示,该系统可以满足大多数嵌入式手持设备的功能要求。但是,要想S3C2410的LCD控制器可以正确有效地控制TFT-LCD,需要设计两者之间的硬
[单片机]
基于<font color='red'>S3C2410</font>的TFT-LCD驱动电路设计
s3c2410中断跳转过程
中断的工作方式如下: 中断是异常模式,当一旦有中断发生,那么就会停止现在正在进行执行的程序,PC指针进而跳入异常向量的地址处。异常地址处,一般存有中断服务子程序的地址,所以,接下来PC指针跳入中断服务子程序中。当完成中断服务子程序后,PC指针会返回到被 打断的程序的下一条地址处,继续执行程序。 在写程序中,如何实现地址的跳转,举例如下: 汇编 _ISR_STARTADDRESS EQU 0x33ffff00 // 中断服务启动栈地址 如果是定时中断 定义定时中断服务子程序: void __irq Timer1_ISR( void ) { ........ //函数体省略 } 现在要把定时中断的
[单片机]
使用S3C2410设计三导联远程心电监护
  主要介绍一种基于S3C2410平台的三导联远程心电监护系统。该系统能够不受时间、空间的限制对心脏病患者进行实时监护,从而方便患者与医护人员随时进行沟通。经过临床测试受到医疗界专家和心脏病患者的高度评价。   1 引 言   随着人们生活水平的提高、生活节奏的加快,心血管疾病的发病率迅速上升,已成为威胁人类身体健康的主要因素之一。而心电图则是治疗此类疾病的主要依据,具有诊断可靠,方法简便,对病人无损害的优点,在现代医学中,变得越来越重要。常规心电图是病人在静卧情况下由心电图仪记录的心电活动,历时仅为几s~1 m,只能获取少量有关心脏状态的信息,所以在有限时间内即使发生心率失常,被发现的概率也是很低的。因此有必要通过相
[医疗电子]
基于S3C2410嵌入式视频监控系统的研究
1 系统硬件结构 本系统采用模块化的结构设计思想,将设备分为主控模块和各个功能模块。主控模块和各功能模块之间有统一的或者特定的接口形式,用户可根据不同的需要选用不同的功能模块,各种类型的数据可以同时传输而不相互干扰,同时也可根据市场的需求继续扩展其它功能模块。远程无线视频监控系统是由以下几个模块组成:嵌入式 ARM2410 核心控制模块、自动报警模块一面使嵌入式模块上的蜂鸣器发出警报声,同时发送报警信号通过GPRS 网络及时的传回远端的监控管理中心,以便管理人员及时发现并处理火情、传感器数据处理模块、USB 摄像头视频图像采集处理模块、GPRS 无线数据传输模块、远程监控软件模块。                     
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved