正在删除 s3c6410裸机程序(2)

发布者:HeavenlyMelody最新更新时间:2024-09-02 来源: 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)

上一篇:s3c6410裸机程序(1)
下一篇:S3C6410移植u-boot-2010.3(1)成功编译的开始

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

s3c2440之外部中断
对s3c2440的硬件操作无非就是配置寄存器,中断也不例外: 需要设置的寄存器: GPGCON :引脚配置寄存器,设置为第二功能,中断引脚; EINTPEND:中断挂起寄存器,当有中断发生且没有被屏蔽,相应位会自动置1,在进入中断服务程序后必须用软件将其相应位清0以免发生错误中断; SRCPND:源挂起寄存器由32位组成,其每一位都涉及一个中断源。如果中断源产生了中断则相应的位被置1并且等待中断服务。此寄存器指示出是哪个中断源正在等待请求服务。 注意:此寄存器不顾INTMAST的屏蔽位,由硬件自动将相应中断位置1,在进入中断服务程序后必须通过写1清除相应位,以防发生错误中断。 EINTMASK:外部中断屏蔽
[单片机]
s3c2440之外部<font color='red'>中断</font>
关于stm32的外部中断与事件的概念
最近在写stm32基础库的时候,发现了一个问题,就是外部中断里,有一个事件寄存器,一直没有明白是干什么用的。网上查了一下,写个总结。 主要的讲,就是在不进入到中断函数的情况下,触发其他的操作。比如,我希望在外部中断的时候,去采集ad。那么其他单片机的做法是,在中断函数中写入adc 采集。而在这里,只需要将事件寄存器置位,然后在其他外设寄存器中设置即可。这样设置,当外部中断被触发时,则可以不用在中断函数中处理adc。直接由事件来驱动adc采集。 这张图是一条外部中断线或外部事件线的示意图,图中信号线上划有一条斜线,旁边标志19字样的注释,表示这样的线路共有19套.图中的蓝色虚线箭头,标出了外部中断信号的传输路径,首先外部
[单片机]
关于stm32的外部<font color='red'>中断</font>与事件的概念
STM32外部中断使用注意事项
stm32尽管所有的gpio都可以设置为外部中断的功能,但是不能把所有的gpio同时设置为外部中断。例如不能把PA0和PB0同时设置为外部中断,因为PA0和PB0共用一个中断线,MCU只把最后完成初始化的管脚设置为外部中断。 如果代码编写者明确知道PA0和PB0不会同时触发,并且触发有相互依赖关系,可以通过分时设置PA0和PB0的外部中断功能。但是在大多数情况下,外部中断的触发都是随机的,那么在设计原理图的时候就要考虑到这种情况,把用到的外部中断管脚设置到后缀不同的管脚上,如PA0,PA1,PB3,PC8,....PD12,PF16,在一个工程中最多能使用16个外部中断,并且每个管脚的后缀不同。 如果设计电路板没有考虑到这种情况,
[单片机]
8051单片机(STC89C52)以定时器中断模式实现倒计时器
之前用轮询方式实现了定时器精准定时, 这里用前后台系统架构实现倒计时器. 每10ms都会触发一次中断处理程序T0_INT(), 根据tcount的值, 决定显示个位数字还是十位数字: 当tcount = 100时, 将tcount置回初始值0, 并将sec的值减1. 当sec的值减到-1时, 将sec重新置回15. #include STC89C5xRC.H unsigned char code DIG_CODE = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};//对应数码管显示0~9 int tcount = 0;//记录经过的10m
[单片机]
8051单片机(STC89C52)以定时器<font color='red'>中断</font>模式实现倒计时器
STM323 USART串口通信中断实现
问题描述:利用stm32串口通信,当PC端发送字符8时,LED PB.0闪亮 第一步:配置系统时钟,这个不用多讲,代码就不贴出来了; 第二步:GPIO端口配置: 设置PA.9为复用推挽输出,PA.10为浮空输入,PB.0,PB.1,PB.2输出并初始化PB.0亮 void GPIO_Config() { GPIOA- CRH=0X04B0; GPIOB- CRL=0X0333; GPIOB- ODR=0X01; } 第三步:USART寄存器配置: void USART_Config() { USART1- BRR = 0x1D4C; U
[单片机]
51单片机的中断基本知识介绍
1、中断的概念 对于单片机中断的概念,我们可以这样理解:单片机处理某一事件A时,发生了另一事件B请求(中断请求);单片机暂时中断当前工作,转去处理事件B(中断响应和中断服务);待单片机将事件B处理完毕,再回到原来事件A被中断的地方继续处理事件A(中断返回),这一过程称为中断。 引起单片机中断的根源或原因: 中断源向单片机提出中断请求。 2、中断优先级 单片机的中断系统一般允许多个中断源,当几个中断源同时向单片机请求中断,要求为它服务的时候,这就存在单片机优先响应哪一个中断源请求的问题。通常根据中断源的轻重缓急排队,优先处理最紧急事件的中断请求源,即规定每一个中断源有一个优先级别。单片机总是先响应优先级别最高的中断请
[单片机]
51单片机的<font color='red'>中断</font>基本知识介绍
第四节:累计定时中断次数使LED灯闪烁
开场白: 上一节提到在累计主循环次数来实现计时,随着主函数里任务量的增加,为了保证延时时间的准确性,要不断修正设定上限阀值const_time_level 。我们该怎么解决这个问题呢?本节教大家利用累计定时中断次数的方法来解决这个问题。这一节要教会大家四个知识点: 第一点:利用累计定时中断次数的方法实现时间延时 第二点:展现鸿哥最完整的实战程序框架。在主函数循环里用switch语句实现状态机的切换,在定时中断里累计中断次数,这两个的结合就是我写代码最本质的框架思想。 第三点:提醒大家C语言中的int ,long变量是由几个字节构成的数据,凡是在main函数和中断函数里有可能同时改变的变量,这个变量应该在主函数中被更改之前,先关
[单片机]
s3c6410 完全由SD卡启动Linux流程
1. s3c6410 SD启动原理 s3c6410 支持Nand Flash本地启动Linux,包括内核,根文件系统,bootloader均写入在Nand Flash.这样可以独立运行. 很多情况下,Nand Flash的某种原因无法写入内核和Rootfs.而使用tftp下载内核,用NFS启动根文件系统比较慢.s3c6410 支持 SD卡启动,经过改造u-boot可以从SD卡引导内核,这样而Linux 又可以从SD卡的装载ext3根文件系统.这样可以制作一个完整的SD卡启动卡. 这样bootloader(u-boot)可以写入SD卡,引导扇区. bootloader的第一阶段把自己装入在内存高端地址看后,可以用两
[单片机]
小广播
设计资源 培训 开发板 精华推荐

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

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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