Android Serial Communication

Source: Internet
Author: User
Indicate the source and author when Reprinting ArticleSource: Http://www.cnblogs.com/xl19862005 Author: xandy

 

Recently, I have been working on serial port communication for Android. The function is probably to communicate with the arm of the Android system and an MCU outside the system, and control the devices mounted to the MCU through the android interface, for example, radio, TV, BT, etc. Let's give a simple explanation of this process. What's wrong is that we hope you can make an axe ......

First, let's look at a picture, as shown below:

I directly read and write the device node/dev/ttymxc1 of the serial port through two threads in the Hal layer.CodeAs follows:

1. init code

 /*  **************************************** **********************
** Fun: init UART (/dev/ttymxc1 );
** In:
** Out: FD sucess,-1 false;
** Init_mcuuart
**************************************** ********************** */
Static Int Init_mcuuart ( Void )
{
Int FD, VaR ;
Portinfo pport_info;
Int Err;

Dbg (dbg_debug, " Init_mcuuart in " );

// Clear message Buf
Memset (& pport_info, 0 , Sizeof (Portinfo ));

// Alloc sent and receive Buf
Psentmessagepackage = malloc ( Sizeof (Msgpkg ));
Preceivemessagepackage = malloc ( Sizeof (Msgpkg ));

FD = open_mcuport ();

Psentmessagepackage-> FD = FD;
Preceivemessagepackage-> FD = FD;

If (FD =- 1 )
{
LogE ( " Init_mcuuart open port error! " );
Return - 1 ;
}

Pport_info.baud_rate = com1mcu_baud;
Pport_info.data_bits = com1mcu_databit;
Pport_info.flow_ctrl = com1mcu_ctrl;
Pport_info.stop_bit = com1mcu_stopbit;
Pport_info.parity = com1mcu_parity;
Pport_info.port_fd = FD;

// Pthread_mutex_lock (& pport_info.portlock );
VaR = Set_portlocked (& pport_info );
// Pthread_mutex_unlock (& pport_info.portlock );

If ( VaR < 0 )
{
LogE (" Set_portlocked error! " );
Return - 1 ;
}

// Handshake message
// Messagepackage (& poweronhandshakecmd, null );

// Messagepackage (& testcmd, "************* com1mcu. C mode for test *********");

// UART send message thread
Sem_init (& psentmessagepackage-> uart_begin, 0 , 0 );
Sem_init (& psentmessagepackage-> uart_end, 0 , 0 );
Psentmessagepackage-> uart_inited = True ;
Err = pthread_create (& psentmessagepackage-> thread_id, null, & uartuploaddata ,( Void *) Psentmessagepackage );

If (Err! = 0 )
LogE ( " Init_mcuuart pthread_create psentmessagepackage error % s! " , Strerror (ERR ));

// UART receive message thread and analyze it
// Sem_init (& preceivemessagepackage-> uart_begin, 0, 0 );
Sem_init (& preceivemessagepackage-> uart_end, 0 ,0 );
Preceivemessagepackage-> uart_inited = True ;
Err = pthread_create (& preceivemessagepackage-> thread_id, null, & uartdownloaddata ,( Void *) Preceivemessagepackage );

If (Err! = 0 )
LogE ( " Init_mcuuart pthread_create preceivemessagepackage error % s! " , Strerror (ERR ));

Return 0 ;
}

2. Data sending callback function

 /*  **************************************** **********************
** Fun: UART send handle
** In: Arg psentmessagepackage
** Out:
** Uartuploaddata
**************************************** *********************** */
Static Void * Uartuploaddata ( Void * Arg)
{
Pmsgpkg updata = (pmsgpkg) ARG;

While ( 1 )
{
Sem_wait (& updata-> uart_begin );
If (! Updata-> uart_inited)
{
Sem_post (& updata-> uart_end );
Break ;
}
// No message to upload
If (Updata-> messagecnt <= 0 )
Sem_wait (& updata-> uart_begin );

Updata-> synccode = syncdata1;

# If 1
If (! Crccheck (uuint8 *) updata, send )) // CRC
{
LogE ( " Uartuploaddata CRC error! " );
Sem_wait (& updata-> uart_begin );
}
# Endif

// Sent message Len = synccodelen (2) + canonical CNT (1) + canonical Len (1) + messagelen (n) + crclen (1)
Send_mcuuart (updata-> FD, updata, updata-> messagelen + 5 );

Sem_post (& updata-> uart_end );

Updata-> messagecnt = 0 ;
Updata-> messagelen = 0 ;
}

Return True ;
}

3. receive data callback function

 /*  **************************************** **********************
** Fun: UART receive handle
** In: Arg preceivemessagepackage
** Out:
** Uartdownloaddata
**************************************** *********************** */
Static Void * Uartdownloaddata ( Void * Arg)
{
Uuint8 buffer [recmsgoncelen];
Pmsgpkg PMSG = (pmsgpkg) ARG;
Int Len, I;

While ( 1 )
{
If (! PMSG-> uart_inited)
{
Sem_post (& PMSG-> uart_end );
Break ;
}

Recv_mcuuart (PMSG-> FD, buffer, & Len, recmsgoncelen, recmsgtimeout );

If (LEN> 0 )
{
// Copy the receive data to the big Buf
For (I = 0 ; I <Len; I ++)
{
If (PMSG-> precpoint> = recmsgbuflen)
PMSG-> precpoint = 0 ;

Receivebuf [PMSG-> precpoint] = buffer [I];
PMSG-> precpoint ++;
}

Memset (buffer, 0 , Recmsgoncelen );
}

Logi ( " Panalyzepoint = % d, precpoint = % d " , PMSG-> panalyzepoint, PMSG-> precpoint );

// Have new message and Prev message have handout to app, analyze from the analyze point
If (PMSG-> panalyzepoint! = PMSG-> precpoint )&&(! PMSG-> handoutflag ))
Analyzemsgpackage (PMSG, & (receivebuf [PMSG-> panalyzepoint]);
}

Return True ;
}

The code in JNI is very simple. The code is initialized, written, and read through the functions in the init, upload, and download Hal layers.

When writing data, add the data header and CRC bits to the Hal through upload, and then write the data to the serial device node in the writing thread ......

When reading data, read the data from the serial device node through the reading thread in Hal for resolution and CRC verification, if the CRC check is normal, the parsed data is transmitted to Java through the JNI layer for use.

It is worth mentioning that the corresponding buffer control is used when receiving data and parsing data. Here I am using a ring buffer with a capacity of 1 kbyte, this prevents the loss of received data.

 

The code in Java is mainly divided into two parts. One part is the method for writing data. This is relatively simple. Just close the local function uart_upload in JNI. The other part is the method for reading data, which is a little troublesome, because when reading data in my system, there may be data that is actively reported, that is, there is no request from arm, if there is data on the MCU side, it will report the data to the arm, such as the key information on the MCU side. I used a thread to process this in the method I was reading and constantly scanned the buffer for parsing data. When correct data has been parsed and the buffer is resolved, in this thread, the message is broadcasted, and then the broadcast is listened to in the app. There are a lot of corresponding code and it will not be sent here!

The last thing to note is that, because the permission of the System user is required to operate the device node, I added Android: shareduserid = "android. UID. system"

Source: Http://www.cnblogs.com/xl19862005 Author: xandy
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.