编程技术分享

分享编程知识,探讨技术创新

0%

简介:基于RK3399核心板的终端服务器**

关注微信公众号,提前获取相关推文

该项目旨在开发一个基于RK3399高性能核心板的终端服务器。该服务器能够连接多种类型的终端设备,提供数据采集、处理、存储、转发以及远程管理等功能。该终端服务器需要具备以下关键特性:

  • 高性能: RK3399处理器提供强大的计算能力,支持高速数据处理和多任务并发。
  • 高可靠性: 系统需要稳定运行,保证数据传输的可靠性和系统的持续可用性。
  • 高扩展性: 系统架构需要易于扩展,方便后续添加新的功能和支持更多的终端设备。
  • 低功耗: 在保证性能的前提下,尽量降低功耗,适应各种应用场景。
  • 易维护性: 系统设计要考虑维护和升级的便利性,方便远程管理和固件更新。

系统开发流程

一个完整的嵌入式系统开发流程通常包括以下几个阶段:

  1. 需求分析阶段:

    • 详细了解终端服务器的功能需求、性能需求、可靠性需求、安全需求、功耗需求、环境条件等。
    • 确定终端服务器的应用场景和目标用户。
    • 编写需求规格说明书,明确项目目标和范围。
  2. 系统设计阶段:

    • 硬件设计: 基于RK3399核心板,设计外围电路,包括电源管理、接口扩展(如以太网、USB、串口、显示接口等)、存储器、传感器接口等。
    • 软件架构设计: 确定系统的软件架构,选择合适的操作系统(如Linux)、实时操作系统(RTOS)或裸机系统,设计模块划分、接口定义、数据流向、控制流程等。
    • 接口设计: 定义硬件接口和软件接口,包括数据传输协议、控制命令格式、API接口等。
    • 数据库设计(如果需要): 设计数据存储方案,选择合适的数据库(如SQLite、嵌入式数据库),定义数据表结构和数据访问接口。
    • 安全性设计: 考虑系统的安全需求,设计安全机制,如身份认证、访问控制、数据加密、安全启动等。
    • 功耗设计: 分析系统的功耗需求,设计功耗管理方案,包括电源管理模式、低功耗模式、时钟频率控制等。
  3. 详细设计阶段:

    • 模块详细设计: 对每个软件模块进行详细设计,包括模块的功能描述、算法设计、数据结构设计、接口详细定义、流程图、状态图等。
    • 代码规范制定: 制定代码编写规范,包括命名约定、代码风格、注释规范、错误处理规范等,保证代码的可读性和可维护性。
    • 测试方案设计: 设计详细的测试方案,包括单元测试、集成测试、系统测试、性能测试、可靠性测试、安全测试等,确保系统质量。
  4. 编码实现阶段:

    • 代码编写: 根据详细设计文档,编写C代码实现各个软件模块。
    • 代码审查: 进行代码审查,检查代码是否符合编码规范,是否存在潜在的错误和安全漏洞。
    • 单元测试: 对每个模块进行单元测试,验证模块功能的正确性。
  5. 集成测试阶段:

    • 模块集成: 将各个模块集成在一起,构建完整的系统。
    • 集成测试: 进行集成测试,验证模块之间的接口和协作是否正确。
  6. 系统测试阶段:

    • 系统功能测试: 测试系统的所有功能是否符合需求规格说明书的要求。
    • 性能测试: 测试系统的性能指标,如响应时间、吞吐量、并发能力、资源利用率等。
    • 可靠性测试: 进行长时间运行测试、压力测试、异常测试等,验证系统的可靠性和稳定性。
    • 安全测试: 进行安全漏洞扫描、渗透测试等,验证系统的安全性。
    • 用户体验测试: (如果适用)进行用户体验测试,评估系统的易用性和用户友好性。
  7. 测试验证阶段:

    • 缺陷跟踪和修复: 记录测试过程中发现的缺陷,跟踪缺陷修复进度,并进行回归测试,确保缺陷得到有效解决。
    • 测试报告编写: 编写详细的测试报告,总结测试结果,评估系统质量。
  8. 维护升级阶段:

    • 系统监控: 部署系统监控工具,实时监控系统运行状态,及时发现和处理异常情况。
    • 故障诊断和修复: 当系统出现故障时,进行故障诊断和修复,恢复系统正常运行。
    • 软件升级: 根据需求或发现的缺陷,进行软件升级,发布新的软件版本。
    • 硬件维护: 定期进行硬件维护,如清洁散热器、更换易损件等,保证硬件的正常运行。
    • 用户支持: 提供用户支持,解答用户疑问,解决用户使用过程中遇到的问题。

代码设计架构:分层模块化架构 + 事件驱动架构

为了构建可靠、高效、可扩展的终端服务器系统,我推荐采用 分层模块化架构事件驱动架构 相结合的设计方案。

1. 分层模块化架构:

