编程技术分享

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

0%

简介:YuzukiRuler 随身Linux小尺子,板载UART和OTG,还有一个1.14小屏幕,支持2.4G Wi-Fi网上冲浪

好的,作为一名高级嵌入式软件开发工程师,我将为您详细阐述针对 “YuzukiRuler 随身Linux小尺子” 项目的最佳代码设计架构,并提供具体的C代码实现示例。这个项目旨在构建一个可靠、高效、可扩展的嵌入式系统平台,我们将从需求分析出发,贯穿系统实现、测试验证到维护升级的整个流程,并确保所采用的技术和方法都经过实践验证。
关注微信公众号,提前获取相关推文

项目概述:YuzukiRuler 随身Linux小尺子

YuzukiRuler 是一款便携式的嵌入式Linux设备,它集成了以下关键功能:

  • 尺子功能:核心功能,用于测量长度。
  • 1.14英寸小屏幕:用于显示测量结果、系统信息和用户界面。
  • 板载UART:用于串口通信,例如调试、数据传输等。
  • OTG USB:支持USB On-The-Go,可以作为USB设备或主机使用,例如连接电脑或外部设备。
  • 2.4G Wi-Fi:支持无线网络连接,用于网络冲浪、数据传输、远程控制等。
  • Linux操作系统:运行在嵌入式处理器上,提供丰富的软件生态和灵活性。

系统架构设计

为了实现 YuzukiRuler 的功能并满足可靠性、高效性和可扩展性的要求,我们将采用分层架构的设计模式。这种架构将系统划分为多个独立的层次,每个层次负责特定的功能,并通过清晰定义的接口与其他层次进行交互。分层架构的优点包括:

  • 模块化:每个层次都是一个独立的模块,易于开发、测试和维护。
  • 可重用性:不同层次的模块可以被重用在其他项目中。
  • 可扩展性:可以方便地添加新的层次或模块来扩展系统功能。
  • 易于理解:清晰的层次结构使得系统更易于理解和维护。

针对 YuzukiRuler 项目,我们设计如下分层架构:

1
2
3
4
5
6
7
8
9
10
11
+---------------------+
| 应用层 (Application Layer) | 用户界面、尺子逻辑、网络应用
+---------------------+
| 中间件层 (Middleware Layer) | 设备管理、网络协议栈、图形库、文件系统
+---------------------+
| 操作系统层 (Operating System Layer) | Linux Kernel
+---------------------+
| 硬件抽象层 (HAL - Hardware Abstraction Layer) | GPIO、UART、SPI、I2C、USB、Wi-Fi驱动
+---------------------+
| 硬件层 (Hardware Layer) | 嵌入式处理器、外围器件 (屏幕、Wi-Fi模块、传感器等)
+---------------------+

各层详细说明:

  1. **硬件层 (Hardware Layer)**:

    • 这是系统的最底层,包括嵌入式处理器(例如基于 ARM Cortex-A 系列的处理器),以及各种外围硬件组件,如:
      • 1.14英寸 LCD 屏幕 (SPI接口)
      • UART 接口
      • OTG USB 接口
      • 2.4G Wi-Fi 模块 (通常是 SDIO 或 SPI/UART 接口)
      • GPIO 用于控制 LED、按钮等
      • 存储器 (Flash, RAM)
      • 电源管理电路
  2. **硬件抽象层 (HAL - Hardware Abstraction Layer)**:

    • HAL 层位于硬件层之上,操作系统层之下。它的主要目的是隔离硬件差异,为上层软件提供统一的硬件访问接口。
    • HAL 层包含各种硬件驱动程序,例如:
      • GPIO 驱动:控制 GPIO 引脚的输入输出,用于控制屏幕背光、读取按键状态等。
      • UART 驱动:实现串口通信,用于调试信息输出和数据传输。
      • SPI 驱动:驱动 SPI 总线,通常用于控制 LCD 屏幕和 Wi-Fi 模块。
      • I2C 驱动:如果使用 I2C 设备,则需要 I2C 驱动。
      • USB 驱动:支持 USB OTG 功能,作为设备或主机。
      • Wi-Fi 驱动:驱动 Wi-Fi 模块,实现无线网络连接。
    • HAL 层提供的接口应该是平台无关的,这样当底层硬件发生变化时,只需要修改 HAL 层,而上层软件不需要修改。
  3. **操作系统层 (Operating System Layer)**:

    • YuzukiRuler 采用 Linux 操作系统。Linux 内核提供了进程管理、内存管理、文件系统、网络协议栈等核心功能。
    • Linux 操作系统为上层软件提供了丰富的系统调用接口和驱动框架,极大地简化了嵌入式系统的开发。
    • 我们可以选择一个轻量级的 Linux 发行版,例如 BuildrootYocto Project 构建定制化的 Linux 系统镜像,以满足 YuzukiRuler 的特定需求。
  4. **中间件层 (Middleware Layer)**:

    • 中间件层构建在操作系统层之上,为应用层提供常用的服务和功能组件。
    • 常见的中间件组件包括:
      • 设备管理:管理系统中的各种设备,例如屏幕、Wi-Fi 模块等。
      • 网络协议栈:TCP/IP 协议栈,用于实现网络通信。
      • 图形库:例如 FramebufferSDL,用于在屏幕上绘制图形和文本。
      • 文件系统:用于管理存储在 Flash 中的文件,例如配置文件、用户数据等。
      • **GUI 框架 (可选)**:例如 Qt Embedded 或 **GTK+**,如果需要更复杂的图形用户界面。
      • **加密库 (可选)**:例如 OpenSSL,用于网络安全通信。
      • **JSON/XML 解析库 (可选)**:用于处理网络数据格式。
  5. **应用层 (Application Layer)**:

    • 应用层是系统的最高层,包含运行在 YuzukiRuler 上的应用程序。
    • 对于 YuzukiRuler 项目,应用层主要包括:
      • **用户界面 (UI)**:负责用户交互,例如显示测量结果、系统菜单、Wi-Fi 设置等。
      • 尺子逻辑:处理尺子功能的核心逻辑,例如读取传感器数据、计算长度、校准等 (如果采用传感器辅助测量)。 在 YuzukiRuler 的情况下,尺子功能更偏向于视觉尺,屏幕上的刻度显示和触摸交互是重点。
      • 网络应用:基于 Wi-Fi 实现的网络功能,例如:
        • 网页浏览 (如果硬件性能允许,可以集成轻量级浏览器)。
        • 数据同步:将测量数据同步到云端服务器或电脑。
        • 远程控制:通过网络远程控制 YuzukiRuler。
        • OTA 升级:通过网络下载和更新系统固件。

