编程技术分享

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

0%

简介:基于GL3224芯片,独立写保护开关,连续拷卡70G文件不掉速。

我将深入分析这个基于GL3224芯片的USB 3.0卡读器项目,并详细阐述最适合的代码设计架构,并提供相应的C代码示例。我将尽可能详细地展开,并涵盖嵌入式系统开发的各个方面。
关注微信公众号,提前获取相关推文

项目概述

本项目旨在开发一个高性能、高可靠性的USB 3.0卡读卡器,核心芯片选用创惟科技(Genesys Logic)的GL3224。该芯片是一款高性能的USB 3.0读卡器控制器,支持多种存储卡协议,如SD、microSD等。项目亮点包括:

  • GL3224方案: 采用高性能的GL3224芯片,确保USB 3.0高速传输性能。
  • 线头分离设计: 可能指的是PCB设计上USB接口部分与主控芯片部分分离,有利于信号完整性和散热。
  • 独立写保护开关: 硬件级别的写保护开关,增强数据安全性和可靠性。
  • 连续拷卡70G文件不掉速: 强调了系统在高负载下的稳定性和持续传输性能,这需要优秀的软件架构和硬件协同。

嵌入式系统开发流程

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

  1. 需求分析:

    • 功能需求: USB 3.0高速数据传输、支持多种SD卡协议、硬件写保护、指示灯状态显示、低功耗设计、兼容性要求(操作系统、设备)。
    • 性能需求: 持续读写速度、响应时间、数据传输稳定性、低延迟。
    • 可靠性需求: 长时间稳定运行、抗干扰能力、错误处理机制、数据完整性。
    • 安全需求: 数据防篡改、写保护机制。
    • 可维护性需求: 代码可读性、模块化设计、易于调试和升级。
    • 环境需求: 工作温度范围、湿度范围、电磁兼容性(EMC)。
    • 成本需求: 物料成本、开发成本、生产成本。
  2. 系统设计:

    • 硬件设计:
      • 芯片选型: GL3224作为主控芯片。
      • 外围电路设计: USB 3.0接口电路、SD卡接口电路、电源管理电路、时钟电路、指示灯电路、写保护开关电路。
      • PCB设计: 高速信号线布线、电源完整性、信号完整性、散热设计。
      • BOM清单: 详细的物料清单。
    • 软件设计:
      • 系统架构设计: 选择合适的软件架构,例如分层架构、模块化架构、事件驱动架构等。
      • 驱动程序设计: GL3224 USB控制器驱动、SD卡控制器驱动、GPIO驱动(指示灯、写保护开关)。
      • 固件逻辑设计: USB协议栈实现、SD卡协议栈实现、数据传输控制、错误处理、状态管理、写保护逻辑。
      • 文件系统接口: 提供文件系统访问接口,方便上层应用使用。
      • 升级方案设计: 固件升级机制(USB DFU、OTA等)。
      • 资源管理: 内存管理、中断管理、定时器管理。
  3. 软件实现:

    • 代码编写: 使用C语言编写驱动程序和固件逻辑代码,遵循编码规范,保证代码质量和可读性。
    • 代码模块化: 将系统分解为独立的模块,提高代码的复用性和可维护性。
    • 代码优化: 针对嵌入式系统的资源限制,进行代码优化,提高效率和性能。
    • 版本控制: 使用Git等版本控制工具管理代码,方便团队协作和版本回溯。
  4. 测试验证:

    • 单元测试: 对每个模块进行独立测试,验证其功能和性能。
    • 集成测试: 将各个模块集成在一起进行测试,验证模块之间的协同工作。
    • 系统测试: 对整个系统进行全面测试,包括功能测试、性能测试、可靠性测试、兼容性测试、压力测试等。
    • 硬件在环测试 (HIL): 使用硬件仿真器或实际硬件进行测试,更接近真实运行环境。
    • 边界测试: 测试系统在极端条件下的表现,例如高温、低温、高湿度、低电压等。
    • 用户场景测试: 模拟用户实际使用场景进行测试,验证用户体验。
  5. 维护升级:

    • 缺陷修复: 根据测试结果和用户反馈,修复软件缺陷。
    • 功能升级: 根据需求变化,添加新的功能或优化现有功能。
    • 性能优化: 持续优化系统性能,提高效率和响应速度。
    • 安全更新: 及时更新安全补丁,防止安全漏洞。
    • 版本管理: 维护软件版本,记录更新日志,方便用户了解和升级。

