smart3250中的静态I/O映射情况
来源:互联网 发布:lol关注软件 编辑:程序博客网 时间:2024/05/04 19:44
根据网络大虾们的指导,基本上搞清楚了smart3250中的静态I/O映射情况。写个blog供以后参考。
****************************网络摘录**************************************
内核提供了在系统启动时通过map_desc结构体静态创建I/O资源到内核地址空间的线性映射表(即page table)的方式,这种映射表是一种一一映射的关系。程序员可以自己定义该I/O内存资源映射后的虚拟地址。创建好了静态映射表,在内核或驱动中访问该 I/O资源时则无需再进行ioreamp动态映射,可以直接通过映射后的I/O虚拟地址去访问它。
machine_desc结构体的成员包含了体系架构相关部分的几个最重要的初始化函数,包括map_io,init_irq, init_machine以及phys_io , timer成员等。这里的map_io成员即内核提供给用户的创建外设I/O资源到内核虚拟地址静态映射表的接口函数。Map_io成员函数会在系统初始化过程中被调用,流程如下:
Start_kernel -> setup_arch() --> paging_init() --> devicemaps_init()中被调用Machine_desc结构体通过MACHINE_START宏来初始化。
****************************网络摘录**************************************
在board-smartarm3250.c文件中的MACHINE_START
MACHINE_START (LPC3XXX, "SmartARM3250 board with the LPC3250 Microcontroller")
/* Maintainer: Kevin Wells, NXP Semiconductors */
.phys_io = UART5_BASE,
.io_pg_offst = ((io_p2v (UART5_BASE))>>18) & 0xfffc,
.boot_params = 0x80000100,
//.map_io = lpc32xx_map_io,
.map_io = smartarm3250_map_io,
.init_irq = lpc32xx_init_irq,
.timer = &lpc32xx_timer,
.init_machine = smartarm3250_board_init,
MACHINE_END
map_io方法对应的函数
static void __init smartarm3250_map_io(void)
{
lpc32xx_map_io();
iotable_init(smartarm3250_io_desc, ARRAY_SIZE(smartarm3250_io_desc));
}
先追踪第一个函数
void __init lpc32xx_map_io(void)
{
iotable_init (lpc32xx_io_desc, ARRAY_SIZE (lpc32xx_io_desc));
}
以下是lpc32xx_io_desc的定义:
static struct map_desc smartarm3250_io_desc[] __initdata = {
{ /* nCS2, CAN SJA1000 */
.virtual = io_p2v(EMC_CS2_BASE),
.pfn = __phys_to_pfn(EMC_CS2_BASE),
.length = SZ_1M,
.type = MT_DEVICE
},
{ /* nCS1, CF Card */
.virtual = io_p2v(EMC_CS1_BASE),
.pfn = __phys_to_pfn(EMC_CS1_BASE),
.length = SZ_1M,
.type = MT_DEVICE
}
};
现在追踪第二个函数
arch-lpc32xx.c文件中
smartarm3250_io_desc结构体的定义
static struct map_desc lpc32xx_io_desc[] __initdata = {
{
.virtual = io_p2v(AHB0_START),
.pfn = __phys_to_pfn(AHB0_START),
.length = AHB0_SIZE,
.type = MT_DEVICE
},
{
.virtual = io_p2v(AHB1_START),
.pfn = __phys_to_pfn(AHB1_START),
.length = AHB1_SIZE,
.type = MT_DEVICE
},
{
.virtual = io_p2v(FABAPB_START),
.pfn = __phys_to_pfn(FABAPB_START),
.length = FABAPB_SIZE,
.type = MT_DEVICE
},
{
.virtual = io_p2v(IRAM_BASE),
.pfn = __phys_to_pfn(IRAM_BASE),
.length = (SZ_64K * 4),
.type = MT_DEVICE
},
};
由上可知,smartarm3250开发板静态映射的物理地址有如下
基地址名称
实际物理地址
大小
范围
EMC_CS2_BASE
0xE2000000
SZ_1M(0x00100000)
0xE2000000-0xE2100000
EMC_CS1_BASE
0xE1000000
SZ_1M(0x00100000)
0xE1000000-0xE1100000
AHB0_START
0x20020000
AHB0_SIZE()
(MLC_BASE - SLC_BASE) + SZ_4K
(0x200A8000-0x20020000)+ 0x00001000
0x20020000-0x200A9000
AHB1_START
0x31000000
AHB1_SIZE()
(EMC_BASE - DMA_BASE) + SZ_4K
(0x31080000-0x31000000)+ 0x00001000
0x31000000-0x31081000
FABAPB_START
0x40004000
FABAPB_SIZE()
(I2C2_BASE - CLK_PM_BASE) + SZ_4K
(0x400A8000- 0x40004000)+ 0x00001000
0x40004000-0x400A9000
IRAM_BASE
0x08000000
SZ_64K * 4()
0x00040000
0x08000000-0x08040000
这些基地址的实际物理地址在include/mach/platform.h中可以找到
以上地址可以在驱动程序中直接调用如下两个函数:
__raw_readl(register_address);
__raw_writel(register_content,register_address);
这样在linux中控制单片机和用裸机程序控制单片机就没什么分别了。
以上地址中,还有未映射的地址部分。如果要在linux中用到,可以在驱动中的probe方法里,调用ioremap()函数,之后就能用了。
上面说介绍的物理地址都是经过io_p2v(x)映射的。
#define IO_BASE 0xF0000000
#define io_p2v(x) (IO_BASE | (((x) & 0xff000000) >> 4) | ((x) & 0x000fffff))
这个宏的意思是:
假设一个数,如0xABCDE123从前到后的16进制值顺序为12345678,即A对应1,B对应2,以此类推。
那么经过这个宏后变为:
AABDE123,即这个数的后5个数不会变,第一个数分裂为2个,去掉原来的第三个数。然后组合起来。
由上可知,如果想让映射后的地址与原来的物理地址一一对应,不产生冲突,所有被映射的地址的8位16进制数的第3个数应相同。lpc3250中,这个第3个数是0
====
http://blog.csdn.net/yongan1006/article/details/7094662
- smart3250中的静态I/O映射情况
- smart3250中的静态I/O映射情况
- 存储映射I/O
- 内存映射I/O
- I/O空间映射
- 存储映射I/O
- I/O空间映射 .
- 存储映射I/O
- 存储映射I/O
- I/O空间映射
- 存储映射I/O
- java1.4中的新I/O:存储器映射文件
- Linux内核访问外设I/O--动态映射(ioremap)和静态映射(map_desc)
- Linux内核访问I/O资源的方法:动态映射(ioremap)和静态映射(map_desc)
- Linux内核访问外设I/O--动态映射(ioremap)和静态映射(map_desc)
- 内存映射文件 I/O
- I/O端口 映射方式
- linux I/O内存映射
- 世界著名汽车公司谱系
- 淡墨写韵,不守起承转合
- 禁用迅雷的浏览器支持
- apache服务器同时发布两个(多个)网站设配置
- JAVA 地狱课时小结
- smart3250中的静态I/O映射情况
- iphone开发基础学习(一)
- UESTC 1720 无平方因子数(数论,容斥)
- AE加载不同数据的方法
- 断想
- 字符串形式表示的整数的范围判断
- 访问者模式讨论篇:java的动态绑定与双分派
- 求两条直线(线段)的交点
- hadoop学习