1、烧录:
首先git上下载项目到本地会下载所有项目,包括所有分支内容,烧录的话得在对应开发板子的分支下烧录,因为各分支的代码是不同的,得在本地切换到相应板子的分支烧录,切换后本地文件也会做相应改变
切换到本地分支后进入环境后执行makefile指令即可编译代码,其中模块的makefile指令大部分如下
#使用make all 命令会首先构建.so文件和rtcd文件,再进入test文件夹,执行make all
all: libzs.so rtcd
$(MAKE) -C test all
include ./../Arch.make # 本Makefile包含上上个文件夹下的Arch.make
CC := $(CROSS_COMPILE)gcc
INCFLAGS := -I include
OBJS := rtcTest.o
LIBS := -lzss_rtc -L../
all: rtcTest # 输入 make all 指令后会构建rtcTest文件
rtcTest: $(OBJS) # 指定依赖
$(CC)$(SYSROOT) -o $@$(OBJS) $(LIBS) #生成目标文件
%.o: %.c
$(CC)$(INCFLAGS) $(SYSROOT) -g -c$< -o $@
.PHONY: clean
clean: # make clean
rm -f *.o
rm -f rtcTest
include ./Arch.make # 包含头文件
CC := $(CROSS_COMPILE)gcc
AR := $(CROSS_COMPILE)ar
RANLIB := $(CROSS_COMPILE)ranlib
CFLAGS := -Wall -pthread -ggdb $(SYSROOT) -I../drivers/
LFLAGS := -lrt
PROGRAMS := ./rtcd
all: libzss_rtc.so $(PROGRAMS) # 目标
$(MAKE) -C test $@
lib: libzss_rtc.so
rtcd: rtc_util.o rtcd.o
$(CC)$(CFLAGS) $(LFLAGS) rtc_util.o rtcd.o -o$@
rtcd.o: rtc_pub.h rtc_priv.h rtcd.c
libzss_rtc.so: rtc_lib.o rtc_socket.o rtc_util.o
$(CC)$(SYSROOT) -fpic -shared -o $@ rtc_lib.o rtc_socket.o rtc_util.o
rtc_util.o: rtc_pub.h rtc_priv.h rtc_util.c
rtc_socket.o: rtc_pub.h rtc_priv.h rtc_socket.c
clean:
rm -f $(PROGRAMS)
rm -f libzss_rtc.so
rm -f *.o # 清除
$(MAKE) -C test $@ # 在test下执行make clean
在编译环境中make all指令即可编译,用TFTP协议将bin文件烧录到板子上即可
tftp -gr 文件名 ip地址 # 传输命令
2、运行:
将动态库放到/usr/local/lib文件目录下,方便程序使用时找到
./rtcd -df # 前台运行
./rtcd & # 后台运行
ps | grep rtcd # 查看进程
3、部分相关代码:
int rtc_get_socket(void) {
int socket_handle;
int len;
struct sockaddr_un remote;
int conn_count = 0;
// 创建socket
if ((socket_handle = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
return -1; // 创建socket失败
}
// 设置socket地址结构
memset(&remote, 0, sizeof(remote));
remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, RTC_SOCKET);
len = offsetof(struct sockaddr_un, sun_path) + strlen(remote.sun_path);
// 尝试连接
while (connect(socket_handle, (struct sockaddr *)&remote, len) == -1) {
if (++conn_count >= SOCKET_CONN_TRY) {
close(socket_handle); // 尝试连接次数达到上限,关闭socket
return -1; // 返回错误
}
return socket_handle;
}
本函数主要做本机内部连接,获取套接字后就尝试开始连接,尝试连接次数为100次
static int daemon_init(void) {
pid_t pid;
if ((pid = fork()) < 0)
return -1;
else if (pid != 0)
exit(0);
setsid();
chdir("/");
umask(0);
return 0;
}
// 创建守护进程,子进程返回0父进程大于0
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
这里的参数含义如下:
sockfd:这是服务器用来监听连接请求的套接字文件描述符。
addr:这是一个指向 sockaddr 结构的指针,该结构会被 accept 填充以包含客户端的地址信息。如果不需要这些信息,可以传递 NULL。
addrlen:这是一个指向 socklen_t 类型的指针,它应该被初始化为 addr 指向的缓冲区的大小。在调用 accept 之后,addrlen 会被设置为实际存储在 addr 中的地址结构的长度。
accept 函数成功时返回一个新的文件描述符,用于后续的读写操作;失败时返回 -1,并设置 errno 来指示错误原因。
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
int main() {
int listen_fd, conn_fd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_addr_len = sizeof(client_addr);
// 创建套接字,绑定地址,监听等操作...
// 接受连接
conn_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &client_addr_len);
if (conn_fd == -1) {
perror("accept");
return 1;
}
// 使用 conn_fd 与客户端进行通信...
// 关闭连接
close(conn_fd);
return 0;
}