最适合的代码设计架构:分层模块化事件驱动架构

考虑到嵌入式系统的复杂性和资源限制,以及本项目对高性能、高可靠性和可扩展性的要求,我推荐采用 分层模块化事件驱动架构。 这种架构具有以下优点:

  • 分层架构: 将系统划分为不同的层次,每一层负责特定的功能,层与层之间通过清晰的接口进行通信。这降低了系统的复杂性,提高了代码的可读性和可维护性。
  • 模块化设计: 将每一层进一步划分为独立的模块,每个模块负责特定的子功能。模块之间松耦合,易于复用、替换和扩展。
  • 事件驱动架构: 系统以事件为中心进行驱动,各个模块通过事件进行异步通信。这提高了系统的响应速度和并发处理能力,尤其适合处理USB和SD卡等外部设备的异步事件。

架构分层

根据项目需求和GL3224芯片的特性,我们可以将软件架构划分为以下层次:

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

    • 封装底层硬件操作,提供统一的硬件访问接口,使上层软件与具体硬件平台解耦。
    • 主要包括:GPIO控制、时钟配置、中断管理、DMA配置、电源管理等。
    • 示例模块:hal_gpio.c, hal_clock.c, hal_irq.c, hal_dma.c, hal_power.c
  2. 设备驱动层 (Device Driver Layer):

    • 负责驱动具体的硬件设备,例如GL3224 USB控制器、SD卡控制器、GPIO等。
    • 提供设备操作的API,供上层软件调用。
    • 示例模块:usb_driver.c (GL3224 USB驱动), sd_card_driver.c (SD卡驱动), gpio_driver.c (GPIO驱动)
  3. 中间件层 (Middleware Layer):

    • 提供通用的系统服务和功能模块,例如USB协议栈、SD卡协议栈、文件系统接口、错误处理、状态管理等。
    • 降低上层应用的开发难度,提高代码的复用性。
    • 示例模块:usb_stack.c (USB协议栈), sd_card_stack.c (SD卡协议栈), file_system_interface.c (文件系统接口), error_handler.c (错误处理), state_manager.c (状态管理)
  4. 应用层 (Application Layer):

    • 实现具体的应用逻辑,例如数据传输控制、用户界面(如果需要)、系统配置等。
    • 调用中间件层提供的接口,完成特定的应用功能。
    • 示例模块:data_transfer_manager.c (数据传输管理), user_interface.c (用户界面 - 如果有), system_config.c (系统配置)

模块化设计

在每一层内部,我们进一步进行模块化设计。例如,在设备驱动层,usb_driver.c 可以进一步划分为:

  • usb_core.c: USB核心驱动,处理USB枚举、配置、端点管理等。
  • usb_bulk.c: USB Bulk传输驱动,用于高速数据传输。
  • usb_interrupt.c: USB中断传输驱动,用于控制传输和状态报告。

在中间件层,sd_card_stack.c 可以划分为:

  • sd_card_protocol.c: SD卡协议实现,处理SD卡命令、数据传输、错误检测。
  • sd_card_command.c: SD卡命令封装和发送。
  • sd_card_data.c: SD卡数据读写操作。

事件驱动机制

系统采用事件驱动机制,例如:

  • USB事件: USB设备连接事件、USB数据接收事件、USB数据发送完成事件、USB设备断开事件。
  • SD卡事件: SD卡插入事件、SD卡拔出事件、SD卡数据准备好事件、SD卡错误事件。
  • GPIO事件: 写保护开关状态变化事件。

当事件发生时,系统会触发相应的事件处理函数,进行相应的处理。事件驱动机制可以提高系统的响应速度,并降低CPU的空闲等待时间。

C 代码实现示例 (框架代码)

为了演示上述架构,我将提供一些关键模块的C代码示例。以下代码主要展示架构思路和关键功能,并非可以直接编译运行的完整代码。

1. config.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
#ifndef CONFIG_H
#define CONFIG_H

// 硬件相关配置
#define USB_CONTROLLER_BASE_ADDR (0x12340000) // GL3224 USB控制器基地址
#define SD_CARD_CONTROLLER_BASE_ADDR (0x56780000) // SD卡控制器基地址
#define GPIO_BASE_ADDR (0x9ABC0000) // GPIO 基地址

