移植环境(
红 {MOD}粗字体字为修改后内容,
蓝 {MOD}粗体字为特别注意内容)
1,开发板:韦东山JZ2440。
2,linux 版本:linux-3.4.23,参考文献:http://blog.csdn.net/fyyy4030/article/details/7243998
S3C2440 芯片具有3 个串口:UART0,1,2,我们下载的Linux-3.4.2已经具备完善的UART0,1 的驱动,但对UART2 却用作了红外通讯(Irda),因此我们需要把UART2 驱动稍微调整一下,以便作为普通串口来用。JZ2440串口电路如图:
于是按照参考文献操作: 【1】修改平台配置代码
我们修改内核中关于 UART2 的配置,打开linux-3.4.2/arch/arm/mach-s3c2440/mach-smdk2440.c 文件,定位到112行附近,找到mini2440_uartcfgs[],如下红 {MOD}代码为修改后的:
static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
.ucon = 0x3c5,
.ulcon = 0x03,
.ufcon = 0x51,
},
[1] = {
.hwport = 1,
.flags = 0,
.ucon = 0x3c5,
.ulcon = 0x03,
.ufcon = 0x51,
},
/* IR port */
[2] = {
.hwport = 2,
.flags = 0,
.ucon = 0x3c5,
//.ulcon = 0x43,//modify by pang change the IR port to Serial port
.ulcon = 0x03,
.ufcon = 0x51,
}
};
再修改串口所使用的端口初始化,打开linux-3.4.2/drivers/tty/serial/samsung.c,定位到55行附近,先加入所需头文件,如下
#include
#include
#include
#include
#include "samsung.h"然后再定位到456行左右,添加如下红 {MOD}部分代码:static int s3c24xx_serial_startup(struct uart_port *port)
{
struct s3c24xx_uart_port *ourport = to_ourport(port);
int ret;
dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)
",
port->mapbase, port->membase);
//---- set up Serial port 2 by pang
if(port->line == 2)
{
s3c2410_gpio_cfgpin(S3C2410_GPH(6), S3C2410_GPH6_TXD2);
s3c2410_gpio_pullup(S3C2410_GPH(6), 1);
s3c2410_gpio_cfgpin(S3C2410_GPH(7), S3C2410_GPH7_RXD2);
s3c2410_gpio_pullup(S3C2410_GPH(7), 1);
}
//---- end
rx_enabled(port) = 1;
ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,
s3c24xx_serial_portname(port), ourport);
if (ret != 0) {
printk(KERN_ERR "cannot get irq %d
", ourport->rx_irq);
return ret;
}
【2】配置内核
make menuconfig
DivicesDrivers->
Characterdevices->
SerialDrivers->
<*>SansungSoC serial support
make uImage后,把arch/arm/boot/uImage加载到板子测试。 echo "fasdfasdf" >/dev/ttySAC2
------------[ cut here ]------------
WARNING: at drivers/gpio/gpio-samsung.c:3105 s3c2410_gpio_pullup+0x44/0x5c()
Modules linked in:
Backtrace:
[] (dump_backtrace+0x0/0x10c) from [] (dump_stack+0x18/0x1c)
r7:00000009 r6:00000c21 r5:c016ffb8 r4:00000000
[] (dump_stack+0x0/0x1c) from [] (warn_slowpath_common+0x50/0x68)
[] (warn_slowpath_common+0x0/0x68) from [] (warn_slowpath_null+0x24/0x2c)
r9:c31e7c00 r8:00000000 r7:00000000 r6:c0617358 r5:c0617338
r4:000000e6
[] (warn_slowpath_null+0x0/0x2c) from [] (s3c2410_gpio_pullup+0x44/0x5c)
[] (s3c2410_gpio_pullup+0x0/0x5c) from [] (s3c24xx_serial_startup+0xb0/0x110)
r5:c0617338 r4:c0617358
[] (s3c24xx_serial_startup+0x0/0x110) from [] (uart_startup+0x6c/0x1dc)
r6:c0617358 r5:c31e7c00 r4:c39f8f10
[] (uart_startup+0x0/0x1dc) from [] (uart_open+0xe8/0x130)
r9:c31e7c00 r8:c31d4000 r7:c322e2c0 r6:c39f8f40 r5:c31e7c00
r4:c39f8f10
[] (uart_open+0x0/0x130) from [] (tty_open+0x264/0x540)
r9:c31e7c00 r8:c31d4000 r7:c38c3920 r6:0cc00042 r5:00000000
r4:c322e2c0
[] (tty_open+0x0/0x540) from [] (chrdev_open+0x8c/0x130)
[] (chrdev_open+0x0/0x130) from [] (__dentry_open+0x204/0x2c8)
r7:c3625438 r6:c380ebd0 r5:c3624958 r4:c322e2c0
[] (__dentry_open+0x0/0x2c8) from [] (nameidata_to_filp+0x68/0x70)
[] (nameidata_to_filp+0x0/0x70) from [] (do_last+0x1b8/0x6c8)
r7:00000022 r6:c3625438 r5:00000041 r4:c31d5ed0
[] (do_last+0x0/0x6c8) from [] (path_openat+0xc4/0x38c)
[] (path_openat+0x0/0x38c) from [] (do_filp_open+0x38/0x8c)
[] (do_filp_open+0x0/0x8c) from [] (do_sys_open+0xe4/0x17c)
r8:ffffff9c r7:00000001 r6:00000003 r5:00000241 r4:c3ad9000
[] (do_sys_open+0x0/0x17c) from [] (sys_open+0x24/0x28)
[] (sys_open+0x0/0x28) from [] (ret_fast_syscall+0x0/0x2c)
---[ end trace 6acbe3f8ea2c6a74 ]---
打印一长串什么鬼东西,用示波器查看Txd引脚的波形,发现是有信号的,只是串口不发送数据的时候为低电平,发送数据的时候是高电平,这个与ttl电平相反!!!于是怀疑修改了mach-smdk2440.c但是不生效,为了验证这一想法,我把该文件故意弄成有语法错误,再次make clean ,make uImage,发现该文件也没有被编译,这就奇怪了,仔细分析编译输出,发现linux-3.4.2/arch/arm/mach-s3c24xx/mach-smdk2440.c倒是编译了,于是终于找到原因了,在linux3.4.2中编译的是mach-s3c24xx文件夹下的mach-smdk2440.c,于是在该文件中做上述改动,make uImage,dnw加载到板子上,测试,修改成功串口正常.但是,还是有echo msg >/dev/ttyS 还是有------------[ cut here ]------------那一长串,那一长串究竟是什么意思呢?网上各种查资料都没有相应的解释,于是回到/samsung.c改动的地方,发现一个可疑的函数s3c2410_gpio_pullup,查找资料发现该函数是设置引脚高电平,会不会是这个函数的问题呢?于是注释掉这个函数,修改后如下:
//---- set up Serial port 2 by pang
if(port->line == 2)
{
s3c2410_gpio_cfgpin(S3C2410_GPH(6), S3C2410_GPH6_TXD2);
// s3c2410_gpio_pullup(S3C2410_GPH(6), 1);
s3c2410_gpio_cfgpin(S3C2410_GPH(7), S3C2410_GPH7_RXD2);
// s3c2410_gpio_pullup(S3C2410_GPH(7), 1);
}
//---- end
重新编译,正常,再也没有一长串出来了^_^。