历史上的今天
返回首页

历史上的今天

今天是:2024年10月11日(星期五)

正在发生

2018年10月11日 | OK6410裸机之中断向量控制器

2018-10-11 来源:eefocus

statr.S文件:

.globl _start

_start:

    // 0 地址 

    b reset                                                  // 复位时,cpu跳到0地址 

    ldr pc, =undefined_instruction          // cpu遇到不能识别的指令时 

    ldr pc, _vector_swi                               // 当执行swi指令时, 进入swi模 式 

    b halt     @ldr    pc, _prefetch_abort  // 预取中止异常 

    b halt     @ldr    pc, _data_abort        // 数据访问异常 

    b halt     @ldr    pc, _not_used           // 没用到 

    ldr    pc, _irq                                        // 0x18 中断异常 

    b halt     @ldr    pc, _fiq                     // 快中断异常 

_irq :

    .word vector_irq

_vector_swi:

    .word vector_swi

vector_swi:

    // 1. 保存现场 

    ldr sp, =0x56000000

    stmdb sp!, {r0-r12, lr}  // lr就是swi的下一条指令地址 

    // 2. 处理异常 

    mrs r0, cpsr

    ldr r1, =swi_str

    bl print_cpsr

    // 3. 恢复现场 

    ldmia sp!, {r0-r12, pc}^ // ^表示把spsr恢复到cpsr 

    

swi_str:

    .word 0x00697773         // swi 

    

undefined_instruction:

    // 1. 保存现场 

    ldr sp, =0x55000000

    stmdb sp!, {r0-r12, lr}

    // 2. 处理异常 

    mrs r0, cpsr

    ldr r1, =und_str

    bl print_cpsr

    // 3. 恢复现场 

    ldmia sp!, {r0-r12, pc}^  // ^表示把spsr恢复到cpsr 

und_str:

    .word 0x00646e75         // und 

usr_str:

    .word 0x00727375         // usr 

vector_irq:

    // 1. 保存现场 

    ldr sp, =0x54000000

    sub lr, lr, #4               //只有swi和und异常lr指向下一条指令,其他异常发生的时候lr都是指向下两条指令

    stmdb sp!, {r0-r12, lr}  // lr就是swi的下一条指令地址 

    // 2. 处理异常 

    bl do_irq

    

    // 3. 恢复现场 

    ldmia sp!, {r0-r12, pc}^  // ^表示把spsr恢复到cpsr 

reset:

// 硬件相关的设置 

    // Peri port setup 

    ldr r0, =0x70000000

    orr r0, r0, #0x13

    mcr p15,0,r0,c15,c2,4       @ 256M(0x70000000-0x7fffffff)

    

// 关看门狗 

    // 往WTCON(0x7E004000)写0 

    ldr r0, =0x7E004000

    mov r1, #0

    str r1, [r0]

    

    // 设置栈 

    ldr sp, =8*1024

    // 设置时钟 

    bl clock_init

    bl ddr_init

    bl init_uart

// 把程序的代码段、数据段复制到它的链接地址去     

    adr r0, _start             // 获得_start指令当前所在的地址 : 0

    ldr r1, =_start           // _start的链接地址 0x51000000 

    

    ldr r2, =bss_start      // bss段的起始链接地址 

    

    sub r2, r2, r1

    

    cmp r0,r1

    beq clean_bss

    

    bl copy2ddr

    cmp r0, #0

    bne halt

        

// 清BSS 

// 把BSS段对应的内存清零 

clean_bss:

    ldr r0, =bss_start

    ldr r1, =bss_end

    mov r3, #0

    cmp r0, r1

    ldreq pc, =on_ddr

clean_loop:

    str r3, [r0], #4

    cmp r0, r1    

    bne clean_loop        

    ldr pc, =on_ddr

on_ddr:

    bl irq_init

    mrs r0, cpsr

    bic    r0,r0,#0x9f  // 清cpsr的I位,M4~M0 

    orr    r0,r0,#0x10

    msr    cpsr,r0       // 进入user mode 

    ldr sp, =0x57000000

    ldr r1, =usr_str

    bl print_cpsr

    

    swi 0

    // cpu进入svc模式

    // 把之前的cpsr保存到spsr_svc 

    // 切换到r13_svc, r14_svc

    // 把swi的下一条指令存到r14(lr)_svc

    // 跳到地址8

              

    bl hello

undef:

    .word 0xff000000

    // cpu进入Undefined模式

    // 把之前的cpsr保存到spsr_und 

    // 切换到r13_und, r14_und

    // 把下一条指令存到r14(lr)_und

    // 跳到地址4

swi_ret:

    bl main