代码实现 (C 语言示例)

为了演示上述架构,我将提供一些 C 语言代码示例,涵盖各个层次的关键功能。由于 3000 行代码的篇幅限制,我将重点展示核心模块的代码结构和关键接口,并使用伪代码或注释来简化一些细节。

1. 硬件抽象层 (HAL) 示例:

hal_gpio.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
#ifndef HAL_GPIO_H
#define HAL_GPIO_H

typedef enum {
GPIO_PIN_1,
GPIO_PIN_2,
// ... 定义所有 GPIO 引脚
GPIO_PIN_MAX
} gpio_pin_t;

typedef enum {
GPIO_MODE_INPUT,
GPIO_MODE_OUTPUT
} gpio_mode_t;

typedef enum {
GPIO_LEVEL_LOW,
GPIO_LEVEL_HIGH
} gpio_level_t;

// 初始化 GPIO 引脚
void hal_gpio_init(gpio_pin_t pin, gpio_mode_t mode);

// 设置 GPIO 引脚输出电平
void hal_gpio_set_level(gpio_pin_t pin, gpio_level_t level);

// 读取 GPIO 引脚输入电平
gpio_level_t hal_gpio_get_level(gpio_pin_t pin);

#endif // HAL_GPIO_H

hal_gpio.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
#include "hal_gpio.h"
#include "soc_gpio.h" // 假设 soc_gpio.h 是 SoC 厂商提供的 GPIO 驱动头文件

void hal_gpio_init(gpio_pin_t pin, gpio_mode_t mode) {
// 将 HAL GPIO pin 映射到 SoC specific GPIO pin
soc_gpio_pin_t soc_pin = map_hal_to_soc_gpio_pin(pin);

if (mode == GPIO_MODE_INPUT) {
soc_gpio_set_mode(soc_pin, SOC_GPIO_MODE_INPUT);
} else if (mode == GPIO_MODE_OUTPUT) {
soc_gpio_set_mode(soc_pin, SOC_GPIO_MODE_OUTPUT);
}
}

void hal_gpio_set_level(gpio_pin_t pin, gpio_level_t level) {
soc_gpio_pin_t soc_pin = map_hal_to_soc_gpio_pin(pin);
if (level == GPIO_LEVEL_LOW) {
soc_gpio_write(soc_pin, SOC_GPIO_LEVEL_LOW);
} else if (level == GPIO_LEVEL_HIGH) {
soc_gpio_write(soc_pin, SOC_GPIO_LEVEL_HIGH);
}
}

gpio_level_t hal_gpio_get_level(gpio_pin_t pin) {
soc_gpio_pin_t soc_pin = map_hal_to_soc_gpio_pin(pin);
soc_gpio_level_t soc_level = soc_gpio_read(soc_pin);
if (soc_level == SOC_GPIO_LEVEL_LOW) {
return GPIO_LEVEL_LOW;
} else {
return GPIO_LEVEL_HIGH;
}
}

// 示例: 将 HAL GPIO pin 映射到 SoC specific GPIO pin (需要根据具体的 SoC 实现)
soc_gpio_pin_t map_hal_to_soc_gpio_pin(gpio_pin_t hal_pin) {
soc_gpio_pin_t soc_pin;
switch (hal_pin) {
case GPIO_PIN_1:
soc_pin = SOC_GPIO_PIN_XX; // 替换为实际的 SoC GPIO pin 定义
break;
case GPIO_PIN_2:
soc_pin = SOC_GPIO_PIN_YY; // 替换为实际的 SoC GPIO pin 定义
break;
// ... 其他 pin 的映射
default:
soc_pin = SOC_GPIO_PIN_INVALID;
break;
}
return soc_pin;
}

hal_uart.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
#ifndef HAL_UART_H
#define HAL_UART_H

typedef enum {
UART_PORT_1,
UART_PORT_2,
// ... 定义所有 UART 端口
UART_PORT_MAX
} uart_port_t;

typedef enum {
UART_BAUDRATE_9600,
UART_BAUDRATE_115200,
// ... 定义其他波特率
} uart_baudrate_t;

// 初始化 UART 端口
void hal_uart_init(uart_port_t port, uart_baudrate_t baudrate);

// 发送一个字节数据
void hal_uart_send_byte(uart_port_t port, uint8_t data);

// 接收一个字节数据 (阻塞式)
uint8_t hal_uart_receive_byte(uart_port_t port);

// 发送字符串
void hal_uart_send_string(uart_port_t port, const char *str);

#endif // HAL_UART_H

hal_uart.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
#include "hal_uart.h"
#include "soc_uart.h" // 假设 soc_uart.h 是 SoC 厂商提供的 UART 驱动头文件

void hal_uart_init(uart_port_t port, uart_baudrate_t baudrate) {
soc_uart_port_t soc_port = map_hal_to_soc_uart_port(port);
soc_uart_baudrate_t soc_baudrate = map_hal_to_soc_baudrate(baudrate);
soc_uart_init(soc_port, soc_baudrate);
}

