HISISS928学习篇---串口232

HISISS928学习篇---串口232 wby 2024-05-27 16:48:07 1505

环境配置

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)的技巧和驾驶体验,我是假设大家已经拿到驾照了(有一点嵌入式开发相关的知识)。上面文章很多一部分都是一笔带过,代码部分也没有注释,我会慢慢完善。希望老司机们多多指正。

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
wby
红包 1 收藏 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
wby
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区