嵌入式爱好者

查看: 12309|回复: 5

在android系统中的linux层调用串口驱动读取数据 -----版主一定要帮助看一下

[复制链接]

15

主题

27

帖子

45

积分

AM335x通行证

扫一扫,手机访问本帖
发表于 2012-5-10 15:30:54 | 显示全部楼层 |阅读模式
这几天我在android的linux层做一个串口通信程序(主要是想摆脱NDK的约束,用C来完成所用功能,就像在LInux下一样),调试始终有问题(将程序放到开发板上,然后通过串口与计算机相连,使用串口调试程序来测试,结果在串口调试助手中要么显示乱码,要么就没有数据)
下面是我的设计步骤:
1、进入android源码的根目录,在/exteral下新建文件夹SerialComm,在SerialComm文件夹下新建源文件SerialComm.c和Android.mk。
源文件内容:
SerialComm.c :
#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#define FALSE -1
#define TRUE 0

/**
*@brief  设置串口通信速率
*@param  fd     类型 int  打开串口的文件句柄
*@param  speed  类型 int  串口速度
*@return  void
*/
int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,
                  B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {38400,  19200,  9600,  4800,  2400,  1200,  300, 38400,  
                  19200,  9600, 4800, 2400, 1200,  300, };
void set_speed(int fd, int speed){
    int   i;
    int   status;
    struct termios   Opt;
    tcgetattr(fd, &Opt);
    for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++)
    {
       if  (speed == name_arr[i])
       {
/**
* tcflush函数刷清(抛弃)输入缓存(终端驱动程序已接收到,但用户程序尚未读)或输出缓存(用户程序已经写,但尚未发送)。queue参数应是下列三个常数之一:
* TCIFLUSH刷清输入队列。
* TCOFLUSH刷清输出队列。
* TCIOFLUSH刷清输入、输出队列。
*/
               tcflush(fd, TCIOFLUSH);//设置前flush     
               cfsetispeed(&Opt, speed_arr[i]);  
               cfsetospeed(&Opt, speed_arr[i]);   
               //通过tcsetattr函数把新的属性设置到串口上。
               //tcsetattr(串口描述符,立即使用或者其他标示,指向termios的指针)
               status = tcsetattr(fd, TCSANOW, &Opt);  
               if  (status != 0)
               {        
                       perror("tcsetattr fd1");  
                       return;     
               }   
               tcflush(fd,TCIOFLUSH);  //设置后flush
       }  
    }
}


/**
*@brief   设置串口数据位,停止位和效验位
*@param  fd     类型  int  打开的串口文件句柄
*@param  databits 类型  int 数据位   取值 为 7 或者8
*@param  stopbits 类型  int 停止位   取值为 1 或者2
*@param  parity  类型  int  效验类型 取值为N,E,O,,S
*/
int set_Parity(int fd, int databits, int stopbits, int parity)
{
    struct termios options;
    if (tcgetattr(fd, &options) != 0)
    {
       perror("SetupSerial 1");
       return (FALSE);
    }
    options.c_cflag &= ~CSIZE;
    switch (databits)
    /*设置数据位数*/
    {
    case 7:
       options.c_cflag |= CS7;
       break;
    case 8:
       options.c_cflag |= CS8;
       break;
    default:
       fprintf(stderr,"Unsupported data size\n");
       return (FALSE);
    }
    switch (parity)
    {
    case 'n':
    case 'N':
       options.c_cflag &= ~PARENB; /* Clear parity enable */
       options.c_iflag &= ~INPCK; /* Enable parity checking */
       break;
    case 'o':
    case 'O':
       options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
       options.c_iflag |= INPCK; /* Disnable parity checking */
       break;
    case 'e':
    case 'E':
       options.c_cflag |= PARENB; /* Enable parity */
       options.c_cflag &= ~PARODD; /* 转换为偶效验*/
       options.c_iflag |= INPCK; /* Disnable parity checking */
       break;
    case 'S':
    case 's': /*as no parity*/
       options.c_cflag &= ~PARENB;
       options.c_cflag &= ~CSTOPB;
       break;
    default:
       fprintf(stderr,"Unsupported parity\n");
       return (FALSE);
    }
    /* 设置停止位*/
    switch (stopbits)
    {
    case 1:
       options.c_cflag &= ~CSTOPB;
       break;
    case 2:
       options.c_cflag |= CSTOPB;
       break;
    default:
       fprintf(stderr,"Unsupported stop bits\n");
       return (FALSE);
    }
    /* Set input parity option */
    if (parity != 'n')
       options.c_iflag |= INPCK;
    tcflush(fd, TCIFLUSH);
    options.c_cc[VTIME] = 150; /* 设置超时15 seconds*/
    options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
    if (tcsetattr(fd, TCSANOW, &options) != 0)
    {
       perror("SetupSerial 3");
       return (FALSE);
    }
    return (TRUE);
}