void hal_uart_send_byte(uart_port_t port, uint8_t data) {
soc_uart_port_t soc_port = map_hal_to_soc_uart_port(port);
soc_uart_send_byte(soc_port, data);
}

uint8_t hal_uart_receive_byte(uart_port_t port) {
soc_uart_port_t soc_port = map_hal_to_soc_uart_port(port);
return soc_uart_receive_byte(soc_port);
}

void hal_uart_send_string(uart_port_t port, const char *str) {
while (*str) {
hal_uart_send_byte(port, *str++);
}
}

// ... (map_hal_to_soc_uart_port, map_hal_to_soc_baudrate 函数的实现类似 GPIO 的映射)

hal_spi.h (类似 GPIO 和 UART,此处省略具体代码)

hal_spi.c (类似 GPIO 和 UART,此处省略具体代码)

2. 板级支持包 (BSP) 示例:

bsp.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef BSP_H
#define BSP_H

// 系统初始化
void bsp_init(void);

// 初始化 LCD 屏幕
void bsp_lcd_init(void);

// 初始化 Wi-Fi 模块
void bsp_wifi_init(void);

// ... 其他板级初始化函数

#endif // BSP_H

bsp.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
#include "bsp.h"
#include "hal_gpio.h"
#include "hal_uart.h"
#include "hal_spi.h"
#include "lcd_driver.h" // 假设 lcd_driver.h 是 LCD 驱动的头文件
#include "wifi_driver.h" // 假设 wifi_driver.h 是 Wi-Fi 驱动的头文件

void bsp_init(void) {
// 初始化系统时钟、中断控制器等 (根据具体 SoC 初始化流程)

// 初始化 UART 用于调试输出
hal_uart_init(UART_PORT_1, UART_BAUDRATE_115200);

printf("System Booting...\r\n"); // 使用 UART 输出启动信息

// 初始化 GPIO (例如 LCD 背光控制引脚)
hal_gpio_init(GPIO_PIN_LCD_BACKLIGHT, GPIO_MODE_OUTPUT);
hal_gpio_set_level(GPIO_PIN_LCD_BACKLIGHT, GPIO_LEVEL_HIGH); // 打开背光

// 初始化 LCD 屏幕
bsp_lcd_init();

// 初始化 Wi-Fi 模块
bsp_wifi_init();

printf("BSP Initialization Done.\r\n");
}

void bsp_lcd_init(void) {
// 初始化 LCD 屏幕的 SPI 接口
// hal_spi_init(...); // 根据 LCD 屏幕的 SPI 配置初始化 SPI

// 调用 LCD 驱动初始化函数
lcd_init();
lcd_clear_screen(LCD_COLOR_BLACK); // 清屏
lcd_set_color(LCD_COLOR_WHITE);
lcd_draw_string(10, 10, "YuzukiRuler Booting...", FONT_8x16); // 显示启动信息
}

void bsp_wifi_init(void) {
// 初始化 Wi-Fi 模块 (例如通过 SPI 或 SDIO 接口)
// wifi_init(...); // 调用 Wi-Fi 驱动初始化函数
printf("Wi-Fi Module Initialized.\r\n"); // 假设 Wi-Fi 初始化成功
}

// ... 其他 BSP 初始化函数的实现

3. 中间件层示例:

lcd_driver.h (简化版的 LCD 驱动头文件)

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
#ifndef LCD_DRIVER_H
#define LCD_DRIVER_H

#include <stdint.h>

// 定义颜色
#define LCD_COLOR_BLACK 0x0000
#define LCD_COLOR_WHITE 0xFFFF
#define LCD_COLOR_RED 0xF800
#define LCD_COLOR_GREEN 0x07E0
#define LCD_COLOR_BLUE 0x001F

// 初始化 LCD
void lcd_init(void);

// 清屏
void lcd_clear_screen(uint16_t color);

// 设置绘图颜色
void lcd_set_color(uint16_t color);

// 画点
void lcd_draw_pixel(uint16_t x, uint16_t y);

// 画线
void lcd_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);

// 绘制矩形
void lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);

// 绘制字符
void lcd_draw_char(uint16_t x, uint16_t y, char c, uint8_t font[]);

// 绘制字符串
void lcd_draw_string(uint16_t x, uint16_t y, const char *str, uint8_t font[]);

// 字体定义 (简化,实际应用中需要更完整的字体数据)
extern const uint8_t FONT_8x16[];

#endif // LCD_DRIVER_H

lcd_driver.c (简化版的 LCD 驱动实现)

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
#include "lcd_driver.h"
#include "hal_spi.h" // 假设 LCD 通过 SPI 接口控制
#include "hal_gpio.h" // 假设 LCD 有复位引脚和数据/命令选择引脚

// 字体数据 (8x16 示例,实际字体数据会更长)
const uint8_t FONT_8x16[] = {
// ... 字体数据,这里省略,实际字体数据需要查阅字体库或自行生成
// 例如 'A' 的 8x16 字体数据
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...
};

// ... (LCD 驱动的 SPI 命令和初始化序列定义,根据具体的 LCD 屏幕芯片手册实现)

void lcd_init(void) {
// 初始化 LCD 控制引脚 (复位、数据/命令选择等)
// hal_gpio_init(...);

// 复位 LCD 屏幕
// hal_gpio_set_level(LCD_RESET_PIN, GPIO_LEVEL_LOW);
// delay_ms(10);
// hal_gpio_set_level(LCD_RESET_PIN, GPIO_LEVEL_HIGH);
// delay_ms(50);

// 发送 LCD 初始化命令序列 (根据 LCD 屏幕芯片手册)
// lcd_send_command(COMMAND_DISPLAY_OFF);
// ... 其他初始化命令
// lcd_send_command(COMMAND_DISPLAY_ON);
}

