[Android app] Linux串口驱动配置,可执行程序测试,App串口通信程序
硬件平臺配置:
平臺:msm8909
默認log串口:Board_KERNEL_CMDLINE := console=ttyHSL0, 115200, n8
對應文件節點:/dev/ttyHSL1
-----------------------------------------------
1.串口的linux驅動配置 (/dev/ttyHSL1)
//msm8909.dtsi blsp1_uart2:serial@78b0000 {compatible = "qcom,msm-lsuart-v14";reg = <0x78b0000 0x200>;interrupts = <0 108 0>;clocks = <&clock_gcc clk_gcc_blsp1_uart2_app_clk><&clock_gcc clk_gcc_blsp1_ahb_clk>;clock-names = "core_clk", "iface_clk"; }//msm8909-qrd.dtsi &blsp1_uart2 {status = "ok";pinctrl-name = "default";pinctrl-0 = <hsuart_active>; }//msm8909-pinctrl.dtsiblsp1_uart2_active {qcom,pins = <&gp 20>, <&gp 21>;qcom,num-grp-pins = <2>;qcom,pin-func = <3>;label = "blsp1_uart2_active";huart_active:default {drive-strength = <16>;bias-disable;}; };blsp1_uart2_sleep {qcom,pins = <&gp 20>, <&gp 21>;qcom, num-grp-pins = <2>;qcom, pin-func = <0>;label = "blsp1_uart2_sleep";huart_sleep:sleep {drive-strength = <2>;bias-disable;}; };碰到一個啟不動的問題,很直接的,開機立馬掛掉的,沒有提示信息的(dtsi里面的錯誤)
?編譯了兩次,發現了問題原因,這個uart和spi共引腳,默認的配置是配置了spi4個腳,我直接把spi另兩個引腳去掉了,但是沒有把qcom,num-grp-pins=<2>修改位2,如果只配2個腳,但是這個為4,會導致啟動不了,log還沒有信息,還挺不好發現的。
(實際中,dtsi導致啟動不了,一種是語法錯誤導致進入fastboot,一種配置錯誤,莫名啟動不了)
2.串口ttyHSL1的C測試程序 (ndk編譯,可執行文件推到system/bin/測試)
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <sys/time.h> #include <time.h> #include <string.h> #include <sys/ioctl.h> #include <termios.h> #include <stdint.h> #include <stdio.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/spi/spidev.h> #include <string.h> #include <assert.h> #include <netinet/in.h> #include <sys/types.h> #include <signal.h> #include <stdlib.h> #include <sys/time.h>#define msleep(x) usleep(x * 1000)/* * 這里類似波特率,需要可以加上多個串口節點 * */ int select_serial_node(int num, char* name) {switch(num){case 1:strcpy(name, "/dev/ttyHSL1");break;case 2:strcpy(name, "/dev/ttyHSL2");break;default:return -1;}return 0; }/* * * 設置波特率,這里case沒多寫,就寫 2 個常用的9600和 115200 */ unsigned int set_baud_rate(int br) {unsigned int baud;switch (br){case 0:baud = B0;break;case 9600:baud = B9600;break;case 115200:baud = B115200;break;default:printf("input err:baud rate not support");return -1;}return baud; }int init_serial_device(char *name, int baud) {int fd;int ret;struct termios options;fd = open(name, O_RDWR | O_NDELAY | O_NOCTTY);if(fd == -1) {printf("%s: open error\n", name);return -1;}//函數tcgetattr,用于獲取終端參數,到options變量ret = tcgetattr(fd, &options);if (-1 == ret)return -1;options.c_cflag &= ~CSIZE; //屏蔽其他標志options.c_cflag |= CS8; //數據8bitoptions.c_cflag &= ~PARENB; //無校驗options.c_cflag &= ~CSTOPB; //設置1位停止位options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);cfsetispeed(&options, baud);cfsetospeed(&options, baud);options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP |IXON);ret = tcsetattr(fd, TCSANOW, &options);if (-1 == ret)return -1;return fd; }void send_serial_data(int fd, char *ptr) {int ret;ret = write(fd, ptr, strlen(ptr));msleep(10); }/* * ex: ./ttyTest 1 115200 "hello JnhnChaos!" * */ int main(int argc, char **argv) {int fd;int bn;int ret;char serial_node_name[25];int serial_num;char message_s[128];speed_t baud;printf("qyc at main begin\n");if (argc != 4) {printf("input error: args should be set to 4 !\n");exit(-1);}//ret = sscanf(argv[1], "%d", &serial_num);serial_num = atoi(argv[1]);memset(serial_node_name, 0, sizeof(serial_node_name));ret = select_serial_node(serial_num, serial_node_name);if(ret == -1) return -1;printf("qyc, serial_node_name == %s\n", serial_node_name);//ret = sscanf(argv[2], "%d", &bn);bn = atoi(argv[2]);baud = set_baud_rate(bn);if (ret == -1) return -1;if(strlen(argv[3]) > 128){printf("input error: args 4 is too long!\n");exit(-1);}memset(message_s, 0, sizeof(message_s));memcpy(message_s, argv[3], strlen(argv[3]));printf("qyc, message will send == %s, len = %u\n", message_s, strlen(message_s));fd = init_serial_device(serial_node_name, baud);if (fd == -1) return -1;send_serial_data(fd, message_s);printf("qyc, end\n");return 0; }中間碰到一個問題,"stack corruption detected , Aborted" 一會兒死機了。。。。?
看了半天,后來發現是serial_node_name的buf設置小了,
在select_serial_node函數里strcpy出現問題。。。。。。
(盡量還是分配大點吧,現在的機器咱不缺那一點)
預期結果:
3.寫app測試發送串口ttyHSL1發送數據
本來以為android里面要加so或者jni, 沒想到別人已經弄好了,直接implement就行了。。。
github:
? ? ? ? ? ?GitHub - AIlll/AndroidSerialPort: Android Serial Port , 基本的Android 串口通信庫
就很簡單了:
1. implementation 'com.aill:AndroidSerialPort:1.0.8'
2.
package com.chao.serialconmunication;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText;import com.aill.androidserialport.SerialPort;import java.io.File; import java.io.IOException; import java.io.OutputStream;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button bt_write;private EditText et_msg;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);intiUi();}private void dataProcess(String str){try {SerialPort serialPort = new SerialPort(new File("/dev/ttyHSL1"), 9600, 0);OutputStream outputStream = serialPort.getOutputStream();byte[] data = str.getBytes();outputStream.write(data);outputStream.flush();} catch (IOException e) {e.printStackTrace();}}private void intiUi(){bt_write = findViewById(R.id.bt_write);et_msg = findViewById(R.id.et_msg_send);bt_write.setOnClickListener(this);}@Overridepublic void onClick(View view){String str = et_msg.getText().toString();str = str + "\r\n";if(!str.isEmpty())dataProcess(str);} }3.可能報SecureException,? 看下/dev/ttyHSL1的權限,chmod 777 /dev/ttyHSL1
4.預期效果
?---------end-------
隨便說說,網上那種動不動需要su的,挺SB的,根本不管原因,
這種權限是可以系統里添加的,也不是每個機器的系統APP都能輕易獲得su權限。?
總結
以上是生活随笔為你收集整理的[Android app] Linux串口驱动配置,可执行程序测试,App串口通信程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AVOD-理解系列(一)
- 下一篇: 社交网络和社会计算入门路径