Linux Serial subsystem development
 help / color / mirror / Atom feed
From: Greg KH <gregkh@linuxfoundation.org>
To: "Kijam López" <kijamve@gmail.com>
Cc: linux-usb@vger.kernel.org, linux-serial@vger.kernel.org
Subject: Re: Driver CH341 USB Adapter Serial Port not Works in Linux
Date: Sun, 13 Apr 2014 22:23:23 -0700	[thread overview]
Message-ID: <20140414052323.GB11480@kroah.com> (raw)
In-Reply-To: <CAMkwOQaqQgDzE430u3TOG85gtqrX-AK0nTWK9dYsJSk-JtK5Mg@mail.gmail.com>

On Mon, Apr 14, 2014 at 12:16:40AM -0430, Kijam López wrote:
> I reported here:
> 
>      https://bugreports.qt-project.org/browse/QTBUG-38305
> 
> But just migrate my APP to ANSI C and is exactly the same.
> 
> My code test in ANSI C:
> 
>      #include <sys/types.h>
>      #include <sys/stat.h>
>      #include <fcntl.h>
>      #include <termios.h>
>      #include <unistd.h>
>      #include <errno.h>
>      #include <stdio.h>
>      #include <string.h>
>      #include <ctype.h>
>      #include <pthread.h>
>      #include <stdlib.h>
>      #include <time.h>
> 
>      #define STX (0x02)
>      #define ETX (0x03)
>      #define ENQ (0x05)
>      #define ACK (0x06)
>      #define NAK (0x15)
>      #define SEP (0x0A)
> 
>      int serial = -1;
>      int finnish = 0;
> 
>      char *buffer = NULL;
>      size_t buffer_size = 0;
>      size_t buffer_len = 0;
> 
>      const char enq[1] = {ENQ};
>      const char ack[1] = {ACK};
>      const char nak[1] = {NAK};
> 
>      pthread_cond_t buffer_no_empty = PTHREAD_COND_INITIALIZER;
>      pthread_mutex_t buffer_mutex = PTHREAD_MUTEX_INITIALIZER;
> 
>      static void debug_str(const char *str, size_t size) {
>           int i;
>           for(i = 0; i < size; ++i)
>                if(isprint(str[i]) && !iscntrl(str[i]))
>                     printf("%c", (char)str[i]);
>                else
>                     printf(" 0x%02X ", (unsigned char) str[i]);
>           printf("\n");
>      }
> 
>      static void flush() {
>           if(serial<0) return;
>           tcflush(serial, TCIFLUSH);
>           tcflush(serial, TCIOFLUSH);
>           tcflush(serial, TCOFLUSH);
>      }
> 
>      static void openPort(const char *port) {
>           serial = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
>           if(serial<0) {
>                printf("Error %u from serial open: %s\n", errno,
> strerror(errno));
>                return ;
>           }
> 
>           struct termios tty;
>           memset(&tty, 0, sizeof(tty));
> 
>           // Set Baud Rate
>           cfsetospeed (&tty, B9600);
>           cfsetispeed (&tty, B9600);
> 
>           tty.c_cflag     |=   PARENB;
>           tty.c_cflag     &=   ~(PARODD | CSTOPB | CSIZE);
>           tty.c_cflag     |=   CS8;
>           tty.c_cflag     |=   CLOCAL;
>           tty.c_cflag     |=   CREAD;
> 
>           tty.c_iflag |= (IXON | IXOFF | IXANY);
> 
>           flush();
> 
>           if ( tcsetattr(serial, TCSANOW, &tty) != 0 )
>                printf("Error %d from tcsetattr: %s\n", errno, strerror(errno));
> 
>           flush();
>      }
> 
>      #define valid_buffer() (buffer_size>3 && buffer[0]==STX &&
> buffer[buffer_size-2] == ETX)
> 
>      static void* thread_read(void* dummy) {
>           unsigned char buf;
>           while(!finnish) {
>                int n = read(serial, &buf, 1);
>                if(n>0) {
>                     pthread_mutex_lock(&buffer_mutex);
>                     if(buf == ENQ) {
>                          printf("Recive ENQ, sending ACK\n");
>                          write(serial, ack, 1);
>                          pthread_mutex_unlock(&buffer_mutex);
>                          continue;
>                     }
>                     if(buffer_size == buffer_len) {
>                          buffer_len *= 2;
>                          buffer = realloc(buffer, (size_t)buffer_len);
>                     }
>                     buffer[buffer_size] = buf;
>                     buffer_size += 1;
>                     printf("Buffer: ");
>                     debug_str(buffer, buffer_size);
>                     if(valid_buffer()) {
>                          printf("Signal buffer_no_empty\n");
>                          pthread_cond_signal(&buffer_no_empty);
>                     }
>                     pthread_mutex_unlock(&buffer_mutex);
>                }else if(n<0 && errno!=11) {
>                     printf("Error %d from serial read: %s\n", errno,
> strerror(errno));
>                }
>           }
>           return NULL;
>      }
> 
>      static void send_and_read(const char *data, size_t size, int
> timeout, char **recv, size_t *size_recv) {
> 
>           printf("Write: ");
>           debug_str(data, size);
> 
>           write(serial, data, size);
> 
>           time_t startTime = time(NULL);
>           struct timespec ts;
>           clock_gettime(CLOCK_REALTIME, &ts);
>           ts.tv_sec += timeout;
> 
>           printf("Wait response...\n");
>           pthread_mutex_lock(&buffer_mutex);
> 
>           while(!valid_buffer() && time(NULL)-startTime<timeout-1)
>                pthread_cond_timedwait(&buffer_no_empty, &buffer_mutex, &ts);
> 
>           if(valid_buffer()) {
>                *recv = malloc(buffer_size+1);
>                *size_recv = buffer_size;
>                memcpy(*recv, buffer, buffer_size);
>                (*recv)[buffer_size]='\0';
>                printf("Read:");
>                debug_str(*recv, buffer_size);
>           }else{
>                printf("Timeout...\n");
>                *recv = NULL;
>                *size_recv = 0;
>           }
>           buffer_size = 0;
>           memset(buffer, 0, buffer_len);
> 
>           pthread_mutex_unlock(&buffer_mutex);
>      }
> 
>      int main(){
>           openPort("/dev/ttyUSB0");
>           if(serial>0) {
>                buffer = malloc(1024);
>                buffer_len = 1024;
>                pthread_t thread;
>                pthread_create(&thread, NULL, thread_read, NULL);
> 
>                char *test = NULL;
>                size_t s = 0;
>                send_and_read(enq, 1, 15, &test, &s);
>                if(s>0)
>                     printf("Test status: OK\n");
>                else
>                     printf("Test status: Fail\n");
> 
>                sleep(3); //Pause...
> 
>                char command[5] = {STX, 'S', '1', ETX, 'a'};
> 
>                send_and_read(command, 5, 15, &test, &s);
>                if(s>0)
>                     printf("Test command: OK\n");
>                else
>                     printf("Test command: Fail\n");
> 
>                finnish = 1;
> 
>                void *dummy;
>                pthread_join(thread, &dummy);
> 
>                close(serial);
>                free(buffer);
>           }
>      }
> 
> My Log of APP:
>      Write:  0x05
>      Wait response...
>      Buffer:  0x02
>      Buffer:  0x02 `
>      Buffer:  0x02 `@
>      Buffer:  0x02 `@ 0x03
>      Buffer:  0x02 `@ 0x03 #
>      Signal buffer_no_empty
>      Read: 0x02 `@ 0x03 #
>      Test status: OK
>      Write:  0x02 S1 0x03 a
>      Wait response...
>      Timeout...
>      Test command: Fail

I'm confused, what should it do?

And what kernel version are you using here?

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2014-04-14  5:20 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-14  0:49 Driver CH341 USB Adapter Serial Port not Works in Linux Kijam López
2014-04-14  1:20 ` Greg KH
2014-04-14  1:21   ` Kijam López
2014-04-14  1:44     ` Greg KH
2014-04-14  4:46       ` Kijam López
2014-04-14  5:23         ` Greg KH [this message]
2014-04-14  5:32           ` Kijam López
2014-04-14  6:36             ` Kijam López
     [not found]               ` <CAMkwOQZe2Gr8YFXGOqdBMiG6nTJj-waJRa9sR2xcnwRuLpRAOA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-04-14  6:42                 ` Kijam López
     [not found]     ` <CAMkwOQa4Wm9vnyDce_tkf3J=h73A3NfX3oAwTaOUeEVduStC4Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-04-14 10:13       ` Karl Palsson
2014-04-14 16:25         ` Kijam López

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140414052323.GB11480@kroah.com \
    --to=gregkh@linuxfoundation.org \
    --cc=kijamve@gmail.com \
    --cc=linux-serial@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox