s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_TOUT0);
咱们能够这样操控外设寄存器,想过它怎样完成的吗?
首要剖析下structmachine_desc (include/asm-arm/Mach/Arch.h)
这是一个非常重要的结构体,内核经过 machine_desc 来操控系统架构相关部分的初始化,包含map_io,init_irq,init_machine,pthys_io,timer等
structmachine_desc{ /* * Note! The first five elements are used * by assembler code in head-armv.S */ unsignedintnr;/* architecture number*/ unsignedintphys_ram;/* start of physical ram */ unsignedintphys_io;/* start of physical io*/ unsignedintio_pg_offst;/* byte offset for io * page tabe entry*/ constchar*name;/* architecture name*/ unsignedlongboot_params;/* tagged list*/ unsignedintvideo_start;/* start of video RAM*/ unsignedintvideo_end;/* end of video RAM*/ unsignedintreserve_lp0:1;/* never has lp0*/ unsignedintreserve_lp1:1;/* never has lp1*/ unsignedintreserve_lp2:1;/* never has lp2*/ unsignedintsoft_reboot:1;/* soft reboot*/ void(*fixup)(structmachine_desc*, structtag*,char**, structmeminfo*); void(*map_io)(void);/* IO mapping function*/ void(*init_irq)(void); structsys_timer*timer;/* system tick timer*/ void(*init_machine)(void); };
|
那咱们怎样创立自己的machine_desc呢?
内核给咱们供给了一个宏:
#defineMACHINE_START(_type,_name)/ conststructmachine_desc __mach_desc_##_type/ __attribute__((__section__(“.arch.info.init”)))={/ .nr=MACH_TYPE_##_type,/ .name=_name, #defineMACHINE_END/ };
|
这样咱们就能够界说自己的machine_desc了
MACHINE_START(SMDK2410,”SMDK2410″)/* @TODO: request a new identifier and switch * to SMDK2410 */ /* Maintainer: Jonas Dietsche */ .phys_ram=S3C2410_SDRAM_PA, .phys_io=S3C2410_PA_UART, .io_pg_offst=(((u32)S3C24XX_VA_UART)>>18)&0xfffc, .boot_params=S3C2410_SDRAM_PA+0x100, .map_io=smdk2410_map_io, .init_irq=smdk2410_init_irq, .init_machine=sdmk2410_init, .timer=&s3c24xx_timer, MACHINE_END
|
这儿咱们创立了 machine_desc,并给其间一些成员赋了值,这适当所以内核给咱们供给的编程接口,这样就能够调用自己的函数了。
这其间map_io 在 setup_arch 中调用调用,咱们跟进去会发现:
在smdk2410_map_io–>s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc))->iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)) 看到:
void__init iotable_init(structmap_desc*io_desc,intnr) { inti; for(i=0;icreate_mapping(io_desc+i); }
|
便是在这儿调用create_mapping()创立的页表,这儿的第一个参数,map_desc 界说如下:
structmap_desc{ unsignedlongvirtual; unsignedlongphysical; unsignedlonglength; unsignedinttype; };
|
create_mapping()便是经过这个结构体创立的映射表,这样咱们能够经过创立 map_desc 然后传给这个函数就能够创立相应的 虚拟地址–>物理地址 映射.
在 inlcude/asm-arch/Arch-s3c2410/Map.h
界说了每一种资源用于 map_desc变量的宏界说,如:
/* MMC controller – available on the S3C2400 */ #defineS3C2400_VA_MMC S3C2400_ADDR(0x00700000) #defineS3C2400_PA_MMC (0x15A00000) #defineS3C2400_SZ_MMC SZ_1M
/* UARTs */ #defineS3C24XX_VA_UART S3C2410_ADDR(0x00800000) #defineS3C2400_PA_UART(0x15000000) #defineS3C2410_PA_UART(0x50000000) #defineS3C24XX_SZ_UART SZ_1M
/* Timers */ #defineS3C24XX_VA_TIMER S3C2410_ADDR(0x00900000) #defineS3C2400_PA_TIMER(0x15100000) #defineS3C2410_PA_TIMER(0x51000000) #defineS3C24XX_SZ_TIMER SZ_1M
|
然后针对详细的某个外设,有详细寄存器的界说,如:
include/asm/arch-s3c2410/regs-timer.h
#ifndef__ASM_ARCH_REGS_TIMER_H #define__ASM_ARCH_REGS_TIMER_H”$Id: timer.h,v 1.4 2003/05/06 19:30:50 ben Exp $”
#defineS3C2410_TIMERREG(x)(S3C24XX_VA_TIMER+(x)) #defineS3C2410_TIMERREG2(tmr,reg)S3C2410_TIMERREG((reg)+0x0c+((tmr)*0x0c))
#defineS3C2410_TCFG0 S3C2410_TIMERREG(0x00) #defineS3C2410_TCFG1 S3C2410_TIMERREG(0x04) #defineS3C2410_TCON S3C2410_TIMERREG(0x08)
#defineS3C2410_TCFG_PRESCALER0_MASK(255<<0) #defineS3C2410_TCFG_PRESCALER1_MASK(255<<8) #defineS3C2410_TCFG_PRESCALER1_SHIFT(8) #defineS3C2410_TCFG_DEADZONE_MASK(255<<16) #defineS3C2410_TCFG_DEADZONE_SHIFT(16) …………………….
|
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/biancheng/274498.html