本文背景:
是真的不喜欢脑子记这些引脚,串口节点,动不动忘记了。
1.首先记录一下硬件引脚----tty节点对应关系
2.找一组/dev/ttyHSL1,先测试一下自环,然后写个app,从app里面读写这个节点
3.通过串口和单片机通信
硬件平台配置:
平台:msm8909
默认log串口:Board_KERNEL_CMDLINE := console=ttyHSL0, 115200, n8
对应文件节点:/dev/ttyHSL1
———————————————–
1.串口的linux驱动配置 (/dev/ttyHSL1)
代码语言:javascript复制//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.dtsi
blsp1_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/测试)
代码语言:javascript复制#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 errorn", name);
return -1;
}
//函数tcgetattr,用于获取终端参数,到options变量
ret = tcgetattr(fd, &options);
if (-1 == ret)
return -1;
options.c_cflag &= ~CSIZE; //屏蔽其他标志
options.c_cflag |= CS8; //数据8bit
options.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 beginn");
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 == %sn", 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 = %un", 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, endn");
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.
代码语言:javascript复制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;
@Override
protected 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);
}
@Override
public void onClick(View view)
{
String str = et_msg.getText().toString();
str = str "rn";
if(!str.isEmpty())
dataProcess(str);
}
}
3.可能报SecureException, 看下/dev/ttyHSL1的权限,chmod 777 /dev/ttyHSL1
4.预期效果
———end——-
随便说说,网上那种动不动需要su的,挺SB的,根本不管原因,
这种权限是可以系统里添加的,也不是每个机器的系统APP都能轻易获得su权限。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/183424.html原文链接:https://javaforall.cn