halt:

    b halt    

=====================================================================

irq.c文件:

#define GPNCON     (*((volatile unsigned long *)0x7F008830))

#define GPNDAT     (*((volatile unsigned long *)0x7F008834))

#define EINT0CON0  (*((volatile unsigned long *)0x7F008900))

#define EINT0MASK  (*((volatile unsigned long *)0x7F008920))

#define EINT0PEND  (*((volatile unsigned long *)0x7F008924))

#define PRIORITY    (*((volatile unsigned long *)0x7F008280))

#define SERVICE     (*((volatile unsigned long *)0x7F008284))

#define SERVICEPEND (*((volatile unsigned long *)0x7F008288))

#define VIC0IRQSTATUS  (*((volatile unsigned long *)0x71200000))

#define VIC0FIQSTATUS  (*((volatile unsigned long *)0x71200004))

#define VIC0RAWINTR    (*((volatile unsigned long *)0x71200008))

#define VIC0INTSELECT  (*((volatile unsigned long *)0x7120000c))

#define VIC0INTENABLE  (*((volatile unsigned long *)0x71200010))

#define VIC0INTENCLEAR (*((volatile unsigned long *)0x71200014))

#define VIC0PROTECTION (*((volatile unsigned long *)0x71200020))

#define VIC0SWPRIORITYMASK (*((volatile unsigned long *)0x71200024))

#define VIC0PRIORITYDAISY  (*((volatile unsigned long *)0x71200028))

#define VIC0VECTADDR0      (*((volatile unsigned long *)0x71200100))

#define VIC0VECTADDR1      (*((volatile unsigned long *)0x71200104))

#define VIC0ADDRESS           (*((volatile unsigned long *)0x71200f00))

void eint0_3_irq(void)

