#make kernel_menuconfig
添加/dev/ttyS2设备(原来只有ttyS0, ttyS1)
Device Drivers --->
Character devices --->
Serial drivers --->
linux-xxx/drivers/char/ralink_gpio.c
以mtk7628nn为例
build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14/drivers/char/ralink_gpio.c
ralink_gpio_init()
{
gpiomode |= RALINK_GPIOMODE_DFT;
gpiomode &= ~0xf000000;
*(volatile u32 *)(RALINK_REG_GPIOMODE) = cpu_to_le32(gpiomode);
}
根据MT7628_ProgrammingGuide_20140428(E2).pdf编程指南
#vi linux-xxx/arch/mips/ralink/init.c
build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14/arch/mips/ralink/init.c
serial_init(57600);
prom_init_serial_port();
添加uart2初始化配置:
serial_setbrg()
{
#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628)
IER(RALINK_SYSCTL_BASE + 0xD00) = 0;
FCR(RALINK_SYSCTL_BASE + 0xD00) = 0;
LCR(RALINK_SYSCTL_BASE + 0xD00) = (UART_LCR_WLEN8 | UART_LCR_DLAB);
DLL(RALINK_SYSCTL_BASE + 0xD00) = clock_divisor & 0xff;
DLM(RALINK_SYSCTL_BASE + 0xD00) = clock_divisor >> 8;
LCR(RALINK_SYSCTL_BASE + 0xD00) = UART_LCR_WLEN8;
IER(RALINK_SYSCTL_BASE + 0xE00) = 0;
FCR(RALINK_SYSCTL_BASE + 0xE00) = 0;
LCR(RALINK_SYSCTL_BASE + 0xE00) = (UART_LCR_WLEN8 | UART_LCR_DLAB);
DLL(RALINK_SYSCTL_BASE + 0xE00) = clock_divisor & 0xff;
DLM(RALINK_SYSCTL_BASE + 0xE00) = clock_divisor >> 8;
LCR(RALINK_SYSCTL_BASE + 0xE00) = UART_LCR_WLEN8;
#else
static struct uart_port serial_req[3];
prom_init_serial_port()
{
memset(serial_req, 0, 3*sizeof(struct uart_port));
~
~
~
~
serial_req[1].membase = ioremap_nocache(RALINK_UART_LITE_BASE, PAGE_SIZE);
#if defined CONFIG_RALINK_MT7628
serial_req[2].type = PORT_16550A;
serial_req[2].line = 2;
serial_req[2].irq = SURFBOARDINT_UART_LITE3;
serial_req[2].flags = UPF_FIXED_TYPE;
serial_req[2].uartclk = 40000000;
serial_req[2].iotype = UPIO_MEM32;
serial_req[2].regshift = 2;
serial_req[2].mapbase = RALINK_UART_LITE3_BASE;
serial_req[2].membase = ioremap_nocache(RALINK_UART_LITE3_BASE, PAGE_SIZE);
#endif
early_serial_setup(&serial_req[0]);
early_serial_setup(&serial_req[1]);
early_serial_setup(&serial_req[2]);
return(0);
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEV_NAME "/dev/ttyS2"
//设置串口波特率
static void set_baudrate (struct termios *opt, unsigned int baudrate)
{
cfsetispeed(opt, baudrate);
cfsetospeed(opt, baudrate);
}
//设置数据位
static void set_data_bit (struct termios *opt, unsigned int databit)
{
opt->c_cflag &= ~CSIZE;
switch (databit) {
case 8:
opt->c_cflag |= CS8;
break;
case 7:
opt->c_cflag |= CS7;
break;
case 6:
opt->c_cflag |= CS6;
break;
case 5:
opt->c_cflag |= CS5;
break;
default:
opt->c_cflag |= CS8;
break;
}
}
//设置校验位
static void set_parity (struct termios *opt, char parity)
{
switch (parity) {
case 'N': /* no parity check */
opt->c_cflag &= ~PARENB;
break;
case 'E': /* even */
opt->c_cflag |= PARENB;
opt->c_cflag &= ~PARODD;
break;
case 'O': /* odd */
opt->c_cflag |= PARENB;
opt->c_cflag |= ~PARODD;
break;
default: /* no parity check */
opt->c_cflag &= ~PARENB;
break;
}
}
//设置停止位
static void set_stopbit (struct termios *opt, const char *stopbit)
{
if (0 == strcmp (stopbit, "1")) {
opt->c_cflag &= ~CSTOPB; /* 1 stop bit */
} else if (0 == strcmp (stopbit, "1")) {
opt->c_cflag &= ~CSTOPB; /* 1.5 stop bit */
} else if (0 == strcmp (stopbit, "2")) {
opt->c_cflag |= CSTOPB; /* 2 stop bits */
} else {
opt->c_cflag &= ~CSTOPB; /* 1 stop bit */
}
}
//串口设置
int set_port_attr (
int fd,
int baudrate, // B1200 B2400 B4800 B9600 .. B115200
int databit, // 5, 6, 7, 8
const char *stopbit, // "1", "1.5", "2"
char parity, // N(o), O(dd), E(ven)
int vtime,
int vmin )
{
struct termios opt;
tcgetattr(fd, &opt);
//设置波特率
set_baudrate(&opt, baudrate);
opt.c_cflag |= CLOCAL | CREAD; /* | CRTSCTS */
//设置数据位
set_data_bit(&opt, databit);
//设置校验位
set_parity(&opt, parity);
//设置停止位
set_stopbit(&opt, stopbit);
//其它设置
opt.c_oflag = 0;
opt.c_lflag |= 0;
opt.c_oflag &= ~OPOST;
opt.c_cc[VTIME] = vtime;
opt.c_cc[VMIN] = vmin;
tcflush (fd, TCIFLUSH);
return (tcsetattr (fd, TCSANOW, &opt));
}
int main(void)
{
int fd;
int len;
char buf[] = "hello ZLG111111!";
int ret;
fd = open(DEV_NAME, O_RDWR | O_NOCTTY);
if(fd < 0) {
perror(DEV_NAME);
return -1;
}
ret = set_port_attr(fd,B115200,8,"1",'N',150,255);
if(ret < 0){
printf("set_port_attr error \n");
return -1;
}
len = write(fd, buf, sizeof(buf));
if (len < 0) {
printf("write data error \n");
}
len = read(fd, buf, sizeof(buf));
if (len < 0) {
printf("read error \n");
return -1;
}
printf("%s", buf);
return (0);
}
【开发指南】M6G2C&A6G2C系列核心板软件开发指南_V1.05 (1) 第十六章串口编程
下载地址
https://download.csdn.net/download/caofengtao1314/10920404