您的位置:首页 > 其它

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。

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
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: