The problem about UART on IMX6 with Android6.0.1

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

The problem about UART on IMX6 with Android6.0.1

3,495 Views
pengxingwei
Contributor III

Hello all,

            my board is IMX6Q/DL SABRESD ,on which is running the Android6.0.1. I use the uart4(ttymxc3) to recevice data, but the problem :When the data length reaches 4096, the data is transmitted everytime ,In other words ,we can't read data if the uart buffer can't reach 4096 byte. I don't know what and why caused the problem  ,and how to solve it ! Thank you !!

0 Kudos
Reply
10 Replies

2,976 Views
nguyenmr
Contributor III

Hi Peng,

did you add: dma-names = "rx";  to &uart{} in device tree?

0 Kudos
Reply

2,976 Views
pengxingwei
Contributor III

Hi Nguyen,

 The defalut device tree about uart :dma-names = "rx","tx"; now I chage it :  dma-names = "tx"; That is, rx does not use the DMA mechanism  ,the problem sloved

0 Kudos
Reply

2,976 Views
nguyenmr
Contributor III

Hi Peng,

try this jni code: UART_JNI_Lib.rar - Google Drive 

0 Kudos
Reply

2,976 Views
pengxingwei
Contributor III

Hi Nguyen,

   Thank you ! my problem had solved ,It is DMA that causes this problem,modefied the kernel dts,the peoblem was solved!

0 Kudos
Reply

2,976 Views
nguyenmr
Contributor III

Hi,

you should review JNI library for UART, maybe it's incorrect config.

i also use IMX6Q (android 6, 4.1.15) to transmit/ receive data on uart port and it can transmit/receive data with any length.

BR.

0 Kudos
Reply

2,976 Views
pengxingwei
Contributor III

Hi Nguyen Mr,

  Thanks for your reply,

my config as follows:

#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <jni.h>
#include "android/log.h"
static const char *TAG="serial_port";
#define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO,  TAG, fmt, ##args)
#define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
static speed_t getBaudrate(jint baudrate)
{
 switch(baudrate) {
 case 0: return B0;
 case 50: return B50;
 case 75: return B75;
 case 110: return B110;
 case 134: return B134;
 case 150: return B150;
 case 200: return B200;
 case 300: return B300;
 case 600: return B600;
 case 1200: return B1200;
 case 1800: return B1800;
 case 2400: return B2400;
 case 4800: return B4800;
 case 9600: return B9600;
 case 19200: return B19200;
 case 38400: return B38400;
 case 57600: return B57600;
 case 115200: return B115200;
 case 230400: return B230400;
 case 460800: return B460800;
 case 500000: return B500000;
 case 576000: return B576000;
 case 921600: return B921600;
 case 1000000: return B1000000;
 case 1152000: return B1152000;
 case 1500000: return B1500000;
 case 2000000: return B2000000;
 case 2500000: return B2500000;
 case 3000000: return B3000000;
 case 3500000: return B3500000;
 case 4000000: return B4000000;
 default: return -1;
 }
}
/*
 * Class:     android_serialport_SerialPort
 * Method:    open
 * Signature: (Ljava/lang/String;II)Ljava/io/FileDescriptor;
 */
JNIEXPORT jobject JNICALL Java_com_strong_pxw_utils_SerialPort_open
  (JNIEnv *env, jclass thiz, jstring path, jint baudrate, jint flags)
{
 int fd;
 speed_t speed;
 jobject mFileDescriptor;
 /* Check arguments */
 {
  speed = getBaudrate(baudrate);
  if (speed == -1) {
   /* TODO: throw an exception */
   LOGE("Invalid baudrate");
   return NULL;
  }
 }
 /* Opening device */
 {
  jboolean iscopy;
  const char *path_utf = (*env)->GetStringUTFChars(env, path, &iscopy);
  LOGD("Opening serial port %s with flags 0x%x", path_utf, O_RDWR | flags);
  fd = open(path_utf, O_RDWR | flags);
  LOGD("open() fd = %d", fd);
  (*env)->ReleaseStringUTFChars(env, path, path_utf);
  if (fd == -1)
  {
   /* Throw an exception */
   LOGE("Cannot open port");
   /* TODO: throw an exception */
   return NULL;
  }
 }
 /* Configure device */
 {
  struct termios cfg;
  LOGD("Configuring serial port");
  if (tcgetattr(fd, &cfg))
  {
   LOGE("tcgetattr() failed");
   close(fd);
   /* TODO: throw an exception */
   return NULL;
  }
  cfmakeraw(&cfg);
  cfsetispeed(&cfg, speed);
  cfsetospeed(&cfg, speed);
  //CLOCAL和CREAD分别用于本地连接和接受使能
  cfg.c_cflag |= (CLOCAL | CREAD); //一般必设置的标志
  cfg.c_cflag &= ~CSIZE;    //8位数据位
  cfg.c_cflag |= CS8;
  //奇校验
  cfg.c_cflag |= PARENB;//校验使能
  cfg.c_cflag |= PARODD;//奇校验
  cfg.c_iflag |= INPCK;
  cfg.c_cflag &= ~CSTOPB;//一位停止位
  cfg.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);//选择原始输入
  cfg.c_oflag &= ~OPOST;//选择原始输出
  cfg.c_oflag &= ~(ONLCR | OCRNL);
  cfg.c_iflag &= ~(ICRNL| INLCR); //Input
  cfg.c_iflag &= ~(IXON | IXOFF | IXANY);//设置软件流控无效
//   cfg.c_oflag = 0;
//   cfg.c_lflag = 0;
  //设置等待时间和最小接收字符
  cfg.c_cc[VTIME] = 0;//等待的时间
  cfg.c_cc[VMIN] = 0;//等待的最小字节数
  tcflush(fd, TCIOFLUSH);
        if (tcsetattr(fd, TCSANOW, &cfg))
  {
   LOGE("tcsetattr() failed");
   close(fd);
   /* TODO: throw an exception */
   return NULL;
  }
 }
 /* Create a corresponding file descriptor */
 {
  jclass cFileDescriptor = (*env)->FindClass(env, "java/io/FileDescriptor");
  jmethodID iFileDescriptor = (*env)->GetMethodID(env, cFileDescriptor, "<init>", "()V");
  jfieldID descriptorID = (*env)->GetFieldID(env, cFileDescriptor, "descriptor", "I");
  mFileDescriptor = (*env)->NewObject(env, cFileDescriptor, iFileDescriptor);
  (*env)->SetIntField(env, mFileDescriptor, descriptorID, (jint)fd);
 }
 return mFileDescriptor;
}
/*
 * Class:     cedric_serial_SerialPort
 * Method:    close
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_strong_pxw_utils_SerialPort_close
  (JNIEnv *env, jobject thiz)
{
 jclass SerialPortClass = (*env)->GetObjectClass(env, thiz);
 jclass FileDescriptorClass = (*env)->FindClass(env, "java/io/FileDescriptor");
 jfieldID mFdID = (*env)->GetFieldID(env, SerialPortClass, "mFd", "Ljava/io/FileDescriptor;");
 jfieldID descriptorID = (*env)->GetFieldID(env, FileDescriptorClass, "descriptor", "I");
 jobject mFd = (*env)->GetObjectField(env, thiz, mFdID);
 jint descriptor = (*env)->GetIntField(env, mFd, descriptorID);
 LOGD("close(fd = %d)", descriptor);
 close(descriptor);
}
I only use the rx to read data,the data will be returned when the data length reach 4096.
the AS log: the read buffer was 512; 
If the buffer size is 1024,
but I use Android4.4.2 OS Previously, the data will be returned immediately 
 So, how to solve the problem on the Android6.0.1(linux4.1.15 kernel)? Thanks
0 Kudos
Reply

2,976 Views
ramyaravichandr
Contributor I

Hi,

It will be helpful if we know the following:

1. Did you try with different sizes of transmit/receive?

2. Which tool are you using for showing the transmission and reception of data?

Thanks,

Ramya

0 Kudos
Reply

2,976 Views
pengxingwei
Contributor III

Hi,

   for the first question, I had changed the recevice buffer size ,but the total data length is also 4096 evevytime;

 for the second question ,I use the serial tools is the android-serialport-api demo

Thanks

0 Kudos
Reply

2,976 Views
ramyaravichandr
Contributor I

Hi Peng,

Thanks for your reply.

Is there any problem in transmitting less than 10 characters?

If my understanding is correct, you are not able to receive characters less than 4096.

If you could let me know the software, version of software you are using, then it will be possible for me to analyse and help you.

Thanks,

Ramya

www.blackpeppertech.com

0 Kudos
Reply

2,976 Views
igorpadykov
NXP Employee
NXP Employee

Hi peng

this may be related to linux high level serial driver as described on

How to increase the serial transmit buffer size in the Kernel. 

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply