s3c6410裸机程序(2)

发布者:TranquilDreamer最新更新时间:2024-09-03 来源: cnblogs关键字:s3c6410  裸机程序  中断程序 手机看文章 扫描二维码
随时随地手机看文章

本来以为自己可以很快就把中断程序写好的,但是没想到知道昨天才有了点眉目,虽然还不知道对不对,但是写出来给大家批评指正。


笔者自从上次写了一个轮询式的按键驱动LED灯之后就一直在弄中断这一部分,可是弄来弄去都没什么起色,只好也中断一段时间去配置自己的linux系统,写写应用程序,果然停了几天后突然就成了,真是不知道怎么回事。下面说说笔者的思路。


笔者从《ARM体系结构与编程》这本书中知道了ARM中有七种中断,中断需要中断向量表,而且中断向量表需要放在最低端从地址空间0开始的连续32字节内,为什么七个中断要32字节呢?因为倒数第三个四字节的空间需要空出来。然后是ARM中的中断处理体系,想必阅者都知道x86的中断过程吧,外设通过外设控制器发出中断信号,被中断控制器拦截并进行一定的处理然后发送给CPU,那么ARM肯定也是有中断控制器的,是什么呢?根据s3c6410的用户手册,笔者知道了叫作VIC(全称的中文翻译叫作中断向量控制器)。这个VIC就相当于PC机中的APIC,下面是出事换VIC的代码:


/* 先清除所有中断*/

rVIC0INTENCLEAR = ~(0x0);

rVIC1INTENCLEAR = ~(0x0);

 

 

/* 置中断类型, 全部为IRQ中断*/

rVIC0INTSELECT = 0x0;

rVIC1INTSELECT = 0x0;

 

rVIC0INTENABLE |= 1 << 0;

rVIC0INTENABLE |= 1 << 1;


这个其实很简单,就是让所有中断无效,然后使能按键中断。初始化了VIC之后呢?中断需要三方面协调才可以发生,中断控制器是一个方面,除此之外cpu要能够接受中断,还有就是外设要能够发送中断信号。下面初始化按键:


tmp = rGPNCON;

tmp &= ~0xFFF;

tmp |= 0xAAA;   // 六个按键全部为设置为中断引脚

rGPNCON = tmp; 

rGPNPUD &= ~0xFFF;

 

tmp = rEINT0PEND;

tmp |= 0x1;

tmp |= 0x1 << 1;

rEINT0PEND = tmp;

 

 

tmp = rEINT0MASK;

tmp &= ~(0x3F);

rEINT0MASK = tmp;

 

初始化按键除了要把引脚设置为中断模式外,还有比较重要的就是要清除中断状态寄存器(向对应位写’1‘)和清除中断屏蔽寄存器(对应位清0)。


到了这里似乎就万事俱备,只差中断程序了,但是笔者上次就是在这里遇到了问题,中断向量表要求在地址空间的最低端,但是SDRAM是从0x50000000开始的,程序肯定要下载到这个地址之后的空间,那么笔者自己写的中断向量表怎么办呢?于是笔者想到了使用MMU,把0地址映射到物理地址的0x50200000(程序下载到这个地方),其它部分做相同映射:


start

Interrupt_Vec                         ; 中断向量表

    ldr     PC, ResetAddr

    ldr     PC, UndefAddr

    ldr     PC, SWIAddr

    ldr     PC, PrefetchAddr

    ldr     PC, DataAbortAddr

    DCD     0x0

    ldr     PC, IRQAddr

    ldr     PC, FIQAddr

     

ResetAddr   DCD     ResetInit

UndefAddr   DCD     UndefHandler

SWIAddr     DCD     SWIHandler

PrefetchAddr    DCD     PrefetchHandler

DataAbortAddr   DCD     DataAbortHandler

            DCD     0x0

IRQAddr     DCD     IRQHandler

FIQAddr     DCD     FIQHandler

 

ReservedSpace    SPACE  16384 - 64          ; 页表只能16KB对齐

PageTable       SPACE   16384                 ; 页表,只实现一级映射,1MSection

 

 

; 以下是用不到的中断

UndefHandler

    subs        pc, r14, #4

SWIHandler

    subs        pc, r14, #4

PrefetchHandler

    subs        pc, r14, #4

DataAbortHandler

    subs        pc, r14, #4