int main(int argc,char* argv[])
{
        //open serial with block
        int fd=open("/dev/s3c2410_serial1",O_RDWR);
        if(fd==-1)
        {
                perror("open error");
                return 0;
        }
    printf("serial1 is be open fd=%d\n",fd);
    set_speed(fd,4800);
    if(set_Parity(fd,8,1,'N')==FALSE)
    {
            printf("Failed to set serial properiy");
            close(fd);
            return 0;
    }
    int iTmp=write(fd,"hello",strlen("hello"));
    printf("iTmp=%d\n",iTmp);
   
    char chTmp[50];
    iTmp=read(fd,chTmp,50);
    printf("chTmp:%s\n",chTmp);
        close(fd);
        return 0;
}


Android.mk:
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS:=optional
LOCAL_SRC_FILES:=SerialComm.c
LOCAL_MODULE:=SerialComm
include $(BUILD_EXECUTABLE)

在android源码的根目录执行:make SerialComm
root@zero-desktop:~/forLinux/android2.3.4_32bit# make SerialComm
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.3.4
TARGET_PRODUCT=generic
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=GRJ06D
============================================
find: `frameworks/base/frameworks/base/docs/html': No such file or directory
find: `out/target/common/docs/gen': No such file or directory
find: `frameworks/base/frameworks/base/docs/html': No such file or directory
find: `out/target/common/docs/gen': No such file or directory
find: `frameworks/base/frameworks/base/docs/html': No such file or directory
find: `out/target/common/docs/gen': No such file or directory
find: `frameworks/base/frameworks/base/docs/html': No such file or directory
find: `out/target/common/docs/gen': No such file or directory
find: `frameworks/base/frameworks/base/docs/html': No such file or directory
find: `out/target/common/docs/gen': No such file or directory
Install: out/host/linux-x86/bin/apriori
Install: out/host/linux-x86/bin/soslim
target Non-prelinked: SerialComm (out/target/product/generic/symbols/system/bin/SerialComm)
Install: out/target/product/generic/system/lib/libdl.so
Install: out/target/product/generic/system/lib/libc.so
Install: out/target/product/generic/system/lib/libstdc++.so
Install: out/target/product/generic/system/lib/libm.so
Install: out/target/product/generic/system/bin/SerialComm
root@zero-desktop:~/forLinux/android2.3.4_32bit#

将SerialComm拷贝到开发板的/root下,连接好串口以及设置好串口调试助手,执行./SerialComm,但是在串口调试助手里面并没有由SerialComm发送过来的数据,同时也不能接收数据。
烦请你帮我看一下问题所在,谢谢!
回复

使用道具 举报

15

主题

27

帖子

45

积分

AM335x通行证

 楼主| 发表于 2012-5-11 15:13:56 | 显示全部楼层
回复 1# jtou100
看来还是自己来回复吧
这里的问题我基本锁定了,就是调用串口驱动的时候我是使用:int fd=open("/dev/s3c2410_serial1",O_RDWR);
这里我已经试了,除了s3c2410_serial0以外,其它三个都不能用,即s3c2410_serial1,s3c2410_serial2,s3c2410_serial3直接调用都不能用
虽然打印信息显示数据已经发送,但是在终端我们不能接受到。请给位同仁都小心一点,也希望版主能够给予解释一下为什么?
回复 支持 反对

使用道具 举报

1

主题

3670

帖子

4181

积分

发表于 2012-5-11 16:33:30 | 显示全部楼层
ttl电平的接电脑上很危险,没把开发板烧了就算万幸了
技术支持电话:0312-3119192
技术支持邮箱:Android@forlinx.com
回复 支持 反对

使用道具 举报

liwanfei999 该用户已被删除
发表于 2012-10-30 17:05:38 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

xiaolonghun 该用户已被删除
发表于 2012-11-9 16:46:10 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋| 飞凌嵌入式 ( 冀ICP备12004394号-1 )

GMT+8, 2024-12-28 09:22

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表