/********************************************************************************
* I.MX6 Linux Serial Baud Rate hacking
* 声明:
* 1. 本文的源代码来自:myzr_android4_2_2_1_1_0.tar.bz2;
* 2. 本文的目的是为了知道I.MX6串口支持的波特率有哪些,最大是多大,
* 并加以验证,因为IMX6DQRM_revC.pdf数据手册上说能达到5Mbit/s:
* High-speed TIA/EIA-232-F compatible, up to 5.0 Mbit/s
* 3. 本文的内容主要用了vim+ctags进行代码跟踪,所以使用了跟踪线路图
* 进行标记,我是这么认为的;
*
* 2015-6-26 晴 深圳 南山平山村 曾剑锋
*******************************************************************************/ \\\\\\\\\\-*- 目录 -*-//////////
| 一、内核驱动代码跟踪:
| 二、Linux C测试代码:
| 三、jni Android.mk写法:
\\\\\\\\\\\\\\\\\/////////////// 一、内核驱动代码跟踪:
//cat drivers/tty/serial/imx.c
static int __init imx_serial_init(void) <----------+
{ |
int ret; |
|
printk(KERN_INFO "Serial: IMX driver\n"); |
|
ret = uart_register_driver(&imx_reg); |
if (ret) |
return ret; |
|
ret = platform_driver_register(&serial_imx_driver); |
if (ret != ) | |
uart_unregister_driver(&imx_reg); | |
| |
return ; +--------+ |
} | |
| |
static void __exit imx_serial_exit(void) | |
{ | |
platform_driver_unregister(&serial_imx_driver); | |
uart_unregister_driver(&imx_reg); | |
} | |
| |
module_init(imx_serial_init); --->---------------*---+
module_exit(imx_serial_exit); |
+-------------+
V
static struct platform_driver serial_imx_driver = {
.probe = serial_imx_probe, --->---+
.remove = serial_imx_remove, |
|
.suspend = serial_imx_suspend, |
.resume = serial_imx_resume, |
.driver = { |
.name = "imx-uart", |
.owner = THIS_MODULE, |
}, ----------------------------+
}; |
V
static int serial_imx_probe(struct platform_device *pdev)
{
......
sport->port.dev = &pdev->dev;
sport->port.mapbase = res->start;
sport->port.membase = base;
sport->port.type = PORT_IMX,
sport->port.iotype = UPIO_MEM;
sport->port.irq = platform_get_irq(pdev, );
sport->rxirq = platform_get_irq(pdev, );
sport->txirq = platform_get_irq(pdev, );
sport->rtsirq = platform_get_irq(pdev, );
sport->port.fifosize = ;
sport->port.ops = &imx_pops; ------------+
sport->port.flags = UPF_BOOT_AUTOCONF; |
sport->port.line = pdev->id; |
init_timer(&sport->timer); |
sport->timer.function = imx_timeout; |
sport->timer.data = (unsigned long)sport; |
...... +----------------------+
} |
V
static struct uart_ops imx_pops = {
.tx_empty = imx_tx_empty,
.set_mctrl = imx_set_mctrl,
.get_mctrl = imx_get_mctrl,
.stop_tx = imx_stop_tx,
.start_tx = imx_start_tx,
.stop_rx = imx_stop_rx,
.enable_ms = imx_enable_ms,
.break_ctl = imx_break_ctl,
.startup = imx_startup,
.shutdown = imx_shutdown,
.set_termios = imx_set_termios, ------------+
.type = imx_type, |
.release_port = imx_release_port, |
.request_port = imx_request_port, |
.config_port = imx_config_port, |
.verify_port = imx_verify_port, |
#if defined(CONFIG_CONSOLE_POLL) |
.poll_get_char = imx_poll_get_char, |
.poll_put_char = imx_poll_put_char, |
#endif +-------------------------------------+
}; |
V
static void imx_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
......
/*
* Ask the core to calculate the divisor for us.
* 获取到的调试信息:
* zengjf port->uartclk : 5000000 --> 最高波特率5Mbit/s
* zengjf baud : 115200 --> 当前设置的波特率
* zengjf quot : 43 --> 不知道啥意思 :)
*/
baud = uart_get_baud_rate(port, termios, old, , port->uartclk / ); ---+
printk("zengjf port->uartclk : %d\n", port->uartclk / ); |
printk("zengjf baud : %d\n", baud); |
quot = uart_get_divisor(port, baud); |
printk("zengjf quot : %d\n", quot); |
...... +-------------------------------------------------------+
} |
|
V //cat drivers/tty/serial/serial_core.c
unsigned int uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
struct ktermios *old, unsigned int min, unsigned int max)
{
......
for (try = ; try < ; try++) {
baud = tty_termios_baud_rate(termios); -----+
...... |
} |
...... +---------------------------------+
} |
|
V //cat drivers/tty/tty_ioctl.c
speed_t tty_termios_baud_rate(struct ktermios *termios)
{
unsigned int cbaud; cbaud = termios->c_cflag & CBAUD; #ifdef BOTHER
/* Magic token for arbitrary speed via c_ispeed/c_ospeed */
if (cbaud == BOTHER)
return termios->c_ospeed;
#endif
if (cbaud & CBAUDEX) {
cbaud &= ~CBAUDEX; if (cbaud < || cbaud + > n_baud_table)
termios->c_cflag &= ~CBAUDEX;
else
cbaud += ;
} /**
* 输出可用的波特率,以下是输出结果(不需要可以删除):
* warning: `zygote' uses 32-bit capabilities (legacy support in use)
* request_suspend_state: wakeup (3->0) at 17554141337 (1970-01-02 00:00:07.145049000 UTC)
* eth0: Freescale FEC PHY driver [Generic PHY] (mii_bus:phy_addr=1:01, irq=-1)
* ADDRCONF(NETDEV_UP): eth0: link is not ready
* acc_open
* acc_release
* ehci_fsl_bus_resume begins, Host 1
* ehci_fsl_bus_resume ends, Host 1
* ehci_fsl_bus_resume begins, DR
* ehci_fsl_bus_suspend begins, Host 1
* ehci_fsl_bus_suspend ends, Host 1
* init: sys_prop: permission denied uid:1003 name:service.bootanim.exit
* zengjf baud_table size : 31
* zengjf baud_table[0] = 0
* zengjf baud_table[1] = 50
* zengjf baud_table[2] = 75
* zengjf baud_table[3] = 110
* zengjf baud_table[4] = 134
* zengjf baud_table[5] = 150
* zengjf baud_table[6] = 200
* zengjf baud_table[7] = 300
* zengjf baud_table[8] = 600
* zengjf baud_table[9] = 1200
* zengjf baud_table[10] = 1800
* zengjf baud_table[11] = 2400
* zengjf baud_table[12] = 4800
* zengjf baud_table[13] = 9600
* zengjf baud_table[14] = 19200
* zengjf baud_table[15] = 38400
* zengjf baud_table[16] = 57600
* zengjf baud_table[17] = 115200
* zengjf baud_table[18] = 230400
* zengjf baud_table[19] = 460800
* zengjf baud_table[20] = 500000
* zengjf baud_table[21] = 576000
* zengjf baud_table[22] = 921600
* zengjf baud_table[23] = 1000000
* zengjf baud_table[24] = 1152000
* zengjf baud_table[25] = 1500000
* zengjf baud_table[26] = 2000000
* zengjf baud_table[27] = 2500000
* zengjf baud_table[28] = 3000000
* zengjf baud_table[29] = 3500000
* zengjf baud_table[30] = 4000000
*/
printk("zengjf baud_table size : %d\n", sizeof(baud_table)/sizeof(baud_table[]));
int i = ;
for(i = ; i < sizeof(baud_table)/sizeof(baud_table[]); i++) {
printk("zengjf baud_table[%d] = %u\n", i, baud_table[i]);
} return baud_table[cbaud]; -->------------+
} |
|
static const speed_t baud_table[] = { <---- +
, , , , , , , , , , , , , -----+
, , , , , , , |
#ifdef __sparc__ |
, , , , |
#else |
, , , , , , , |
, , , |
#endif |
}; // 波特率对应的宏,主要是应用层用 |
+-----------------------------+
#ifndef __sparc__ |
static const tcflag_t baud_bits[] = { V
B0, B50, B75, B110, B134, B150, B200, B300, B600, ->-----+
B1200, B1800, B2400, B4800, B9600, B19200, B38400, |
B57600, B115200, B230400, B460800, B500000, B576000, |
B921600, B1000000, B1152000, B1500000, B2000000, B2500000, |
B3000000, B3500000, B4000000 |
}; |
#else |
static const tcflag_t baud_bits[] = { |
B0, B50, B75, B110, B134, B150, B200, B300, B600, |
B1200, B1800, B2400, B4800, B9600, B19200, B38400, |
B57600, B115200, B230400, B460800, B76800, B153600, |
B307200, B614400, B921600 |
}; |
#endif |
|
/* c_cflag bit meaning */ |
#define CBAUD 0010017 |
#define B0 0000000 /* hang up */ |
#define B50 0000001 <------------------------+
#define B75 0000002
#define B110 0000003
#define B134 0000004
#define B150 0000005
#define B200 0000006
#define B300 0000007
#define B600 0000010
#define B1200 0000011
#define B1800 0000012
#define B2400 0000013
#define B4800 0000014
#define B9600 0000015
#define B19200 0000016
#define B38400 0000017
#define EXTA B19200
#define EXTB B38400
#define CSIZE 0000060
#define CS5 0000000
#define CS6 0000020
#define CS7 0000040
#define CS8 0000060
#define CSTOPB 0000100
#define CREAD 0000200
#define PARENB 0000400
#define PARODD 0001000
#define HUPCL 0002000
#define CLOCAL 0004000
#define CBAUDEX 0010000
#define BOTHER 0010000
#define B57600 0010001
#define B115200 0010002
#define B230400 0010003
#define B460800 0010004
#define B500000 0010005
#define B576000 0010006
#define B921600 0010007
#define B1000000 0010010
#define B1152000 0010011
#define B1500000 0010012
#define B2000000 0010013
#define B2500000 0010014
#define B3000000 0010015
#define B3500000 0010016
#define B4000000 0010017
#define CIBAUD 002003600000 /* input baud rate */
#define CMSPAR 010000000000 /* mark or space (stick) parity */
#define CRTSCTS 020000000000 /* flow control */ 二、Linux C测试代码:
// 测试代码参考:http://blog.csdn.net/shui1025701856/article/details/7571686
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> //文件控制定义
#include <termios.h> //终端控制定义
#include <errno.h> #define DEVICE "/dev/ttymxc2" int serial_fd = ; //打开串口并初始化设置
init_serial(void)
{
serial_fd = open(DEVICE, O_RDWR | O_NOCTTY | O_NDELAY);
if (serial_fd < ) {
perror("open");
return -;
} //串口主要设置结构体termios <termios.h>
struct termios options; /**1. tcgetattr函数用于获取与终端相关的参数。
*参数fd为终端的文件描述符,返回的结果保存在termios结构体中
*/
tcgetattr(serial_fd, &options);
/**2. 修改所获得的参数*/
options.c_cflag |= (CLOCAL | CREAD); //设置控制模式状态,本地连接,接收使能
options.c_cflag &= ~CSIZE; //字符长度,设置数据位之前一定要屏掉这个位
options.c_cflag &= ~CRTSCTS; //无硬件流控
options.c_cflag |= CS8; //8位数据长度
options.c_cflag &= ~CSTOPB; //1位停止位
options.c_iflag |= IGNPAR; //无奇偶检验位
options.c_oflag = ; //输出模式
options.c_lflag = ; //不激活终端模式
//cfsetospeed(&options, B115200); //设置波特率
cfsetospeed(&options, B1500000); //设置波特率 /**3. 设置新属性,TCSANOW:所有改变立即生效*/
tcflush(serial_fd, TCIFLUSH); //溢出数据可以接收,但不读
tcsetattr(serial_fd, TCSANOW, &options); return ;
} /**
*串口发送数据
*@fd:串口描述符
*@data:待发送数据
*@datalen:数据长度
*/
int uart_send(int fd, char *data, int datalen)
{
int len = ;
len = write(fd, data, datalen); //实际写入的长度
if(len == datalen) {
return len;
} else {
tcflush(fd, TCOFLUSH); //TCOFLUSH刷新写入的数据但不传送
return -;
} return ;
} /**
*串口接收数据
*要求启动后,在pc端发送ascii文件
*/
int uart_recv(int fd, char *data, int datalen)
{
int len=, ret = ;
fd_set fs_read;
struct timeval tv_timeout; FD_ZERO(&fs_read);
FD_SET(fd, &fs_read);
tv_timeout.tv_sec = (*/+);
tv_timeout.tv_usec = ; ret = select(fd+, &fs_read, NULL, NULL, &tv_timeout);
printf("ret = %d\n", ret);
//如果返回0,代表在描述符状态改变前已超过timeout时间,错误返回-1 if (FD_ISSET(fd, &fs_read)) {
len = read(fd, data, datalen);
printf("len = %d\n", len);
return len;
} else {
perror("select");
return -;
} return ;
} int main(int argc, char **argv)
{
init_serial(); char buf[]="hello world";
char buf1[];
int i = ;
while (i--) {
uart_send(serial_fd, buf, );
printf("\n");
uart_recv(serial_fd, buf1, );
printf("uart receive %s\n", buf1);
} close(serial_fd);
return ;
} 三、jni Android.mk写法:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS)
LOCAL_MODULE := UART_test
LOCAL_SRC_FILES := UART_test.c include $(BUILD_EXECUTABLE)