将系统软件划分为多个层次和模块,每个层次负责不同的功能,模块之间通过清晰的接口进行通信。这种架构可以提高代码的可读性、可维护性、可测试性和可重用性。

  • 硬件抽象层 (HAL - Hardware Abstraction Layer):

    • 封装底层硬件操作,提供统一的硬件访问接口。
    • 包括GPIO驱动、UART驱动、SPI驱动、I2C驱动、以太网驱动、USB驱动、显示驱动、存储驱动等。
    • 屏蔽硬件差异,方便上层应用移植和硬件更换。
  • 操作系统抽象层 (OSAL - Operating System Abstraction Layer):

    • 封装操作系统API,提供统一的操作系统服务接口。
    • 包括线程管理、进程管理、内存管理、同步机制(互斥锁、信号量、条件变量)、定时器、中断管理、文件系统等。
    • 提高代码的操作系统兼容性,方便系统移植到不同的操作系统平台。
  • 网络通信层 (Network Communication Layer):

    • 负责网络协议栈的实现,处理网络数据的发送和接收。
    • 支持TCP/IP协议栈、UDP协议栈、HTTP协议、MQTT协议、WebSocket协议等。
    • 提供网络Socket接口,方便上层应用进行网络通信。
  • 数据处理层 (Data Processing Layer):

    • 负责数据的解析、处理、转换、存储等。
    • 包括数据解析模块、数据校验模块、数据转换模块、数据压缩模块、数据加密模块、数据库访问模块等。
    • 实现数据的业务逻辑处理。
  • 服务逻辑层 (Service Logic Layer):

    • 实现终端服务器的核心业务逻辑功能。
    • 包括设备管理模块、用户管理模块、数据采集模块、数据转发模块、命令处理模块、告警处理模块、远程管理模块等。
    • 提供终端服务器对外提供的各种服务。
  • 应用接口层 (Application Interface Layer):

    • 提供对外API接口,方便上层应用或外部系统调用终端服务器的功能。
    • 可以是C API、RESTful API、Websocket API等。
  • 应用层/表示层 (Application/Presentation Layer):

    • 用户界面,可以是本地命令行界面、Web界面、图形界面等。
    • 负责用户交互和数据显示。

2. 事件驱动架构:

系统采用事件驱动机制,以异步事件的方式处理各种请求和操作。当外部事件发生时(如网络数据到达、定时器超时、用户输入等),系统会产生相应的事件,并由事件处理模块进行处理。

  • 事件队列: 用于存储待处理的事件。
  • 事件调度器: 从事件队列中取出事件,并分发给相应的事件处理模块。
  • 事件处理模块: 负责处理特定类型的事件,执行相应的操作。
  • 事件生成器: 系统各个模块都可以生成事件,并将其放入事件队列。

事件驱动架构的优势:

  • 高并发性: 能够高效处理大量并发事件,提高系统响应速度和吞吐量。
  • 低耦合性: 模块之间通过事件进行通信,降低模块之间的依赖性。
  • 易扩展性: 方便添加新的事件类型和事件处理模块,扩展系统功能。
  • 实时性: 能够及时响应外部事件,满足实时性要求较高的应用场景。

我将提供尽可能详细和全面的代码示例,涵盖上述架构的各个层次和模块,并包含必要的注释和错误处理。请注意,以下代码仅为示例,实际项目需要根据具体需求进行调整和完善。

为了结构清晰,代码将分成多个文件,并使用 Makefile 进行编译管理。

目录结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
terminal_server/
├── src/
│ ├── hal/
│ │ ├── hal_gpio.c
│ │ ├── hal_uart.c
│ │ ├── hal_eth.c
│ │ ├── hal_timer.c
│ │ ├── hal_i2c.c
│ │ ├── hal_spi.c
│ │ ├── hal_display.c
│ │ ├── hal_storage.c
│ │ └── hal.h
│ ├── osal/
│ │ ├── osal_thread.c
│ │ ├── osal_mutex.c
│ │ ├── osal_sem.c
│ │ ├── osal_timer.c
│ │ ├── osal_mem.c
│ │ └── osal.h
│ ├── network/
│ │ ├── net_socket.c
│ │ ├── net_tcp.c
│ │ ├── net_udp.c
│ │ ├── net_http.c
│ │ ├── net_mqtt.c
│ │ └── network.h
│ ├── data_process/
│ │ ├── data_parse.c
│ │ ├── data_verify.c
│ │ ├── data_convert.c
│ │ ├── data_compress.c
│ │ ├── data_encrypt.c
│ │ ├── data_db.c
│ │ └── data_process.h
│ ├── service_logic/
│ │ ├── device_manager.c
│ │ ├── user_manager.c
│ │ ├── data_collect.c
│ │ ├── data_forward.c
│ │ ├── command_process.c
│ │ ├── alarm_process.c
│ │ ├── remote_manage.c
│ │ └── service_logic.h
│ ├── app_interface/
│ │ ├── api_c.c
│ │ ├── api_restful.c
│ │ └── app_interface.h
│ ├── application/
│ │ ├── cli_app.c
│ │ └── web_app.c
│ ├── event_driver/
│ │ ├── event_queue.c
│ │ ├── event_scheduler.c
│ │ └── event_driver.h
│ ├── config/
│ │ ├── config_manager.c
│ │ └── config.h
│ ├── log/
│ │ ├── log_manager.c
│ │ └── log.h
│ ├── main.c
│ └── common.h
├── include/
│ ├── hal.h
│ ├── osal.h
│ ├── network.h
│ ├── data_process.h
│ ├── service_logic.h
│ ├── app_interface.h
│ ├── event_driver.h
│ ├── config.h
│ ├── log.h
│ └── common.h
├── Makefile
└── README.md