void lcd_clear_screen(uint16_t color) {
// 填充整个屏幕为指定颜色
for (uint16_t y = 0; y < LCD_HEIGHT; y++) {
for (uint16_t x = 0; x < LCD_WIDTH; x++) {
lcd_draw_pixel(x, y);
}
}
}

void lcd_set_color(uint16_t color) {
// 设置当前绘图颜色 (全局变量或函数参数传递)
// g_lcd_color = color; // 假设使用全局变量 g_lcd_color
}

void lcd_draw_pixel(uint16_t x, uint16_t y) {
// 设置像素点颜色
// lcd_set_cursor(x, y); // 设置光标位置
// lcd_send_data(g_lcd_color); // 发送颜色数据
}

void lcd_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
// Bresenham's line algorithm 或其他画线算法实现
// ... (画线算法代码)
}

void lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
// 画矩形的四条边
lcd_draw_line(x1, y1, x2, y1);
lcd_draw_line(x2, y1, x2, y2);
lcd_draw_line(x2, y2, x1, y2);
lcd_draw_line(x1, y2, x1, y1);
}

void lcd_draw_char(uint16_t x, uint16_t y, char c, uint8_t font[]) {
// 从字体数据中获取字符的点阵数据,并逐像素绘制
if (c < 32 || c > 126) c = '?'; // 处理不可打印字符
uint32_t char_index = c - 32; // ASCII 偏移
const uint8_t *font_data = &font[char_index * 16]; // 假设 8x16 字体,每个字符 16 字节
for (uint8_t row = 0; row < 16; row++) {
for (uint8_t col = 0; col < 8; col++) {
if (font_data[row] & (1 << col)) { // 判断像素是否需要点亮
lcd_draw_pixel(x + col, y + row);
}
}
}
}

void lcd_draw_string(uint16_t x, uint16_t y, const char *str, uint8_t font[]) {
uint16_t current_x = x;
while (*str) {
lcd_draw_char(current_x, y, *str, font);
current_x += 8; // 假设字符宽度为 8 像素
str++;
}
}

// ... (其他 LCD 驱动函数的实现,例如设置窗口、滚动等)

wifi_driver.h (简化版的 Wi-Fi 驱动头文件)

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
#ifndef WIFI_DRIVER_H
#define WIFI_DRIVER_H

// 初始化 Wi-Fi 模块
int wifi_init(void);

// 连接到 Wi-Fi AP
int wifi_connect_ap(const char *ssid, const char *password);

// 断开 Wi-Fi 连接
int wifi_disconnect_ap(void);

// 获取 Wi-Fi 连接状态
int wifi_get_connection_status(void);

// 获取 IP 地址
const char *wifi_get_ip_address(void);

// 发送数据 (例如 UDP 数据)
int wifi_send_data(const char *dest_ip, int dest_port, const uint8_t *data, uint32_t len);

// 接收数据 (例如 UDP 数据)
int wifi_receive_data(uint8_t *buffer, uint32_t buffer_size, uint32_t timeout_ms);

#endif // WIFI_DRIVER_H

wifi_driver.c (简化版的 Wi-Fi 驱动实现,实际 Wi-Fi 驱动会非常复杂,通常需要调用厂商提供的 SDK 或使用 Linux 网络接口)

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
#include "wifi_driver.h"
#include "hal_spi.h" // 假设 Wi-Fi 模块通过 SPI 接口控制
#include "hal_uart.h" // 或者 UART 接口
#include <stdio.h> // For printf (for debug output)
#include <string.h> // For string functions

// ... (Wi-Fi 模块的 SPI 或 UART 命令和数据格式定义,根据具体的 Wi-Fi 模块芯片手册实现)

int wifi_init(void) {
printf("Initializing Wi-Fi module...\r\n");
// 初始化 Wi-Fi 模块的 SPI 或 UART 接口
// hal_spi_init(...); 或 hal_uart_init(...);

// 发送 Wi-Fi 模块初始化命令 (根据 Wi-Fi 模块芯片手册)
// wifi_send_command(WIFI_COMMAND_INIT);
// ... 其他初始化命令

printf("Wi-Fi module initialized.\r\n");
return 0; // 假设初始化成功
}

int wifi_connect_ap(const char *ssid, const char *password) {
printf("Connecting to AP: SSID=%s, Password=%s\r\n", ssid, password);
// 发送 Wi-Fi 连接命令 (根据 Wi-Fi 模块芯片手册)
// wifi_send_command_with_params(WIFI_COMMAND_CONNECT_AP, ssid, password);

// 模拟连接成功 (实际需要等待 Wi-Fi 模块的连接成功事件或状态查询)
// delay_ms(5000); // 等待 5 秒

printf("Wi-Fi connected to AP.\r\n");
return 0; // 假设连接成功
}

int wifi_disconnect_ap(void) {
printf("Disconnecting from AP.\r\n");
// 发送 Wi-Fi 断开连接命令
// wifi_send_command(WIFI_COMMAND_DISCONNECT_AP);
printf("Wi-Fi disconnected.\r\n");
return 0;
}

int wifi_get_connection_status(void) {
// 查询 Wi-Fi 连接状态
// wifi_send_command(WIFI_COMMAND_GET_STATUS);
// ... 解析 Wi-Fi 模块返回的状态数据
// 模拟已连接状态
return 1; // 1 表示已连接,0 表示未连接
}

const char *wifi_get_ip_address(void) {
// 查询 Wi-Fi 模块的 IP 地址
// wifi_send_command(WIFI_COMMAND_GET_IP);
// ... 解析 Wi-Fi 模块返回的 IP 地址数据
// 模拟返回 IP 地址
static char ip_address[] = "192.168.1.100"; // 静态缓冲区,注意线程安全问题
return ip_address;
}