FIQHandler

    subs        pc, r14, #4

 

     

EnableMMU

    ; Invalidate entire Cache

    mov     r0, #0

    mcr     p15, 0, r0, c7, c7, 0  

     

    ; Load PageTableBase 

    ldr     r0, =PageTable

    mcr     p15, 0, r0, c2, c0, 0   

     

    ;Field control

    ldr     r0, =0xFFFFFFFF

    mcr     p15, 0, r0, c3, c0, 0

      

     

    ; Enable MMU, Enable I Cache, Disable AP bits

    mrc     p15, 0, r0, c1, c0, 0

    orr     r0, r0, #0x1000

    orr     r0, r0, #0x800000

    orr     r0, r0, #0x1

    mcr     p15, 0, r0, c1, c0, 0

     

     

    mov     pc, r14

    LTORG

     

ResetInit                          ; 复位,设置栈

    LDR     r13, =0x50400000

    bl      _SetPageTable

    bl      EnableMMU

    b       Main

    LTORG

     

IRQHandler                       ; 中断处理

    stmfd   sp!, {r0-r3, r12, r14}

    ldr     r14, =IRQRet

    b       _HandleIRQ

IRQRet

    ldmfd   sp!, {r0-r3, r12, r14}

    subs        pc, r14, #4

     

    LTORG

 至于_SetPageTable这个程序使用c语言实现的:


  


extern int PageTable[];

#define L1_DESCRIPTOR       2

 

int _SetPageTable(void)

{

    int PhyBase;

    int i;

     

    PhyBase = 0x50200000 + L1_DESCRIPTOR;

    PageTable[0] = PhyBase;

     

    for (i = 1; i < 4096; i++)

    {

        PhyBase = 0x0 + L1_DESCRIPTOR + i * 0x00100000;

        PageTable[i] = PhyBase;

    }

    return 0;

}


这样以后,MMU就算是开启了,笔者编译仿真了一下,发现EnableMMU这个程序运行顺利,而且这之后的代码还能正确运行,然后笔者写了中断程序,仍然是按键驱动LED,发现竟然正确运行了。


主函数如下:


void Main(void)

{

 

    InitVIC();  

     

    InitGPIO();

 

    EnableIRQ();

     

    while (1);

}


这就是主流程,可以看出来笔者确实用的中断实现了按键驱动LED。


虽然到这里为止笔者的第一个中断程序算是写出来了,但是上述的程序很容易在中断内部或者InitGPIO函数内死循环,不知道为什么,只好以后解决了,先这样吧!


好文要顶 关注我 收藏该文 微信分享


关键字:s3c6410  裸机程序  中断程序 引用地址:s3c6410裸机程序(2)

上一篇:ARM平台linux内核Notes 1
下一篇:U-Boot-2009-03移植笔记(从Nandflash启动一)

推荐阅读最新更新时间:2024-11-07 12:07

