目录
小总结
编译框架完善
代码风格
开源协议选择
小总结
经过两个月的努力现在已经写了457MB的代码了
.
├── board
│ ├── Linux
│ │ └── 4_9_88
│ │ └── ARM32
│ │ └── 100ask
│ │ └── imx6ull_mini
│ └── README.md
├── build
│ ├── make_conf.mk
│ ├── Makefile
│ └── make_fun.mk
├── client
│ ├── client.py
│ ├── global_var.py
│ ├── __pycache__
│ │ ├── global_var.cpython-38.pyc
│ │ ├── show.cpython-38.pyc
│ │ ├── tcp.cpython-38.pyc
│ │ └── tool.cpython-38.pyc
│ ├── README.md
│ ├── show.py
│ ├── tcp.py
│ ├── tcp_test.py
│ └── tool.py
├── CREDITS
├── driver
│ ├── 01_driver
│ │ ├── 01_led
│ │ │ ├── led_drv.c
│ │ │ ├── led_test.c
│ │ │ └── Makefile
│ │ ├── 02_sr501
│ │ │ ├── Makefile
│ │ │ ├── sr501_drv.c
│ │ │ └── sr501_test.c
│ │ ├── 03_sr04
│ │ │ ├── Makefile
│ │ │ ├── sr04_poll_drv.c
│ │ │ └── sr04_poll_test.c
│ │ ├── 04_irda
│ │ │ ├── irda_drv.c
│ │ │ ├── irda_test.c
│ │ │ └── Makefile
│ │ ├── 05_motor
│ │ │ ├── Makefile
│ │ │ ├── motor_drv.c
│ │ │ └── motor_test.c
│ │ ├── 06_dht11
│ │ │ ├── dht11_arm_drv.c
│ │ │ ├── dht11_drv.c
│ │ │ ├── dht11_iio_drv.c
│ │ │ ├── dht11_test.c
│ │ │ └── Makefile
│ │ └── 07_ds18b20
│ │ ├── ds18b20_drv.c
│ │ ├── ds18b20_test.c
│ │ └── Makefile
│ ├── 02_device_tree
│ │ ├── 05_motor
│ │ │ ├── button_test.c
│ │ │ ├── gpio_dev.c
│ │ │ ├── gpio_drv.c
│ │ │ └── Makefile
│ │ └── 09_irda_ok
│ │ ├── button_test.c
│ │ ├── gpio_drv.c
│ │ └── Makefile
│ ├── 03_iic
│ │ └── 01_at24c02
│ │ ├── i2c_drv.c
│ │ ├── i2c_test.c
│ │ └── Makefile
│ └── 04_spi
│ └── 01_dac
│ ├── dac_drv.c
│ ├── dac_test.c
│ └── Makefile
├── OS
│ └── openharmony
│ └── rootfs
│ └── linux
│ └── etc
│ └── issue
├── output
├── README.md
├── release
│ └── release.h
├── server
│ ├── build
│ │ ├── make_conf.mk
│ │ ├── Makefile
│ │ └── make_fun.mk
│ ├── include
│ │ ├── driver_handle.h
│ │ ├── global.h
│ │ ├── net.h
│ │ ├── pthread_ctl.h
│ │ ├── tcp.h
│ │ └── tool.h
│ ├── output
│ │ └── cebss_server-0.0.0
│ └── src
│ ├── driver_handle.c
│ ├── pthread_ctl.c
│ ├── server.c
│ ├── tcp.c
│ └── tool.c
└── tools
├── bash
│ ├── add_head.sh
│ ├── cebss_start.sh
│ ├── clear_test.sh
│ ├── close_printk.sh
│ ├── delete_file.sh
│ ├── mk_pro_dir.sh
│ ├── mount_nfs.sh
│ ├── net.sh
│ └── open_printk.sh
├── include
│ └── cJSON.h
└── src
└── cJSON.c41 directories, 81 files
一共81个源文件,下面我先来把编译框架完善了
编译框架完善
先来验证一下内置的api
MAJOR = 0
MINOR = 1
PATCH = 0
NAME = tianyu.xin
TOP_DIR =
SERVER_DIR =
# 定义当前目录的绝对路径变量
CURRENT_DIR := $(abspath ..)
all:
@echo "当前目录的绝对路径是: $(CURRENT_DIR)"
# all:
# @echo "Building the whole project..."
# $(MAKE) -C
# $(MAKE) -C lib
# clean:
# @echo "Cleaning the whole project..."
# $(MAKE) -C src clean
# $(MAKE) -C lib clean
.PHONY: all
DEBUG ?= 0
PRINT ?= 1
# -f 指定非默认的Makefile文件
all:
@echo "Welcome to the cebss compilation system."
@echo "Building the whole project..."
$(MAKE) -C $(SERVER_BUILD_DIR) debug=$(DEBUG) KBUILD_VERBOSE=$(PRINT)
试一试能不能成功操作子目录的make
一次就成了
MAJOR = 0
MINOR = 1
PATCH = 0
NAME = tianyu.xin
# 定义当前目录的绝对路径变量
CEBSS_DIR := $(abspath ..)
OUTPUT_DIR := $(CEBSS_DIR)/output
SERVER_DIR := $(CEBSS_DIR)/server
SERVER_OUTPUT_DIR := $(SERVER_DIR)/output
SERVER_BUILD_DIR := $(SERVER_DIR)/build
SERVER_APP := cebss_server-$(MAJOR).$(MINOR).$(PATCH)
# Aesthetic treatment
ECHO_END := \033[01;0m
ECHO_GREEN := \033[32m
ECHO_RED := \033[01;31m
ECHO_YELLOW := \033[33m
ECHO_BLUE := \033[34m
ECHO_GREEN_YELLOW := \033[42;30m
DEBUG ?= 0
PRINT ?= 1
# -f 指定非默认的Makefile文件
all:
@echo "Welcome to the cebss compilation system."
@echo "Building the whole project..."
$(MAKE) -C $(SERVER_BUILD_DIR) debug=$(DEBUG) KBUILD_VERBOSE=$(PRINT)
cp $(SERVER_OUTPUT_DIR)/$(SERVER_APP) $(OUTPUT_DIR)
clean:
@echo "Cleaning the whole project..."
$(MAKE) -C $(SERVER_BUILD_DIR) clean
.PHONY: all clean help
我想用py来编译
先试试py的这个命令行
def main():
# 创建一个解析器对象
parser = argparse.ArgumentParser(description='这是一个构建脚本')
# 添加参数
parser.add_argument('--debug', type=int, default=0, help='开启调试模式,值为1时启用')
parser.add_argument('--print-level', type=int, default=1, help='打印级别,0表示不打印,1表示打印')
parser.add_argument('--target', type=str, choices=['all', 'clean'], help='构建目标,可选值为all或clean')
# 解析命令行参数
args = parser.parse_args()
# 现在你可以使用args.debug, args.print_level, 和 args.target来获取参数值
print(f"Debug level: {args.debug}")
print(f"Print level: {args.print_level}")
print(f"Target: {args.target}")
# 根据参数值执行相应的操作...
# ...
if __name__ == '__main__':
main()
哦吼木有问题
#! /usr/bin/python3
'''
fuction : 编译脚本
author : 辛天宇
date : 2024-4-25
-------------------------------
author date modify
'''
import subprocess
import argparse
import os
import sys
path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'build')
os.chdir(path)
def run_make_target(target, debug=0, print_level=1):
# 构建make命令的字符串
cmd = ["make", target, f"DEBUG={debug}", f"PRINT={print_level}"]
# 运行make命令
process = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def make_all():
cmd = ["make","all"]
process = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# 打印输出结果
print(process.stdout.decode())
if process.stderr:
print(f"Error: {process.stderr.decode()}")
def main():
# # 创建一个解析器对象
# parser = argparse.ArgumentParser(description='这是一个构建脚本')
# # 添加参数
# parser.add_argument('--debug', type=int, default=0, help='开启调试模式,值为1时启用')
# parser.add_argument('--print-level', type=int, default=1, help='打印级别,0表示不打印,1表示打印')
# parser.add_argument('--target', type=str, choices=['all', 'clean'], help='构建目标,可选值为all或clean')
# # 解析命令行参数
# args = parser.parse_args()
# # 现在你可以使用args.debug, args.print_level, 和 args.target来获取参数值
# print(f"Debug level: {args.debug}")
# print(f"Print level: {args.print_level}")
# print(f"Target: {args.target}")
# # 根据参数值执行相应的操作...
# # ...
make_all()
print(path)
if __name__ == '__main__':
main()
代码风格
大概就像下面这样
/*
* File name : tcp.c
* Function : tcp handle && driver control
* Date : 2024-04-25
* Version : 0.1.0
*/
/************************************************************************************
*************************************INCLUDE*****************************************
*************************************************************************************/
#include "tcp.h"
#include "net.h"
#include "global.h"
#include "tool.h"
/************************************************************************************
***************************************EXTERN****************************************
*************************************************************************************/
***********
/*
* func : usage
* return : error code
* input : Command line arguments and sizes
* output :NULL
* author date modify
--------------------------------
xintianyu 2024-4-10 create
*/
int usage(int argc, char *argv[])
{
if (argc != 3)
{
printf("Usage: %s <ip_address> <port>\n", argv[0]);
return ERROR;
}
else
{
return NOERROR;
}
}
/*
* func : NULL function
* return : NULL
* input : NULL
* output :NULL
* author date modify
--------------------------------
xintianyu 2024-4-10 create
*/
void do_nothing()
{
/*void*/
}
/*
* func : tcp handle
* return : err code
* input : Command line arguments and sizes
* output :NULL
* author date modify
--------------------------------
xintianyu 2024-4-10 create
*/
int tcp_server(int argc, char *argv[])
{
int server_fd, client_fd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
char *ip_address = argv[1];
int port = atoi(argv[2]);
/* 创建TCP套接字 */
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
/* 支持快速重新绑定 */
int b_reuse = 1;
setsockopt (server_fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof (int));
/* 设置服务器地址信息 */
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(ip_address);
server_addr.sin_port = htons(port);
/* 绑定套接字到服务器地址 */
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
/* 监听套接字 */
if (listen(server_fd, 5) < 0) {
perror("listen failed");
exit(EXIT_FAILURE);
}
printf("Server listening on %s:%d...\n", ip_address, port);
/* 处理僵尸进程 */
signal(SIGCHLD, SIG_IGN);
/* 接受客户端连接 */
if ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len)) < 0) {
perror("accept failed");
goto err1;
}
/* 打印客户端信息 */
char client_ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);
printf("Client connected from %s:%d\n", client_ip, ntohs(client_addr.sin_port));
if (ERROR == do_client(client_fd))
{
perror("client disconnect.....");
goto err2;
}
err2:
close(client_fd);
err1:
close(server_fd);
return NOERROR;
}
/************************************************************************************
***************************************LOCAL*****************************************
************************************************************************************/
/*
* func : client handle
* return : err code
* input : file descriptor
* output :NULL
* author date modify
--------------------------------
xintianyu 2024-4-10 create
xintianyu 2024-4-25 V-0.1.0
*/
int do_client(int acceptfd)
{
char rx_buffer[BUFFER_SIZE];
int ret;
while(1)
{
// 接收客户端消息
memset(rx_buffer, 0, BUFFER_SIZE);
ssize_t bytes_read = recv(acceptfd, rx_buffer, BUFFER_SIZE - 1, 0);
if (bytes_read < 0)
{
perror("recv failed");
return ERROR;
}
else
{
printf("Received message: %s\n", rx_buffer);
if ('Q' == rx_buffer[0] || 0 == rx_buffer[0])
{
printf("client quit....\n");
return ERROR;
}
else
{
ret = select_driver(rx_buffer, acceptfd);
}
if (ret != ERROR)
{
/*do nothing*/
}
else
{
// 回复客户端消息
//strcpy(tx_buffer, "Hello, client!\n");
/*确保消息以换行符结尾,并打印接收到的消息*/
if (bytes_read > 0 && rx_buffer[bytes_read - 1] != '\n') {
rx_buffer[bytes_read] = '\n';
rx_buffer[bytes_read + 1] = '\0';
}
if (send(acceptfd, rx_buffer, strlen(rx_buffer), 0) < 0)
{
perror("send failed");
}
}
}
}
return NOERROR;
}
/*
* func : driver handle
* return : err code
* input : <cmd> (device code) <accepted> (file descriptor)
* output :NULL
* author date modify
--------------------------------
xintianyu 2024-4-10 create
xintianyu 2024-4-25 V-0.1.0
*/
int select_driver(char * cmd, int acceptfd)
{
/* TODO 传递参数后需改为使用通信结构体 */
/* TODO 所有的魔鬼数字都要进行定义 */
int ret = 0;
int get_data = 0;
MSG drv_msg;
char *tx_buffer;
char buf[32];
char irda_data=' ';
DIRECTION direction;
CMD drv_cmd;
if('@' == cmd[0])
{
#if (STD_ON == DEBUG)
//printf("cmd[0] = @\n");
#endif/*STD_ON == DEBUG*/
drv_msg.device = extract_digit_number(cmd, 1, 3);
//printf("device is %d\n", drv_msg.device);
/*TODO 后续需升级为多线程模式调用驱动*/
switch(drv_msg.device)
{
case 0:
/*TODO 日志打印等级控制*/
/*TODO用设备结构体后这里要封装一下*/
printf("LED!!!\n");
if ('g' == cmd[4])
{
direction = direction_get;
drv_cmd = cmd_no;
led_handle(direction, &drv_cmd);
if (cmd_close == drv_cmd)
{
tx_buffer = "@000g0";
}
else if(cmd_open == drv_cmd)
{
tx_buffer = "@000g1";
}
}
else
{
if ('1' == cmd[5])
drv_cmd = cmd_open;
else if ('0' == cmd[5])
drv_cmd = cmd_close;
direction = direction_put;
if (NOERROR == led_handle(direction, &drv_cmd))
{
tx_buffer = "@000p1";
}
else
{
tx_buffer = "@000p0";
}
}
if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
{
perror("send failed");
}
break;
case 1:
printf("SR501!!!\n");
/*TODO 这里封装成带回调函数的处理函数通过传入处理函数做数据处理*/
if ('g' == cmd[4])
{
sr501_handle(&get_data);
if (sr501_some == get_data)
{
tx_buffer = "@001g1";
}
else if(sr501_nobody == get_data)
{
tx_buffer = "@001g0";
}
}
if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
{
perror("send failed");
}
break;
case 2:
printf("SR04!!!\n");
if ('g' == cmd[4])
{
ret = sr04_handle(&get_data);
if (NOERROR == ret)
{
sprintf(buf,"@002g%03d", get_data);
tx_buffer = buf;
}
else
{
tx_buffer = "@002e";
}
}
printf(">>>>>>%s\n",tx_buffer);
if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
{
perror("send failed");
}
break;
case 3:
printf("IRDA!!!\n");
if ('g' == cmd[4])
{
ret = irda_handle(&irda_data);
if (NOERROR == ret)
{
sprintf(buf,"@003g%c", irda_data);
tx_buffer = buf;
}
else
{
tx_buffer = "@003e";
}
}
printf(">>>>>>%s\n",tx_buffer);
if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
{
perror("send failed");
}
break;
case 4:
printf("motor!!!\n");
if ('s' == cmd[4])
{
if(0 == cmd[5])
{
/*/0 /n*/
get_data = extract_digit_number(cmd, 6, (strlen(&cmd[5])-2));
}
else
{
get_data = -extract_digit_number(cmd, 6, (strlen(&cmd[5])-2));
}
printf("getdata == %d\n",get_data);
ret = motor_handle(get_data);
if (NOERROR == ret)
{
tx_buffer = "@004s";
}
else
{
tx_buffer = "@004e";
}
}
if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
{
perror("send failed");
}
break;
case 5:
printf("dht11!!!\n");
if ('g' == cmd[4])
{
ret = dht11_handle(buf);
tx_buffer = buf;
}
printf(">>>>>>%s\n",tx_buffer);
if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
{
perror("send failed");
}
break;
case 6:
printf("ds18b20!!!\n");
if ('g' == cmd[4])
{
ret = ds18b20_handle(buf);
tx_buffer = buf;
}
printf(">>>>>>%s\n",tx_buffer);
if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
{
perror("send failed");
}
break;
case 7:
printf("AT24C02!!!\n");
if ('g' == cmd[4])
{
direction = direction_get;
}
else
{
direction = direction_put;
printf("%s\n", &cmd[5]);
printf("写入长度 %d\n", strlen(&cmd[5]));
memset(buf, 0, 32);
strncpy(buf, &cmd[5], strlen(&cmd[5]));
}
ret = at24c02_handle(direction, buf, strlen(&cmd[5]));
if (NOERROR == ret)
{
tx_buffer = buf;
}
else
{
tx_buffer = "@007e";
}
printf(">>>>>>%s\n",tx_buffer);
if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
{
perror("send failed");
}
break;
case 8:
printf("DAC!!!\n");
if ('p' == cmd[4])
{
direction = direction_put;
get_data = extract_digit_number(cmd, 5, (strlen(&cmd[5])));
if (NOERROR == dac_handle(&get_data))
{
tx_buffer = "@008p";
}
else
{
tx_buffer = "@008e";
}
}
else
{
tx_buffer = "@008e";
}
if (send(acceptfd, tx_buffer, strlen(tx_buffer), 0) < 0)
{
perror("send failed");
}
break;
default:
printf("Unknown equipment!!!\n");
}
}
else
{
printf("cmd[0] ERROR!!!\n");
ret = ERROR;
}
return ret;
}
其他的也都这样修改
开源协议选择
找到了一张神图感觉说的挺不错的。本着开放的原则我就不过多设限了,但是我以前没开源过东西不太了解怕踩坑。真是不知道该怎么选,我看韦东山老师用的MIT那我也用这个好了。
其实码云上这个解释更完善一些
最流行的开源协议什么,如何选择合适的开源协议?中国第一个违反GPL的案例,腾讯影音为什么会被ffmepg谴责——TechParty1204小沙龙第2个主题分享_哔哩哔哩_bilibili
开源协议是什么?都有什么区别?_哔哩哔哩_bilibili
有个很有意思的事情,鸿蒙有八百多个仓库,但是好多个仓库用的开源协议都不一样,好有趣。
兄弟们。一定要重视开源协议,没有大家的无私奉献就没有现在的互联网。后面我也学某厂搞个“耻辱柱”,你们不遵守就给你都钉上。(手动狗头)
V-0.1.0版本发布
CEBSS: Chip evaluation board self-test system based on OpenHamony