I.MX6 Linux Serial Baud Rate hacking的更多相关文章

  1. I.MX6 Linux I2C device& driver hacking

    /******************************************************************************************* * I.MX6 ...

  2. Non-standard serial port baud rate setting

    ////combuad_recv.cpp #include <stdio.h> /*标准输入输出定义*/ #include <stdlib.h> /*标准函数库定义*/ #in ...

  3. I.MX6 ar1020 SPI device driver hacking

    /************************************************************************************ * I.MX6 ar1020 ...

  4. CANBus Determining Network Baud Rate, Automatic bit-rate detection

    http://www.canbushack.com/blog/index.php?title=determining-network-baud-rate Determining Network Bau ...

  5. I.MX6 Linux U-boot 环境变量解析

    /********************************************************************************** * I.MX6 Linux U- ...

  6. I.MX6 Linux mipi配置数据合成

    /*************************************************************************** * I.MX6 Linux mipi配置数据合 ...

  7. I.MX6 Linux、Jni ioctl 差异

    /*********************************************************************** * I.MX6 Linux.Jni ioctl 差异 ...

  8. ti processor sdk linux am335x evm Makefile hacking

    # # ti processor sdk linux am335x evm Makefile hacking # 说明: # 本文主要对TI的sdk中的Makefile脚本进行解读,是为了了解其工作机 ...

  9. I.MX6 linux Qt 同时支持Touch、mouse

    /***************************************************************************** * I.MX6 linux Qt 同时支持 ...

随机推荐

  1. 将正在使用的Ubuntu14.04 制作成镜像文件

    remastersys 是一个能够备份你的ubuntu系统的工具. 源码在github上能找到:Remastersys Source 可以直接 apt 安装: sudo add-apt-reposit ...

  2. 测试报告 之 testNG + Velocity 编写自定义html测试报告

    之前用testNG自带的test-outputemailable-report.html,做出的UI自动化测试报告,页面不太好看. 在网上找到一个新的报告编写,自己尝试了一下,埋了一些坑,修改了输出时 ...

  3. [ios]"The identity used to sign the executable is no longer valid"错误解决方法

    重新去开发者网站,申请一遍profiles 参考:http://www.bubuko.com/infodetail-982908.html 我出现这个错误的情况,程序提交app store之后,第二天 ...

  4. 《A_Pancers》团队项目用户验收评审

    团队项目用户验收评审 一.关于源代码管理的10 个问题: 1.你的团队的源代码控制在哪里?用的是什么系统?如何处理文件的锁定问题? 我们的项目都在github上面,用的win10系统,并且我们的文件没 ...

  5. 《剑指offer》第三十二题(之字形打印二叉树)

    // 面试题32(三):之字形打印二叉树 // 题目:请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺 // 序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印, / ...

  6. Pyhon 日志管理 -- logging

    Pyhon 日志管理 -- logging 一直觉得运行程序是能打印日志是一个神奇的事情,不懂日志产生的原理,后来听说Pyhton 有一个logging模块,So,要好好研究一下. 先贴出代码,看看她 ...

  7. Python map/reduce

    2017-07-31 18:20:59 一.map函数 map():会根据提供的函数对指定序列做映射.第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 ...

  8. 配置rsync 同步数据 rpm包安装rsync及配置

    [root@Hammer home]# rpm -qa |grep rsync #检查系统是否安装了rsync软件包rsync-2.6.8-3.1[root@Hammer CentOS]# rpm - ...

  9. android--------AndroidStudio 关闭 Install Run

    前面讲热修复的时候说到了一个 AndroidStudio关闭Instant Run的问题 ,今天来简单的写一下. Android Studio 工具中是有很多好东西的,要全部的知道的话,还是要下点功夫 ...

  10. 43 HTML CSS

    第一部分: 1.meta 标签中:meta 标签中 <meta http-equvi = "refresh" content="2;URL= https://www ...