{

    int i;

    

    printf("eint0_3_irq\n\r");  // K1~K4 

    for (i = 0; i < 4; i ++)

    {

        if (EINT0PEND & (1<

        {

            if (GPNDAT & (1<

            {

                printf("K%d released\n\r", i+1);

            }

            else

            {

                printf("K%d pressed\n\r", i+1);

            }

        }

    }

}

void eint4_11_irq(void)

{

    int i;

    printf("eint4_11_irq\n\r"); // K5~K6 

    for (i = 4; i < 6; i ++)

    {

        if (EINT0PEND & (1<

        {

            if (GPNDAT & (1<

            {

                printf("K%d released\n\r", i+1);

            }

            else

            {

                printf("K%d pressed\n\r", i+1);

            }

        }

    }

}

void irq_init(void)

{

    // 配置GPIO引脚为中断引脚 

    // GPN0~5 设为中断引脚 

    GPNCON &= ~(0xfff);

    GPNCON |= 0xaaa;

    // 设置中断触发方式为: 双边沿触发 

    EINT0CON0 &= ~(0xfff);

    EINT0CON0 |= 0x777;

    // 使能中断 

    EINT0MASK &= ~(0x3f);

    // 在中断控制器里使能这些中断 

    VIC0INTENABLE |= (0x3); // bit0: eint0~3, bit1: eint4~11  

//发生中断时硬件会把VIC0VECTADDR0赋给VIC0ADDRESS(第一组为VIC0ADDRESS,第二组为VIC1ADDRESS)

    VIC0VECTADDR0 = eint0_3_irq;  

    

//发生中断时硬件会把VIC0VECTADDR1赋给VIC0ADDRESS(第一组为VIC0ADDRESS,第二组为VIC1ADDRESS)

    VIC0VECTADDR1 = eint4_11_irq; 

    // 设置优先级 

}

//在中断向量控制器中有两个中断组,每一组有32个中断,在第一组中断发生时硬件会自动把VIC0VECTADDR

//寄存器的值给VIC0ADDRESS,在第二组中断发生时硬件会自动把VIC1VECTADDR寄存器的值给

//VIC1ADDRESS,只要提前把中断服务函数的地址赋给对应的寄存器,在发生中断的时候就会在do_irq函数中

//把VIC0ADDRESS或则VIC1ADDRESS值给函数指针执行就可以运行中断服务函数

void do_irq(void)

{

    int i = 0;

    void (*the_isr)(void);

    //第一组的32个中断对应为VIC0ADDRESS,第二组的32个中断对应为VIC1ADDRESS

    the_isr = VIC0ADDRESS; 

        

    // 2.1 分辨是哪个中断 

    // 2.2 调用它的处理函数     

    // 2.3 清中断     

    the_isr();

    

    EINT0PEND   = 0x3f;  // 清中断 

    VIC0ADDRESS = 0;

}

=====================================================================

Makefile文件:

CC      = arm-linux-gcc

LD      = arm-linux-ld

AR      = arm-linux-ar

OBJCOPY = arm-linux-objcopy

OBJDUMP = arm-linux-objdump

INCLUDEDIR     := $(shell pwd)/include

CFLAGS             := -Wall -Os -fno-builtin-printf 

CPPFLAGS        := -nostdinc -I$(INCLUDEDIR)

export     CC AR LD OBJCOPY OBJDUMP INCLUDEDIR CFLAGS CPPFLAGS 

objs := start.o sdram.o nand.o clock.o uart.o irq.o  main.o lib/libc.a

uart.bin: $(objs)

    ${LD} -Tuart.lds -o uart.elf $^

    ${OBJCOPY} -O binary -S uart.elf $@

    ${OBJDUMP} -D uart.elf > uart.dis

.PHONY : lib/libc.a

lib/libc.a:

    cd lib; make; cd ..

    

%.o:%.c

    ${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

%.o:%.S

    ${CC} $(CPPFLAGS) $(CFLAGS) -c -o $@ $<

clean:

    make  clean -C lib

    rm -f uart.bin uart.elf uart.dis *.o

    

=====================================================================

uart.lds链接文件:

SECTIONS {

    . = 0x50000000;

    

    .text : {

            start.o

            clock.o

            sdram.o

            nand.o

            * (.text)

    }

    . = ALIGN(4);

    .rodata : {

            * (.rodata)

    }

    . = ALIGN(4);

    .data : {

            * (.data)

    }

    . = ALIGN(4);

    bss_start = .;

    .bss  : { *(.bss)  *(COMMON) }

    bss_end = .;

}

OK6410裸机之中断向量控制器


推荐阅读

史海拾趣

ABOV(现代单片机)公司的发展小趣事

ABOV(现代单片机)是一家韩国的半导体公司,以下是该公司发展的五个相关故事:

  1. 公司成立和初期发展: ABOV公司成立于1997年,总部位于韩国首尔。公司专注于设计、制造和销售嵌入式系统解决方案,主要产品包括微控制器(MCU)和嵌入式闪存等。成立初期,ABOV致力于技术创新和产品研发,建立起一支技术精湛的研发团队。

  2. 技术创新和产品推出: ABOV在技术创新方面投入了大量资源,不断推出新产品和解决方案。公司的现代单片机产品以其高性能、低功耗和丰富的功能而闻名。ABOV还在嵌入式闪存技术方面取得了重大突破,推动了嵌入式系统的发展和普及。

  3. 市场拓展和国际合作: 随着产品技术的不断成熟和市场需求的增长,ABOV积极拓展国际市场,并与全球各地的客户建立了合作关系。公司的现代单片机产品被广泛应用于消费电子、汽车电子、工业控制等领域,赢得了客户的信赖和认可。

  4. 持续投入研发和创新: ABOV持续投入研发,并不断提升产品性能和功能。公司注重与客户的密切合作,根据客户需求进行定制化开发,为客户提供个性化的解决方案。ABOV还与学术机构和合作伙伴合作,共同推动技术创新和产业发展。

  5. 未来展望和发展方向: ABOV将继续致力于技术创新和产品升级,加强在嵌入式系统领域的研发和应用。公司将继续拓展国际市场,加强与客户和合作伙伴的合作,推动现代单片机技术的发展和普及,为全球的电子行业做出更大的贡献。

北京人民电器厂公司的发展小趣事

随着北京人民电器产品的不断优化和升级,其生产的GM系列直流断路器在发电、输变电系统中得到了广泛应用。众多电力企业和项目都选择了北京人民电器的产品,这不仅是对其产品质量和技术水平的认可,也进一步推动了公司在电力行业的深入发展。

绿索超容(GreenSource)公司的发展小趣事

近年来,随着新能源产业的快速发展,北京人民电器紧跟时代步伐,在新能源领域取得了重要突破。公司推出的真安型零飞弧直流断路器,解决了直流低压系统中长期存在的外喷电弧问题,为新能源行业的发展提供了重要的技术支持。这一创新成果不仅得到了行业的广泛认可,也为公司在新能源领域的发展打开了新的局面。

这五个故事只是北京人民电器在电子行业发展历程中的一部分,但它们足以展现出公司在技术创新、产品应用、生产自动化、人才队伍建设以及新能源领域发展等方面的努力和成就。这些故事不仅记录了北京人民电器的成长轨迹,也见证了中国电子行业的蓬勃发展。

GradConn Ltd公司的发展小趣事

GradConn Ltd的创立初期,公司便明确了其专注于电子连接器和同轴电缆组件的市场定位。这一战略选择使GradConn能够迅速在通讯、工业、医疗和汽车等领域建立起稳定的客户基础。通过不断研发创新,GradConn推出了一系列高质量的产品,如板对板连接器、电缆组件连接器以及SIM卡连接器等,满足了市场对精密、可靠连接解决方案的迫切需求。

EDAL公司的发展小趣事

随着技术的不断进步和市场的变化,EDAL公司意识到必须不断优化产品以满足客户的需求。公司投入大量研发资源,对EDA工具进行迭代升级,推出了更加智能化、用户友好的产品。同时,EDAL公司积极拓展市场,与全球各大芯片设计公司建立了合作关系,将产品销售到世界各地。

Corporation Soneet公司的发展小趣事

在市场推广的过程中,Soneet注重品牌形象的建立。公司积极参加各类行业展会和技术交流会议,展示其最新技术和产品。同时,Soneet还通过媒体宣传、社交媒体营销等方式,提高品牌知名度和美誉度。这些努力使得Soneet在消费者心中树立了良好的品牌形象。

问答坊 | AI 解惑

HAL是Hardware Abstraction Layer的首字母缩写

hal正是我们下一步要关心的,接下来我会分析HAL的实现原理。 HAL是Hardware Abstraction Layer的首字母缩写。我最早是在Winnt 3.5的帮助中知道这个名词的,对帮助文档中的说法我比较认同,所以一直对它抱有好感。不过Windows下的HAL和Linux下的HAL ...…

查看全部问答>

程序中的变量名在编译之后成了什么?

我一直有个疑惑,我们都知道内存中的数据是分段存储的,但是我就一直不能理解,程序编译之后,源程序中的变量名是否也编译成为数据值了,而且这个变量的指针是由谁指向的,当变量名也被编译为值的情况下,必然会导致内存的占用,是否就是说,从节约 ...…

查看全部问答>

得勋章了,高兴,新的一年,继续努力,进着有分!!!!

在eeworld里面有两个月了,认识了好多朋友,也学到了很多,多谢eeworld的网友们,新的一年,继续努力------- 宇帆嵌入式交流群1,气氛很好,能给大家提供一个技术交流群,很高兴,嘿嘿!现在正式推出宇帆嵌入式交流群2, 群号61273439,欢迎大家多 ...…

查看全部问答>

wince5.0 uvc协议的摄象头驱动问题

我有一个USB的摄象头(UVC协议),在XP系统上插上后会自己找到驱动,但是在CE上需要驱动,那WINCE5.0上有无通用的UVC协议的驱动呢,还有WINCE6.0是否就直接支持UVC协议了~…

查看全部问答>

c#在WINCE模拟器上怎么获得WebBrowser上加载html源代码?? 在线求解!!!

我通过WebBrowser.text取不出来 是空的 通过WebBrowser.DocumentText 系统调试 提示错误    错误 1 属性或索引器“System.Windows.Forms.WebBrowser.DocumentText”无法用于此上下文中,因为它缺少 get 访问器 F:\\Ezine\\FrmMain ...…

查看全部问答>

DSP优化

从在DSP上做智能视频以来,看到很多优化的文档, 受益非浅,在这根据俺这短短的经验, 也总结一二。优化分很多方面, 或者说不同的层次,不同方面的考虑的问题和优化方式完全不同, 俺稍微懂点的会慢慢展开, 不懂的继续学习 ...1)系统2)算法3) ...…

查看全部问答>

stm32库升级到3.3.0后systick中断优先级如何设定

stm32库升级到3.3.0 后原来的函数NVIC_SystemHandlerPriorityConfig没有了。 这个函数是用来定义Cortex-M3 中断的,在V3.3.0中没找到与之相对应的函数。 请高手指点一二,谢谢…

查看全部问答>

128 和美新加速度传感器MXC6202

谁用过美新的加速度传感器 MXC6202G…

查看全部问答>

电动汽车控制器(新能源项目)

国内电动汽车(电动客车)制造商使用的驱动电机主要有三款,1.直流有刷电机(串励电机和他励电机)。2.直流永磁无刷电机。3.交流感应电机。三者向比较:直流有刷电机,优点是扭矩大,驱动控制相对简单,国内的控制器厂家也有不少,缺点是体积 ...…

查看全部问答>

flash烧写问题

在CCS3.3下下到RAM中运行一切正常,但用FLASHBURN下载时FBTC642.out的版本不对。 改到CCS2.2下重新编译现在下到RAM中运行都不正常,(程序会卡在同一处),望哪位能提供CCS3.3下烧 flash的方法或其他步骤…

查看全部问答>