Live & Learn
分类: 嵌入式
2011-03-31 16:37:30
一、Linux 驱动的基本理论
我们来看一下两个结构体的定义:
struct platform_device {
};
在arch/arm/mach-s 3c2440/mach-mini2440.c中初始化
struct device {
#ifdef CONFIG_NUMA
#endif
};
};
在drivers/serial/8250.c中初始化
struct device_driver {
};
二、ST16C554
三、移植过程
1.
添加头文件
#ifdef CONFIG_SERIAL_8250_MINI2440_ST16C554
#include
#endif
初始化st16c554的platform_device数据结构
static struct plat_serial8250_port mini2440_st16c554_8250_data[] = {
[0] =
{
.mapbase = 0x18000000,
.irq = IRQ_EINT4,
.uartclk = 1843200,
.iotype = UPIO_MEM,//UPIO_MEM32,
.flags = (UPF_BOOT_AUTOCONF | UPF_IOREMAP),
.regshift = 0,
},
[1] =
{
.mapbase = 0x18000008,
.irq = IRQ_EINT5,
.uartclk = 1843200,
.iotype = UPIO_MEM,//UPIO_MEM32,
.flags = (UPF_BOOT_AUTOCONF | UPF_IOREMAP),
.regshift = 0,
},
[2] =
{
.mapbase = 0x18000010,
.irq = IRQ_EINT6,
.uartclk = 1843200,
.iotype = UPIO_MEM,//UPIO_MEM32,
.flags = (UPF_BOOT_AUTOCONF | UPF_IOREMAP),
.regshift = 0,
},
[3] =
{
.mapbase = 0x18000018,
.irq = IRQ_EINT8,
.uartclk = 1843200,
.iotype = UPIO_MEM,//UPIO_MEM32,
.flags = (UPF_BOOT_AUTOCONF | UPF_IOREMAP),
.regshift = 0,
},
{}
};
static struct platform_device mini2440_device_st16c554 = {
.name = "serial8250",
.id = PLAT8250_DEV_EXAR_ST16C554,
.dev = {
.platform_data = &mini2440_st16c554_8250_data,
},
};
将st16c554对应的platform_device数据结构体添加到mini2440对应的platform_device数据结构体中。
static struct platform_device *mini2440_devices[] __initdata = {
//#ifdef CONFIG_SERIAL_8250_MINI2440_ST16C554
//#endif
};
2.修改 drivers/serial/8250.c
#ifdef CONFIG_SERIAL_8250_MINI2440_ST16C554
#include
#endif
修改S3C2440 四个Bank使用的的 bus width为8位,以及设定这四个Bank的总线 timing。
static int __init serial8250_init(void)
{
#ifdef CONFIG_SERIAL_8250_MINI2440_ST16C554
// *((volatile unsigned int *)S3C2410_BANKCON1) = 0x1f7c;
// *((volatile unsigned int *)S3C2410_BANKCON2) = 0x1f7c;
*((volatile unsigned int *)S3C2410_BANKCON3) = 0x1f7c; //0x5650;//0x1f7c; //Clock.
// *((volatile unsigned int *)S3C2410_BANKCON5) = 0x1f7c;
#endif
#ifdef CONFIG_SPARC
#else
#endif
#ifdef CONFIG_8250_MINI2440_ST16C554
serial8250_isa_devs =
platform_device_alloc("serial8250", PLAT8250_DEV_EXAR_ST16C554);
#else
#endif
修改中断信号的类型为下降沿触发
#ifdef CONFIG_SERIAL_8250_MINI2440_ST16C554
#else
#endif
3.修改 drivers/serial/Kconfig
添加一个编译配置选项
config SERIAL_8250_MINI2440_ST16C554
To compile this driver as a module, choose M here: the module will be called 8250_mini2440_st16c554.
4.重新编译内核
> make menucofig
Device Drivers
保存.config文件
> make zImage
这样驱动就添加好了,如果你的根文件系统使用了mdev,那么不用做任何修改,mdev会自动地将四个新串口添加在 /dev/serial/tty目录下面,分别为 ttyS0, ttyS1, ttyS2, ttyS3。
查看更详细的信息
> cat /proc/tty/driver/serial 将显示四个串口的物理地址和虚拟地址