代码示例 (部分模块,完整代码请见附件或后续补充):

1. common.h (通用定义)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#ifndef COMMON_H
#define COMMON_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>

// 定义错误码
typedef enum {
ERROR_NONE = 0,
ERROR_GENERAL,
ERROR_NULL_POINTER,
ERROR_INVALID_PARAM,
ERROR_TIMEOUT,
ERROR_NOT_SUPPORTED,
ERROR_NO_MEMORY,
// ... 更多错误码
} error_code_t;

// 定义通用状态类型
typedef enum {
STATE_IDLE,
STATE_RUNNING,
STATE_STOPPED,
STATE_ERROR,
// ... 更多状态
} system_state_t;

// 定义日志等级
typedef enum {
LOG_LEVEL_DEBUG,
LOG_LEVEL_INFO,
LOG_LEVEL_WARN,
LOG_LEVEL_ERROR,
LOG_LEVEL_FATAL,
} log_level_t;

// 定义设备类型
typedef enum {
DEVICE_TYPE_SENSOR,
DEVICE_TYPE_ACTUATOR,
DEVICE_TYPE_CAMERA,
DEVICE_TYPE_CONTROLLER,
// ... 更多设备类型
} device_type_t;

#endif // COMMON_H

2. hal/hal.h (硬件抽象层头文件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#ifndef HAL_H
#define HAL_H

#include "common.h"

// GPIO 相关
typedef enum {
GPIO_PIN_1,
GPIO_PIN_2,
// ... 更多GPIO引脚定义
} gpio_pin_t;

typedef enum {
GPIO_DIRECTION_INPUT,
GPIO_DIRECTION_OUTPUT,
} gpio_direction_t;

typedef enum {
GPIO_LEVEL_LOW,
GPIO_LEVEL_HIGH,
} gpio_level_t;

error_code_t hal_gpio_init(gpio_pin_t pin, gpio_direction_t direction);
error_code_t hal_gpio_write(gpio_pin_t pin, gpio_level_t level);
gpio_level_t hal_gpio_read(gpio_pin_t pin);

// UART 相关
typedef enum {
UART_PORT_1,
UART_PORT_2,
// ... 更多UART端口定义
} uart_port_t;

typedef struct {
uint32_t baudrate;
uint8_t data_bits;
uint8_t stop_bits;
char parity; // 'N', 'E', 'O'
} uart_config_t;

error_code_t hal_uart_init(uart_port_t port, uart_config_t *config);
error_code_t hal_uart_send_data(uart_port_t port, const uint8_t *data, uint32_t len);
uint32_t hal_uart_receive_data(uart_port_t port, uint8_t *buffer, uint32_t max_len);

// ... 其他硬件接口的抽象定义 (以太网, 定时器, I2C, SPI, 显示, 存储等)

#endif // HAL_H

3. hal/hal_gpio.c (硬件抽象层 GPIO 实现 - 示例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "hal.h"
#include <stdio.h> // 示例使用标准库,实际可能需要硬件相关的头文件

error_code_t hal_gpio_init(gpio_pin_t pin, gpio_direction_t direction) {
// 硬件初始化代码 (RK3399 GPIO 初始化)
printf("HAL GPIO: Initializing GPIO pin %d, direction %d\n", pin, direction);
// ... 实际硬件操作代码
return ERROR_NONE;
}

error_code_t hal_gpio_write(gpio_pin_t pin, gpio_level_t level) {
// 硬件写GPIO代码 (RK3399 GPIO 写操作)
printf("HAL GPIO: Writing GPIO pin %d, level %d\n", pin, level);
// ... 实际硬件操作代码
return ERROR_NONE;
}

gpio_level_t hal_gpio_read(gpio_pin_t pin) {
// 硬件读GPIO代码 (RK3399 GPIO 读操作)
printf("HAL GPIO: Reading GPIO pin %d\n", pin);
// ... 实际硬件操作代码
return GPIO_LEVEL_LOW; // 示例默认返回低电平
}

4. osal/osal.h (操作系统抽象层头文件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#ifndef OSAL_H
#define OSAL_H

#include "common.h"

// 线程相关
typedef void (*thread_entry_t)(void *arg);
typedef void *thread_handle_t;

thread_handle_t osal_thread_create(thread_entry_t entry, void *arg, const char *name);
error_code_t osal_thread_join(thread_handle_t thread);
void osal_thread_sleep_ms(uint32_t ms);

// 互斥锁相关
typedef void *mutex_handle_t;
mutex_handle_t osal_mutex_create(void);
error_code_t osal_mutex_lock(mutex_handle_t mutex);
error_code_t osal_mutex_unlock(mutex_handle_t mutex);
error_code_t osal_mutex_destroy(mutex_handle_t mutex);

// 信号量相关
typedef void *sem_handle_t;
sem_handle_t osal_sem_create(uint32_t initial_count);
error_code_t osal_sem_post(sem_handle_t sem);
error_code_t osal_sem_wait(sem_handle_t sem, uint32_t timeout_ms); // 带超时等待
error_code_t osal_sem_destroy(sem_handle_t sem);

// 定时器相关
typedef void (*timer_callback_t)(void *arg);
typedef void *timer_handle_t;

timer_handle_t osal_timer_create(timer_callback_t callback, void *arg, uint32_t period_ms, bool is_periodic);
error_code_t osal_timer_start(timer_handle_t timer);
error_code_t osal_timer_stop(timer_handle_t timer);
error_code_t osal_timer_destroy(timer_handle_t timer);

// 内存管理相关 (简单示例,实际可能需要更复杂的内存池管理)
void *osal_malloc(size_t size);
void osal_free(void *ptr);

// ... 其他操作系统服务抽象 (中断管理, 文件系统等)

#endif // OSAL_H

5. osal/osal_thread.c (操作系统抽象层线程实现 - Linux pthreads 示例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "osal.h"
#include <pthread.h>
#include <unistd.h>
#include <errno.h>

typedef struct {
thread_entry_t entry;
void *arg;
} thread_param_t;

static void *thread_wrapper(void *param) {
thread_param_t *thread_param = (thread_param_t *)param;
thread_param->entry(thread_param->arg);
osal_free(thread_param); // 释放参数结构体内存
pthread_exit(NULL);
return NULL; // 为了消除编译器警告
}

thread_handle_t osal_thread_create(thread_entry_t entry, void *arg, const char *name) {
pthread_t thread_id;
pthread_attr_t attr;
thread_param_t *param = (thread_param_t *)osal_malloc(sizeof(thread_param_t));
if (param == NULL) {
return NULL; // 内存分配失败
}
param->entry = entry;
param->arg = arg;

pthread_attr_init(&attr);
// 可以设置线程属性,如栈大小、优先级等
int ret = pthread_create(&thread_id, &attr, thread_wrapper, param);
pthread_attr_destroy(&attr);

if (ret != 0) {
osal_free(param); // 创建失败,释放参数结构体内存
perror("pthread_create failed"); // 输出错误信息
return NULL;
}
return (thread_handle_t)thread_id;
}

error_code_t osal_thread_join(thread_handle_t thread) {
if (pthread_join((pthread_t)thread, NULL) != 0) {
perror("pthread_join failed");
return ERROR_GENERAL;
}
return ERROR_NONE;
}

void osal_thread_sleep_ms(uint32_t ms) {
usleep(ms * 1000); // usleep 以微秒为单位
}

6. network/network.h (网络通信层头文件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef NETWORK_H
#define NETWORK_H

#include "common.h"

// Socket 相关
typedef int socket_handle_t; // 使用 int 作为 socket 句柄,实际类型取决于操作系统

socket_handle_t net_socket_create(int domain, int type, int protocol);
error_code_t net_socket_bind(socket_handle_t sockfd, const char *ip_addr, uint16_t port);
error_code_t net_socket_listen(socket_handle_t sockfd, int backlog);
socket_handle_t net_socket_accept(socket_handle_t sockfd, char *client_ip, uint16_t *client_port);
error_code_t net_socket_connect(socket_handle_t sockfd, const char *server_ip, uint16_t server_port);
int32_t net_socket_send(socket_handle_t sockfd, const uint8_t *data, uint32_t len);
int32_t net_socket_recv(socket_handle_t sockfd, uint8_t *buffer, uint32_t max_len);
error_code_t net_socket_close(socket_handle_t sockfd);

// HTTP 协议相关 (简单示例)
error_code_t net_http_get(const char *url, char **response_data, uint32_t *response_len);
error_code_t net_http_post(const char *url, const char *post_data, char **response_data, uint32_t *response_len);

// MQTT 协议相关 (可以定义 MQTT 客户端 API)
// ...

// ... 其他网络协议接口定义

#endif // NETWORK_H

7. network/net_socket.c (网络通信层 Socket 实现 - Linux sockets 示例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "network.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>

socket_handle_t net_socket_create(int domain, int type, int protocol) {
int sockfd = socket(domain, type, protocol);
if (sockfd < 0) {
perror("socket creation failed");
return -1; // 返回 -1 表示错误
}
return sockfd;
}

error_code_t net_socket_bind(socket_handle_t sockfd, const char *ip_addr, uint16_t port) {
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
if (ip_addr == NULL || strcmp(ip_addr, "0.0.0.0") == 0) {
addr.sin_addr.s_addr = INADDR_ANY; // 绑定到所有网卡
} else {
if (inet_pton(AF_INET, ip_addr, &addr.sin_addr) <= 0) {
perror("inet_pton failed");
close(sockfd);
return ERROR_INVALID_PARAM;
}
}

if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind failed");
close(sockfd);
return ERROR_GENERAL;
}
return ERROR_NONE;
}

error_code_t net_socket_listen(socket_handle_t sockfd, int backlog) {
if (listen(sockfd, backlog) < 0) {
perror("listen failed");
close(sockfd);
return ERROR_GENERAL;
}
return ERROR_NONE;
}

socket_handle_t net_socket_accept(socket_handle_t sockfd, char *client_ip, uint16_t *client_port) {
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
int client_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_addr_len);
if (client_sockfd < 0) {
perror("accept failed");
return -1;
}

if (client_ip != NULL) {
inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);
}
if (client_port != NULL) {
*client_port = ntohs(client_addr.sin_port);
}
return client_sockfd;
}

error_code_t net_socket_connect(socket_handle_t sockfd, const char *server_ip, uint16_t server_port) {
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
if (inet_pton(AF_INET, server_ip, &server_addr.sin_addr) <= 0) {
perror("inet_pton failed");
close(sockfd);
return ERROR_INVALID_PARAM;
}

if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("connect failed");
close(sockfd);
return ERROR_GENERAL;
}
return ERROR_NONE;
}

int32_t net_socket_send(socket_handle_t sockfd, const uint8_t *data, uint32_t len) {
ssize_t bytes_sent = send(sockfd, data, len, 0);
if (bytes_sent < 0) {
perror("send failed");
return -1;
}
return (int32_t)bytes_sent;
}

int32_t net_socket_recv(socket_handle_t sockfd, uint8_t *buffer, uint32_t max_len) {
ssize_t bytes_received = recv(sockfd, buffer, max_len, 0);
if (bytes_received < 0) {
perror("recv failed");
return -1;
}
return (int32_t)bytes_received;
}

error_code_t net_socket_close(socket_handle_t sockfd) {
if (close(sockfd) < 0) {
perror("close failed");
return ERROR_GENERAL;
}
return ERROR_NONE;
}

8. service_logic/service_logic.h (服务逻辑层头文件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#ifndef SERVICE_LOGIC_H
#define SERVICE_LOGIC_H

#include "common.h"
#include "hal.h"
#include "osal.h"
#include "network.h"
#include "data_process.h"
#include "event_driver.h"
#include "config.h"
#include "log.h"

// 设备管理模块
error_code_t device_manager_init(void);
error_code_t device_register(device_type_t type, const char *device_id);
error_code_t device_unregister(const char *device_id);
// ... 设备管理其他API

// 用户管理模块
error_code_t user_manager_init(void);
error_code_t user_login(const char *username, const char *password);
error_code_t user_logout(void);
// ... 用户管理其他API

// 数据采集模块
error_code_t data_collect_init(void);
error_code_t start_data_collection(const char *device_id);
error_code_t stop_data_collection(const char *device_id);
// ... 数据采集其他API

// 数据转发模块
error_code_t data_forward_init(void);
error_code_t add_forwarding_rule(const char *source_device_id, const char *destination_server_ip, uint16_t destination_server_port);
error_code_t remove_forwarding_rule(const char *source_device_id);
// ... 数据转发其他API

// 命令处理模块
error_code_t command_process_init(void);
error_code_t process_command(const char *command_str, char **response_str, uint32_t *response_len);
// ... 命令处理其他API

// 告警处理模块
error_code_t alarm_process_init(void);
error_code_t raise_alarm(const char *device_id, const char *alarm_message);
error_code_t clear_alarm(const char *device_id, const char *alarm_message);
// ... 告警处理其他API

// 远程管理模块
error_code_t remote_manage_init(void);
error_code_t start_remote_management_server(uint16_t port);
error_code_t stop_remote_management_server(void);
// ... 远程管理其他API

#endif // SERVICE_LOGIC_H

9. service_logic/device_manager.c (服务逻辑层设备管理模块 - 示例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include "service_logic.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 假设使用链表存储设备信息
typedef struct device_info_s {
char device_id[64];
device_type_t type;
// ... 其他设备信息
struct device_info_s *next;
} device_info_t;

static device_info_t *device_list_head = NULL;
static mutex_handle_t device_list_mutex; // 保护设备列表的互斥锁

error_code_t device_manager_init(void) {
device_list_mutex = osal_mutex_create();
if (device_list_mutex == NULL) {
return ERROR_NO_MEMORY;
}
device_list_head = NULL;
return ERROR_NONE;
}

error_code_t device_register(device_type_t type, const char *device_id) {
if (device_id == NULL) {
return ERROR_INVALID_PARAM;
}

osal_mutex_lock(device_list_mutex); // 加锁

// 检查设备ID是否已存在
device_info_t *current = device_list_head;
while (current != NULL) {
if (strcmp(current->device_id, device_id) == 0) {
osal_mutex_unlock(device_list_mutex); // 解锁
return ERROR_INVALID_PARAM; // 设备ID已存在
}
current = current->next;
}

// 创建新的设备信息节点
device_info_t *new_device = (device_info_t *)osal_malloc(sizeof(device_info_t));
if (new_device == NULL) {
osal_mutex_unlock(device_list_mutex); // 解锁
return ERROR_NO_MEMORY;
}
strncpy(new_device->device_id, device_id, sizeof(new_device->device_id) - 1);
new_device->device_id[sizeof(new_device->device_id) - 1] = '\0'; // 确保字符串结尾
new_device->type = type;
new_device->next = device_list_head;
device_list_head = new_device;

osal_mutex_unlock(device_list_mutex); // 解锁
printf("Device registered: ID=%s, Type=%d\n", device_id, type);
return ERROR_NONE;
}

error_code_t device_unregister(const char *device_id) {
if (device_id == NULL) {
return ERROR_INVALID_PARAM;
}

osal_mutex_lock(device_list_mutex); // 加锁

device_info_t *current = device_list_head;
device_info_t *prev = NULL;

while (current != NULL) {
if (strcmp(current->device_id, device_id) == 0) {
if (prev == NULL) {
device_list_head = current->next; // 删除头节点
} else {
prev->next = current->next;
}
osal_free(current);
osal_mutex_unlock(device_list_mutex); // 解锁
printf("Device unregistered: ID=%s\n", device_id);
return ERROR_NONE;
}
prev = current;
current = current->next;
}

osal_mutex_unlock(device_list_mutex); // 解锁
return ERROR_INVALID_PARAM; // 设备ID未找到
}

// ... 设备管理模块其他API 的实现 (例如: 获取设备信息, 获取设备列表等)

10. event_driver/event_driver.h (事件驱动层头文件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#ifndef EVENT_DRIVER_H
#define EVENT_DRIVER_H

#include "common.h"

// 事件类型定义
typedef enum {
EVENT_TYPE_NONE,
EVENT_TYPE_DATA_RECEIVED,
EVENT_TYPE_TIMER_EXPIRED,
EVENT_TYPE_COMMAND_RECEIVED,
EVENT_TYPE_ALARM_RAISED,
// ... 更多事件类型
} event_type_t;

// 事件数据结构
typedef struct event_s {
event_type_t type;
void *data; // 事件相关数据,根据事件类型不同而不同
// ... 其他事件属性,如优先级、时间戳等
} event_t;

// 事件处理函数类型
typedef error_code_t (*event_handler_t)(event_t *event);

// 事件驱动 API
error_code_t event_queue_init(uint32_t queue_size);
error_code_t event_queue_enqueue(event_t *event);
error_code_t event_queue_dequeue(event_t *event, uint32_t timeout_ms); // 带超时等待
error_code_t event_scheduler_register_handler(event_type_t type, event_handler_t handler);
error_code_t event_scheduler_dispatch(void); // 事件调度主循环

#endif // EVENT_DRIVER_H

11. event_driver/event_queue.c (事件驱动层事件队列实现 - 简单环形队列示例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include "event_driver.h"
#include "osal.h"
#include <stdlib.h>

#define DEFAULT_EVENT_QUEUE_SIZE 128

typedef struct event_queue_s {
event_t *queue;
uint32_t head;
uint32_t tail;
uint32_t size;
mutex_handle_t mutex;
sem_handle_t sem_empty; // 信号量,用于指示队列是否为空
sem_handle_t sem_full; // 信号量,用于指示队列是否已满
} event_queue_t;

static event_queue_t event_queue;

error_code_t event_queue_init(uint32_t queue_size) {
if (queue_size == 0) {
queue_size = DEFAULT_EVENT_QUEUE_SIZE;
}
event_queue.queue = (event_t *)osal_malloc(sizeof(event_t) * queue_size);
if (event_queue.queue == NULL) {
return ERROR_NO_MEMORY;
}
memset(event_queue.queue, 0, sizeof(event_t) * queue_size);
event_queue.head = 0;
event_queue.tail = 0;
event_queue.size = queue_size;
event_queue.mutex = osal_mutex_create();
if (event_queue.mutex == NULL) {
osal_free(event_queue.queue);
return ERROR_NO_MEMORY;
}
event_queue.sem_empty = osal_sem_create(queue_size); // 初始为空信号量计数为队列大小
if (event_queue.sem_empty == NULL) {
osal_free(event_queue.queue);
osal_mutex_destroy(event_queue.mutex);
return ERROR_NO_MEMORY;
}
event_queue.sem_full = osal_sem_create(0); // 初始为满信号量计数为 0
if (event_queue.sem_full == NULL) {
osal_free(event_queue.queue);
osal_mutex_destroy(event_queue.mutex);
osal_sem_destroy(event_queue.sem_empty);
return ERROR_NO_MEMORY;
}
return ERROR_NONE;
}

error_code_t event_queue_enqueue(event_t *event) {
if (event == NULL) {
return ERROR_INVALID_PARAM;
}

osal_sem_wait(event_queue.sem_empty, -1); // 等待队列有空闲位置 (无限等待)
osal_mutex_lock(event_queue.mutex);

memcpy(&event_queue.queue[event_queue.tail], event, sizeof(event_t));
event_queue.tail = (event_queue.tail + 1) % event_queue.size;

osal_mutex_unlock(event_queue.mutex);
osal_sem_post(event_queue.sem_full); // 通知队列有数据可读
return ERROR_NONE;
}

error_code_t event_queue_dequeue(event_t *event, uint32_t timeout_ms) {
if (event == NULL) {
return ERROR_INVALID_PARAM;
}

if (osal_sem_wait(event_queue.sem_full, timeout_ms) != ERROR_NONE) { // 等待队列有数据 (带超时)
return ERROR_TIMEOUT; // 超时返回
}
osal_mutex_lock(event_queue.mutex);

memcpy(event, &event_queue.queue[event_queue.head], sizeof(event_t));
event_queue.head = (event_queue.head + 1) % event_queue.size;

osal_mutex_unlock(event_queue.mutex);
osal_sem_post(event_queue.sem_empty); // 通知队列有空闲位置
return ERROR_NONE;
}

12. event_driver/event_scheduler.c (事件驱动层事件调度器 - 示例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "event_driver.h"
#include "osal.h"
#include <stdio.h>

#define MAX_EVENT_HANDLERS 32

typedef struct event_handler_entry_s {
event_type_t type;
event_handler_t handler;
} event_handler_entry_t;

static event_handler_entry_t event_handlers[MAX_EVENT_HANDLERS];
static uint32_t handler_count = 0;

error_code_t event_scheduler_register_handler(event_type_t type, event_handler_t handler) {
if (handler_count >= MAX_EVENT_HANDLERS) {
return ERROR_NO_MEMORY; // 注册处理函数数量已达上限
}
event_handlers[handler_count].type = type;
event_handlers[handler_count].handler = handler;
handler_count++;
return ERROR_NONE;
}

error_code_t event_scheduler_dispatch(void) {
event_t event;
error_code_t ret;

while (1) { // 事件调度主循环
ret = event_queue_dequeue(&event, -1); // 从事件队列获取事件 (无限等待)
if (ret == ERROR_NONE) {
for (uint32_t i = 0; i < handler_count; i++) {
if (event_handlers[i].type == event.type) {
if (event_handlers[i].handler != NULL) {
event_handlers[i].handler(&event); // 调用事件处理函数
break; // 找到处理函数后退出循环
}
}
}
// 如果没有找到对应的处理函数,可以进行默认处理或记录日志
if (ret != ERROR_NONE) {
printf("Error processing event type: %d, error code: %d\n", event.type, ret);
}
} else if (ret == ERROR_TIMEOUT) {
// 队列超时,通常不会发生,因为dequeue 使用了无限等待
printf("Event queue dequeue timeout!\n");
} else {
printf("Event queue dequeue error: %d\n", ret);
// 队列错误处理
}
}
return ERROR_NONE; // 理论上不会执行到这里
}

13. main.c (主程序入口)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "common.h"
#include "hal.h"
#include "osal.h"
#include "network.h"
#include "data_process.h"
#include "service_logic.h"
#include "event_driver.h"
#include "config.h"
#include "log.h"

// 示例事件处理函数
error_code_t handle_data_received_event(event_t *event) {
printf("Event Handler: Data Received Event, data: %s\n", (char *)event->data);
// ... 数据处理逻辑
osal_free(event->data); // 释放事件数据内存
return ERROR_NONE;
}

error_code_t handle_timer_expired_event(event_t *event) {
printf("Event Handler: Timer Expired Event, timer ID: %d\n", *(int *)event->data);
osal_free(event->data); // 释放事件数据内存
return ERROR_NONE;
}

int main() {
printf("Starting Terminal Server...\n");

// 初始化各个模块
if (hal_init() != ERROR_NONE) { // 假设 hal.c 中有 hal_init 函数
printf("HAL initialization failed!\n");
return -1;
}
if (osal_init() != ERROR_NONE) { // 假设 osal.c 中有 osal_init 函数
printf("OSAL initialization failed!\n");
return -1;
}
if (event_queue_init(128) != ERROR_NONE) {
printf("Event Queue initialization failed!\n");
return -1;
}
if (event_scheduler_register_handler(EVENT_TYPE_DATA_RECEIVED, handle_data_received_event) != ERROR_NONE) {
printf("Register data received event handler failed!\n");
return -1;
}
if (event_scheduler_register_handler(EVENT_TYPE_TIMER_EXPIRED, handle_timer_expired_event) != ERROR_NONE) {
printf("Register timer expired event handler failed!\n");
return -1;
}
if (device_manager_init() != ERROR_NONE) {
printf("Device Manager initialization failed!\n");
return -1;
}
if (user_manager_init() != ERROR_NONE) {
printf("User Manager initialization failed!\n");
return -1;
}
if (data_collect_init() != ERROR_NONE) {
printf("Data Collect initialization failed!\n");
return -1;
}
if (data_forward_init() != ERROR_NONE) {
printf("Data Forward initialization failed!\n");
return -1;
}
if (command_process_init() != ERROR_NONE) {
printf("Command Process initialization failed!\n");
return -1;
}
if (alarm_process_init() != ERROR_NONE) {
printf("Alarm Process initialization failed!\n");
return -1;
}
if (remote_manage_init() != ERROR_NONE) {
printf("Remote Manage initialization failed!\n");
return -1;
}
if (log_manager_init() != ERROR_NONE) {
printf("Log Manager initialization failed!\n");
return -1;
}
if (config_manager_init() != ERROR_NONE) {
printf("Config Manager initialization failed!\n");
return -1;
}
if (network_init() != ERROR_NONE) { // 假设 network.c 中有 network_init 函数
printf("Network initialization failed!\n");
return -1;
}
if (data_process_init() != ERROR_NONE) { // 假设 data_process.c 中有 data_process_init 函数
printf("Data Process initialization failed!\n");
return -1;
}


// 示例:创建并发送一个数据接收事件
event_t data_event;
data_event.type = EVENT_TYPE_DATA_RECEIVED;
char *data_str = strdup("Hello from terminal server!");
data_event.data = data_str;
event_queue_enqueue(&data_event);

// 示例:创建一个定时器事件 (假设有 osal_timer_create 和 osal_timer_start)
int timer_id = 1;
int *timer_id_ptr = (int *)osal_malloc(sizeof(int));
*timer_id_ptr = timer_id;
timer_handle_t timer = osal_timer_create((timer_callback_t)NULL, timer_id_ptr, 5000, true); // 5秒周期定时器
if (timer != NULL) {
event_t timer_event;
timer_event.type = EVENT_TYPE_TIMER_EXPIRED;
timer_event.data = timer_id_ptr;
osal_timer_start(timer); // 启动定时器 (回调函数为 NULL,仅触发事件)
// 定时器事件会在定时器到期时自动加入事件队列
} else {
osal_free(timer_id_ptr); // 定时器创建失败,释放内存
printf("Timer creation failed!\n");
}


printf("Terminal Server initialized and running...\n");

// 启动事件调度器
event_scheduler_dispatch(); // 进入事件调度主循环

// ... (理论上不会执行到这里,因为 event_scheduler_dispatch 是无限循环)

return 0;
}

Makefile (示例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
CC = gcc
CFLAGS = -Wall -g -Iinclude
LDFLAGS = -lpthread

SRCDIR = src
BUILDDIR = build
TARGET = terminal_server

SRC_FILES = $(wildcard $(SRCDIR)/**/*.c)
OBJ_FILES = $(patsubst $(SRCDIR)/%.c,$(BUILDDIR)/%.o,$(SRC_FILES))

$(BUILDDIR)/%.o: $(SRCDIR)/%.c include/*.h
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) -c $< -o $@

all: $(BUILDDIR) $(TARGET)

$(TARGET): $(OBJ_FILES)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ_FILES) -o $@

$(BUILDDIR):
@mkdir -p $(BUILDDIR)

clean:
rm -rf $(BUILDDIR) $(TARGET)

.PHONY: all clean

技术和方法实践验证

本项目中采用的各种技术和方法都是经过实践验证的,包括:

  • 分层模块化架构: 在大型嵌入式系统开发中广泛应用,有效降低系统复杂性,提高可维护性和可扩展性。
  • 事件驱动架构: 特别适合于需要处理大量异步事件的系统,如网络服务器、UI系统等,能够提高系统效率和响应速度。
  • C语言: 嵌入式系统开发的主流语言,具有高效、灵活、可移植性好等优点。
  • Linux操作系统 (示例代码基于 Linux): 开源、成熟、功能强大的操作系统,为嵌入式系统提供了丰富的资源和支持。RK3399 核心板通常运行 Linux 或 Android 系统,Linux 更适合作为服务器系统。
  • POSIX 线程 (pthreads): Linux 和其他 POSIX 兼容系统提供的标准线程库,用于实现多线程并发。
  • Sockets API: 网络编程的基础 API,用于实现 TCP/IP 通信。
  • 环形队列: 高效的数据结构,常用于实现事件队列、消息队列等。
  • 互斥锁和信号量: 常用的同步机制,用于保护共享资源和实现线程同步。
  • Makefile: 自动化构建工具,方便代码编译和管理。
  • 代码审查、单元测试、集成测试、系统测试: 软件质量保证的关键环节,确保代码质量和系统稳定性。
  • 日志系统: 用于记录系统运行状态、错误信息等,方便调试和维护。
  • 配置管理: 将系统配置参数独立管理,方便修改和部署。

总结

上述代码设计架构和C代码实现方案,结合分层模块化架构和事件驱动架构,能够构建一个可靠、高效、可扩展的基于RK3399核心板的终端服务器系统。代码示例涵盖了硬件抽象层、操作系统抽象层、网络通信层、服务逻辑层、事件驱动层等关键模块,并提供了详细的注释和说明。

请注意,以上代码只是一个框架和示例,需要根据具体的硬件平台、操作系统和功能需求进行适配和调整。 完整和可编译的代码工程需要您根据上述结构和示例代码进行填充和完善。 如果您需要更详细的代码或更具体的模块实现,请随时提出更具体的问题,我会尽力提供更深入的解答和代码示例。

欢迎关注我的其它发布渠道