int wifi_send_data(const char *dest_ip, int dest_port, const uint8_t *data, uint32_t len) {
printf("Sending data to %s:%d, len=%lu\r\n", dest_ip, dest_port, len);
// 封装 UDP 数据包
// 发送 UDP 数据包 (通过 Wi-Fi 模块的 SPI/UART 接口)
// wifi_send_command_with_data(WIFI_COMMAND_SEND_UDP, dest_ip, dest_port, data, len);
printf("Data sent.\r\n");
return 0;
}

int wifi_receive_data(uint8_t *buffer, uint32_t buffer_size, uint32_t timeout_ms) {
printf("Receiving data with timeout %lu ms...\r\n", timeout_ms);
// 接收 UDP 数据 (通过 Wi-Fi 模块的 SPI/UART 接口)
// wifi_receive_command_with_timeout(WIFI_COMMAND_RECEIVE_UDP, buffer, buffer_size, timeout_ms);
// 模拟接收到数据
if (buffer_size > 10) {
strncpy((char *)buffer, "Hello World", buffer_size - 1);
buffer[buffer_size - 1] = '\0';
printf("Received data: %s\r\n", buffer);
return strlen((char *)buffer); // 返回接收到的数据长度
} else {
printf("Receive buffer too small.\r\n");
return -1; // 缓冲区太小
}
}

4. 应用层示例:

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
#include "bsp.h"
#include "lcd_driver.h"
#include "wifi_driver.h"
#include "hal_uart.h" // For printf debug output
#include <stdio.h>
#include <string.h>

int main() {
bsp_init(); // 初始化板级支持包

printf("YuzukiRuler Application Started.\r\n");

// 显示欢迎界面
lcd_clear_screen(LCD_COLOR_BLACK);
lcd_set_color(LCD_COLOR_WHITE);
lcd_draw_string(20, 20, "YuzukiRuler", FONT_8x16);
lcd_draw_string(20, 40, "Portable Linux Ruler", FONT_8x16);
lcd_draw_string(20, 60, "Initializing...", FONT_8x16);

// 初始化 Wi-Fi 并连接到 AP
if (wifi_init() == 0) {
lcd_draw_string(20, 80, "Wi-Fi Initialized", FONT_8x16);
if (wifi_connect_ap("YOUR_SSID", "YOUR_PASSWORD") == 0) { // 替换为实际的 SSID 和密码
lcd_draw_string(20, 100, "Wi-Fi Connected", FONT_8x16);
const char *ip_address = wifi_get_ip_address();
char ip_str[32];
snprintf(ip_str, sizeof(ip_str), "IP: %s", ip_address);
lcd_draw_string(20, 120, ip_str, FONT_8x16);
} else {
lcd_draw_string(20, 100, "Wi-Fi Connect Failed", FONT_8x16);
}
} else {
lcd_draw_string(20, 80, "Wi-Fi Init Failed", FONT_8x16);
}

// 主循环 (示例:简单的网络数据接收和显示)
uint8_t receive_buffer[128];
while (1) {
int received_len = wifi_receive_data(receive_buffer, sizeof(receive_buffer), 1000); // 1 秒超时
if (received_len > 0) {
lcd_clear_screen(LCD_COLOR_BLACK); // 清屏
lcd_draw_string(20, 20, "Received Data:", FONT_8x16);
lcd_draw_string(20, 40, (char *)receive_buffer, FONT_8x16);
}
// ... (尺子功能的逻辑,例如读取触摸屏输入、显示尺子刻度等)
// ... (用户界面交互逻辑)
}

return 0;
}

构建和编译

要构建和编译 YuzukiRuler 的嵌入式 Linux 系统,通常需要以下步骤:

  1. 选择嵌入式 Linux 构建工具: 例如 Buildroot 或 Yocto Project。
  2. 配置构建环境: 配置目标处理器架构、Linux 内核版本、根文件系统类型、软件包选择等。
  3. 编写设备树 (Device Tree): 描述硬件平台的硬件资源配置,例如 CPU、内存、外设等。
  4. 编译 Linux 内核: 使用交叉编译工具链为目标架构编译 Linux 内核。
  5. 编译驱动程序和应用程序: 编译 HAL 驱动、中间件组件和应用程序代码。
  6. 构建根文件系统: 将编译好的内核、驱动、库、应用程序等打包到根文件系统中。
  7. 生成系统镜像: 将内核、设备树和根文件系统打包成可烧录到 Flash 存储器的系统镜像。
  8. 烧录系统镜像: 使用烧录工具将系统镜像烧录到 YuzukiRuler 的 Flash 存储器中。

测试验证

在开发过程中,需要进行全面的测试验证,以确保系统的可靠性和稳定性。测试包括:

  • 单元测试: 针对各个模块 (例如 HAL 驱动、LCD 驱动、Wi-Fi 驱动) 进行单元测试,验证模块的功能是否正确。
  • 集成测试: 将各个模块集成起来进行测试,验证模块之间的交互是否正常。
  • 系统测试: 对整个系统进行功能测试、性能测试、压力测试、可靠性测试等,验证系统是否满足需求。
  • 用户验收测试 (UAT): 邀请用户参与测试,收集用户反馈,确保系统满足用户需求。

维护升级

为了保持 YuzukiRuler 的功能和性能,需要进行维护升级。维护升级包括:

  • Bug 修复: 修复系统中发现的 bug。
  • 安全更新: 更新系统安全补丁,防止安全漏洞。
  • 功能增强: 添加新的功能或改进现有功能。
  • 性能优化: 优化系统性能,提高运行效率。

