MTK6572 串口模拟sim卡开发笔记
2015-12-22 15:10
585 查看
1. LSR Line status register
2. LCR Line control register Determines characteristics of serial communication signals.
3. FCR FIFO chontrol register FCR is used to control the trigger levels of the FIFOs or flush the FIFOs
4. DLL Divisor Latch(LS)
1. 相关文件: 修改CFG_LOG_BAUDRATE CFG_UART_LOG cust_bldr.h
\mediatek\platform\mt6582\preloader\src\drivers\platform.c
\mediatek\platform\mt6582\lk\platform.c
\mediatek\config\mt6572\autoconfig\kconfig\project
mediatek\external\bluetooth\driver\standalonemtk.c里有设置非标波特率的函数,网上也有相关函数。
frameworks/base/core/jni/android_hardware_SerialPort.cpp
frameworks/base/core/java/android/hardware/SerialPort.java
刚开始是对这个驱动不太了解,分层的界限不是很清楚。
platform_uart.c uart.c serial_core.c(ioctl)
混杂设备、字符设备、平台设备三者的注册方式不同。uart死属于字符设备。
如果下载了完整的Android项目的源代码,
则可以在“/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin”目录下找到交叉编译工具,(我下载的目录在
alps/prebuilts/gcc/linux-x86/arm/arm-
arm-eabi-4.6/bin arm-linux-androideabi-4.6/
arm-eabi-4.7/bin arm-linux-androideabi-4.7/)
比如Android所用的arm-eabi-gcc-4.2.1。 Android并没有采用glibc作为C库,
而是采用了Google自己开发的Bionic Libc,它的官方Toolchain也是基于Bionic Libc而并非glibc的。
这使得使用或移植其他Toolchain来用于Android要比较麻烦:
在Google公布用于Android的官方Toolchain之前,多数的Android爱好者使用的Toolchain是在http://www.codesourcery.com/gnu_toolchains/arm/download.html
下载的一个通用的Toolchain,它用来编译和移植Android 的Linux内核是可行的,因为内核并不需要C库,但是开发Android的应用程序时,
直接采用或者移植其他的Toolchain都比较麻烦,
其他Toolchain编译的应用程序只能采用静态编译的方式才能运行于Android模拟器中,
这显然是实际开发中所不能接受的方式。目前尚没有看到说明成功移植其他交叉编译器来编译Android应用程序的资料。
adb shell 进shell环境,传输文件给手机adb push x.txt /sdcard/x.txt
arm-none-linux-gnueabi-gcc下载 http://blog.csdn.net/ee230/article/details/41513957 另一个网址 http://www.veryarm.com/arm-none-linux-gnueabi-gcc
解压 tar -xjvf arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 -C bin/
vim /etc/profile export PATH=~/bin/arm-2014.05/bin/:$PATH
arm-none-linux-gnueabi-gcc -o hello helloworld.c -static
查看编译后文件:file setbaud
setbaud: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped
可能问题(我没有遇到):
64位ubuntu无法使用32位编译器。出现:
error: arm-none-linux-gnueabi-gcc: No such file or directory
解决:
sudo apt-get install libc6:i386 libgcc1:i386 gcc-4.6-base:i386 libstdc++5:i386 libstdc++6:i386
mt6572 串口值:15,14 4103是八进制的,定义在kernel\include\asm-generic\termbits.h termios.h include termbits.h
38400 15
19200 14
9600 13
4800 12
2400 11
1200 9
300 7
57600 4097
115200 4098
230400 4099
460800 4100
921600 4103
110 3
#define ASYNC_SPD_CUST (ASYNC_SPD_HI|ASYNC_SPD_VHI)
cp system.img userdata.img cache.img recovery.img boot.img kernel kernel_rtech72_we_72_kk.bin ramdisk-recovery.img ramdisk.img logo.bin appsboot.* lk.bin secro.img preloader_rtech72_we_72_kk.bin installed-files.txt clean_steps.mk MT6572_Android_scatter.txt EBR1 MBR previous_build_config.mk custom_build_verno android-info.txt /media/sf_BaiduYunDownload/MT6572debug/image/20151225/
提升UART port的permission,同样以UART1为例
./obj/CUSTGEN/config/init.project.rc
./root/init.project.rc
mediatek\kernel\drivers\uart\uart.c mtk_uart_set_baud中联发科的处理逻辑:
custom_divisor[31] == 1, then custom_divisor[30..0] == custom baud rate
uart_ioctl case TIOCSSERIAL:->uart_set_info->uart_change_speed->mtk_uart_set_termios->mtk_uart_set_baud
echo "0 0 0 0" > /proc/sys/kernel/printk
There are three different types of tty drivers: console, serial port, and pty.tty驱动包括三种 console, 串口,还有pty。
2. LCR Line control register Determines characteristics of serial communication signals.
3. FCR FIFO chontrol register FCR is used to control the trigger levels of the FIFOs or flush the FIFOs
4. DLL Divisor Latch(LS)
1. 相关文件: 修改CFG_LOG_BAUDRATE CFG_UART_LOG cust_bldr.h
\mediatek\platform\mt6582\preloader\src\drivers\platform.c
\mediatek\platform\mt6582\lk\platform.c
\mediatek\config\mt6572\autoconfig\kconfig\project
mediatek\external\bluetooth\driver\standalonemtk.c里有设置非标波特率的函数,网上也有相关函数。
frameworks/base/core/jni/android_hardware_SerialPort.cpp
frameworks/base/core/java/android/hardware/SerialPort.java
刚开始是对这个驱动不太了解,分层的界限不是很清楚。
platform_uart.c uart.c serial_core.c(ioctl)
混杂设备、字符设备、平台设备三者的注册方式不同。uart死属于字符设备。
如果下载了完整的Android项目的源代码,
则可以在“/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin”目录下找到交叉编译工具,(我下载的目录在
alps/prebuilts/gcc/linux-x86/arm/arm-
arm-eabi-4.6/bin arm-linux-androideabi-4.6/
arm-eabi-4.7/bin arm-linux-androideabi-4.7/)
比如Android所用的arm-eabi-gcc-4.2.1。 Android并没有采用glibc作为C库,
而是采用了Google自己开发的Bionic Libc,它的官方Toolchain也是基于Bionic Libc而并非glibc的。
这使得使用或移植其他Toolchain来用于Android要比较麻烦:
在Google公布用于Android的官方Toolchain之前,多数的Android爱好者使用的Toolchain是在http://www.codesourcery.com/gnu_toolchains/arm/download.html
下载的一个通用的Toolchain,它用来编译和移植Android 的Linux内核是可行的,因为内核并不需要C库,但是开发Android的应用程序时,
直接采用或者移植其他的Toolchain都比较麻烦,
其他Toolchain编译的应用程序只能采用静态编译的方式才能运行于Android模拟器中,
这显然是实际开发中所不能接受的方式。目前尚没有看到说明成功移植其他交叉编译器来编译Android应用程序的资料。
adb shell 进shell环境,传输文件给手机adb push x.txt /sdcard/x.txt
arm-none-linux-gnueabi-gcc下载 http://blog.csdn.net/ee230/article/details/41513957 另一个网址 http://www.veryarm.com/arm-none-linux-gnueabi-gcc
解压 tar -xjvf arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 -C bin/
vim /etc/profile export PATH=~/bin/arm-2014.05/bin/:$PATH
arm-none-linux-gnueabi-gcc -o hello helloworld.c -static
查看编译后文件:file setbaud
setbaud: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped
可能问题(我没有遇到):
64位ubuntu无法使用32位编译器。出现:
error: arm-none-linux-gnueabi-gcc: No such file or directory
解决:
sudo apt-get install libc6:i386 libgcc1:i386 gcc-4.6-base:i386 libstdc++5:i386 libstdc++6:i386
mt6572 串口值:15,14 4103是八进制的,定义在kernel\include\asm-generic\termbits.h termios.h include termbits.h
38400 15
19200 14
9600 13
4800 12
2400 11
1200 9
300 7
57600 4097
115200 4098
230400 4099
460800 4100
921600 4103
110 3
#define ASYNC_SPD_CUST (ASYNC_SPD_HI|ASYNC_SPD_VHI)
cp system.img userdata.img cache.img recovery.img boot.img kernel kernel_rtech72_we_72_kk.bin ramdisk-recovery.img ramdisk.img logo.bin appsboot.* lk.bin secro.img preloader_rtech72_we_72_kk.bin installed-files.txt clean_steps.mk MT6572_Android_scatter.txt EBR1 MBR previous_build_config.mk custom_build_verno android-info.txt /media/sf_BaiduYunDownload/MT6572debug/image/20151225/
提升UART port的permission,同样以UART1为例
./obj/CUSTGEN/config/init.project.rc
./root/init.project.rc
mediatek\kernel\drivers\uart\uart.c mtk_uart_set_baud中联发科的处理逻辑:
custom_divisor[31] == 1, then custom_divisor[30..0] == custom baud rate
uart_ioctl case TIOCSSERIAL:->uart_set_info->uart_change_speed->mtk_uart_set_termios->mtk_uart_set_baud
echo "0 0 0 0" > /proc/sys/kernel/printk
There are three different types of tty drivers: console, serial port, and pty.tty驱动包括三种 console, 串口,还有pty。
001 #include <termios.h> 002 #include <sys/ioctl.h> 003 #include <stdio.h> /*标准输入输出定义*/ 004 #include <stdlib.h> /*标准函数库定义*/ 005 #include <unistd.h> /*Unix标准函数定义*/ 006 #include <sys/types.h> /**/ 007 #include <sys/stat.h> /**/ 008 #include <fcntl.h> /*文件控制定义*/ 009 #include <termios.h> /*PPSIX终端控制定义*/ 010 #include <errno.h> /*错误号定义*/ 011 #include <linux/serial.h> 012 013 #define TRUE 1 014 #define FALSE 0 015 016 /* 017 *功能:用于测试非标准波特率串口。 018 *此代码仅限于运行在X86架构的环境下,其他架构并未测试。在arm下未测试 019 *请在root下编译此代码 020 *如有问题,联系我:靳小都 hellojinhongdu#126.com 021 */ 022 023 struct serial_t { 024 int fd; 025 char *device;/*/dev/ttyS0,...*/ 026 int baud; 027 int databit;/*5,6,7,8*/ 028 char parity;/*O,E,N*/ 029 int stopbit;/*1,2*/ 030 int startbit;/*1*/ 031 struct termios options; 032 }; 033 034 035 int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300, 036 B38400, B19200, B9600, B4800, B2400, B1200, B300, }; 037 int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 038 38400, 19200, 9600, 4800, 2400, 1200, 300, }; 039 040 void set_speed(int fd, int speed) 041 { 042 int i; 043 int status; 044 struct termios Opt; 045 tcgetattr(fd, &Opt); 046 for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) 047 { 048 if (speed == name_arr[i]) 049 { 050 tcflush(fd, TCIOFLUSH); 051 cfsetispeed(&Opt, speed_arr[i]); 052 cfsetospeed(&Opt, speed_arr[i]); 053 status = tcsetattr(fd, TCSANOW, &Opt); 054 if (status != 0) 055 perror("tcsetattr fd1"); 056 return; 057 } 058 tcflush(fd,TCIOFLUSH); 059 } 060 } 061 062 //设置为特诉波特率,比如28800 063 int serial_set_speci_baud(struct serial_t *tty,int baud) 064 { 065 struct serial_struct ss,ss_set; 066 tcgetattr(tty->fd,&tty->options); 067 cfsetispeed(&tty->options,B38400); 068 cfsetospeed(&tty->options,B38400); 069 070 tcflush(tty->fd,TCIFLUSH);/*handle unrecevie char*/ 071 tcsetattr(tty->fd,TCSANOW,&tty->options); 072 if((ioctl(tty->fd,TIOCGSERIAL,&ss))<0){ 073 printf("BAUD: error to get the serial_struct info:%s\n",strerror(errno)); 074 return -1; 075 } 076 ss.flags = ASYNC_SPD_CUST; 077 ss.custom_divisor = ss.baud_base / baud; 078 079 printf("ss.custom_divisor = %d \r\n",ss.custom_divisor); 080 081 if((ioctl(tty->fd,TIOCSSERIAL,&ss))<0){ 082 printf("BAUD: error to set serial_struct:%s\n",strerror(errno)); 083 //return -2; 084 } 085 086 ioctl(tty->fd,TIOCGSERIAL,&ss_set); 087 printf("BAUD: success set baud to %d,custom_divisor=%d,baud_base=%d\n", 088 baud,ss_set.custom_divisor,ss_set.baud_base); 089 090 return 0; 091 } 092 093 /*get serial's current attribute*/ 094 static int serial_get_attr(struct serial_t *tty) 095 { 096 097 if(tcgetattr(tty->fd,&tty->options) != 0){ 098 099 printf("SERIAL: can't get serial's attribute\n"); 100 return -1; 101 102 } 103 104 return 0; 105 106 } 107 108 /*update serial's attrbute*/ 109 static int serial_attr_update(struct serial_t *tty) 110 { 111 112 tcflush(tty->fd,TCIFLUSH);/*handle unrecevie char*/ 113 114 if((tcsetattr(tty->fd,TCSANOW,&tty->options)) < 0){ 115 116 return -1; 117 118 } 119 120 return 0; 121 122 } 123 124 static int serial_init_databit(struct serial_t *tty) 125 { 126 127 if(serial_get_attr(tty)<0) 128 return -1; 129 130 tty->options.c_cflag &= ~CSIZE; 131 switch(tty->databit){ 132 133 case 5: tty->options.c_cflag |= CS5;break; 134 case 6: tty->options.c_cflag |= CS6;break; 135 case 7: tty->options.c_cflag |= CS7;break; 136 case 8: tty->options.c_cflag |= CS8;break; 137 default: 138 printf("SERIAL: unsupported databit %d\n",tty->databit); 139 return -2; 140 141 } 142 143 if(serial_attr_update(tty) < 0) 144 return -3; 145 146 printf("SERIAL: set databit to %d\n",tty->databit); 147 return 0; 148 149 } 150 151 static int serial_init_parity(struct serial_t *tty) 152 { 153 154 if(serial_get_attr(tty)<0) 155 return -1; 156 157 /*ignore framing and parity error*/ 158 tty->options.c_iflag = IGNPAR; 159 160 switch (tty->parity){ 161 162 case 'n': 163 case 'N': 164 /* Clear parity enable */ 165 tty->options.c_cflag &= ~PARENB; 166 /* Enable parity checking */ 167 tty->options.c_iflag &= ~INPCK; 168 break; 169 case 'o': 170 case 'O': 171 /* 设置为奇校检*/ 172 tty->options.c_cflag |= (PARODD|PARENB); 173 /* Disnable parity checking */ 174 tty->options.c_iflag |= (INPCK|ISTRIP); 175 break; 176 case 'e': 177 case 'E': 178 /* Enable parity */ 179 tty->options.c_cflag |= PARENB; 180 /* 转换为偶效验*/ 181 tty->options.c_cflag &= ~PARODD; 182 /* Disnable parity checking */ 183 tty->options.c_iflag |= (INPCK|ISTRIP); 184 break; 185 default: 186 printf("SERIAL: unsupported parity %c\n",tty->parity); 187 return -2; 188 189 } 190 191 if(serial_attr_update(tty) < 0) 192 return -3; 193 194 printf("SERIAL: set parity to %c\n",tty->parity); 195 196 return 0; 197 198 } 199 200 static int serial_init_stopbit(struct serial_t *tty) 201 { 202 203 if(serial_get_attr(tty)<0) 204 return -1; 205 206 switch(tty->stopbit){ 207 208 case 1: 209 tty->options.c_cflag &= ~CSTOPB;break; 210 case 2: 211 tty->options.c_cflag |= CSTOPB;break; 212 default: 213 printf("SERIAL: unsupported stopbit %d\n",tty->stopbit); 214 return -2; 215 216 } 217 218 if(serial_attr_update(tty) < 0) 219 return -3; 220 221 printf("SERIAL: set stopbit to %d\n",tty->stopbit); 222 223 return 0; 224 225 } 226 227 /** 228 *@brief 设置串口数据位,停止位和效验位 229 *@param fd 类型 int 打开的串口文件句柄* 230 *@param databits 类型 int 数据位 取值 为 7 或者8* 231 *@param stopbits 类型 int 停止位 取值为 1 或者2* 232 *@param parity 类型 int 效验类型 取值为N,E,O,,S 233 */ 234 int set_Parity(int fd,int databits,int stopbits,int parity) 235 { 236 struct termios options; 237 if ( tcgetattr( fd,&options) != 0) 238 { 239 perror("SetupSerial 1"); 240 return(FALSE); 241 } 242 options.c_cflag &= ~CSIZE; 243 switch (databits) /*设置数据位数*/ 244 { 245 case 7: 246 options.c_cflag |= CS7; 247 break; 248 case 8: 249 options.c_cflag |= CS8; 250 break; 251 default: 252 fprintf(stderr,"Unsupported data size\n"); 253 return (FALSE); 254 } 255 switch (parity) 256 { 257 case 'n': 258 case 'N': 259 options.c_cflag &= ~PARENB; /* Clear parity enable */ 260 options.c_iflag &= ~INPCK; /* Enable parity checking */ 261 break; 262 case 'o': 263 case 'O': 264 options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/ 265 options.c_iflag |= INPCK; /* Disnable parity checking */ 266 break; 267 case 'e': 268 case 'E': 269 options.c_cflag |= PARENB; /* Enable parity */ 270 options.c_cflag &= ~PARODD; /* 转换为偶效验*/ 271 options.c_iflag |= INPCK; /* Disnable parity checking */ 272 break; 273 case 'S': 274 case 's': /*as no parity*/ 275 options.c_cflag &= ~PARENB; 276 options.c_cflag &= ~CSTOPB; 277 break; 278 default: 279 fprintf(stderr,"Unsupported parity\n"); 280 return (FALSE); 281 } 282 /* 设置停止位*/ 283 switch (stopbits) 284 { 285 case 1: 286 options.c_cflag &= ~CSTOPB; 287 break; 288 case 2: 289 options.c_cflag |= CSTOPB; 290 break; 291 default: 292 fprintf(stderr,"Unsupported stop bits\n"); 293 return (FALSE); 294 } 295 /* Set input parity option */ 296 if (parity != 'n') 297 options.c_iflag |= INPCK; 298 options.c_cc[VTIME] = 150; // 15 seconds 299 options.c_cc[VMIN] = 0; 300 301 tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */ 302 if (tcsetattr(fd,TCSANOW,&options) != 0) 303 { 304 perror("SetupSerial 3"); 305 return (FALSE); 306 } 307 return (TRUE); 308 } 309 310 //用法:只要指定serial_t的baud就可以了 311 312 static struct serial_t __seri_conf[] = { 313 [0] = {//connect with b board, ttyS0 314 .device = "/dev/ttyS1", 315 .baud = 28800, 316 .databit = 8, 317 .parity = 'N', 318 .stopbit = 1, 319 }, 320 }; 321 322 /** 323 *@breif main() 324 */ 325 int main(int argc, char **argv) { 326 327 int fd; 328 int nread; 329 char buff[512]; 330 331 fd = open(__seri_conf->device, O_RDWR | O_NOCTTY | O_NONBLOCK); 332 __seri_conf->fd = fd; 333 serial_set_speci_baud(__seri_conf, __seri_conf->baud); 334 /* 335 if (set_Parity(__seri_conf->fd, 8, 1, 'N') == FALSE) 336 { 337 printf("Set Parity Error\n"); 338 } 339 */ 340 if(serial_init_databit(__seri_conf)<0) 341 printf("serial_init_databit error\n"); 342 if(serial_init_parity(__seri_conf)<0) 343 printf("serial_init_parity error\n"); 344 if(serial_init_stopbit(__seri_conf)<0) 345 printf("serial_init_stopbit error\n"); 346 347 //struct termios opt; 348 tcgetattr(__seri_conf->fd,&__seri_conf->options); 349 __seri_conf->options.c_iflag &=~(BRKINT|ICRNL|INPCK|ISTRIP|IXON); 350 __seri_conf->options.c_lflag &=~(ICANON|ECHO|ECHOE|ECHONL|ISIG|IEXTEN); 351 __seri_conf->options.c_oflag &=~(OPOST); 352 if(tcsetattr(__seri_conf->fd,TCSANOW,&__seri_conf->options)!=0) 353 printf("error"); 354 355 356 while (1) { 357 char ct[10] = "hello"; 358 write(__seri_conf->fd, ct, 10); 359 360 puts("hello world 28800 test 8888!\n"); 361 sleep(1); 362 363 nread = read(__seri_conf->fd,buff,256); 364 if(nread>0) 365 { 366 printf("recv :%d ***%s\r\n",nread,buff); 367 } 368 369 } 370 close(fd); 371 }
相关文章推荐
- 判断当前网络状态 显示网络小图标
- Filter进行登录验证时循环重定向的解决方法(转)
- C++学习笔记-泛型算法
- C++学习笔记-泛型算法
- 程序报0xc0150002和0xc000007b错误的解决方法
- 闪客工具:微信本地调试工具
- Android样式开发之selector
- iOS常用判断的宏定义:系统版本号,屏幕宽高,设备型号, 自定义NSLog等
- Linux目录结构
- SQL Server 2008 R2 添加登录账户配置权限
- swift学习日志——可变参数
- 欢迎使用CSDN-markdown编辑器
- Myisam与Innodb的选择
- vim替换操作整理大全
- java Date 和 javascript Date
- 如何解决requireJs的模块加载超时
- Mac下添加java环境变量
- NO.161 如何做禅道二次开发(2):找到要修改的文件
- 查看grid正常集群状态 crs_stat -t
- hdu 5366(排列组合)