HISISS928学习篇---串口232
环境配置
SS928原生的linux系统经过裁剪,只有一些基础指令,因此不建议在板端直接编译。本文使用的是虚拟机(ubuntu)+交叉编译的方式,在ubuntu中编译出可执行文件。
开发环境搭建
1.方式一(推荐)
直接使用ebaina提供的ubuntu镜像,镜像链接
https://pan.baidu.com/s/1ikHmf5o4HWW38PJ8-Mdunw 提取码:2cf5
解压之后,使用VMware创建新的虚拟机,此步骤可以自行探索。
2.方式二
在自己之前的虚拟机基础上直接安装ebaina提供的交叉编译链即可。或找教程先一步一步安装配置虚拟机,再安装交叉编译工具链。
安装过程
将上图的交叉编译工具的压缩包传输到虚拟机中,解压。(如果不知道怎么传输文件到虚拟机,可自行探索)
然后执行上图中的aarch64-linux.install安装脚本。工具链默认安装在 opt/linux/x86-arm
然后再命令行输入aar,尝试tab补全
如果能正确输出交叉编译工具,则说明安装成功。
题外话
使用不同的编译工具是因为我们运行代码的平台(cpu)不同,现在我们常用硬件平台主要有x86架构,arm结构和riSc-V架构。我们想在pc(x86)上将代码编程成arm架构能够识别的二进制可执行文件,就需要用交叉编译。可能有人会问:我之前在windows端开发单片机不需要交叉编译工具啊?这是因为windows系统用的人多,为了方便开发者,很多开发用到的各种工具都帮大家集成好了。这种集成式的开发环境可以一键编译,不像linux下需要手动敲指令。但因为linux社区的高度开源,在未来基于linux的开发也会越来越方便。
串口实例
项目结构如下图
此项目结构相对简单,主要有相应的头文件(rc.common.h),串口驱动文件(rc_hal.c\rc_ml.c),应用文件(rc_apply.c)和编译链接文件(CMakeLists.txt)组成。bulid文件夹下的所有文件是编译后产生的。
代码
rc_apply.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include "rc_common.h"
void* thread_function_send(void* arg) {
int i = 0;
while (1){
debug("sending");
char data[] = {0xaa,0xaa,0x00,0x00};
rs232_apply.send("send success\n");
sleep(5);
i++;
if(i>5){
break;
}
}
return NULL;
}
void* thread_function_receive(void* arg) {
int i = 0;
while (1){
debug("receiving");
rs232_apply.receive(rs232_apply.buffer,sizeof(rs232_apply.buffer));
debug("received");
debug(rs232_apply.buffer);
sleep(5);
i++;
if(i>5){
break;
}
}
return NULL;
}
void debug(const char *str){
printf("%s \n",str);
fflush(stdout);
}
void main(){
pthread_t send1,receve1;
int thread_arg1 = 1, thread_arg2 = 2;
int reg;
reg = rc232_init();
if (reg < 0){
debug("rc_init failed\n");
close_serial_port(serial_info.fd);
exit(0);
}
if (pthread_create(&send1, NULL, thread_function_send, &thread_arg1) != 0) {
perror("pthread_create");
return 1;
}
if (pthread_create(&receve1, NULL, thread_function_receive, &thread_arg2) != 0) {
perror("pthread_create");
return 1;
}
if (pthread_join(send1, NULL) != 0) {
perror("pthread_join");
return 1;
}
if (pthread_join(receve1, NULL) != 0) {
perror("pthread_join");
return 1;
}
printf("main end\n");
rs232_apply.close(serial_info.fd);
}
rc_hal.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>
#include "rc_common.h"
// 打开串口设备
int open_serial_port(const char *device) {
int fd = open(device, O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0) {
perror("open");
}
return fd;
}
// 关闭串口设备
void close_serial_port(int fd) {
close(fd);
}
// 读数据
int read_from_serial(int fd, char *buf, size_t len) {
int n = read(fd, buf, len);
if (n < 0) {
perror("read");
}
return n;
}
// 写数据
int write_to_serial(int fd, const char *buf, size_t len) {
int n = write(fd, buf, len);
if (n < 0) {
perror("write");
}
return n;
}
rc_ml.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>
#include "rc_common.h"
RS232Config rs232_config = {
.device = "/dev/ttyAMA4",
.baud_rate = B115200,
.data_bits = 8,
.stop_bits = 1,
.parity = 0,
};
SERIAL_info serial_info = {
.fd = -1,
};
RS232_apply rs232_apply;
// 配置串口属性
int configure_serial_port(RS232Config config) {
int fd = serial_info.fd;
struct termios tty;
if (tcgetattr(fd, &tty) != 0) {
perror("tcgetattr");
return -1;
}
cfsetospeed(&tty, (speed_t)config.baud_rate);
cfsetispeed(&tty, (speed_t)config.baud_rate);
tty.c_cflag &= ~CSIZE;
switch (config.data_bits) {
case 7: tty.c_cflag |= CS7; break;
case 8: tty.c_cflag |= CS8; break;
default: tty.c_cflag |= CS8; break;
}
switch (config.stop_bits) {
case 2: tty.c_cflag |= CSTOPB; break;
default: tty.c_cflag &= ~CSTOPB; break;
}
switch (config.parity) {
case 1: tty.c_cflag |= PARENB; tty.c_cflag &= ~PARODD; break;
case 2: tty.c_cflag |= PARENB; tty.c_cflag |= PARODD; break;
default: tty.c_cflag &= ~PARENB; break;
}
tty.c_cflag |= (CLOCAL | CREAD);
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
tty.c_oflag &= ~OPOST;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 1;
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
perror("tcsetattr");
return -1;
}
return 0;
}
// 发送数据
void send_data(const char *data) {
if (serial_info.fd == -1) {
printf("Serial port not open\n");
return;
}
write_to_serial(serial_info.fd,data, strlen(data));
}
// 接收数据
void receive_data(char *buffer, size_t length) {
if (serial_info.fd == -1) {
printf("Serial port not open\n");
return;
}
int n = read_from_serial(serial_info.fd, buffer, length - 1);
if (n >= 0) {
buffer[n] = '\0'; // null-terminate the string
}
}
int rc232_init(){
serial_info.fd = open_serial_port(rs232_config.device);
configure_serial_port(rs232_config);
rs232_apply.send = send_data;
rs232_apply.receive = receive_data;
rs232_apply.init = rc232_init;
rs232_apply.close = close_serial_port;
return 0;
}
rc_common.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>
// RS232 配置结构体
typedef struct {
int baud_rate;
int data_bits;
int stop_bits;
int parity;
char device[20];
} RS232Config;
typedef struct {
int fd;
}SERIAL_info;
typedef struct {
int (*init) ();
void (*close) (int fd);
void (*send) (const char *data);
void (*receive) (char *buffer, size_t length);
char buffer[100];
} RS232_apply;
extern RS232Config rs232_config;
extern SERIAL_info serial_info;
extern RS232_apply rs232_apply;
int open_serial_port(const char *device);
void close_serial_port(int fd);
int read_from_serial(int fd, char *buf, size_t len);
int write_to_serial(int fd, const char *buf, size_t len);
RS232Config create_rs232_config(const char *device, int baud_rate, int data_bits, int stop_bits, int parity);
int configure_serial_port(RS232Config config);
void send_data(const char *data);
void receive_data(char *buffer, size_t length);
int rc232_init();
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 3.8)
PROJECT(UART)
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_C_COMPILER "aarch64-mix210-linux-gcc")
SET(CMAKE_CXX_COMPILER "aarch64-mix210-linux-g++")
SET(CMAKE_CXX_FLAGS "-static")
SET(TOOLCHAIN_DIR "/opt/linux/x86-arm")
SET(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_DIR})
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
aux_source_directory(${CMAKE_SOURCE_DIR}/source DIR_SRCS)
include_directories(${CMAKE_SOURCE_DIR}/include)
ADD_EXECUTABLE(UART ${DIR_SRCS})
find_package(Threads REQUIRED)
target_link_libraries(UART Threads::Threads)
编译
构建好上面的项目文件之后,我们在CMakeLists文件同级目录下新建build文件夹
mkdir build
cd build
cmake ..
make
编译成功后build文件夹下就生成了UART的可执行文件
下载验证
ss928平台自带有tftp服务,可以通过tftp或者自己搭建的NFS、SSH等完成文件的上传和下载。
这一部分内容我会再写一个篇,替大家踩踩坑。
剩下的就是连接232设备,使用串口助手调试了。
写在最后
这是我第一篇博客,写的不好望海涵。首先我肯定不是一位老司机,写博客的目的不是妄想教会大家开车,而是分享国产新车(ss928)的技巧和驾驶体验,我是假设大家已经拿到驾照了(有一点嵌入式开发相关的知识)。上面文章很多一部分都是一笔带过,代码部分也没有注释,我会慢慢完善。希望老司机们多多指正。
- 分享
- 举报
![易百纳技术社区](https://ebaina.oss-cn-hangzhou.aliyuncs.com/production/direct/resource/202306/14/empty.png)
-
浏览量:2805次2023-04-14 17:35:17
-
浏览量:9274次2022-11-10 18:07:40
-
浏览量:3854次2020-08-30 12:27:19
-
浏览量:3051次2020-08-10 19:30:45
-
浏览量:3042次2020-08-30 10:14:12
-
浏览量:438次2023-09-08 10:47:07
-
浏览量:3474次2020-08-18 19:54:58
-
浏览量:5518次2022-09-19 14:17:36
-
浏览量:13484次2022-09-15 15:54:04
-
浏览量:5056次2022-09-23 09:10:47
-
浏览量:5930次2022-09-16 15:39:40
-
浏览量:3946次2022-09-26 09:49:49
-
浏览量:2171次2020-08-23 21:47:22
-
浏览量:3743次2020-10-10 15:51:00
-
浏览量:5475次2022-09-21 14:30:18
-
浏览量:4584次2022-09-20 15:23:26
-
浏览量:9514次2021-04-20 15:42:26
-
浏览量:3383次2022-09-22 11:37:57
-
浏览量:5928次2021-03-01 10:14:26
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
![易百纳技术社区](https://ebaina.oss-cn-hangzhou.aliyuncs.com/res/avatar/noavatar_middle.gif)
wby
![易百纳技术社区](/img/web/choose_active.png)
![易百纳技术社区](/img/web/choose_active.png)
![易百纳技术社区](/img/web/choose_active.png)
![易百纳技术社区](/img/web/choose_active.png)
![易百纳技术社区](/img/web/choose_active.png)
![易百纳技术社区](/img/web/paywx.png)
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明