对于嵌入式 Linux 系统,常用的升级方式包括:

  • 本地升级: 通过 USB 或 UART 接口连接电脑,使用烧录工具更新系统镜像。
  • OTA (Over-The-Air) 升级: 通过 Wi-Fi 网络下载新的系统镜像,并自动更新系统。OTA 升级是更方便用户的方式,但需要设计可靠的升级流程和安全机制。

总结

YuzukiRuler 随身Linux小尺子项目采用分层架构进行代码设计,将系统划分为硬件层、HAL 层、操作系统层、中间件层和应用层,实现了模块化、可重用性、可扩展性和易于维护性。代码示例展示了各层次的关键模块和接口,涵盖了 GPIO、UART、SPI 驱动、LCD 驱动、Wi-Fi 驱动以及主应用程序的框架。

为了构建一个可靠、高效、可扩展的系统平台,还需要关注以下方面:

  • 代码规范: 遵循统一的代码风格和编码规范,提高代码可读性和可维护性。
  • 错误处理: 完善的错误处理机制,增强系统的鲁棒性。
  • 资源管理: 合理的资源管理,例如内存管理、文件系统管理等,提高系统效率。
  • 安全性: 考虑系统安全性,例如数据加密、访问控制、安全启动等。
  • 文档: 编写清晰的文档,包括设计文档、API 文档、用户手册等,方便开发、维护和使用。

