• 中断裸机程序


    硬件平台:JZ2440

    head.s        -->  启动文件,设置异常向量表

    init.c           -->  初始化中断

    interrupt.c  --> 中断处理程序

    s3c2440.h  --> 寄存器映射

    head.s 源码:

    .extern main
    .text
    .global _start
    _start:
    
    @ 异常向量表
    
    @ 0x00  复位
    b Reset
    
    @ 0x04  指令未定义
    Undefine_instruct:
    b Undefine_instruct
    
    @ 0x08  软件中断
    Software_interrupt:
    b Software_interrupt
    
    @ 0x0c  预取指中断
    Prefetch_abort:
    b Prefetch_abort
    
    @ 0x10  数据访问中断
    Data_abort:
    b Data_abort
    
    @ 0x14 保留
    
    @ 0x18 外部访问中断
    b Handle_irq
    
    @ 0x1c  快速中断
    Fiq:
    b Fiq
    
    Reset:
        ldr sp,=4096        @ 复位自动进入超级用户模式
        bl disable_watch_dog
    
        msr cpsr_c,#0xd2    @ 进入中断模式
        ldr sp,=3072
    
        msr cpsr_c,#0xd3    @ 进入超级用户模式
        ldr sp,=4096
        bl led_init         
        bl interrupt_init
    
        msr cpsr_c,#0x5f   @ 开中断,并进入系统模式
        ldr lr,=loop_main
        ldr pc,=main
    loop_main:
             b loop_main
    
    Handle_irq:
        sub lr,lr,#4
        stmdb sp!,{r0-r12,lr}
    
        ldr lr,=eint_return
        ldr pc,=eint_interrupt
    eint_return:
        ldmia sp!,{r0-r12,pc}^

    init.c源码:

    #include"s3c2440.h"
    /*
     * LED1,LED2,LED4对应GPF4、GPF5、GPF6
     */
    #define    GPF4_out    (1<<(4*2))
    #define    GPF5_out    (1<<(5*2))
    #define    GPF6_out    (1<<(6*2))
    
    #define    GPF4_msk    (3<<(4*2))
    #define    GPF5_msk    (3<<(5*2))
    #define    GPF6_msk    (3<<(6*2))
    
    /*
     * S2,S3,S4对应GPF0、GPF2、GPG3
     */
    #define GPF0_eint     (0x2<<(0*2))
    #define GPF2_eint     (0x2<<(2*2))
    #define GPG3_eint     (0x2<<(3*2))
    
    #define GPF0_msk    (3<<(0*2))
    #define GPF2_msk    (3<<(2*2))
    #define GPG3_msk    (3<<(3*2)) 
    
    
    void disable_watch_dog(void)
    {
        WTCON = 0;
    }
    
    void led_init(void)
    {
         // LED1,LED2,LED4对应的3根引脚设为输出
        GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk);
        GPFCON |= GPF4_out | GPF5_out | GPF6_out;
    }
    
    void interrupt_init(void)
    {
           // S2,S3对应的2根引脚设为中断引脚 EINT0,ENT2
        GPFCON &= ~(GPF0_msk | GPF2_msk);
        GPFCON |= GPF0_eint | GPF2_eint;
    
        // S4对应的引脚设为中断引脚EINT11
        GPGCON &= ~GPG3_msk;
        GPGCON |= GPG3_eint;
    
        EINTMASK &= (~(1<<11));
        INTMSK &= (~(1<<0))&(~(1<<2))&(~(1<<5));
        PRIORITY = (PRIORITY&((~0x01) | (0x3 << 7))) | (0x0 << 7);
    }

    interrupt.c 源码:

    #include"s3c2440.h"
    
    void eint_interrupt(void)
    {
        unsigned long offset = INTOFFSET;
    
        switch (offset)
        {
            case 0:
            {
                 GPFDAT |= (0x7<<4);
                GPFDAT &= ~(1<<4);
                break;
            }
    
            case 2:
            {
                 GPFDAT |= (0x7<<4);
                GPFDAT &= ~(1<<5);
                break;
            }
    
            case 5:
            {
                 GPFDAT |= (0x7<<4);
                GPFDAT &= ~(1 << 6);
                break;
            }
            defult:break;
        }
    
        if (offset == 5) EINTPEND = (1 << 11);
        SRCPND = 1 << offset;
        INTPND = 1 << offset;
    }

    main.c 源码:

    int main(void)
    {
        while (1);
        return 0;
    }

    s3c2440.h 源码:

    #ifndef _S3C2440_H_
    #define _S3C2440_H_
    
    
    //看门狗
    #define WTCON    (*(unsigned long *)0x53000000)
    
    //GPIO
    #define GPFCON   (*(unsigned long *)0x56000050)
    #define GPFDAT   (*(unsigned long *)0x56000054)
    #define GPFUP    (*(unsigned long *)0x56000058)
    #define GPGCON   (*(unsigned long *)0x56000060)
    #define GPGDAT   (*(unsigned long *)0x56000064)
    #define GPGUP    (*(unsigned long *)0x56000068)
    
    //interrupt
    #define INTMSK   (*(unsigned long *)0x4a000008)
    #define PRIORITY (*(unsigned long *)0x4a00000c)
    #define SRCPND   (*(unsigned long *)0x4a000000)
    #define INTPND   (*(unsigned long *)0x4a000010)
    #define INTOFFSET (*(unsigned long *)0x4a000014)
    
    #define EINTMASK (*(unsigned long *)0x560000a4)
    #define EINTPEND (*(unsigned long *)0x560000a8)
    
    
    
    #endif

    编译的Makefile:

    objs:=head.o init.o main.o interrupt.o
    
    interrupt.bin:$(objs)
        arm-linux-ld -Ttext 0x00000000 -o interrupt_elf  $^
        arm-linux-objcopy -O binary -S interrupt_elf $@
        arm-linux-objdump -D -m arm interrupt_elf > interrupt.dis
    
    %.o:%.c
        arm-linux-gcc -o $@ -c $<
    
    %.o:%.s
        arm-linux-gcc -o $@ -c $<
    
    clean:
        rm -f *.o *.dis *.bin interrupt_elf
  • 相关阅读:
    2018JAVA面试题附答案
    微服务概述
    Java后台开发面试题总结
    郁金香搜索引擎方案
    单点登录
    Redis为什么是单线程
    数据库原理-范式
    权限分配之一级菜单优化添加和编辑页面图标
    权限分配之一级菜单保留原搜索条件
    django分页的东西, 不详细, 但是也足够了。
  • 原文地址:https://www.cnblogs.com/zsy12138/p/10407775.html
Copyright © 2020-2023  润新知