#define LED_GREEN_GPIO_PIN (0) // 绿灯 GPIO 引脚
#define WRITE_PROTECT_GPIO_PIN (1) // 写保护开关 GPIO 引脚

// 系统时钟频率 (Hz)
#define SYSTEM_CLOCK_FREQUENCY (120000000) // 120MHz

// USB 相关配置
#define USB_BULK_ENDPOINT_IN (1) // Bulk IN 端点地址
#define USB_BULK_ENDPOINT_OUT (2) // Bulk OUT 端点地址
#define USB_MAX_PACKET_SIZE (512) // USB 最大包大小

// SD 卡相关配置
#define SD_CARD_CLOCK_FREQUENCY (50000000) // SD卡时钟频率 50MHz

// ... 其他配置 ...

#endif // CONFIG_H

2. hal_gpio.hhal_gpio.c - HAL GPIO 模块

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

#include <stdint.h>
#include <stdbool.h>

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(uint32_t pin, gpio_mode_t mode);

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

// 读取 GPIO 引脚输入电平
gpio_level_t hal_gpio_get_level(uint32_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
#include "hal_gpio.h"
#include "config.h"

// 假设 GPIO 寄存器定义 (实际需查阅 GL3224 芯片手册)
typedef struct {
volatile uint32_t MODER; // 模式寄存器
volatile uint32_t OTYPER; // 输出类型寄存器
volatile uint32_t OSPEEDR; // 输出速度寄存器
volatile uint32_t PUPDR; // 上下拉电阻寄存器
volatile uint32_t IDR; // 输入数据寄存器
volatile uint32_t ODR; // 输出数据寄存器
// ... 其他寄存器 ...
} gpio_reg_t;

static gpio_reg_t *gpio_regs = (gpio_reg_t *)GPIO_BASE_ADDR; // GPIO 寄存器基地址

void hal_gpio_init(uint32_t pin, gpio_mode_t mode) {
// 根据 pin 和 mode 初始化 GPIO 寄存器
// (具体实现需要参考 GL3224 芯片手册)
if (mode == GPIO_MODE_OUTPUT) {
// 配置为输出模式
// ...
} else {
// 配置为输入模式
// ...
}
}

void hal_gpio_set_level(uint32_t pin, gpio_level_t level) {
// 设置 GPIO 输出电平
if (level == GPIO_LEVEL_HIGH) {
// 设置高电平
// ...
} else {
// 设置低电平
// ...
}
}

gpio_level_t hal_gpio_get_level(uint32_t pin) {
// 读取 GPIO 输入电平
// ...
return GPIO_LEVEL_LOW; // 示例,实际需要读取寄存器值
}

3. gpio_driver.hgpio_driver.c - GPIO 驱动模块

gpio_driver.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef GPIO_DRIVER_H
#define GPIO_DRIVER_H

#include <stdbool.h>

// 初始化 LED 指示灯
void gpio_led_init(void);

// 控制 LED 指示灯状态
void gpio_led_set_state(bool on);

// 初始化写保护开关
void gpio_write_protect_init(void);

// 获取写保护开关状态
bool gpio_write_protect_get_state(void);

#endif // GPIO_DRIVER_H

gpio_driver.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 "gpio_driver.h"
#include "hal_gpio.h"
#include "config.h"

void gpio_led_init(void) {
hal_gpio_init(LED_GREEN_GPIO_PIN, GPIO_MODE_OUTPUT);
gpio_led_set_state(false); // 默认关闭 LED
}

void gpio_led_set_state(bool on) {
if (on) {
hal_gpio_set_level(LED_GREEN_GPIO_PIN, GPIO_LEVEL_HIGH); // 点亮 LED
} else {
hal_gpio_set_level(LED_GREEN_GPIO_PIN, GPIO_LEVEL_LOW); // 关闭 LED
}
}

void gpio_write_protect_init(void) {
hal_gpio_init(WRITE_PROTECT_GPIO_PIN, GPIO_MODE_INPUT);
}

bool gpio_write_protect_get_state(void) {
gpio_level_t level = hal_gpio_get_level(WRITE_PROTECT_GPIO_PIN);
// 假设开关按下为低电平,表示写保护启用
return (level == GPIO_LEVEL_LOW);
}

4. usb_driver.husb_driver.c - USB 驱动模块 (框架)

usb_driver.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef USB_DRIVER_H
#define USB_DRIVER_H

#include <stdint.h>
#include <stdbool.h>

// USB 初始化
bool usb_init(void);

// USB 事件处理函数类型
typedef void (*usb_event_handler_t)(uint32_t event);

// 注册 USB 事件处理函数
void usb_register_event_handler(usb_event_handler_t handler);

// USB Bulk 数据发送
bool usb_bulk_transmit(uint8_t *data, uint32_t length);

// USB Bulk 数据接收 (非阻塞)
bool usb_bulk_receive(uint8_t *buffer, uint32_t buffer_size, uint32_t *received_length);

#endif // USB_DRIVER_H

usb_driver.c (框架 - 实际实现非常复杂,需要深入理解USB协议和GL3224芯片手册)

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
#include "usb_driver.h"
#include "config.h"
#include "hal_usb.h" // 假设的 HAL USB 模块

static usb_event_handler_t usb_event_handler = NULL;

bool usb_init(void) {
// 初始化 GL3224 USB 控制器硬件
// 配置 USB PHY, 时钟, 中断等
// (具体实现参考 GL3224 芯片手册)
hal_usb_init(); // 假设的 HAL USB 初始化函数

// 配置 USB 设备描述符, 配置描述符, 字符串描述符等
// ...

// 使能 USB 中断
hal_usb_enable_interrupt();

return true;
}

void usb_register_event_handler(usb_event_handler_t handler) {
usb_event_handler = handler;
}

bool usb_bulk_transmit(uint8_t *data, uint32_t length) {
// 将数据通过 USB Bulk IN 端点发送
// 需要处理数据分包, DMA传输等
// (具体实现参考 GL3224 芯片手册和 USB Bulk 传输协议)
hal_usb_bulk_send_data(USB_BULK_ENDPOINT_IN, data, length); // 假设的 HAL USB Bulk 发送函数
return true;
}

bool usb_bulk_receive(uint8_t *buffer, uint32_t buffer_size, uint32_t *received_length) {
// 从 USB Bulk OUT 端点接收数据 (非阻塞)
// 需要检查是否有数据到达, 读取数据并返回实际接收长度
// (具体实现参考 GL3224 芯片手册和 USB Bulk 传输协议)
return hal_usb_bulk_receive_data(USB_BULK_ENDPOINT_OUT, buffer, buffer_size, received_length); // 假设的 HAL USB Bulk 接收函数
}

// USB 中断处理函数 (假设)
void usb_interrupt_handler(void) {
uint32_t event = hal_usb_get_event(); // 获取 USB 事件 (假设的 HAL 函数)

if (usb_event_handler != NULL) {
usb_event_handler(event); // 调用注册的事件处理函数
}

// 清除中断标志
hal_usb_clear_interrupt();
}

5. sd_card_driver.hsd_card_driver.c - SD卡驱动模块 (框架)

sd_card_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
#ifndef SD_CARD_DRIVER_H
#define SD_CARD_DRIVER_H

#include <stdint.h>
#include <stdbool.h>

// SD 卡初始化
bool sd_card_init(void);

// 读取 SD 卡扇区
bool sd_card_read_sector(uint32_t sector_address, uint8_t *buffer, uint32_t sector_count);

// 写入 SD 卡扇区
bool sd_card_write_sector(uint32_t sector_address, const uint8_t *buffer, uint32_t sector_count);

// 获取 SD 卡容量 (扇区数)
uint64_t sd_card_get_capacity(void);

// 检测 SD 卡是否插入
bool sd_card_is_inserted(void);

// 注册 SD 卡事件处理函数
typedef void (*sd_card_event_handler_t)(uint32_t event);
void sd_card_register_event_handler(sd_card_event_handler_t handler);

#endif // SD_CARD_DRIVER_H

sd_card_driver.c (框架 - 实际实现取决于 SD卡接口类型 SPI/SDIO,以及SD卡协议)

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
#include "sd_card_driver.h"
#include "config.h"
#include "hal_sd_card.h" // 假设的 HAL SD卡模块
#include "gpio_driver.h" // 使用 GPIO 驱动获取写保护状态

static sd_card_event_handler_t sd_card_event_handler = NULL;

bool sd_card_init(void) {
// 初始化 SD 卡控制器硬件
// 配置 SD 卡时钟, 总线宽度, 电压等
// (具体实现参考 GL3224 芯片手册和 SD卡协议)
hal_sd_card_init(); // 假设的 HAL SD卡初始化函数

// SD 卡初始化序列 (CMD0, CMD8, ACMD41, CMD17 等)
// ...

return true;
}

bool sd_card_read_sector(uint32_t sector_address, uint8_t *buffer, uint32_t sector_count) {
// 读取 SD 卡扇区数据
// 需要发送 SD 卡读取命令, 接收数据
// (具体实现参考 SD卡协议)
return hal_sd_card_read_sectors(sector_address, buffer, sector_count); // 假设的 HAL SD卡扇区读取函数
}

bool sd_card_write_sector(uint32_t sector_address, const uint8_t *buffer, uint32_t sector_count) {
// 写入 SD 卡扇区数据
// 需要先检查写保护状态
if (gpio_write_protect_get_state()) {
// 写保护已启用,禁止写入
return false;
}

// 发送 SD 卡写入命令, 发送数据
// (具体实现参考 SD卡协议)
return hal_sd_card_write_sectors(sector_address, buffer, sector_count); // 假设的 HAL SD卡扇区写入函数
}

uint64_t sd_card_get_capacity(void) {
// 获取 SD 卡容量 (扇区数)
// 需要发送 SD 卡容量查询命令 (CMD9 或 CMD10)
// (具体实现参考 SD卡协议)
return hal_sd_card_get_capacity_sectors(); // 假设的 HAL SD卡获取容量函数
}

bool sd_card_is_inserted(void) {
// 检测 SD 卡是否插入 (可能通过 GPIO 检测)
// ...
return true; // 假设 SD 卡已插入
}

void sd_card_register_event_handler(sd_card_event_handler_t handler) {
sd_card_event_handler = handler;
}

// SD 卡事件处理函数 (假设,例如卡插入/拔出事件)
void sd_card_event_handler_func(uint32_t event) {
if (sd_card_event_handler != NULL) {
sd_card_event_handler(event);
}
}

6. data_transfer_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
#include "data_transfer_manager.h"
#include "usb_driver.h"
#include "sd_card_driver.h"
#include "gpio_driver.h"
#include <stdio.h> // 用于示例 printf

#define TRANSFER_BUFFER_SIZE (4 * 1024) // 4KB 传输缓冲区

static uint8_t transfer_buffer[TRANSFER_BUFFER_SIZE];

// 数据传输任务 (示例 - 从 SD 卡读取数据并通过 USB 发送)
void data_transfer_task(void) {
uint32_t sector_address = 0;
uint32_t sectors_per_transfer = TRANSFER_BUFFER_SIZE / 512; // 每次传输的扇区数 (假设扇区大小 512 bytes)
uint32_t received_length;

printf("Data Transfer Task Started...\n");

while (1) {
// 1. 从 SD 卡读取数据
if (sd_card_read_sector(sector_address, transfer_buffer, sectors_per_transfer)) {
// 2. 通过 USB 发送数据
if (usb_bulk_transmit(transfer_buffer, TRANSFER_BUFFER_SIZE)) {
sector_address += sectors_per_transfer; // 更新扇区地址
// 可以添加传输进度显示,错误处理等
printf("Transferred %u sectors, current sector: %u\n", sectors_per_transfer, sector_address);
} else {
printf("USB Bulk Transmit Error!\n");
// 错误处理逻辑
break;
}
} else {
printf("SD Card Read Error!\n");
// 错误处理逻辑
break;
}

// 可以添加延时,或者根据实际需求调整传输速率
// ...
}

printf("Data Transfer Task Finished.\n");
}

// USB 事件处理函数 (示例)
void usb_event_handler_func(uint32_t event) {
switch (event) {
case USB_EVENT_CONNECTED:
printf("USB Device Connected!\n");
gpio_led_set_state(true); // 连接成功,点亮 LED
// 启动数据传输任务
data_transfer_task();
break;
case USB_EVENT_DISCONNECTED:
printf("USB Device Disconnected!\n");
gpio_led_set_state(false); // 断开连接,关闭 LED
// 停止数据传输任务 (如果正在进行)
break;
// ... 其他 USB 事件处理 ...
default:
break;
}
}

// SD 卡事件处理函数 (示例)
void sd_card_event_handler_func(uint32_t event) {
switch (event) {
case SD_CARD_EVENT_INSERTED:
printf("SD Card Inserted!\n");
// SD 卡插入处理
break;
case SD_CARD_EVENT_REMOVED:
printf("SD Card Removed!\n");
// SD 卡拔出处理
break;
// ... 其他 SD 卡事件处理 ...
default:
break;
}
}


void data_transfer_manager_init(void) {
// 注册 USB 事件处理函数
usb_register_event_handler(usb_event_handler_func);
// 注册 SD 卡事件处理函数
sd_card_register_event_handler(sd_card_event_handler_func);
}

7. 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
#include "config.h"
#include "hal_clock.h"
#include "hal_irq.h"
#include "gpio_driver.h"
#include "usb_driver.h"
#include "sd_card_driver.h"
#include "data_transfer_manager.h"

int main() {
// 1. 初始化系统时钟
hal_clock_init(SYSTEM_CLOCK_FREQUENCY);

// 2. 初始化中断控制器
hal_irq_init();

// 3. 初始化 GPIO 驱动
gpio_led_init();
gpio_write_protect_init();

// 4. 初始化 USB 驱动
if (!usb_init()) {
// USB 初始化失败处理
while(1); // 死循环
}

// 5. 初始化 SD 卡驱动
if (!sd_card_init()) {
// SD 卡初始化失败处理
while(1); // 死循环
}

// 6. 初始化数据传输管理器
data_transfer_manager_init();

// 7. 使能全局中断
hal_irq_enable_global();

printf("System Initialized. Waiting for USB connection...\n");

// 8. 主循环 (事件驱动,无需主动轮询)
while (1) {
// 系统进入低功耗模式,等待事件发生
// ...
}

return 0;
}

关键技术和方法

  • DMA (Direct Memory Access): 为了实现连续拷卡70G文件不掉速,必须采用DMA技术。DMA允许外设(如USB控制器、SD卡控制器)直接访问系统内存,无需CPU的参与,大大提高了数据传输效率,降低了CPU负载。在usb_driver.csd_card_driver.c中,数据传输函数需要使用HAL层提供的DMA接口进行数据传输。
  • 中断处理: 采用中断驱动方式处理USB和SD卡事件,提高系统响应速度。例如,USB数据接收完成、SD卡数据准备好等事件都应该通过中断来通知CPU进行处理。
  • 多缓冲技术: 为了提高数据传输效率和避免数据丢失,可以使用多缓冲技术。例如,在USB Bulk传输中,可以使用双缓冲或多缓冲,在发送数据的同时,可以准备下一个要发送的数据。
  • 错误处理机制: 完善的错误处理机制对于保证系统可靠性至关重要。需要处理USB传输错误、SD卡读写错误、硬件错误等,并进行相应的错误恢复或上报。
  • 状态管理: 使用状态机管理系统状态,例如USB连接状态、SD卡状态、数据传输状态等。状态机可以帮助理清系统逻辑,提高代码的可维护性。
  • 代码优化: 针对嵌入式系统的资源限制,需要进行代码优化,例如减少内存占用、提高代码执行效率、优化中断处理流程等。可以采用编译优化、算法优化、汇编代码优化等方法。
  • 硬件写保护开关支持: 在SD卡驱动层,需要读取GPIO引脚的状态,判断写保护开关是否启用。如果启用,则禁止SD卡写入操作。
  • 性能测试和压力测试: 为了验证系统在高负载下的稳定性和持续传输性能,需要进行严格的性能测试和压力测试。例如,使用专业的USB测试工具和SD卡性能测试软件,模拟连续拷卡70G文件的场景,测试系统的传输速度、稳定性、温度等指标。

总结

以上代码示例和架构设计方案提供了一个基于GL3224芯片的USB 3.0卡读器嵌入式系统开发的框架。实际开发过程中,需要根据GL3224芯片手册、USB协议、SD卡协议以及具体硬件电路进行详细设计和代码实现。
为了达到“连续拷卡70G文件不掉速”的目标,需要在软件层面进行精细的优化,包括DMA的配置、缓冲区的管理、中断处理的效率、以及文件系统接口的优化。 硬件方面,PCB设计的信号完整性和散热设计也至关重要。

希望这个详细的解答能够帮助你理解嵌入式系统开发流程和代码架构设计,并为你基于GL3224芯片的USB 3.0卡读卡器项目开发提供参考。

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