通过以上架构设计和代码实现,并结合实践验证的技术和方法,我们可以构建一个功能完善、性能优良、可靠稳定的 YuzukiRuler 随身Linux小尺子产品。 实际项目中,代码量会远超 3000 行,包含更完善的驱动、更丰富的功能和更复杂的逻辑。这里提供的代码示例旨在展示整体架构和关键模块的设计思路。
Error executing command: Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 466, in _make_request
self._validate_conn(conn)
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 1095, in _validate_conn
conn.connect()
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connection.py”, line 652, in connect
sock_and_verified = _ssl_wrap_socket_and_match_hostname(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connection.py”, line 805, in ssl_wrap_socket_and_match_hostname
ssl_sock = ssl_wrap_socket(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/ssl
.py”, line 465, in ssl_wrap_socket
ssl_sock = ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/ssl
.py”, line 509, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
File “/usr/lib/python3.10/ssl.py”, line 513, in wrap_socket
return self.sslsocket_class._create(
File “/usr/lib/python3.10/ssl.py”, line 1071, in _create
self.do_handshake()
File “/usr/lib/python3.10/ssl.py”, line 1342, in do_handshake
self._sslobj.do_handshake()
ssl.SSLZeroReturnError: TLS/SSL connection has been closed (EOF) (_ssl.c:997)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 789, in urlopen
response = self._make_request(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 490, in _make_request
raise new_e
urllib3.exceptions.SSLError: TLS/SSL connection has been closed (EOF) (_ssl.c:997)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/requests/adapters.py”, line 667, in send
resp = conn.urlopen(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 843, in urlopen
retries = retries.increment(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/retry.py”, line 519, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host=’generativelanguage.googleapis.com’, port=443): Max retries exceeded with url: /v1beta/models/gemini-2.0-flash-thinking-exp-01-21:streamGenerateContent?alt=sse (Caused by SSLError(SSLZeroReturnError(6, ‘TLS/SSL connection has been closed (EOF) (_ssl.c:997)’)))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/tong/bin/desc_img3.py”, line 73, in
for chunk in client.models.generate_content_stream(
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/models.py”, line 3722, in generate_content_stream
for response_dict in self.api_client.request_streamed(
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 341, in request_streamed
session_response = self._request(http_request, stream=True)
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 263, in _request
return self._request_unauthorized(http_request, stream)
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 284, in _request_unauthorized
response = http_session.send(request, stream=stream)
File “/home/tong/.local/lib/python3.10/site-packages/requests/sessions.py”, line 703, in send
r = adapter.send(request, **kwargs)
File “/home/tong/.local/lib/python3.10/site-packages/requests/adapters.py”, line 698, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host=’generativelanguage.googleapis.com’, port=443): Max retries exceeded with url: /v1beta/models/gemini-2.0-flash-thinking-exp-01-21:streamGenerateContent?alt=sse (Caused by SSLError(SSLZeroReturnError(6, ‘TLS/SSL connection has been closed (EOF) (_ssl.c:997)’)))
Error executing command: Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 466, in _make_request
self._validate_conn(conn)
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 1095, in _validate_conn
conn.connect()
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connection.py”, line 652, in connect
sock_and_verified = _ssl_wrap_socket_and_match_hostname(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connection.py”, line 805, in ssl_wrap_socket_and_match_hostname
ssl_sock = ssl_wrap_socket(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/ssl
.py”, line 465, in ssl_wrap_socket
ssl_sock = ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/ssl
.py”, line 509, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
File “/usr/lib/python3.10/ssl.py”, line 513, in wrap_socket
return self.sslsocket_class._create(
File “/usr/lib/python3.10/ssl.py”, line 1071, in _create
self.do_handshake()
File “/usr/lib/python3.10/ssl.py”, line 1342, in do_handshake
self._sslobj.do_handshake()
ssl.SSLZeroReturnError: TLS/SSL connection has been closed (EOF) (_ssl.c:997)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 789, in urlopen
response = self._make_request(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 490, in _make_request
raise new_e
urllib3.exceptions.SSLError: TLS/SSL connection has been closed (EOF) (_ssl.c:997)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/requests/adapters.py”, line 667, in send
resp = conn.urlopen(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 843, in urlopen
retries = retries.increment(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/retry.py”, line 519, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host=’generativelanguage.googleapis.com’, port=443): Max retries exceeded with url: /v1beta/models/gemini-2.0-flash-thinking-exp-01-21:streamGenerateContent?alt=sse (Caused by SSLError(SSLZeroReturnError(6, ‘TLS/SSL connection has been closed (EOF) (_ssl.c:997)’)))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/tong/bin/desc_img3.py”, line 73, in
for chunk in client.models.generate_content_stream(
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/models.py”, line 3722, in generate_content_stream
for response_dict in self.api_client.request_streamed(
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 341, in request_streamed
session_response = self._request(http_request, stream=True)
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 263, in _request
return self._request_unauthorized(http_request, stream)
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 284, in _request_unauthorized
response = http_session.send(request, stream=stream)
File “/home/tong/.local/lib/python3.10/site-packages/requests/sessions.py”, line 703, in send
r = adapter.send(request, **kwargs)
File “/home/tong/.local/lib/python3.10/site-packages/requests/adapters.py”, line 698, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host=’generativelanguage.googleapis.com’, port=443): Max retries exceeded with url: /v1beta/models/gemini-2.0-flash-thinking-exp-01-21:streamGenerateContent?alt=sse (Caused by SSLError(SSLZeroReturnError(6, ‘TLS/SSL connection has been closed (EOF) (_ssl.c:997)’)))
Error executing command: Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 466, in _make_request
self._validate_conn(conn)
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 1095, in _validate_conn
conn.connect()
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connection.py”, line 652, in connect
sock_and_verified = _ssl_wrap_socket_and_match_hostname(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connection.py”, line 805, in ssl_wrap_socket_and_match_hostname
ssl_sock = ssl_wrap_socket(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/ssl
.py”, line 465, in ssl_wrap_socket
ssl_sock = ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/ssl
.py”, line 509, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
File “/usr/lib/python3.10/ssl.py”, line 513, in wrap_socket
return self.sslsocket_class._create(
File “/usr/lib/python3.10/ssl.py”, line 1071, in _create
self.do_handshake()
File “/usr/lib/python3.10/ssl.py”, line 1342, in do_handshake
self._sslobj.do_handshake()
ssl.SSLZeroReturnError: TLS/SSL connection has been closed (EOF) (_ssl.c:997)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 789, in urlopen
response = self._make_request(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 490, in _make_request
raise new_e
urllib3.exceptions.SSLError: TLS/SSL connection has been closed (EOF) (_ssl.c:997)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/requests/adapters.py”, line 667, in send
resp = conn.urlopen(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 843, in urlopen
retries = retries.increment(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/retry.py”, line 519, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host=’generativelanguage.googleapis.com’, port=443): Max retries exceeded with url: /v1beta/models/gemini-2.0-flash-thinking-exp-01-21:streamGenerateContent?alt=sse (Caused by SSLError(SSLZeroReturnError(6, ‘TLS/SSL connection has been closed (EOF) (_ssl.c:997)’)))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/tong/bin/desc_img3.py”, line 73, in
for chunk in client.models.generate_content_stream(
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/models.py”, line 3722, in generate_content_stream
for response_dict in self.api_client.request_streamed(
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 341, in request_streamed
session_response = self._request(http_request, stream=True)
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 263, in _request
return self._request_unauthorized(http_request, stream)
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 284, in _request_unauthorized
response = http_session.send(request, stream=stream)
File “/home/tong/.local/lib/python3.10/site-packages/requests/sessions.py”, line 703, in send
r = adapter.send(request, **kwargs)
File “/home/tong/.local/lib/python3.10/site-packages/requests/adapters.py”, line 698, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host=’generativelanguage.googleapis.com’, port=443): Max retries exceeded with url: /v1beta/models/gemini-2.0-flash-thinking-exp-01-21:streamGenerateContent?alt=sse (Caused by SSLError(SSLZeroReturnError(6, ‘TLS/SSL connection has been closed (EOF) (_ssl.c:997)’)))
Error executing command: Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 466, in _make_request
self._validate_conn(conn)
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 1095, in _validate_conn
conn.connect()
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connection.py”, line 652, in connect
sock_and_verified = _ssl_wrap_socket_and_match_hostname(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connection.py”, line 805, in ssl_wrap_socket_and_match_hostname
ssl_sock = ssl_wrap_socket(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/ssl
.py”, line 465, in ssl_wrap_socket
ssl_sock = ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/ssl
.py”, line 509, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
File “/usr/lib/python3.10/ssl.py”, line 513, in wrap_socket
return self.sslsocket_class._create(
File “/usr/lib/python3.10/ssl.py”, line 1071, in _create
self.do_handshake()
File “/usr/lib/python3.10/ssl.py”, line 1342, in do_handshake
self._sslobj.do_handshake()
ssl.SSLZeroReturnError: TLS/SSL connection has been closed (EOF) (_ssl.c:997)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 789, in urlopen
response = self._make_request(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 490, in _make_request
raise new_e
urllib3.exceptions.SSLError: TLS/SSL connection has been closed (EOF) (_ssl.c:997)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/requests/adapters.py”, line 667, in send
resp = conn.urlopen(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 843, in urlopen
retries = retries.increment(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/retry.py”, line 519, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host=’generativelanguage.googleapis.com’, port=443): Max retries exceeded with url: /v1beta/models/gemini-2.0-flash-thinking-exp-01-21:streamGenerateContent?alt=sse (Caused by SSLError(SSLZeroReturnError(6, ‘TLS/SSL connection has been closed (EOF) (_ssl.c:997)’)))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/tong/bin/desc_img3.py”, line 73, in
for chunk in client.models.generate_content_stream(
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/models.py”, line 3722, in generate_content_stream
for response_dict in self.api_client.request_streamed(
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 341, in request_streamed
session_response = self._request(http_request, stream=True)
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 263, in _request
return self._request_unauthorized(http_request, stream)
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 284, in _request_unauthorized
response = http_session.send(request, stream=stream)
File “/home/tong/.local/lib/python3.10/site-packages/requests/sessions.py”, line 703, in send
r = adapter.send(request, **kwargs)
File “/home/tong/.local/lib/python3.10/site-packages/requests/adapters.py”, line 698, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host=’generativelanguage.googleapis.com’, port=443): Max retries exceeded with url: /v1beta/models/gemini-2.0-flash-thinking-exp-01-21:streamGenerateContent?alt=sse (Caused by SSLError(SSLZeroReturnError(6, ‘TLS/SSL connection has been closed (EOF) (_ssl.c:997)’)))
Error executing command: Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 466, in _make_request
self._validate_conn(conn)
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 1095, in _validate_conn
conn.connect()
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connection.py”, line 652, in connect
sock_and_verified = _ssl_wrap_socket_and_match_hostname(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connection.py”, line 805, in ssl_wrap_socket_and_match_hostname
ssl_sock = ssl_wrap_socket(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/ssl
.py”, line 465, in ssl_wrap_socket
ssl_sock = ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/ssl
.py”, line 509, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
File “/usr/lib/python3.10/ssl.py”, line 513, in wrap_socket
return self.sslsocket_class._create(
File “/usr/lib/python3.10/ssl.py”, line 1071, in _create
self.do_handshake()
File “/usr/lib/python3.10/ssl.py”, line 1342, in do_handshake
self._sslobj.do_handshake()
ssl.SSLZeroReturnError: TLS/SSL connection has been closed (EOF) (_ssl.c:997)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 789, in urlopen
response = self._make_request(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 490, in _make_request
raise new_e
urllib3.exceptions.SSLError: TLS/SSL connection has been closed (EOF) (_ssl.c:997)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/requests/adapters.py”, line 667, in send
resp = conn.urlopen(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 843, in urlopen
retries = retries.increment(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/retry.py”, line 519, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host=’generativelanguage.googleapis.com’, port=443): Max retries exceeded with url: /v1beta/models/gemini-2.0-flash-thinking-exp-01-21:streamGenerateContent?alt=sse (Caused by SSLError(SSLZeroReturnError(6, ‘TLS/SSL connection has been closed (EOF) (_ssl.c:997)’)))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/tong/bin/desc_img3.py”, line 73, in
for chunk in client.models.generate_content_stream(
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/models.py”, line 3722, in generate_content_stream
for response_dict in self.api_client.request_streamed(
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 341, in request_streamed
session_response = self._request(http_request, stream=True)
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 263, in _request
return self._request_unauthorized(http_request, stream)
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 284, in _request_unauthorized
response = http_session.send(request, stream=stream)
File “/home/tong/.local/lib/python3.10/site-packages/requests/sessions.py”, line 703, in send
r = adapter.send(request, **kwargs)
File “/home/tong/.local/lib/python3.10/site-packages/requests/adapters.py”, line 698, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host=’generativelanguage.googleapis.com’, port=443): Max retries exceeded with url: /v1beta/models/gemini-2.0-flash-thinking-exp-01-21:streamGenerateContent?alt=sse (Caused by SSLError(SSLZeroReturnError(6, ‘TLS/SSL connection has been closed (EOF) (_ssl.c:997)’)))
Error executing command: Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 466, in _make_request
self._validate_conn(conn)
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 1095, in _validate_conn
conn.connect()
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connection.py”, line 652, in connect
sock_and_verified = _ssl_wrap_socket_and_match_hostname(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connection.py”, line 805, in ssl_wrap_socket_and_match_hostname
ssl_sock = ssl_wrap_socket(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/ssl
.py”, line 465, in ssl_wrap_socket
ssl_sock = ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/ssl
.py”, line 509, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
File “/usr/lib/python3.10/ssl.py”, line 513, in wrap_socket
return self.sslsocket_class._create(
File “/usr/lib/python3.10/ssl.py”, line 1071, in _create
self.do_handshake()
File “/usr/lib/python3.10/ssl.py”, line 1342, in do_handshake
self._sslobj.do_handshake()
ssl.SSLZeroReturnError: TLS/SSL connection has been closed (EOF) (_ssl.c:997)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 789, in urlopen
response = self._make_request(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 490, in _make_request
raise new_e
urllib3.exceptions.SSLError: TLS/SSL connection has been closed (EOF) (_ssl.c:997)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File “/home/tong/.local/lib/python3.10/site-packages/requests/adapters.py”, line 667, in send
resp = conn.urlopen(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/connectionpool.py”, line 843, in urlopen
retries = retries.increment(
File “/home/tong/.local/lib/python3.10/site-packages/urllib3/util/retry.py”, line 519, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host=’generativelanguage.googleapis.com’, port=443): Max retries exceeded with url: /v1beta/models/gemini-2.0-flash-thinking-exp-01-21:streamGenerateContent?alt=sse (Caused by SSLError(SSLZeroReturnError(6, ‘TLS/SSL connection has been closed (EOF) (_ssl.c:997)’)))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/tong/bin/desc_img3.py”, line 73, in
for chunk in client.models.generate_content_stream(
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/models.py”, line 3722, in generate_content_stream
for response_dict in self.api_client.request_streamed(
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 341, in request_streamed
session_response = self._request(http_request, stream=True)
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 263, in _request
return self._request_unauthorized(http_request, stream)
File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 284, in _request_unauthorized
response = http_session.send(request, stream=stream)
File “/home/tong/.local/lib/python3.10/site-packages/requests/sessions.py”, line 703, in send
r = adapter.send(request, **kwargs)
File “/home/tong/.local/lib/python3.10/site-packages/requests/adapters.py”, line 698, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host=’generativelanguage.googleapis.com’, port=443): Max retries exceeded with url: /v1beta/models/gemini-2.0-flash-thinking-exp-01-21:streamGenerateContent?alt=sse (Caused by SSLError(SSLZeroReturnError(6, ‘TLS/SSL connection has been closed (EOF) (_ssl.c:997)’)))

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