s3c6410裸机程序(2)
本来以为自己可以很快就把中断程序写好的,但是没想到知道昨天才有了点眉目,虽然还不知道对不对,但是写出来给大家批评指正。 笔者自从上次写了一个轮询式的按键驱动LED灯之后就一直在弄中断这一部分,可是弄来弄去都没什么起色,只好也中断一段时间去配置自己的linux系统,写写应用程序,果然停了几天后突然就成了,真是不知道怎么回事。下面说说笔者的思路。 笔者从《ARM体系结构与编程》这本书中知道了ARM中有七种中断,中断需要中断向量表,而且中断向量表需要放在最低端从地址空间0开始的连续32字节内,为什么七个中断要32字节呢?因为倒数第三个四字节的空间需要空出来。然后是ARM中的中断处理体系,想必阅者都知道x86的中断过程吧,外设通过
[单片机]
使能S3C6410的VFP,浮点协处理器
之前一直不知道如何使能硬件协处理器,刚刚在网上找到了方法, 配置好RVDS,选择相应的内核,选择硬件VFP 在初始化代码中加入 VFPEnable EQU (0x40000000) ;VFP使能设置 ;------------------------------------ ; 启用通过协处理器访问VFP控制寄存器 ;------------------------------------ MRC p15, 0, r0, c1, c0, 2 ORR r0, r0, #0x00F00000 MCR p15, 0, r0, c1, c0, 2 ;----------
[单片机]
使能<font color='red'>S3C6410</font>的VFP,浮点协处理器
深入理解ARM体系架构(S3C6410)---S3C6410存储映射
S3C6410的物理内存分成Memory和Pheriperal两部分,地址范围分别为0x0~0x6fffffff和0x7fffffff~0xffffffff。系统通过 SPINE总线访问Memory空间,通过PERI总线访问Pheriperal空间。而为了适应不同外设的访问速度,又分别通过AHB总线访问LCD、 Camera、Accelerator等高速外设,通过APB总线访问iic、watchdog等低速外设。 Memory: (1)启动镜像区物理地址为0x00000000~0x07ffffff,共128MB,是用来启动系统的。但是这个范围内并没有实际的存储介质与之对应,只能在通过OM 选择具体的启动介质后再把相应
[单片机]
深入理解ARM体系架构(<font color='red'>S3C6410</font>)---<font color='red'>S3C6410</font>存储映射
S3C6410之uboot回炉再造(2)地址无关性
这一篇写得有点慢,期间为了弄清楚一些细节的问题耽搁了,不过写得也会更详细。 1 /* 2 ************************************************************************* 3 * 4 * CPU_init_critical registers 5 * 6 * setup important registers 7 * setup memory timing 8 * 9 ************************************************************************* 10 */ 11 /* 12 * we
[单片机]
STM32 USART中断程序
尽管网上的例程一堆堆,但还是花了好几天时间才跑通了一个USART通过中断方式实现的小程序。相当无比地郁闷啊。记录一下遇到的问题: 1. 配置RCC的时机 在主程序中通过查询方式收发数据时,结果并不稳定。对比了ST提供的例程中的设置,将RCC配置提到了所有配置的最前面后,功能实现。结论:应先配置RCC,再初始化其他外设。 2. RAM下调试遇到的问题 在上述查询方式的基础上,增加对NVIC的配置,USART的中断设置,以及ISR中的处理过程,放到RAM下调试,无法进入ISR。有以下两个测试结果:1)在主程序while中调用USART_GetITStatus,判断USART中断事件是否发生及中断是否使能,结果为SET。2)
[单片机]
STM32 USART<font color='red'>中断</font>小<font color='red'>程序</font>
eclipse调试arm裸机程序
一、集成开发环境 软件部分:eclipse , GDB Server , Jlink软件 硬件部分:Jlink硬件 准备工作1:从SD/NOR Flash启动,格式化nand flash 准备工作2:硬件连接 1. Jlink连接 2. 串口连接 3. nand启动 二、安装GDB Server 解压:tar xvzf arm-linux-gdb-7.5.tar.gz 进入目录:cd arm-linux-gdb-7.5 编译安装:./build-all 上面执行好后,gdb工具就安装好了,安装在/opt/arm-linux-gdb 为了方便使用,需要添加环境变量:
[单片机]
eclipse调试arm<font color='red'>裸机</font><font color='red'>程序</font>
S3C6410移植u-boot-2010.3(4)uboot的dnw功能添加
  由于我电脑win7上的DNW-USB驱动一直装不上,所以选择在ubuntu下完成dnw的操作实现与uImage的引导。   先给开发板的uboot添加dnw功能   具体文件可以git这里 https://github.com/plinx/uboot_dnw   1、将cmd_usbd.c拷贝到common目录下   2、添加规则到/common/Makefile # core command ... COBJS-y += cmd_usbd.o   3、将usbd-otg-hs.h,usbd-otg-hs.c拷贝到u-boot/cpu/arm1176/s3c64xx/   4、将regs.h,s3c64
[单片机]
<font color='red'>S3C6410</font>移植u-boot-2010.3(4)uboot的dnw功能添加
mini2440 裸机程序程序心得
1、写裸机程序心得 硬件初始化:a、关闭看门狗 b、初始化时钟 c、配置sdram,并初始化 软件初始化:a、设置堆栈 SP b、设置返回地址 c、调用函数 d、清理工作 看门狗代码: void disable_watch_dog(void) { WTCON = 0; // 关闭WATCHDOG很简单,往这个寄存器写0即可 } 初始化时钟: #define S3C2440_MPLL_200MHZ ((0x5c 12)|(0x01 4)|(0x02)) #define S3C2440_MPLL_400MHZ ((0x5c 12)|(0x01 4)|(0x01)) /* * 对于MPLLC
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved