硬件协同设计 C/C++ 实例

硬件协同设计 C/C++ 实例

1. 嵌入式系统设计与驱动开发

1.1 GPIO 控制实例

以下是一个针对通用微控制器的 GPIO 控制库,展示了软件如何直接操作硬件寄存器:

c

/**
 * gpio.h - 通用 GPIO 控制接口
 * 
 * 硬件协同设计的典型示例:直接操作硬件寄存器的同时
 * 提供抽象接口方便软件层使用
 */

#ifndef GPIO_H
#define GPIO_H

#include <stdint.h>

// GPIO 方向设置
typedef enum {
    GPIO_DIR_INPUT = 0,
    GPIO_DIR_OUTPUT = 1
} GpioDirection;

// GPIO 输出电平
typedef enum {
    GPIO_LEVEL_LOW = 0,
    GPIO_LEVEL_HIGH = 1
} GpioLevel;

// GPIO 模式配置
typedef enum {
    GPIO_MODE_PUSHPULL = 0,   // 推挽输出 
    GPIO_MODE_OPENDRAIN = 1,  // 开漏输出
    GPIO_MODE_PULLUP = 2,     // 上拉输入
    GPIO_MODE_PULLDOWN = 3,   // 下拉输入
    GPIO_MODE_FLOAT = 4       // 浮空输入
} GpioMode;

// GPIO 端口定义
typedef enum {
    GPIO_PORT_A = 0,
    GPIO_PORT_B = 1,
    GPIO_PORT_C = 2,
    GPIO_PORT_D = 3,
    GPIO_PORT_E = 4
} GpioPort;

/**
 * 初始化 GPIO 端口
 * 
 * @param port GPIO 端口号
 * @param pin 引脚编号 (0-15)
 * @param direction 输入/输出方向
 * @param mode GPIO 模式
 * @return 0 表示成功,非零表示失败
 */
int gpio_init(GpioPort port, uint8_t pin, GpioDirection direction, GpioMode mode);

/**
 * 设置 GPIO 引脚电平
 * 
 * @param port GPIO 端口号
 * @param pin 引脚编号 (0-15)
 * @param level 输出电平
 * @return 0 表示成功,非零表示失败
 */
int gpio_write(GpioPort port, uint8_t pin, GpioLevel level);

/**
 * 读取 GPIO 引脚电平
 * 
 * @param port GPIO 端口号
 * @param pin 引脚编号 (0-15)
 * @return 引脚电平
 */
GpioLevel gpio_read(GpioPort port, uint8_t pin);

/**
 * 切换 GPIO 引脚电平
 * 
 * @param port GPIO 端口号
 * @param pin 引脚编号 (0-15)
 * @return 0 表示成功,非零表示失败
 */
int gpio_toggle(GpioPort port, uint8_t pin);

#endif /* GPIO_H */

c

/**
 * gpio.c - GPIO 控制接口实现 (基于 STM32F4xx)
 *
 * 硬件协同设计示例:根据特定微控制器寄存器布局实现抽象接口
 * 这使得软件可以适应不同的硬件平台,同时保持相同的 API
 */

#include "gpio.h"

// STM32F4xx 的 GPIO 寄存器定义
#define GPIO_BASE_ADDRESS 0x40020000
#define GPIOA_BASE_OFFSET 0x0000
#define GPIOB_BASE_OFFSET 0x0400
#define GPIOC_BASE_OFFSET 0x0800
#define GPIOD_BASE_OFFSET 0x0C00
#define GPIOE_BASE_OFFSET 0x1000

// GPIO 寄存器偏移
#define GPIO_MODER_OFFSET   0x00 // 模式寄存器
#define GPIO_OTYPER_OFFSET  0x04 // 输出类型寄存器
#define GPIO_OSPEEDR_OFFSET 0x08 // 输出速度寄存器
#define GPIO_PUPDR_OFFSET   0x0C // 上拉/下拉寄存器
#define GPIO_IDR_OFFSET     0x10 // 输入数据寄存器
#define GPIO_ODR_OFFSET     0x14 // 输出数据寄存器
#define GPIO_BSRR_OFFSET    0x18 // 位设置/复位寄存器

// 启用 GPIO 时钟的 RCC 寄存器
#define RCC_BASE_ADDRESS    0x40023800
#define RCC_AHB1ENR_OFFSET  0x30
#define RCC_AHB1ENR         (*(volatile uint32_t*)(RCC_BASE_ADDRESS + RCC_AHB1ENR_OFFSET))

// 获取 GPIO 寄存器地址
static volatile uint32_t* gpio_get_register(GpioPort port, uint32_t offset) {
    uint32_t base_addr = GPIO_BASE_ADDRESS;
    
    switch (port) {
        case GPIO_PORT_A: base_addr += GPIOA_BASE_OFFSET; break;
        case GPIO_PORT_B: base_addr += GPIOB_BASE_OFFSET; break;
        case GPIO_PORT_C: base_addr += GPIOC_BASE_OFFSET; break;
        case GPIO_PORT_D: base_addr += GPIOD_BASE_OFFSET; break;
        case GPIO_PORT_E: base_addr += GPIOE_BASE_OFFSET; break;
        default: return NULL;
    }
    
    return (volatile uint32_t*)(base_addr + offset);
}

int gpio_init(GpioPort port, uint8_t pin, GpioDirection direction, GpioMode mode) {
    // 检查参数有效性
    if (pin > 15 || port > GPIO_PORT_E) {
        return -1;
    }
    
    // 启用对应 GPIO 端口的时钟
    RCC_AHB1ENR |= (1 << port);
    
    // 获取寄存器地址
    volatile uint32_t* moder = gpio_get_register(port, GPIO_MODER_OFFSET);
    volatile uint32_t* otyper = gpio_get_register(port, GPIO_OTYPER_OFFSET);
    volatile uint32_t* pupdr = gpio_get_register(port, GPIO_PUPDR_OFFSET);
    
    if (!moder || !otyper || !pupdr) {
        return -1;
    }
    
    // 设置 GPIO 方向 (输入/输出模式)
    // 每个引脚用 2 位表示模式
    *moder &= ~(3UL << (pin * 2)); // 清除原来的设置
    *moder |= ((uint32_t)direction << (pin * 2));
    
    // 设置输出类型 (推挽/开漏)
    if (mode == GPIO_MODE_OPENDRAIN) {
        *otyper |= (1UL << pin);  // 开漏输出
    } else {
        *otyper &= ~(1UL << pin); // 推挽输出
    }
    
    // 设置上拉/下拉电阻
    *pupdr &= ~(3UL << (pin * 2)); // 清除原来的设置
    if (mode == GPIO_MODE_PULLUP) {
        *pupdr |= (1UL << (pin * 2)); // 上拉电阻
    } else if (mode == GPIO_MODE_PULLDOWN) {
        *pupdr |= (2UL << (pin * 2)); // 下拉电阻
    }
    // 其它模式保持浮空
    
    return 0;
}

int gpio_write(GpioPort port, uint8_t pin, GpioLevel level) {
    // 检查参数有效性
    if (pin > 15 || port > GPIO_PORT_E) {
        return -1;
    }
    
    // 使用 BSRR (位设置/复位寄存器) 进行原子写操作
    volatile uint32_t* bsrr = gpio_get_register(port, GPIO_BSRR_OFFSET);
    if (!bsrr) {
        return -1;
    }
    
    if (level == GPIO_LEVEL_HIGH) {
        *bsrr = (1UL << pin);          // 设置位
    } else {
        *bsrr = (1UL << (pin + 16));   // 复位位 (高 16 位用于复位)
    }
    
    return 0;
}

GpioLevel gpio_read(GpioPort port, uint8_t pin) {
    // 检查参数有效性
    if (pin > 15 || port > GPIO_PORT_E) {
        return GPIO_LEVEL_LOW; // 出错时默认返回低电平
    }
    
    // 读取输入数据寄存器
    volatile uint32_t* idr = gpio_get_register(port, GPIO_IDR_OFFSET);
    if (!idr) {
        return GPIO_LEVEL_LOW;
    }
    
    // 检查对应位是否为高电平
    return (*idr & (1UL << pin)) ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW;
}

int gpio_toggle(GpioPort port, uint8_t pin) {
    // 检查参数有效性
    if (pin > 15 || port > GPIO_PORT_E) {
        return -1;
    }
    
    // 读取当前输出数据寄存器
    volatile uint32_t* odr = gpio_get_register(port, GPIO_ODR_OFFSET);
    if (!odr) {
        return -1;
    }
    
    // 切换对应位
    *odr ^= (1UL << pin);
    
    return 0;
}

1.2 SPI 通信驱动实例

下面是一个 SPI 通信驱动,展示了如何通过软件控制 SPI 硬件模块:

c

/**
 * spi.h - SPI 控制接口
 *
 * 提供软件接口以控制硬件 SPI 模块
 */

#ifndef SPI_H
#define SPI_H

#include <stdint.h>

// SPI 模块选择
typedef enum {
    SPI_MODULE_1 = 0,
    SPI_MODULE_2 = 1,
    SPI_MODULE_3 = 2
} SpiModule;

// SPI 模式
typedef enum {
    SPI_MODE_0 = 0, // CPOL=0, CPHA=0
    SPI_MODE_1 = 1, // CPOL=0, CPHA=1
    SPI_MODE_2 = 2, // CPOL=1, CPHA=0
    SPI_MODE_3 = 3  // CPOL=1, CPHA=1
} SpiMode;

// SPI 波特率预分频系数
typedef enum {
    SPI_BAUDRATE_DIV2 = 0,
    SPI_BAUDRATE_DIV4 = 1,
    SPI_BAUDRATE_DIV8 = 2,
    SPI_BAUDRATE_DIV16 = 3,
    SPI_BAUDRATE_DIV32 = 4,
    SPI_BAUDRATE_DIV64 = 5,
    SPI_BAUDRATE_DIV128 = 6,
    SPI_BAUDRATE_DIV256 = 7
} SpiBaudRatePrescaler;

// SPI 数据大小
typedef enum {
    SPI_DATASIZE_8BIT = 0,
    SPI_DATASIZE_16BIT = 1
} SpiDataSize;

// SPI 配置结构体
typedef struct {
    SpiMode mode;                // SPI 模式
    SpiBaudRatePrescaler baud;   // 波特率预分频
    SpiDataSize dataSize;        // 数据大小
    uint8_t lsbFirst;            // 1 = LSB 优先,0 = MSB 优先
} SpiConfig;

/**
 * 初始化 SPI 模块
 *
 * @param module SPI 模块编号
 * @param config SPI 配置参数
 * @return 0 表示成功,非零表示失败
 */
int spi_init(SpiModule module, const SpiConfig* config);

/**
 * 发送并接收一个字节/字的数据 (全双工)
 *
 * @param module SPI 模块编号
 * @param data 要发送的数据
 * @return 接收到的数据
 */
uint16_t spi_transfer(SpiModule module, uint16_t data);

/**
 * 发送多个字节的数据
 *
 * @param module SPI 模块编号
 * @param txData 要发送的数据缓冲区
 * @param rxData 接收数据的缓冲区 (可以为 NULL)
 * @param length 数据长度
 * @return 0 表示成功,非零表示失败
 */
int spi_transfer_buffer(SpiModule module, const uint8_t* txData, uint8_t* rxData, uint16_t length);

/**
 * 选择 SPI 片选信号
 *
 * @param port 片选信号所在的 GPIO 端口
 * @param pin 片选信号的引脚编号
 * @param select 1 表示选中,0 表示取消选中
 * @return 0 表示成功,非零表示失败
 */
int spi_chip_select(uint8_t port, uint8_t pin, uint8_t select);

#endif /* SPI_H */

c

/**
 * spi.c - SPI 控制接口实现 (基于 STM32F4xx)
 *
 * 硬件协同设计示例:软件根据硬件寄存器映射实现通信接口
 */

#include "spi.h"
#include "gpio.h" // 使用前文定义的 GPIO 函数

// STM32F4xx 的 SPI 寄存器定义
#define SPI1_BASE_ADDRESS 0x40013000
#define SPI2_BASE_ADDRESS 0x40003800
#define SPI3_BASE_ADDRESS 0x40003C00

// SPI 寄存器偏移量
#define SPI_CR1_OFFSET    0x00 // 控制寄存器 1
#define SPI_CR2_OFFSET    0x04 // 控制寄存器 2
#define SPI_SR_OFFSET     0x08 // 状态寄存器
#define SPI_DR_OFFSET     0x0C // 数据寄存器

// SPI 控制寄存器 1 (CR1) 位定义
#define SPI_CR1_CPHA      0x01 // 时钟相位
#define SPI_CR1_CPOL      0x02 // 时钟极性
#define SPI_CR1_MSTR      0x04 // 主模式
#define SPI_CR1_BR_SHIFT  3    // 波特率控制位偏移
#define SPI_CR1_SPE       0x40 // SPI 使能
#define SPI_CR1_LSBFIRST  0x80 // 帧格式 (LSB/MSB)
#define SPI_CR1_SSI       0x100 // 内部从设备选择
#define SPI_CR1_SSM       0x200 // 软件从设备管理
#define SPI_CR1_DFF       0x800 // 数据帧格式 (8/16 位)

// SPI 状态寄存器 (SR) 位定义
#define SPI_SR_RXNE       0x01 // 接收缓冲区非空
#define SPI_SR_TXE        0x02 // 发送缓冲区空
#define SPI_SR_BSY        0x80 // 忙标志

// 启用时钟的 RCC 寄存器
#define RCC_BASE_ADDRESS  0x40023800
#define RCC_APB2ENR_OFFSET 0x44 // APB2 外设时钟使能寄存器
#define RCC_APB1ENR_OFFSET 0x40 // APB1 外设时钟使能寄存器

#define RCC_APB2ENR       (*(volatile uint32_t*)(RCC_BASE_ADDRESS + RCC_APB2ENR_OFFSET))
#define RCC_APB1ENR       (*(volatile uint32_t*)(RCC_BASE_ADDRESS + RCC_APB1ENR_OFFSET))

// SPI1 在 APB2 上,SPI2/3 在 APB1 上
#define RCC_APB2ENR_SPI1EN 0x1000 // SPI1 时钟使能位
#define RCC_APB1ENR_SPI2EN 0x4000 // SPI2 时钟使能位
#define RCC_APB1ENR_SPI3EN 0x8000 // SPI3 时钟使能位

// 获取 SPI 寄存器地址
static volatile uint32_t* spi_get_register(SpiModule module, uint32_t offset) {
    uint32_t base_addr;
    
    switch (module) {
        case SPI_MODULE_1: base_addr = SPI1_BASE_ADDRESS; break;
        case SPI_MODULE_2: base_addr = SPI2_BASE_ADDRESS; break;
        case SPI_MODULE_3: base_addr = SPI3_BASE_ADDRESS; break;
        default: return NULL;
    }
    
    return (volatile uint32_t*)(base_addr + offset);
}

int spi_init(SpiModule module, const SpiConfig* config) {
    // 检查参数有效性
    if (module > SPI_MODULE_3 || !config) {
        return -1;
    }
    
    // 启用 SPI 时钟
    switch (module) {
        case SPI_MODULE_1:
            RCC_APB2ENR |= RCC_APB2ENR_SPI1EN;
            break;
        case SPI_MODULE_2:
            RCC_APB1ENR |= RCC_APB1ENR_SPI2EN;
            break;
        case SPI_MODULE_3:
            RCC_APB1ENR |= RCC_APB1ENR_SPI3EN;
            break;
    }
    
    // 获取控制寄存器
    volatile uint32_t* cr1 = spi_get_register(module, SPI_CR1_OFFSET);
    volatile uint32_t* cr2 = spi_get_register(module, SPI_CR2_OFFSET);
    
    if (!cr1 || !cr2) {
        return -1;
    }
    
    // 禁用 SPI 以进行配置
    *cr1 &= ~SPI_CR1_SPE;
    
    // 配置 SPI 模式 (CPOL, CPHA)
    uint32_t temp = *cr1;
    temp &= ~(SPI_CR1_CPHA | SPI_CR1_CPOL); // 清除模式位
    temp |= config->mode; // 设置模式
    
    // 配置为主模式
    temp |= SPI_CR1_MSTR;
    
    // 配置波特率
    temp &= ~(0x7 << SPI_CR1_BR_SHIFT); // 清除波特率位
    temp |= (config->baud << SPI_CR1_BR_SHIFT);
    
    // 配置数据大小 (8/16 位)
    if (config->dataSize == SPI_DATASIZE_16BIT) {
        temp |= SPI_CR1_DFF;
    } else {
        temp &= ~SPI_CR1_DFF;
    }
    
    // 配置位顺序 (MSB/LSB 优先)
    if (config->lsbFirst) {
        temp |= SPI_CR1_LSBFIRST;
    } else {
        temp &= ~SPI_CR1_LSBFIRST;
    }
    
    // 启用软件 NSS 管理并将 NSS 内部拉高 (避免进入从模式)
    temp |= (SPI_CR1_SSM | SPI_CR1_SSI);
    
    // 写回 CR1 寄存器
    *cr1 = temp;
    
    // 配置 CR2 寄存器,开启 RXNE 中断
    *cr2 = 0x00; // 默认不启用中断
    
    // 启用 SPI
    *cr1 |= SPI_CR1_SPE;
    
    return 0;
}

uint16_t spi_transfer(SpiModule module, uint16_t data) {
    // 获取 SPI 寄存器
    volatile uint32_t* sr = spi_get_register(module, SPI_SR_OFFSET);
    volatile uint32_t* dr = spi_get_register(module, SPI_DR_OFFSET);
    
    if (!sr || !dr) {
        return 0;
    }
    
    // 等待发送缓冲区为空
    while (!(*sr & SPI_SR_TXE));
    
    // 发送数据
    *dr = data;
    
    // 等待接收数据完成
    while (!(*sr & SPI_SR_RXNE));
    
    // 读取接收到的数据
    return *dr;
}

int spi_transfer_buffer(SpiModule module, const uint8_t* txData, uint8_t* rxData, uint16_t length) {
    // 获取 SPI 寄存器
    volatile uint32_t* sr = spi_get_register(module, SPI_SR_OFFSET);
    volatile uint32_t* dr = spi_get_register(module, SPI_DR_OFFSET);
    volatile uint32_t* cr1 = spi_get_register(module, SPI_CR1_OFFSET);
    
    if (!sr || !dr || !cr1) {
        return -1;
    }
    
    // 检查数据帧格式,确定是 8 位还是 16 位模式
    uint8_t is16bit = (*cr1 & SPI_CR1_DFF) ? 1 : 0;
    
    // 对于每个字节/字进行传输
    for (uint16_t i = 0; i < length; i++) {
        uint16_t out_data, in_data;
        
        // 准备发送数据
        if (is16bit) {
            if (txData) {
                out_data = (txData[i*2] << 8) | txData[i*2 + 1];
            } else {
                out_data = 0xFFFF; // 发送哑数据以接收有效数据
            }
        } else {
            if (txData) {
                out_data = txData[i];
            } else {
                out_data = 0xFF; // 发送哑数据以接收有效数据
            }
        }
        
        // 等待发送缓冲区为空
        while (!(*sr & SPI_SR_TXE));
        
        // 发送数据
        *dr = out_data;
        
        // 等待接收数据完成
        while (!(*sr & SPI_SR_RXNE));
        
        // 读取接收到的数据
        in_data = *dr;
        
        // 保存接收到的数据
        if (rxData) {
            if (is16bit) {
                rxData[i*2] = (in_data >> 8) & 0xFF;
                rxData[i*2 + 1] = in_data & 0xFF;
            } else {
                rxData[i] = in_data & 0xFF;
            }
        }
    }
    
    // 等待 SPI 不忙
    while (*sr & SPI_SR_BSY);
    
    return 0;
}

int spi_chip_select(uint8_t port, uint8_t pin, uint8_t select) {
    // 使用 GPIO 函数管理片选信号
    return gpio_write((GpioPort)port, pin, select ? GPIO_LEVEL_LOW : GPIO_LEVEL_HIGH);
}

1.3 定时器PWM控制实例

以下是一个生成PWM信号的示例,展示了如何使用定时器硬件单元:

c

/**
 * pwm.h - PWM 控制接口
 *
 * 提供软件接口以控制定时器生成 PWM 信号
 */

#ifndef PWM_H
#define PWM_H

#include <stdint.h>

// 定时器选择
typedef enum {
    TIMER_1 = 0,
    TIMER_2 = 1,
    TIMER_3 = 2,
    TIMER_4 = 3,
    TIMER_5 = 4
} TimerNumber;

// 定时器通道
typedef enum {
    TIMER_CHANNEL_1 = 0,
    TIMER_CHANNEL_2 = 1,
    TIMER_CHANNEL_3 = 2,
    TIMER_CHANNEL_4 = 3
} TimerChannel;

// PWM 配置结构体
typedef struct {
    uint32_t frequency;      // PWM 频率 (Hz)
    uint8_t dutyCycle;       // 占空比 (0-100%)
    uint8_t polarity;        // 0 = 正向极性,1 = 反向极性
} PwmConfig;

/**
 * 初始化 PWM 通道
 *
 * @param timer 定时器编号
 * @param channel 通道编号
 * @param config PWM 配置参数
 * @return 0 表示成功,非零表示失败
 */
int pwm_init(TimerNumber timer, TimerChannel channel, const PwmConfig* config);

/**
 * 启动 PWM 输出
 *
 * @param timer 定时器编号
 * @param channel 通道编号
 * @return 0 表示成功,非零表示失败
 */
int pwm_start(TimerNumber timer, TimerChannel channel);

/**
 * 停止 PWM 输出
 *
 * @param timer 定时器编号
 * @param channel 通道编号
 * @return 0 表示成功,非零表示失败
 */
int pwm_stop(TimerNumber timer, TimerChannel channel);

/**
 * 更新 PWM 占空比
 *
 * @param timer 定时器编号
 * @param channel 通道编号
 * @param dutyCycle 占空比 (0-100%)
 * @return 0 表示成功,非零表示失败
 */
int pwm_set_duty_cycle(TimerNumber timer, TimerChannel channel, uint8_t dutyCycle);

/**
 * 更新 PWM 频率
 *
 * @param timer 定时器编号
 * @param frequency 频率 (Hz)
 * @return 0 表示成功,非零表示失败
 */
int pwm_set_frequency(TimerNumber timer, uint32_t frequency);

#endif /* PWM_H */

c

/**
 * pwm.c - PWM 控制接口实现 (基于 STM32F4xx)
 *
 * 硬件协同设计示例:通过软件控制定时器硬件单元产生精确的 PWM 信号
 */

#include "pwm.h"

// STM32F4xx 的定时器寄存器定义
#define TIM1_BASE_ADDRESS 0x40010000
#define TIM2_BASE_ADDRESS 0x40000000
#define TIM3_BASE_ADDRESS 0x40000400
#define TIM4_BASE_ADDRESS 0x40000800
#define TIM5_BASE_ADDRESS 0x40000C00

// 定时器寄存器偏移量
#define TIM_CR1_OFFSET     0x00 // 控制寄存器 1
#define TIM_CR2_OFFSET     0x04 // 控制寄存器 2
#define TIM_SMCR_OFFSET    0x08 // 从模式控制寄存器
#define TIM_DIER_OFFSET    0x0C // DMA/中断使能寄存器
#define TIM_SR_OFFSET      0x10 // 状态寄存器
#define TIM_EGR_OFFSET     0x14 // 事件生成寄存器
#define TIM_CCMR1_OFFSET   0x18 // 捕获/比较模式寄存器 1
#define TIM_CCMR2_OFFSET   0x1C // 捕获/比较模式寄存器 2
#define TIM_CCER_OFFSET    0x20 // 捕获/比较使能寄存器
#define TIM_CNT_OFFSET     0x24 // 计数器
#define TIM_PSC_OFFSET     0x28 // 预分频器
#define TIM_ARR_OFFSET     0x2C // 自动重装载寄存器
#define TIM_CCR1_OFFSET    0x34 // 捕获/比较寄存器 1
#define TIM_CCR2_OFFSET    0x38 // 捕获/比较寄存器 2
#define TIM_CCR3_OFFSET    0x3C // 捕获/比较寄存器 3
#define TIM_CCR4_OFFSET    0x40 // 捕获/比较寄存器 4
#define TIM_BDTR_OFFSET    0x44 // 刹车和死区寄存器 (仅高级定时器)

// 定义控制位
#define TIM_CR1_CEN        0x0001 // 计数器使能
#define TIM_CR1_ARPE       0x0080 // 自动重装载使能

#define TIM_CCMR1_OC1M     0x0070 // 输出比较 1 模式掩码
#define TIM_CCMR1_OC2M     0x7000 // 输出比较 2 模式掩码
#define TIM_CCMR2_OC3M     0x0070 // 输出比较 3 模式掩码
#define TIM_CCMR2_OC4M     0x7000 // 输出比较 4 模式掩码

#define TIM_CCMR1_OC1PE    0x0008 // 输出比较 1 预装载使能
#define TIM_CCMR1_OC2PE    0x0800 // 输出比较 2 预装载使能
#define TIM_CCMR2_OC3PE    0x0008 // 输出比较 3 预装载使能
#define TIM_CCMR2_OC4PE    0x0800 // 输出比较 4 预装载使能

#define TIM_CCER_CC1E      0x0001 // 捕获/比较 1 输出使能
#define TIM_CCER_CC2E      0x0010 // 捕获/比较 2 输出使能
#define TIM_CCER_CC3E      0x0100 // 捕获/比较 3 输出使能
#define TIM_CCER_CC4E      0x1000 // 捕获/比较 4 输出使能

#define TIM_CCER_CC1P      0x0002 // 捕获/比较 1 输出极性
#define TIM_CCER_CC2P      0x0020 // 捕获/比较 2 输出极性
#define TIM_CCER_CC3P      0x0200 // 捕获/比较 3 输出极性
#define TIM_CCER_CC4P      0x2000 // 捕获/比较 4 输出极性

#define TIM_BDTR_MOE       0x8000 // 主输出使能 (仅高级定时器)

// PWM 模式 1 的模式值 (当计数值<比较值时通道为有效电平)
#define TIM_OCMODE_PWM1    0x0060

// 启用时钟的 RCC 寄存器
#define RCC_BASE_ADDRESS   0x40023800
#define RCC_APB2ENR_OFFSET 0x44 // APB2 外设时钟使能寄存器
#define RCC_APB1ENR_OFFSET 0x40 // APB1 外设时钟使能寄存器

#define RCC_APB2ENR        (*(volatile uint32_t*)(RCC_BASE_ADDRESS + RCC_APB2ENR_OFFSET))
#define RCC_APB1ENR        (*(volatile uint32_t*)(RCC_BASE_ADDRESS + RCC_APB1ENR_OFFSET))

// TIM1 在 APB2 上,TIM2-5 在 APB1 上
#define RCC_APB2ENR_TIM1EN 0x0001 // TIM1 时钟使能位
#define RCC_APB1ENR_TIM2EN 0x0001 // TIM2 时钟使能位
#define RCC_APB1ENR_TIM3EN 0x0002 // TIM3 时钟使能位
#define RCC_APB1ENR_TIM4EN 0x0004 // TIM4 时钟使能位
#define RCC_APB1ENR_TIM5EN 0x0008 // TIM5 时钟使能位

// 系统时钟 (假设为 84MHz)
#define SYSTEM_CLOCK       84000000UL

// 获取定时器寄存器地址
static volatile uint32_t* timer_get_register(TimerNumber timer, uint32_t offset) {
    uint32_t base_addr;
    
    switch (timer) {
        case TIMER_1: base_addr = TIM1_BASE_ADDRESS; break;
        case TIMER_2: base_addr = TIM2_BASE_ADDRESS; break;
        case TIMER_3: base_addr = TIM3_BASE_ADDRESS; break;
        case TIMER_4: base_addr = TIM4_BASE_ADDRESS; break;
        case TIMER_5: base_addr = TIM5_BASE_ADDRESS; break;
        default: return NULL;
    }
    
    return (volatile uint32_t*)(base_addr + offset);
}

// 获取捕获比较寄存器地址
static volatile uint32_t* timer_get_ccr_register(TimerNumber timer, TimerChannel channel) {
    uint32_t offset;
    
    switch (channel) {
        case TIMER_CHANNEL_1: offset = TIM_CCR1_OFFSET; break;
        case TIMER_CHANNEL_2: offset = TIM_CCR2_OFFSET; break;
        case TIMER_CHANNEL_3: offset = TIM_CCR3_OFFSET; break;
        case TIMER_CHANNEL_4: offset = TIM_CCR4_OFFSET; break;
        default: return NULL;
    }
    
    return timer_get_register(timer, offset);
}

int pwm_init(TimerNumber timer, TimerChannel channel, const PwmConfig* config) {
    // 检查参数有效性
    if (timer > TIMER_5 || channel > TIMER_CHANNEL_4 || !config || 
        config->dutyCycle > 100) {
        return -1;
    }
    
    // 启用定时器时钟
    switch (timer) {
        case TIMER_1:
            RCC_APB2ENR |= RCC_APB2ENR_TIM1EN;
            break;
        case TIMER_2:
            RCC_APB1ENR |= RCC_APB1ENR_TIM2EN;
            break;
        case TIMER_3:
            RCC_APB1ENR |= RCC_APB1ENR_TIM3EN;
            break;
        case TIMER_4:
            RCC_APB1ENR |= RCC_APB1ENR_TIM4EN;
            break;
        case TIMER_5:
            RCC_APB1ENR |= RCC_APB1ENR_TIM5EN;
            break;
    }
    
    // 获取关键寄存器
    volatile uint32_t* cr1 = timer_get_register(timer, TIM_CR1_OFFSET);
    volatile uint32_t* psc = timer_get_register(timer, TIM_PSC_OFFSET);
    volatile uint32_t* arr = timer_get_register(timer, TIM_ARR_OFFSET);
    volatile uint32_t* ccmr1 = timer_get_register(timer, TIM_CCMR1_OFFSET);
    volatile uint32_t* ccmr2 = timer_get_register(timer, TIM_CCMR2_OFFSET);
    volatile uint32_t* ccer = timer_get_register(timer, TIM_CCER_OFFSET);
    volatile uint32_t* ccr = timer_get_ccr_register(timer, channel);
    volatile uint32_t* bdtr = NULL;
    
    if (timer == TIMER_1) {
        bdtr = timer_get_register(timer, TIM_BDTR_OFFSET);
    }
    
    if (!cr1 || !psc || !arr || !ccmr1 || !ccmr2 || !ccer || !ccr) {
        return -1;
    }
    
    // 禁用定时器便于设置
    *cr1 &= ~TIM_CR1_CEN;
    
    // 计算 PSC 和 ARR 值以获得所需频率
    // 假设定时器时钟为 84MHz
    uint32_t timerClock = SYSTEM_CLOCK;
    
    if (timer != TIMER_1) {
        timerClock /= 2; // APB1 定时器时钟为系统时钟的一半
    }
    
    // 需要确定最佳的 PSC 值,使 ARR 在合适的范围内 (16-bit 或 32-bit)
    uint32_t prescaler = 0;
    uint32_t period = 0;
    uint32_t maxARR = (timer == TIMER_2 || timer == TIMER_5) ? 0xFFFFFFFF : 0xFFFF;
    
    // 尝试找到最佳预分频值
    for (prescaler = 0; prescaler <= 0xFFFF; prescaler++) {
        period = timerClock / ((prescaler + 1) * config->frequency);
        
        if (period <= maxARR) {
            break;
        }
    }
    
    if (prescaler > 0xFFFF || period < 2) {
        // 无法达到请求的频率
        return -1;
    }
    
    // 设置预分频和自动重装载值
    *psc = prescaler;
    *arr = period;
    
    // 计算占空比对应的比较值
    uint32_t compareValue = (period * config->dutyCycle) / 100;
    
    // 防止占空比 100% 时比较值等于 ARR+1
    if (compareValue >= period) {
        compareValue = period - 1;
    }
    
    // 根据通道配置输出比较模式为 PWM 模式 1
    switch (channel) {
        case TIMER_CHANNEL_1:
            *ccmr1 &= ~TIM_CCMR1_OC1M;          // 清除当前模式
            *ccmr1 |= TIM_OCMODE_PWM1;          // 设置为 PWM 模式 1
            *ccmr1 |= TIM_CCMR1_OC1PE;          // 启用预装载
            break;
        case TIMER_CHANNEL_2:
            *ccmr1 &= ~TIM_CCMR1_OC2M;          // 清除当前模式
            *ccmr1 |= (TIM_OCMODE_PWM1 << 8);   // 设置为 PWM 模式 1
            *ccmr1 |= TIM_CCMR1_OC2PE;          // 启用预装载
            break;
        case TIMER_CHANNEL_3:
            *ccmr2 &= ~TIM_CCMR2_OC3M;          // 清除当前模式
            *ccmr2 |= TIM_OCMODE_PWM1;          // 设置为 PWM 模式 1
            *ccmr2 |= TIM_CCMR2_OC3PE;          // 启用预装载
            break;
        case TIMER_CHANNEL_4:
            *ccmr2 &= ~TIM_CCMR2_OC4M;          // 清除当前模式
            *ccmr2 |= (TIM_OCMODE_PWM1 << 8);   // 设置为 PWM 模式 1
            *ccmr2 |= TIM_CCMR2_OC4PE;          // 启用预装载
            break;
    }
    
    // 设置通道极性
    switch (channel) {
        case TIMER_CHANNEL_1:
            if (config->polarity) {
                *ccer |= TIM_CCER_CC1P;   // 反向极性
            } else {
                *ccer &= ~TIM_CCER_CC1P;  // 正向极性
            }
            break;
        case TIMER_CHANNEL_2:
            if (config->polarity) {
                *ccer |= TIM_CCER_CC2P;   // 反向极性
            } else {
                *ccer &= ~TIM_CCER_CC2P;  // 正向极性
            }
            break;
        case TIMER_CHANNEL_3:
            if (config->polarity) {
                *ccer |= TIM_CCER_CC3P;   // 反向极性
            } else {
                *ccer &= ~TIM_CCER_CC3P;  // 正向极性
            }
            break;
        case TIMER_CHANNEL_4:
            if (config->polarity) {
                *ccer |= TIM_CCER_CC4P;   // 反向极性
            } else {
                *ccer &= ~TIM_CCER_CC4P;  // 正向极性
            }
            break;
    }
    
    // 设置比较值
    *ccr = compareValue;
    
    // 配置 CR1 寄存器
    *cr1 |= TIM_CR1_ARPE;  // 使能自动重装载预装寄存器
    
    // 如果是高级定时器,需要设置 BDTR 寄存器
    if (timer == TIMER_1 && bdtr) {
        *bdtr |= TIM_BDTR_MOE;  // 主输出使能
    }
    
    return 0;
}

int pwm_start(TimerNumber timer, TimerChannel channel) {
    // 检查参数有效性
    if (timer > TIMER_5 || channel > TIMER_CHANNEL_4) {
        return -1;
    }
    
    // 获取关键寄存器
    volatile uint32_t* cr1 = timer_get_register(timer, TIM_CR1_OFFSET);
    volatile uint32_t* ccer = timer_get_register(timer, TIM_CCER_OFFSET);
    
    if (!cr1 || !ccer) {
        return -1;
    }
    
    // 启用对应通道的输出
    switch (channel) {
        case TIMER_CHANNEL_1:
            *ccer |= TIM_CCER_CC1E;
            break;
        case TIMER_CHANNEL_2:
            *ccer |= TIM_CCER_CC2E;
            break;
        case TIMER_CHANNEL_3:
            *ccer |= TIM_CCER_CC3E;
            break;
        case TIMER_CHANNEL_4:
            *ccer |= TIM_CCER_CC4E;
            break;
    }
    
    // 启用定时器
    *cr1 |= TIM_CR1_CEN;
    
    return 0;
}

int pwm_stop(TimerNumber timer, TimerChannel channel) {
    // 检查参数有效性
    if (timer > TIMER_5 || channel > TIMER_CHANNEL_4) {
        return -1;
    }
    
    // 获取关键寄存器
    volatile uint32_t* ccer = timer_get_register(timer, TIM_CCER_OFFSET);
    
    if (!ccer) {
        return -1;
    }
    
    // 禁用对应通道的输出
    switch (channel) {
        case TIMER_CHANNEL_1:
            *ccer &= ~TIM_CCER_CC1E;
            break;
        case TIMER_CHANNEL_2:
            *ccer &= ~TIM_CCER_CC2E;
            break;
        case TIMER_CHANNEL_3:
            *ccer &= ~TIM_CCER_CC3E;
            break;
        case TIMER_CHANNEL_4:
            *ccer &= ~TIM_CCER_CC4E;
            break;
    }
    
    return 0;
}

int pwm_set_duty_cycle(TimerNumber timer, TimerChannel channel, uint8_t dutyCycle) {
    // 检查参数有效性
    if (timer > TIMER_5 || channel > TIMER_CHANNEL_4 || dutyCycle > 100) {
        return -1;
    }
    
    // 获取关键寄存器
    volatile uint32_t* arr = timer_get_register(timer, TIM_ARR_OFFSET);
    volatile uint32_t* ccr = timer_get_ccr_register(timer, channel);
    
    if (!arr || !ccr) {
        return -1;
    }
    
    // 获取当前周期值
    uint32_t period = *arr;
    
    // 计算新的比较值
    uint32_t compareValue = (period * dutyCycle) / 100;
    
    // 防止占空比 100% 时比较值等于 ARR+1
    if (compareValue >= period) {
        compareValue = period - 1;
    }
    
    // 设置新的比较值
    *ccr = compareValue;
    
    return 0;
}

int pwm_set_frequency(TimerNumber timer, uint32_t frequency) {
    // 检查参数有效性
    if (timer > TIMER_5 || frequency == 0) {
        return -1;
    }
    
    // 获取关键寄存器
    volatile uint32_t* cr1 = timer_get_register(timer, TIM_CR1_OFFSET);
    volatile uint32_t* psc = timer_get_register(timer, TIM_PSC_OFFSET);
    volatile uint32_t* arr = timer_get_register(timer, TIM_ARR_OFFSET);
    
    if (!cr1 || !psc || !arr) {
        return -1;
    }
    
    // 临时停止定时器
    uint32_t cr1_val = *cr1;
    *cr1 &= ~TIM_CR1_CEN;
    
    // 计算新的 PSC 和 ARR 值以获得所需频率
    uint32_t timerClock = SYSTEM_CLOCK;
    
    if (timer != TIMER_1) {
        timerClock /= 2; // APB1 定时器时钟为系统时钟的一半
    }
    
    // 尝试找到最佳预分频值
    uint32_t prescaler = 0;
    uint32_t period = 0;
    uint32_t maxARR = (timer == TIMER_2 || timer == TIMER_5) ? 0xFFFFFFFF : 0xFFFF;
    
    for (prescaler = 0; prescaler <= 0xFFFF; prescaler++) {
        period = timerClock / ((prescaler + 1) * frequency);
        
        if (period <= maxARR) {
            break;
        }
    }
    
    if (prescaler > 0xFFFF || period < 2) {
        // 无法达到请求的频率
        // 恢复定时器运行状态
        *cr1 = cr1_val;
        return -1;
    }
    
    // 设置新的预分频和自动重装载值
    *psc = prescaler;
    *arr = period;
    
    // 恢复定时器运行状态
    *cr1 = cr1_val;
    
    return 0;
}

1.4 ADC转换实例

以下示例展示了一个 ADC 驱动的实现:

c

/**
 * adc.h - ADC 控制接口
 *
 * 提供软件接口以控制 ADC 模块进行模拟量采集
 */

#ifndef ADC_H
#define ADC_H

#include <stdint.h>

// ADC 模块编号
typedef enum {
    ADC_MODULE_1 = 0,
    ADC_MODULE_2 = 1,
    ADC_MODULE_3 = 2
} AdcModule;

// ADC 通道
typedef enum {
    ADC_CHANNEL_0 = 0,
    ADC_CHANNEL_1 = 1,
    ADC_CHANNEL_2 = 2,
    ADC_CHANNEL_3 = 3,
    ADC_CHANNEL_4 = 4,
    ADC_CHANNEL_5 = 5,
    ADC_CHANNEL_6 = 6,
    ADC_CHANNEL_7 = 7,
    ADC_CHANNEL_8 = 8,
    ADC_CHANNEL_9 = 9,
    ADC_CHANNEL_10 = 10,
    ADC_CHANNEL_11 = 11,
    ADC_CHANNEL_12 = 12,
    ADC_CHANNEL_13 = 13,
    ADC_CHANNEL_14 = 14,
    ADC_CHANNEL_15 = 15,
    ADC_CHANNEL_TEMP = 16,  // 内部温度传感器
    ADC_CHANNEL_VREF = 17   // 内部参考电压
} AdcChannel;

// ADC 采样周期
typedef enum {
    ADC_SAMPLETIME_3CYCLES = 0,
    ADC_SAMPLETIME_15CYCLES = 1,
    ADC_SAMPLETIME_28CYCLES = 2,
    ADC_SAMPLETIME_56CYCLES = 3,
    ADC_SAMPLETIME_84CYCLES = 4,
    ADC_SAMPLETIME_112CYCLES = 5,
    ADC_SAMPLETIME_144CYCLES = 6,
    ADC_SAMPLETIME_480CYCLES = 7
} AdcSampleTime;

// ADC 分辨率
typedef enum {
    ADC_RESOLUTION_12BIT = 0,
    ADC_RESOLUTION_10BIT = 1,
    ADC_RESOLUTION_8BIT = 2,
    ADC_RESOLUTION_6BIT = 3
} AdcResolution;

// ADC 触发源(用于外部触发)
typedef enum {
    ADC_TRIGGER_NONE = 0,
    ADC_TRIGGER_TIMER1_CC1 = 1,
    ADC_TRIGGER_TIMER1_CC2 = 2,
    ADC_TRIGGER_TIMER1_CC3 = 3,
    ADC_TRIGGER_TIMER2_CC2 = 4,
    ADC_TRIGGER_TIMER3_TRGO = 6,
    ADC_TRIGGER_EXTI11 = 15
} AdcTrigger;

// ADC 配置结构体
typedef struct {
    AdcResolution resolution;        // ADC 分辨率
    uint8_t continuousMode;          // 1 = 连续转换模式,0 = 单次转换模式
    AdcTrigger externalTrigger;      // 外部触发源,ADC_TRIGGER_NONE 表示软件触发
    uint8_t dataAlign;               // 1 = 左对齐,0 = 右对齐
} AdcConfig;

// ADC 通道配置结构体
typedef struct {
    AdcChannel channel;              // ADC 通道
    AdcSampleTime sampleTime;        // 采样时间
    uint8_t rank;                    // 转换序列中的顺序 (1-16)
} AdcChannelConfig;

/**
 * 初始化 ADC 模块
 *
 * @param module ADC 模块编号
 * @param config ADC 配置参数
 * @return 0 表示成功,非零表示失败
 */
int adc_init(AdcModule module, const AdcConfig* config);

/**
 * 配置 ADC 通道
 *
 * @param module ADC 模块编号
 * @param channelConfig 通道配置参数
 * @return 0 表示成功,非零表示失败
 */
int adc_config_channel(AdcModule module, const AdcChannelConfig* channelConfig);

/**
 * 启动 ADC 转换
 *
 * @param module ADC 模块编号
 * @return 0 表示成功,非零表示失败
 */
int adc_start_conversion(AdcModule module);

/**
 * 等待 ADC 转换完成
 *
 * @param module ADC 模块编号
 * @param timeout 超时时间 (毫秒),0 表示无限等待
 * @return 0 表示成功,非零表示失败或超时
 */
int adc_wait_for_conversion(AdcModule module, uint32_t timeout);

/**
 * 读取 ADC 转换结果
 *
 * @param module ADC 模块编号
 * @return ADC 转换结果
 */
uint16_t adc_read_value(AdcModule module);

/**
 * 进行单通道 ADC 采样(阻塞方式)
 *
 * @param module ADC 模块编号
 * @param channel ADC 通道
 * @param sampleTime 采样时间
 * @return ADC 转换结果,失败时返回 0xFFFF
 */
uint16_t adc_sample_channel(AdcModule module, AdcChannel channel, AdcSampleTime sampleTime);

#endif /* ADC_H */

c

/**
 * adc.c - ADC 控制接口实现 (基于 STM32F4xx)
 *
 * 硬件协同设计示例:通过软件控制 ADC 硬件单元进行模拟量采集
 */

#include "adc.h"

// STM32F4xx 的 ADC 寄存器定义
#define ADC1_BASE_ADDRESS  0x40012000
#define ADC2_BASE_ADDRESS  0x40012100
#define ADC3_BASE_ADDRESS  0x40012200
#define ADC_COMMON_BASE    0x40012300

// ADC 寄存器偏移量
#define ADC_SR_OFFSET      0x00 // 状态寄存器
#define ADC_CR1_OFFSET     0x04 // 控制寄存器 1
#define ADC_CR2_OFFSET     0x08 // 控制寄存器 2
#define ADC_SMPR1_OFFSET   0x0C // 采样时间寄存器 1
#define ADC_SMPR2_OFFSET   0x10 // 采样时间寄存器 2
#define ADC_JOFR1_OFFSET   0x14 // 注入通道数据偏移寄存器 1
#define ADC_JOFR2_OFFSET   0x18 // 注入通道数据偏移寄存器 2
#define ADC_JOFR3_OFFSET   0x1C // 注入通道数据偏移寄存器 3
#define ADC_JOFR4_OFFSET   0x20 // 注入通道数据偏移寄存器 4
#define ADC_HTR_OFFSET     0x24 // 看门狗高阈值寄存器
#define ADC_LTR_OFFSET     0x28 // 看门狗低阈值寄存器
#define ADC_SQR1_OFFSET    0x2C // 规则序列寄存器 1
#define ADC_SQR2_OFFSET    0x30 // 规则序列寄存器 2
#define ADC_SQR3_OFFSET    0x34 // 规则序列寄存器 3
#define ADC_JSQR_OFFSET    0x38 // 注入序列寄存器
#define ADC_JDR1_OFFSET    0x3C // 注入数据寄存器 1
#define ADC_JDR2_OFFSET    0x40 // 注入数据寄存器 2
#define ADC_JDR3_OFFSET    0x44 // 注入数据寄存器 3
#define ADC_JDR4_OFFSET    0x48 // 注入数据寄存器 4
#define ADC_DR_OFFSET      0x4C // 规则数据寄存器

// ADC 通用寄存器偏移量
#define ADC_CSR_OFFSET     0x00 // 通用状态寄存器
#define ADC_CCR_OFFSET     0x04 // 通用控制寄存器
#define ADC_CDR_OFFSET     0x08 // 通用规则数据寄存器

// ADC 控制位定义
#define ADC_SR_EOC         0x00000002 // 转换结束标志
#define ADC_SR_STRT        0x00000010 // 规则转换开始标志

#define ADC_CR1_SCAN       0x00000100 // 扫描模式
#define ADC_CR1_EOCIE      0x00000020 // 转换结束中断使能
#define ADC_CR1_RES_MASK   0x00000030 // 分辨率掩码
#define ADC_CR1_RES_12BIT  0x00000000 // 12 位分辨率
#define ADC_CR1_RES_10BIT  0x00000010 // 10 位分辨率
#define ADC_CR1_RES_8BIT   0x00000020 // 8 位分辨率
#define ADC_CR1_RES_6BIT   0x00000030 // 6 位分辨率

#define ADC_CR2_ADON       0x00000001 // ADC 开启
#define ADC_CR2_CONT       0x00000002 // 连续转换模式
#define ADC_CR2_ALIGN      0x00000800 // 数据对齐 (0=右对齐,1=左对齐)
#define ADC_CR2_EXTEN_MASK 0x0000C000 // 外部触发使能掩码
#define ADC_CR2_EXTEN_NONE 0x00000000 // 禁用外部触发
#define ADC_CR2_EXTEN_RISING 0x00004000 // 上升沿触发
#define ADC_CR2_EXTSEL_MASK 0x00000F00 // 外部触发选择掩码
#define ADC_CR2_SWSTART    0x40000000 // 启动规则转换

// RCC 寄存器定义
#define RCC_BASE_ADDRESS   0x40023800
#define RCC_APB2ENR_OFFSET 0x44 // APB2 外设时钟使能寄存器

#define RCC_APB2ENR        (*(volatile uint32_t*)(RCC_BASE_ADDRESS + RCC_APB2ENR_OFFSET))
#define RCC_APB2ENR_ADC1EN 0x00000100 // ADC1 时钟使能位
#define RCC_APB2ENR_ADC2EN 0x00000200 // ADC2 时钟使能位
#define RCC_APB2ENR_ADC3EN 0x00000400 // ADC3 时钟使能位

// 系统滴答定时器,用于延时
#define SYSTICK_BASE       0xE000E010
#define SYSTICK_CTRL       (*(volatile uint32_t*)(SYSTICK_BASE))
#define SYSTICK_LOAD       (*(volatile uint32_t*)(SYSTICK_BASE + 0x04))
#define SYSTICK_VAL        (*(volatile uint32_t*)(SYSTICK_BASE + 0x08))

// 系统时钟 (假设为 84MHz)
#define SYSTEM_CLOCK       84000000UL

// 毫秒延时函数
static void delay_ms(uint32_t ms) {
    // 设置滴答定时器
    SYSTICK_LOAD = SYSTEM_CLOCK / 8000; // 1 ms
    SYSTICK_VAL = 0;
    SYSTICK_CTRL = 0x01; // 启用定时器
    
    for (uint32_t i = 0; i < ms; i++) {
        // 等待计数到 0 (位 16 会被置 1)
        while (!(SYSTICK_CTRL & 0x10000));
    }
    
    // 禁用定时器
    SYSTICK_CTRL = 0;
}

// 获取 ADC 寄存器地址
static volatile uint32_t* adc_get_register(AdcModule module, uint32_t offset) {
    uint32_t base_addr;
    
    switch (module) {
        case ADC_MODULE_1: base_addr = ADC1_BASE_ADDRESS; break;
        case ADC_MODULE_2: base_addr = ADC2_BASE_ADDRESS; break;
        case ADC_MODULE_3: base_addr = ADC3_BASE_ADDRESS; break;
        default: return NULL;
    }
    
    return (volatile uint32_t*)(base_addr + offset);
}

// 获取 ADC 通用寄存器地址
static volatile uint32_t* adc_get_common_register(uint32_t offset) {
    return (volatile uint32_t*)(ADC_COMMON_BASE + offset);
}

int adc_init(AdcModule module, const AdcConfig* config) {
    // 检查参数有效性
    if (module > ADC_MODULE_3 || !config) {
        return -1;
    }
    
    // 启用 ADC 时钟
    switch (module) {
        case ADC_MODULE_1:
            RCC_APB2ENR |= RCC_APB2ENR_ADC1EN;
            break;
        case ADC_MODULE_2:
            RCC_APB2ENR |= RCC_APB2ENR_ADC2EN;
            break;
        case ADC_MODULE_3:
            RCC_APB2ENR |= RCC_APB2ENR_ADC3EN;
            break;
    }
    
    // 获取关键寄存器
    volatile uint32_t* cr1 = adc_get_register(module, ADC_CR1_OFFSET);
    volatile uint32_t* cr2 = adc_get_register(module, ADC_CR2_OFFSET);
    
    if (!cr1 || !cr2) {
        return -1;
    }
    
    // 复位 ADC 配置
    *cr1 = 0;
    *cr2 = 0;
    
    // 设置 ADC 分辨率
    switch (config->resolution) {
        case ADC_RESOLUTION_12BIT:
            *cr1 |= ADC_CR1_RES_12BIT;
            break;
        case ADC_RESOLUTION_10BIT:
            *cr1 |= ADC_CR1_RES_10BIT;
            break;
        case ADC_RESOLUTION_8BIT:
            *cr1 |= ADC_CR1_RES_8BIT;
            break;
        case ADC_RESOLUTION_6BIT:
            *cr1 |= ADC_CR1_RES_6BIT;
            break;
    }
    
    // 设置扫描模式
    *cr1 |= ADC_CR1_SCAN;
    
    // 设置连续转换模式
    if (config->continuousMode) {
        *cr2 |= ADC_CR2_CONT;
    }
    
    // 设置数据对齐
    if (config->dataAlign) {
        *cr2 |= ADC_CR2_ALIGN;
    }
    
    // 设置外部触发源
    if (config->externalTrigger != ADC_TRIGGER_NONE) {
        *cr2 &= ~ADC_CR2_EXTSEL_MASK;
        *cr2 |= ((config->externalTrigger & 0x0F) << 24);
        *cr2 |= ADC_CR2_EXTEN_RISING;
    }
    
    // 使能 ADC
    *cr2 |= ADC_CR2_ADON;
    
    // 延时稳定
    delay_ms(1);
    
    return 0;
}

int adc_config_channel(AdcModule module, const AdcChannelConfig* channelConfig) {
    // 检查参数有效性
    if (module > ADC_MODULE_3 || !channelConfig || 
        channelConfig->channel > ADC_CHANNEL_VREF || 
        channelConfig->rank < 1 || channelConfig->rank > 16) {
        return -1;
    }
    
    // 获取采样时间寄存器
    volatile uint32_t* smpr1 = adc_get_register(module, ADC_SMPR1_OFFSET);
    volatile uint32_t* smpr2 = adc_get_register(module, ADC_SMPR2_OFFSET);
    
    // 获取序列寄存器
    volatile uint32_t* sqr1 = adc_get_register(module, ADC_SQR1_OFFSET);
    volatile uint32_t* sqr2 = adc_get_register(module, ADC_SQR2_OFFSET);
    volatile uint32_t* sqr3 = adc_get_register(module, ADC_SQR3_OFFSET);
    
    if (!smpr1 || !smpr2 || !sqr1 || !sqr2 || !sqr3) {
        return -1;
    }
    
    // 设置通道采样时间
    if (channelConfig->channel < 10) {
        // 通道0-9在SMPR2中
        uint32_t shift = channelConfig->channel * 3;
        *smpr2 &= ~(0x7UL << shift);
        *smpr2 |= (channelConfig->sampleTime & 0x7) << shift;
    } else if (channelConfig->channel < 18) {
        // 通道10-17在SMPR1中
        uint32_t shift = (channelConfig->channel - 10) * 3;
        *smpr1 &= ~(0x7UL << shift);
        *smpr1 |= (channelConfig->sampleTime & 0x7) << shift;
    }
    
    // 设置转换序列
    uint8_t rank = channelConfig->rank;
    if (rank <= 6) {
        // 排序1-6在SQR3中
        uint32_t shift = (rank - 1) * 5;
        *sqr3 &= ~(0x1FUL << shift);
        *sqr3 |= (channelConfig->channel & 0x1F) << shift;
    } else if (rank <= 12) {
        // 排序7-12在SQR2中
        uint32_t shift = (rank - 7) * 5;
        *sqr2 &= ~(0x1FUL << shift);
        *sqr2 |= (channelConfig->channel & 0x1F) << shift;
    } else {
        // 排序13-16在SQR1中
        uint32_t shift = (rank - 13) * 5;
        *sqr1 &= ~(0x1FUL << shift);
        *sqr1 |= (channelConfig->channel & 0x1F) << shift;
    }
    
    // 设置序列长度
    *sqr1 &= ~(0xFUL << 20);
    if (rank > (*sqr1 >> 20) & 0xF) {
        *sqr1 |= ((rank & 0xF) << 20);
    }
    
    // 如果是温度传感器或内部参考电压通道,需要额外配置
    if (channelConfig->channel == ADC_CHANNEL_TEMP || 
        channelConfig->channel == ADC_CHANNEL_VREF) {
        volatile uint32_t* ccr = adc_get_common_register(ADC_CCR_OFFSET);
        if (ccr) {
            *ccr |= 0x00800000; // 启用温度传感器和内部参考电压
        }
    }
    
    return 0;
}

int adc_start_conversion(AdcModule module) {
    // 检查参数有效性
    if (module > ADC_MODULE_3) {
        return -1;
    }
    
    // 获取状态和控制寄存器
    volatile uint32_t* sr = adc_get_register(module, ADC_SR_OFFSET);
    volatile uint32_t* cr2 = adc_get_register(module, ADC_CR2_OFFSET);
    
    if (!sr || !cr2) {
        return -1;
    }
    
    // 清除转换结束标志
    *sr &= ~ADC_SR_EOC;
    
    // 启动转换
    *cr2 |= ADC_CR2_SWSTART;
    
    return 0;
}

int adc_wait_for_conversion(AdcModule module, uint32_t timeout) {
    // 检查参数有效性
    if (module > ADC_MODULE_3) {
        return -1;
    }
    
    // 获取状态寄存器
    volatile uint32_t* sr = adc_get_register(module, ADC_SR_OFFSET);
    
    if (!sr) {
        return -1;
    }
    
    // 等待转换完成或超时
    uint32_t elapsed = 0;
    while (!(*sr & ADC_SR_EOC)) {
        if (timeout && elapsed >= timeout) {
            return -1; // 超时
        }
        delay_ms(1);
        elapsed++;
    }
    
    return 0;
}

uint16_t adc_read_value(AdcModule module) {
    // 检查参数有效性
    if (module > ADC_MODULE_3) {
        return 0xFFFF; // 返回最大值表示错误
    }
    
    // 获取数据寄存器
    volatile uint32_t* dr = adc_get_register(module, ADC_DR_OFFSET);
    
    if (!dr) {
        return 0xFFFF;
    }
    
    // 读取并返回转换结果
    return (*dr & 0xFFFF);
}

uint16_t adc_sample_channel(AdcModule module, AdcChannel channel, AdcSampleTime sampleTime) {
    // 设置 ADC 配置
    AdcConfig config = {
        .resolution = ADC_RESOLUTION_12BIT,
        .continuousMode = 0, // 单次转换模式
        .externalTrigger = ADC_TRIGGER_NONE, // 软件触发
        .dataAlign = 0 // 右对齐
    };
    
    // 初始化 ADC
    if (adc_init(module, &config) != 0) {
        return 0xFFFF;
    }
    
    // 设置通道配置
    AdcChannelConfig channelConfig = {
        .channel = channel,
        .sampleTime = sampleTime,
        .rank = 1 // 只有一个通道时,排序为1
    };
    
    if (adc_config_channel(module, &channelConfig) != 0) {
        return 0xFFFF;
    }
    
    // 启动转换
    if (adc_start_conversion(module) != 0) {
        return 0xFFFF;
    }
    
    // 等待转换完成
    if (adc_wait_for_conversion(module, 100) != 0) { // 设置超时为100ms
        return 0xFFFF;
    }
    
    // 读取并返回转换结果
    return adc_read_value(module);
}

2. FPGA 与软件协同设计

2.1 基于 AXI 总线的软件/硬件接口

c

/**
 * axi_hw_acc.h - AXI 总线硬件加速器接口
 * 
 * 用于在 SoC 上控制 FPGA 内实现的硬件加速器
 */

#ifndef AXI_HW_ACC_H
#define AXI_HW_ACC_H

#include <stdint.h>

// 硬件加速器命令类型
typedef enum {
    AXI_CMD_START = 0x01,        // 启动加速器
    AXI_CMD_STOP = 0x02,         // 停止加速器
    AXI_CMD_RESET = 0x03,        // 重置加速器
    AXI_CMD_CONFIG = 0x04,       // 配置加速器
    AXI_CMD_GET_STATUS = 0x05    // 获取加速器状态
} AxiCommand;

// 硬件加速器状态标志
typedef enum {
    AXI_STATUS_IDLE = 0x00,      // 空闲状态
    AXI_STATUS_BUSY = 0x01,      // 忙状态
    AXI_STATUS_DONE = 0x02,      // 完成状态
    AXI_STATUS_ERROR = 0x03      // 错误状态
} AxiStatus;

// 硬件加速器配置结构体 (根据具体加速器可以修改)
typedef struct {
    uint32_t inputAddress;       // 输入数据地址
    uint32_t outputAddress;      // 输出数据地址
    uint32_t dataLength;         // 数据长度
    uint32_t operation;          // 操作类型
    uint32_t flags;              // 其他配置标志
} AxiAccConfig;

/**
 * 打开 AXI 硬件加速器设备
 * 
 * @param baseAddress 加速器基地址
 * @return 0 表示成功,非零表示失败
 */
int axi_acc_open(uint32_t baseAddress);

/**
 * 关闭 AXI 硬件加速器设备
 * 
 * @return 0 表示成功,非零表示失败
 */
int axi_acc_close(void);

/**
 * 发送命令到硬件加速器
 * 
 * @param cmd 命令类型
 * @param arg 命令参数 (根据命令类型而定)
 * @return 0 表示成功,非零表示失败
 */
int axi_acc_send_command(AxiCommand cmd, uint32_t arg);

/**
 * 配置硬件加速器
 * 
 * @param config 配置参数
 * @return 0 表示成功,非零表示失败
 */
int axi_acc_configure(const AxiAccConfig* config);

/**
 * 获取硬件加速器状态
 * 
 * @return 加速器状态
 */
AxiStatus axi_acc_get_status(void);

/**
 * 等待硬件加速器完成操作
 * 
 * @param timeout_ms 超时时间 (毫秒),0 表示无限等待
 * @return 0 表示成功,非零表示超时或失败
 */
int axi_acc_wait_completion(uint32_t timeout_ms);

/**
 * 读取硬件加速器寄存器
 * 
 * @param regOffset 寄存器偏移地址
 * @return 寄存器值
 */
uint32_t axi_acc_read_register(uint32_t regOffset);

/**
 * 写入硬件加速器寄存器
 * 
 * @param regOffset 寄存器偏移地址
 * @param value 要写入的值
 * @return 0 表示成功,非零表示失败
 */
int axi_acc_write_register(uint32_t regOffset, uint32_t value);

#endif /* AXI_HW_ACC_H */

c

/**
 * axi_hw_acc.c - AXI 总线硬件加速器接口实现
 * 
 * 基于内存映射 I/O 实现与 FPGA 加速器的通信
 */

#include "axi_hw_acc.h"
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>

// 硬件加速器寄存器偏移定义
#define AXI_REG_CONTROL         0x00    // 控制寄存器
#define AXI_REG_STATUS          0x04    // 状态寄存器
#define AXI_REG_INPUT_ADDR      0x08    // 输入数据地址寄存器
#define AXI_REG_OUTPUT_ADDR     0x0C    // 输出数据地址寄存器
#define AXI_REG_DATA_LENGTH     0x10    // 数据长度寄存器
#define AXI_REG_OPERATION       0x14    // 操作类型寄存器
#define AXI_REG_FLAGS           0x18    // 标志寄存器
#define AXI_REG_INTERRUPT       0x1C    // 中断状态/清除寄存器

// 控制寄存器位定义
#define AXI_CTRL_START          0x00000001  // 启动位
#define AXI_CTRL_STOP           0x00000002  // 停止位
#define AXI_CTRL_RESET          0x00000004  // 复位位
#define AXI_CTRL_IRQ_ENABLE     0x00000008  // 中断使能位

// 状态寄存器位定义
#define AXI_STATUS_MASK         0x00000003  // 状态掩码
#define AXI_STATUS_IRQ_FLAG     0x00000010  // 中断标志

// 文件描述符和内存映射指针
static int mem_fd = -1;
static volatile uint32_t* axi_base_ptr = NULL;
static uint32_t axi_base_addr = 0;

// 毫秒级延时函数
static void delay_ms(uint32_t ms) {
    struct timespec ts;
    ts.tv_sec = ms / 1000;
    ts.tv_nsec = (ms % 1000) * 1000000;
    nanosleep(&ts, NULL);
}

int axi_acc_open(uint32_t baseAddress) {
    // 保存基址以便后续使用
    axi_base_addr = baseAddress;
    
    // 打开 /dev/mem 设备以进行内存映射访问
    mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
    if (mem_fd < 0) {
        perror("打开 /dev/mem 失败");
        return -1;
    }
    
    // 映射硬件加速器寄存器空间到进程地址空间
    // 假设加速器有 4KB (0x1000) 的寄存器空间
    axi_base_ptr = (volatile uint32_t*)mmap(NULL, 0x1000, 
                                           PROT_READ | PROT_WRITE, 
                                           MAP_SHARED, 
                                           mem_fd, 
                                           baseAddress);
    
    if (axi_base_ptr == MAP_FAILED) {
        perror("内存映射失败");
        close(mem_fd);
        mem_fd = -1;
        return -1;
    }
    
    // 发送复位命令确保加速器处于已知状态
    return axi_acc_send_command(AXI_CMD_RESET, 0);
}

int axi_acc_close(void) {
    int ret = 0;
    
    // 关闭前确保加速器不在运行
    axi_acc_send_command(AXI_CMD_STOP, 0);
    
    // 取消内存映射
    if (axi_base_ptr != NULL && axi_base_ptr != MAP_FAILED) {
        if (munmap((void*)axi_base_ptr, 0x1000) != 0) {
            perror("取消内存映射失败");
            ret = -1;
        }
        axi_base_ptr = NULL;
    }
    
    // 关闭文件描述符
    if (mem_fd >= 0) {
        if (close(mem_fd) != 0) {
            perror("关闭文件描述符失败");
            ret = -1;
        }
        mem_fd = -1;
    }
    
    return ret;
}

int axi_acc_send_command(AxiCommand cmd, uint32_t arg) {
    // 确保设备已打开
    if (axi_base_ptr == NULL || axi_base_ptr == MAP_FAILED) {
        fprintf(stderr, "设备未打开\n");
        return -1;
    }
    
    // 根据命令类型设置相应的控制寄存器位
    uint32_t ctrl_value = 0;
    
    switch (cmd) {
        case AXI_CMD_START:
            ctrl_value = AXI_CTRL_START;
            if (arg & 0x1) {
                ctrl_value |= AXI_CTRL_IRQ_ENABLE; // 启用中断
            }
            break;
            
        case AXI_CMD_STOP:
            ctrl_value = AXI_CTRL_STOP;
            break;
            
        case AXI_CMD_RESET:
            ctrl_value = AXI_CTRL_RESET;
            break;
            
        case AXI_CMD_CONFIG:
            // 配置命令由 axi_acc_configure 函数处理
            return -1;
            
        case AXI_CMD_GET_STATUS:
            // 获取状态命令由 axi_acc_get_status 函数处理
            return -1;
            
        default:
            fprintf(stderr, "未知命令\n");
            return -1;
    }
    
    // 写入控制寄存器
    axi_base_ptr[AXI_REG_CONTROL / 4] = ctrl_value;
    
    // 如果是复位命令,需要等待一段时间后再清除复位状态
    if (cmd == AXI_CMD_RESET) {
        delay_ms(10); // 等待10毫秒
        axi_base_ptr[AXI_REG_CONTROL / 4] = 0; // 清除复位状态
    }
    
    return 0;
}

int axi_acc_configure(const AxiAccConfig* config) {
    // 确保设备已打开
    if (axi_base_ptr == NULL || axi_base_ptr == MAP_FAILED) {
        fprintf(stderr, "设备未打开\n");
        return -1;
    }
    
    // 确保加速器处于空闲状态
    AxiStatus status = axi_acc_get_status();
    if (status != AXI_STATUS_IDLE && status != AXI_STATUS_DONE) {
        fprintf(stderr, "加速器非空闲状态, 当前状态: %d\n", status);
        return -1;
    }
    
    // 写入配置参数到相应寄存器
    axi_base_ptr[AXI_REG_INPUT_ADDR / 4] = config->inputAddress;
    axi_base_ptr[AXI_REG_OUTPUT_ADDR / 4] = config->outputAddress;
    axi_base_ptr[AXI_REG_DATA_LENGTH / 4] = config->dataLength;
    axi_base_ptr[AXI_REG_OPERATION / 4] = config->operation;
    axi_base_ptr[AXI_REG_FLAGS / 4] = config->flags;
    
    return 0;
}

AxiStatus axi_acc_get_status(void) {
    // 确保设备已打开
    if (axi_base_ptr == NULL || axi_base_ptr == MAP_FAILED) {
        fprintf(stderr, "设备未打开\n");
        return AXI_STATUS_ERROR;
    }
    
    // 读取状态寄存器并提取状态位
    uint32_t status_reg = axi_base_ptr[AXI_REG_STATUS / 4];
    return (AxiStatus)(status_reg & AXI_STATUS_MASK);
}

int axi_acc_wait_completion(uint32_t timeout_ms) {
    // 确保设备已打开
    if (axi_base_ptr == NULL || axi_base_ptr == MAP_FAILED) {
        fprintf(stderr, "设备未打开\n");
        return -1;
    }
    
    // 记录开始时间
    uint32_t start_time = (uint32_t)time(NULL) * 1000;
    uint32_t current_time;
    AxiStatus status;
    
    // 轮询加速器状态直到完成、出错或超时
    do {
        status = axi_acc_get_status();
        
        if (status == AXI_STATUS_DONE || status == AXI_STATUS_ERROR) {
            // 如果有中断标志,清除它
            if (axi_base_ptr[AXI_REG_STATUS / 4] & AXI_STATUS_IRQ_FLAG) {
                axi_base_ptr[AXI_REG_INTERRUPT / 4] = AXI_STATUS_IRQ_FLAG;
            }
            
            // 如果操作完成并且没有错误,返回成功
            return (status == AXI_STATUS_DONE) ? 0 : -1;
        }
        
        // 检查是否超时
        if (timeout_ms > 0) {
            current_time = (uint32_t)time(NULL) * 1000;
            if (current_time - start_time >= timeout_ms) {
                fprintf(stderr, "等待加速器完成操作超时\n");
                return -1;
            }
        }
        
        // 短暂休眠以避免忙等待占用过多 CPU
        delay_ms(1);
        
    } while (1);
    
    // 不应该到达这里
    return -1;
}

uint32_t axi_acc_read_register(uint32_t regOffset) {
    // 确保设备已打开
    if (axi_base_ptr == NULL || axi_base_ptr == MAP_FAILED) {
        fprintf(stderr, "设备未打开\n");
        return 0xFFFFFFFF; // 返回全1表示错误
    }
    
    // 确保偏移地址有效 (假设寄存器空间为4KB)
    if (regOffset >= 0x1000 || (regOffset & 0x3) != 0) {
        fprintf(stderr, "无效的寄存器偏移: 0x%08X\n", regOffset);
        return 0xFFFFFFFF;
    }
    
    // 读取并返回寄存器值
    return axi_base_ptr[regOffset / 4];
}

int axi_acc_write_register(uint32_t regOffset, uint32_t value) {
    // 确保设备已打开
    if (axi_base_ptr == NULL || axi_base_ptr == MAP_FAILED) {
        fprintf(stderr, "设备未打开\n");
        return -1;
    }
    
    // 确保偏移地址有效 (假设寄存器空间为4KB)
    if (regOffset >= 0x1000 || (regOffset & 0x3) != 0) {
        fprintf(stderr, "无效的寄存器偏移: 0x%08X\n", regOffset);
        return -1;
    }
    
    // 写入寄存器
    axi_base_ptr[regOffset / 4] = value;
    
    return 0;
}

2.2 硬件加速器应用示例 - 矩阵乘法

c

/**
 * matrix_multiply.h - 矩阵乘法硬件加速器接口
 * 
 * 提供利用FPGA矩阵乘法加速器的软件API
 */

#ifndef MATRIX_MULTIPLY_H
#define MATRIX_MULTIPLY_H

#include <stdint.h>
#include "axi_hw_acc.h"

// 矩阵乘法操作类型
typedef enum {
    MATRIX_OP_NORMAL = 0,        // 普通矩阵乘法 C = A * B
    MATRIX_OP_TRANSPOSE_A = 1,   // A转置乘法 C = A^T * B
    MATRIX_OP_TRANSPOSE_B = 2,   // B转置乘法 C = A * B^T
    MATRIX_OP_TRANSPOSE_AB = 3   // 双转置乘法 C = A^T * B^T
} MatrixOperation;

// 矩阵乘法描述符
typedef struct {
    float* matrixA;          // 矩阵A数据指针
    float* matrixB;          // 矩阵B数据指针
    float* matrixC;          // 结果矩阵C数据指针
    uint32_t rowsA;          // 矩阵A的行数
    uint32_t colsA;          // 矩阵A的列数
    uint32_t colsB;          // 矩阵B的列数
    MatrixOperation op;      // 操作类型
} MatrixMultiplyDesc;

/**
 * 初始化矩阵乘法加速器
 * 
 * @param baseAddress 加速器基地址
 * @return 0 表示成功,非零表示失败
 */
int matrix_multiply_init(uint32_t baseAddress);

/**
 * 关闭矩阵乘法加速器
 * 
 * @return 0 表示成功,非零表示失败
 */
int matrix_multiply_close(void);

/**
 * 执行矩阵乘法运算
 * 
 * @param desc 矩阵乘法描述符
 * @param useHardware 是否使用硬件加速 (1=使用,0=软件实现)
 * @return 0 表示成功,非零表示失败
 */
int matrix_multiply_execute(MatrixMultiplyDesc* desc, int useHardware);

/**
 * 进行矩阵乘法性能测试
 * 
 * @param size 方阵大小
 * @param iterations 迭代次数
 * @return 0 表示成功,非零表示失败
 */
int matrix_multiply_benchmark(uint32_t size, uint32_t iterations);

#endif /* MATRIX_MULTIPLY_H */

c

/**
 * matrix_multiply.c - 矩阵乘法硬件加速器实现
 * 
 * 硬件协同设计的典型应用:同时提供硬件加速和软件实现
 */

#include "matrix_multiply.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>

// DMA缓冲区分配和内存管理函数
static void* alloc_dma_buffer(size_t size);
static void free_dma_buffer(void* buffer);
static uint64_t get_physical_address(void* virtual_address);

// 软件矩阵乘法实现
static int matrix_multiply_software(MatrixMultiplyDesc* desc);

// 获取当前时间(毫秒)
static uint64_t get_time_ms(void) {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (uint64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
}

int matrix_multiply_init(uint32_t baseAddress) {
    // 打开并初始化AXI硬件加速器
    return axi_acc_open(baseAddress);
}

int matrix_multiply_close(void) {
    // 关闭AXI硬件加速器
    return axi_acc_close();
}

int matrix_multiply_execute(MatrixMultiplyDesc* desc, int useHardware) {
    // 参数验证
    if (!desc || !desc->matrixA || !desc->matrixB || !desc->matrixC) {
        fprintf(stderr, "矩阵描述符或矩阵数据为空\n");
        return -1;
    }
    
    if (desc->rowsA == 0 || desc->colsA == 0 || desc->colsB == 0) {
        fprintf(stderr, "矩阵维度无效\n");
        return -1;
    }
    
    // 根据需要选择硬件或软件实现
    if (useHardware) {
        // 使用硬件加速器实现
        
        // 分配DMA缓冲区用于传输数据
        size_t sizeA = desc->rowsA * desc->colsA * sizeof(float);
        size_t sizeB = desc->colsA * desc->colsB * sizeof(float);
        size_t sizeC = desc->rowsA * desc->colsB * sizeof(float);
        
        float* dmaA = (float*)alloc_dma_buffer(sizeA);
        float* dmaB = (float*)alloc_dma_buffer(sizeB);
        float* dmaC = (float*)alloc_dma_buffer(sizeC);
        
        if (!dmaA || !dmaB || !dmaC) {
            fprintf(stderr, "分配DMA缓冲区失败\n");
            if (dmaA) free_dma_buffer(dmaA);
            if (dmaB) free_dma_buffer(dmaB);
            if (dmaC) free_dma_buffer(dmaC);
            return -1;
        }
        
        // 复制输入数据到DMA缓冲区
        memcpy(dmaA, desc->matrixA, sizeA);
        memcpy(dmaB, desc->matrixB, sizeB);
        
        // 获取物理地址用于配置硬件加速器
        uint64_t phyAddrA = get_physical_address(dmaA);
        uint64_t phyAddrB = get_physical_address(dmaB);
        uint64_t phyAddrC = get_physical_address(dmaC);
        
        if (phyAddrA == 0 || phyAddrB == 0 || phyAddrC == 0) {
            fprintf(stderr, "获取物理地址失败\n");
            free_dma_buffer(dmaA);
            free_dma_buffer(dmaB);
            free_dma_buffer(dmaC);
            return -1;
        }
        
        // 配置硬件加速器
        AxiAccConfig hwConfig;
        hwConfig.inputAddress = (uint32_t)phyAddrA;  // 矩阵A物理地址
        hwConfig.outputAddress = (uint32_t)phyAddrC; // 结果矩阵C物理地址
        hwConfig.dataLength = desc->rowsA;           // 行数
        hwConfig.operation = desc->op;               // 操作类型
        
        // 额外配置信息(使用flags字段)
        hwConfig.flags = ((uint32_t)phyAddrB & 0xFFFFFFFF)  // 矩阵B物理地址低32位
                       | ((uint32_t)desc->colsA << 16)      // A列数(高16位)
                       | ((uint32_t)desc->colsB);           // B列数(低16位)
        
        // 发送配置到硬件
        if (axi_acc_configure(&hwConfig) != 0) {
            fprintf(stderr, "配置硬件加速器失败\n");
            free_dma_buffer(dmaA);
            free_dma_buffer(dmaB);
            free_dma_buffer(dmaC);
            return -1;
        }
        
        // 启动硬件加速器
        if (axi_acc_send_command(AXI_CMD_START, 1) != 0) {
            fprintf(stderr, "启动硬件加速器失败\n");
            free_dma_buffer(dmaA);
            free_dma_buffer(dmaB);
            free_dma_buffer(dmaC);
            return -1;
        }
        
        // 等待计算完成
        if (axi_acc_wait_completion(5000) != 0) {  // 5秒超时
            fprintf(stderr, "硬件加速器执行超时或出错\n");
            free_dma_buffer(dmaA);
            free_dma_buffer(dmaB);
            free_dma_buffer(dmaC);
            return -1;
        }
        
        // 从DMA缓冲区复制结果到目标矩阵
        memcpy(desc->matrixC, dmaC, sizeC);
        
        // 释放DMA缓冲区
        free_dma_buffer(dmaA);
        free_dma_buffer(dmaB);
        free_dma_buffer(dmaC);
        
    } else {
        // 使用软件实现
        return matrix_multiply_software(desc);
    }
    
    return 0;
}

int matrix_multiply_benchmark(uint32_t size, uint32_t iterations) {
    int ret = 0;
    uint64_t sw_time_total = 0, hw_time_total = 0;
    uint64_t start_time, end_time;
    
    // 分配矩阵内存
    float* matrixA = (float*)malloc(size * size * sizeof(float));
    float* matrixB = (float*)malloc(size * size * sizeof(float));
    float* matrixC_sw = (float*)malloc(size * size * sizeof(float));
    float* matrixC_hw = (float*)malloc(size * size * sizeof(float));
    
    if (!matrixA || !matrixB || !matrixC_sw || !matrixC_hw) {
        fprintf(stderr, "内存分配失败\n");
        if (matrixA) free(matrixA);
        if (matrixB) free(matrixB);
        if (matrixC_sw) free(matrixC_sw);
        if (matrixC_hw) free(matrixC_hw);
        return -1;
    }
    
    // 随机生成测试数据
    srand(time(NULL));
    for (uint32_t i = 0; i < size * size; i++) {
        matrixA[i] = (float)rand() / RAND_MAX;
        matrixB[i] = (float)rand() / RAND_MAX;
    }
    
    // 准备矩阵乘法描述符
    MatrixMultiplyDesc desc;
    desc.matrixA = matrixA;
    desc.matrixB = matrixB;
    desc.rowsA = size;
    desc.colsA = size;
    desc.colsB = size;
    desc.op = MATRIX_OP_NORMAL;
    
    // 执行软件矩阵乘法基准测试
    for (uint32_t i = 0; i < iterations; i++) {
        desc.matrixC = matrixC_sw;
        
        start_time = get_time_ms();
        ret = matrix_multiply_execute(&desc, 0);  // 使用软件实现
        end_time = get_time_ms();
        
        if (ret != 0) {
            fprintf(stderr, "软件矩阵乘法执行失败\n");
            break;
        }
        
        sw_time_total += (end_time - start_time);
    }
    
    // 执行硬件矩阵乘法基准测试
    for (uint32_t i = 0; i < iterations; i++) {
        desc.matrixC = matrixC_hw;
        
        start_time = get_time_ms();
        ret = matrix_multiply_execute(&desc, 1);  // 使用硬件加速
        end_time = get_time_ms();
        
        if (ret != 0) {
            fprintf(stderr, "硬件矩阵乘法执行失败\n");
            break;
        }
        
        hw_time_total += (end_time - start_time);
    }
    
    // 验证结果一致性
    if (ret == 0) {
        int mismatch = 0;
        for (uint32_t i = 0; i < size * size; i++) {
            if (fabsf(matrixC_sw[i] - matrixC_hw[i]) > 1e-4) {
                mismatch++;
            }
        }
        
        if (mismatch > 0) {
            fprintf(stderr, "结果不匹配: %d 个元素(共 %u 个)\n", mismatch, size * size);
            ret = -1;
        }
    }
    
    // 打印性能数据
    if (ret == 0) {
        float sw_avg_time = (float)sw_time_total / iterations;
        float hw_avg_time = (float)hw_time_total / iterations;
        float speedup = sw_avg_time / hw_avg_time;
        
        printf("矩阵乘法基准测试 (尺寸: %u x %u, 迭代: %u)\n", size, size, iterations);
        printf("软件实现平均时间: %.2f ms\n", sw_avg_time);
        printf("硬件加速平均时间: %.2f ms\n", hw_avg_time);
        printf("加速比: %.2f x\n", speedup);
    }
    
    // 释放内存
    free(matrixA);
    free(matrixB);
    free(matrixC_sw);
    free(matrixC_hw);
    
    return ret;
}

// 软件矩阵乘法实现
static int matrix_multiply_software(MatrixMultiplyDesc* desc) {
    uint32_t i, j, k;
    uint32_t rowsA = desc->rowsA;
    uint32_t colsA = desc->colsA;
    uint32_t colsB = desc->colsB;
    
    // 初始化结果矩阵
    memset(desc->matrixC, 0, rowsA * colsB * sizeof(float));
    
    // 根据操作类型执行不同的矩阵乘法
    switch (desc->op) {
        case MATRIX_OP_NORMAL:
            // C = A * B
            for (i = 0; i < rowsA; i++) {
                for (j = 0; j < colsB; j++) {
                    for (k = 0; k < colsA; k++) {
                        desc->matrixC[i * colsB + j] += 
                            desc->matrixA[i * colsA + k] * desc->matrixB[k * colsB + j];
                    }
                }
            }
            break;
            
        case MATRIX_OP_TRANSPOSE_A:
            // C = A^T * B
            for (i = 0; i < colsA; i++) {
                for (j = 0; j < colsB; j++) {
                    for (k = 0; k < rowsA; k++) {
                        desc->matrixC[i * colsB + j] += 
                            desc->matrixA[k * colsA + i] * desc->matrixB[k * colsB + j];
                    }
                }
            }
            break;
            
        case MATRIX_OP_TRANSPOSE_B:
            // C = A * B^T
            for (i = 0; i < rowsA; i++) {
                for (j = 0; j < colsA; j++) {
                    for (k = 0; k < colsB; k++) {
                        desc->matrixC[i * colsA + j] += 
                            desc->matrixA[i * colsA + k] * desc->matrixB[j * colsB + k];
                    }
                }
            }
            break;
            
        case MATRIX_OP_TRANSPOSE_AB:
            // C = A^T * B^T
            for (i = 0; i < colsA; i++) {
                for (j = 0; j < colsA; j++) {
                    for (k = 0; k < rowsA; k++) {
                        desc->matrixC[i * colsA + j] += 
                            desc->matrixA[k * colsA + i] * desc->matrixB[j * colsB + k];
                    }
                }
            }
            break;
            
        default:
            fprintf(stderr, "未知的矩阵操作类型: %d\n", desc->op);
            return -1;
    }
    
    return 0;
}

// DMA缓冲区分配 (简化实现,实际代码需根据目标平台调整)
static void* alloc_dma_buffer(size_t size) {
    // 在实际系统中,这里通常使用特殊的API来分配物理连续内存
    // 例如在Linux中可能使用DMA缓冲区API或contiguous memory allocator
    // 这里仅作为示例,使用常规内存分配
    return malloc(size);
}

static void free_dma_buffer(void* buffer) {
    free(buffer);
}

static uint64_t get_physical_address(void* virtual_address) {
    // 在实际系统中,这里需要使用特定平台的方法获取物理地址
    // 例如在Linux中可能使用/proc/self/pagemap或特定驱动API
    // 这里仅作为示例,直接返回虚拟地址的值(不正确,但作为示例)
    return (uint64_t)virtual_address;
}

2.3 自定义硬件IP核的接口实现

cpp

/**
 * custom_ip.h - 自定义硬件IP核的C++接口
 * 
 * 提供面向对象的封装,用于访问FPGA中的自定义IP核
 */

#ifndef CUSTOM_IP_H
#define CUSTOM_IP_H

#include <cstdint>
#include <string>
#include <vector>
#include <memory>

namespace hw_accel {

// 前向声明
class CustomIPImpl;

/**
 * 自定义硬件IP核的C++接口类
 */
class CustomIP {
public:
    /**
     * 构造函数
     * 
     * @param device_name 设备名称
     * @param base_address 基地址
     */
    CustomIP(const std::string& device_name, uint64_t base_address);
    
    /**
     * 析构函数
     */
    ~CustomIP();
    
    /**
     * 打开设备
     * 
     * @return 成功返回true,失败返回false
     */
    bool open();
    
    /**
     * 关闭设备
     */
    void close();
    
    /**
     * 检查设备是否已打开
     * 
     * @return 已打开返回true,否则返回false
     */
    bool is_open() const;
    
    /**
     * 获取设备名称
     * 
     * @return 设备名称
     */
    std::string get_device_name() const;
    
    /**
     * 获取设备基地址
     * 
     * @return 基地址
     */
    uint64_t get_base_address() const;
    
    /**
     * 从指定偏移读取32位数据
     * 
     * @param offset 寄存器偏移
     * @return 32位寄存器值
     */
    uint32_t read_register(uint32_t offset) const;
    
    /**
     * 向指定偏移写入32位数据
     * 
     * @param offset 寄存器偏移
     * @param value 要写入的值
     */
    void write_register(uint32_t offset, uint32_t value);
    
    /**
     * 读取一块连续的32位数据
     * 
     * @param offset 起始偏移
     * @param length 数据长度(32位字数)
     * @return 32位数据向量
     */
    std::vector<uint32_t> read_block(uint32_t offset, size_t length) const;
    
    /**
     * 写入一块连续的32位数据
     * 
     * @param offset 起始偏移
     * @param data 要写入的数据向量
     */
    void write_block(uint32_t offset, const std::vector<uint32_t>& data);
    
    /**
     * 等待指定位置位
     * 
     * @param offset 寄存器偏移
     * @param mask 位掩码
     * @param timeout_ms 超时时间(毫秒)
     * @return 成功返回true,超时返回false
     */
    bool wait_for_bit_set(uint32_t offset, uint32_t mask, uint32_t timeout_ms = 1000) const;
    
    /**
     * 等待指定位清零
     * 
     * @param offset 寄存器偏移
     * @param mask 位掩码
     * @param timeout_ms 超时时间(毫秒)
     * @return 成功返回true,超时返回false
     */
    bool wait_for_bit_clear(uint32_t offset, uint32_t mask, uint32_t timeout_ms = 1000) const;
    
    /**
     * 获取最后一个错误消息
     * 
     * @return 错误消息
     */
    std::string get_last_error() const;
    
private:
    // 私有实现 (PIMPL模式)
    std::unique_ptr<CustomIPImpl> impl_;
    
    // 禁止拷贝和赋值
    CustomIP(const CustomIP&) = delete;
    CustomIP& operator=(const CustomIP&) = delete;
};

} // namespace hw_accel

#endif /* CUSTOM_IP_H */

cpp

/**
 * custom_ip.cpp - 自定义硬件IP核的C++接口实现
 * 
 * 使用PIMPL设计模式隐藏实现细节
 */

#include "custom_ip.h"
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <chrono>
#include <thread>
#include <system_error>
#include <cerrno>
#include <cstring>

namespace hw_accel {

// 私有实现类
class CustomIPImpl {
public:
    CustomIPImpl(const std::string& device_name, uint64_t base_address)
        : device_name_(device_name),
          base_address_(base_address),
          fd_(-1),
          mapped_addr_(nullptr),
          mapped_size_(0),
          last_error_() {}
    
    ~CustomIPImpl() {
        close();
    }
    
    bool open() {
        // 如果已经打开,先关闭
        if (fd_ >= 0) {
            close();
        }
        
        // 清除上一次错误
        last_error_.clear();
        
        // 打开/dev/mem设备文件
        fd_ = ::open("/dev/mem", O_RDWR | O_SYNC);
        if (fd_ < 0) {
            last_error_ = "打开/dev/mem失败: " + std::string(strerror(errno));
            return false;
        }
        
        // 设置映射大小 (假设为4KB)
        mapped_size_ = 4096;
        
        // 使用mmap映射硬件地址空间
        mapped_addr_ = mmap(nullptr, mapped_size_, PROT_READ | PROT_WRITE, 
                          MAP_SHARED, fd_, base_address_);
        
        if (mapped_addr_ == MAP_FAILED) {
            last_error_ = "内存映射失败: " + std::string(strerror(errno));
            ::close(fd_);
            fd_ = -1;
            mapped_addr_ = nullptr;
            return false;
        }
        
        return true;
    }
    
    void close() {
        if (mapped_addr_ != nullptr && mapped_addr_ != MAP_FAILED) {
            munmap(mapped_addr_, mapped_size_);
            mapped_addr_ = nullptr;
        }
        
        if (fd_ >= 0) {
            ::close(fd_);
            fd_ = -1;
        }
    }
    
    bool is_open() const {
        return (fd_ >= 0 && mapped_addr_ != nullptr && mapped_addr_ != MAP_FAILED);
    }
    
    std::string get_device_name() const {
        return device_name_;
    }
    
    uint64_t get_base_address() const {
        return base_address_;
    }
    
    uint32_t read_register(uint32_t offset) const {
        if (!is_open()) {
            const_cast<CustomIPImpl*>(this)->last_error_ = "设备未打开";
            return 0xFFFFFFFF;
        }
        
        if (offset >= mapped_size_) {
            const_cast<CustomIPImpl*>(this)->last_error_ = "访问超出映射范围";
            return 0xFFFFFFFF;
        }
        
        // 读取寄存器值
        volatile uint32_t* reg_ptr = static_cast<volatile uint32_t*>(mapped_addr_) + (offset / 4);
        return *reg_ptr;
    }
    
    void write_register(uint32_t offset, uint32_t value) {
        if (!is_open()) {
            last_error_ = "设备未打开";
            return;
        }
        
        if (offset >= mapped_size_) {
            last_error_ = "访问超出映射范围";
            return;
        }
        
        // 写入寄存器值
        volatile uint32_t* reg_ptr = static_cast<volatile uint32_t*>(mapped_addr_) + (offset / 4);
        *reg_ptr = value;
    }
    
    std::vector<uint32_t> read_block(uint32_t offset, size_t length) const {
        std::vector<uint32_t> result;
        
        if (!is_open()) {
            const_cast<CustomIPImpl*>(this)->last_error_ = "设备未打开";
            return result;
        }
        
        if (offset + length * 4 > mapped_size_) {
            const_cast<CustomIPImpl*>(this)->last_error_ = "访问超出映射范围";
            return result;
        }
        
        // 预先分配空间
        result.reserve(length);
        
        // 读取连续的寄存器块
        volatile uint32_t* reg_ptr = static_cast<volatile uint32_t*>(mapped_addr_) + (offset / 4);
        for (size_t i = 0; i < length; ++i) {
            result.push_back(reg_ptr[i]);
        }
        
        return result;
    }
    
    void write_block(uint32_t offset, const std::vector<uint32_t>& data) {
        if (!is_open()) {
            last_error_ = "设备未打开";
            return;
        }
        
        if (offset + data.size() * 4 > mapped_size_) {
            last_error_ = "访问超出映射范围";
            return;
        }
        
        // 写入连续的寄存器块
        volatile uint32_t* reg_ptr = static_cast<volatile uint32_t*>(mapped_addr_) + (offset / 4);
        for (size_t i = 0; i < data.size(); ++i) {
            reg_ptr[i] = data[i];
        }
    }
    
    bool wait_for_bit_set(uint32_t offset, uint32_t mask, uint32_t timeout_ms) const {
        if (!is_open()) {
            const_cast<CustomIPImpl*>(this)->last_error_ = "设备未打开";
            return false;
        }
        
        // 获取当前时间
        auto start_time = std::chrono::steady_clock::now();
        
        // 轮询等待指定位置位
        while (true) {
            uint32_t value = read_register(offset);
            
            // 检查指定位是否已置位
            if ((value & mask) == mask) {
                return true;
            }
            
            // 检查是否超时
            auto current_time = std::chrono::steady_clock::now();
            auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
                current_time - start_time).count();
            
            if (elapsed >= timeout_ms) {
                const_cast<CustomIPImpl*>(this)->last_error_ = "等待位置位超时";
                return false;
            }
            
            // 短暂休眠以避免过度占用CPU
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
        }
    }
    
    bool wait_for_bit_clear(uint32_t offset, uint32_t mask, uint32_t timeout_ms) const {
        if (!is_open()) {
            const_cast<CustomIPImpl*>(this)->last_error_ = "设备未打开";
            return false;
        }
        
        // 获取当前时间
        auto start_time = std::chrono::steady_clock::now();
        
        // 轮询等待指定位

cpp

        // 轮询等待指定位清零
        while (true) {
            uint32_t value = read_register(offset);
            
            // 检查指定位是否已清零
            if ((value & mask) == 0) {
                return true;
            }
            
            // 检查是否超时
            auto current_time = std::chrono::steady_clock::now();
            auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
                current_time - start_time).count();
            
            if (elapsed >= timeout_ms) {
                const_cast<CustomIPImpl*>(this)->last_error_ = "等待位清零超时";
                return false;
            }
            
            // 短暂休眠以避免过度占用CPU
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
        }
    }
    
    std::string get_last_error() const {
        return last_error_;
    }
    
private:
    std::string device_name_;    // 设备名称
    uint64_t base_address_;      // 基地址
    int fd_;                     // 文件描述符
    void* mapped_addr_;          // 内存映射地址
    size_t mapped_size_;         // 映射大小
    std::string last_error_;     // 最后一个错误消息
};

// CustomIP的外部实现,委托给CustomIPImpl

CustomIP::CustomIP(const std::string& device_name, uint64_t base_address)
    : impl_(new CustomIPImpl(device_name, base_address)) {
}

CustomIP::~CustomIP() = default;

bool CustomIP::open() {
    return impl_->open();
}

void CustomIP::close() {
    impl_->close();
}

bool CustomIP::is_open() const {
    return impl_->is_open();
}

std::string CustomIP::get_device_name() const {
    return impl_->get_device_name();
}

uint64_t CustomIP::get_base_address() const {
    return impl_->get_base_address();
}

uint32_t CustomIP::read_register(uint32_t offset) const {
    return impl_->read_register(offset);
}

void CustomIP::write_register(uint32_t offset, uint32_t value) {
    impl_->write_register(offset, value);
}

std::vector<uint32_t> CustomIP::read_block(uint32_t offset, size_t length) const {
    return impl_->read_block(offset, length);
}

void CustomIP::write_block(uint32_t offset, const std::vector<uint32_t>& data) {
    impl_->write_block(offset, data);
}

bool CustomIP::wait_for_bit_set(uint32_t offset, uint32_t mask, uint32_t timeout_ms) const {
    return impl_->wait_for_bit_set(offset, mask, timeout_ms);
}

bool CustomIP::wait_for_bit_clear(uint32_t offset, uint32_t mask, uint32_t timeout_ms) const {
    return impl_->wait_for_bit_clear(offset, mask, timeout_ms);
}

std::string CustomIP::get_last_error() const {
    return impl_->get_last_error();
}

} // namespace hw_accel

2.4 FFT 硬件加速器实例

cpp

/**
 * fft_accelerator.h - FFT 硬件加速器接口
 * 
 * 使用自定义IP核实现FFT运算的硬件加速
 */

#ifndef FFT_ACCELERATOR_H
#define FFT_ACCELERATOR_H

#include <cstdint>
#include <vector>
#include <complex>
#include <memory>
#include "custom_ip.h"

namespace hw_accel {

// 前向声明
class FFTAcceleratorImpl;

/**
 * FFT 硬件加速器类
 */
class FFTAccelerator {
public:
    /**
     * 构造函数
     * 
     * @param ip_core 自定义IP核对象
     */
    explicit FFTAccelerator(std::shared_ptr<CustomIP> ip_core);
    
    /**
     * 析构函数
     */
    ~FFTAccelerator();
    
    /**
     * 初始化加速器
     * 
     * @return 成功返回true,失败返回false
     */
    bool initialize();
    
    /**
     * 执行FFT运算
     * 
     * @param input 输入数据 (复数向量)
     * @param inverse 是否执行IFFT (true = IFFT, false = FFT)
     * @param useHardware 是否使用硬件加速 (true = 硬件, false = 软件)
     * @return 结果数据 (复数向量)
     */
    std::vector<std::complex<float>> execute(
        const std::vector<std::complex<float>>& input,
        bool inverse = false,
        bool useHardware = true);
    
    /**
     * 获取最后一个错误消息
     * 
     * @return 错误消息
     */
    std::string get_last_error() const;
    
    /**
     * 执行性能基准测试
     * 
     * @param fft_size FFT尺寸 (2的幂次方)
     * @param iterations 迭代次数
     * @return 成功返回true,失败返回false
     */
    bool benchmark(uint32_t fft_size, uint32_t iterations);
    
private:
    // 私有实现 (PIMPL模式)
    std::unique_ptr<FFTAcceleratorImpl> impl_;
    
    // 禁止拷贝和赋值
    FFTAccelerator(const FFTAccelerator&) = delete;
    FFTAccelerator& operator=(const FFTAccelerator&) = delete;
};

} // namespace hw_accel

#endif /* FFT_ACCELERATOR_H */

cpp

/**
 * fft_accelerator.cpp - FFT 硬件加速器实现
 * 
 * 实现软硬件协同的FFT运算,支持在硬件加速不可用时回退到软件实现
 */

#include "fft_accelerator.h"
#include <cmath>
#include <algorithm>
#include <iostream>
#include <chrono>
#include <cstring>
#include <numeric>

namespace hw_accel {

// FFT加速器寄存器偏移
#define FFT_REG_CONTROL      0x00  // 控制寄存器
#define FFT_REG_STATUS       0x04  // 状态寄存器
#define FFT_REG_SIZE         0x08  // FFT大小寄存器
#define FFT_REG_DATA_ADDR    0x0C  // 数据地址寄存器
#define FFT_REG_CONFIG       0x10  // 配置寄存器
#define FFT_REG_SCALE        0x14  // 缩放因子寄存器
#define FFT_REG_VERSION      0x18  // 版本信息寄存器

// 控制寄存器位
#define FFT_CTRL_START       0x01  // 启动计算
#define FFT_CTRL_RESET       0x02  // 复位核心
#define FFT_CTRL_INVERSE     0x04  // IFFT模式
#define FFT_CTRL_IRQ_ENABLE  0x08  // 中断使能

// 状态寄存器位
#define FFT_STATUS_DONE      0x01  // 操作完成
#define FFT_STATUS_BUSY      0x02  // 正在计算
#define FFT_STATUS_ERROR     0x04  // 错误标志
#define FFT_STATUS_IRQ       0x08  // 中断标志

// 配置寄存器位
#define FFT_CONFIG_SCALING   0x01  // 启用自动缩放
#define FFT_CONFIG_ZEROFILL  0x02  // 启用零填充

// 私有实现类
class FFTAcceleratorImpl {
public:
    FFTAcceleratorImpl(std::shared_ptr<CustomIP> ip_core)
        : ip_core_(ip_core),
          initialized_(false),
          last_error_() {}
    
    bool initialize() {
        // 检查IP核是否已打开
        if (!ip_core_ || !ip_core_->is_open()) {
            last_error_ = "IP核未打开";
            return false;
        }
        
        // 读取版本信息
        uint32_t version = ip_core_->read_register(FFT_REG_VERSION);
        
        // 检查版本兼容性 (假设版本号必须大于等于0x01000000)
        if (version < 0x01000000) {
            char version_str[16];
            snprintf(version_str, sizeof(version_str), "0x%08X", version);
            last_error_ = "不支持的FFT加速器版本: " + std::string(version_str);
            return false;
        }
        
        // 复位FFT核心
        ip_core_->write_register(FFT_REG_CONTROL, FFT_CTRL_RESET);
        
        // 等待复位完成
        if (!ip_core_->wait_for_bit_clear(FFT_REG_CONTROL, FFT_CTRL_RESET, 1000)) {
            last_error_ = "FFT核心复位超时";
            return false;
        }
        
        // 设置标准配置
        ip_core_->write_register(FFT_REG_CONFIG, FFT_CONFIG_SCALING);
        
        initialized_ = true;
        return true;
    }
    
    std::vector<std::complex<float>> execute(
        const std::vector<std::complex<float>>& input,
        bool inverse,
        bool useHardware) {
        
        // 检查输入大小是否为2的幂次方
        size_t size = input.size();
        if (size == 0 || (size & (size - 1)) != 0) {
            last_error_ = "输入大小必须为2的幂次方";
            return std::vector<std::complex<float>>();
        }
        
        // 根据需要选择硬件或软件实现
        if (useHardware && initialized_) {
            return execute_hardware(input, inverse);
        } else {
            return execute_software(input, inverse);
        }
    }
    
    std::string get_last_error() const {
        if (!last_error_.empty()) {
            return last_error_;
        }
        
        if (ip_core_) {
            return ip_core_->get_last_error();
        }
        
        return "未知错误";
    }
    
    bool benchmark(uint32_t fft_size, uint32_t iterations) {
        if (fft_size == 0 || (fft_size & (fft_size - 1)) != 0) {
            last_error_ = "FFT大小必须为2的幂次方";
            return false;
        }
        
        std::cout << "FFT基准测试 (尺寸: " << fft_size << ", 迭代: " << iterations << ")" << std::endl;
        
        // 生成随机测试数据
        std::vector<std::complex<float>> test_data;
        test_data.reserve(fft_size);
        
        for (uint32_t i = 0; i < fft_size; i++) {
            float real = static_cast<float>(rand()) / RAND_MAX * 2.0f - 1.0f;
            float imag = static_cast<float>(rand()) / RAND_MAX * 2.0f - 1.0f;
            test_data.push_back(std::complex<float>(real, imag));
        }
        
        // 软件FFT基准测试
        auto sw_start = std::chrono::high_resolution_clock::now();
        
        for (uint32_t i = 0; i < iterations; i++) {
            auto sw_result = execute_software(test_data, false);
            
            // 防止编译器优化掉结果
            if (sw_result.size() == 0) {
                std::cout << "软件FFT失败" << std::endl;
                return false;
            }
        }
        
        auto sw_end = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double, std::milli> sw_time = sw_end - sw_start;
        
        // 硬件FFT基准测试
        auto hw_start = std::chrono::high_resolution_clock::now();
        
        for (uint32_t i = 0; i < iterations; i++) {
            auto hw_result = execute_hardware(test_data, false);
            
            // 防止编译器优化掉结果
            if (hw_result.size() == 0) {
                std::cout << "硬件FFT失败: " << get_last_error() << std::endl;
                return false;
            }
        }
        
        auto hw_end = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double, std::milli> hw_time = hw_end - hw_start;
        
        // 计算加速比
        double speedup = sw_time.count() / hw_time.count();
        
        // 打印性能结果
        std::cout << "软件FFT时间: " << sw_time.count() / iterations << " ms/op" << std::endl;
        std::cout << "硬件FFT时间: " << hw_time.count() / iterations << " ms/op" << std::endl;
        std::cout << "加速比: " << speedup << " x" << std::endl;
        
        return true;
    }
    
private:
    // 硬件FFT实现
    std::vector<std::complex<float>> execute_hardware(
        const std::vector<std::complex<float>>& input,
        bool inverse) {
        
        size_t size = input.size();
        
        // 检查输入大小是否为2的幂次方
        if (size == 0 || (size & (size - 1)) != 0) {
            last_error_ = "输入大小必须为2的幂次方";
            return std::vector<std::complex<float>>();
        }
        
        // 配置FFT大小
        ip_core_->write_register(FFT_REG_SIZE, static_cast<uint32_t>(size));
        
        // 准备输入/输出缓冲区
        std::vector<uint32_t> data_buffer;
        data_buffer.reserve(size * 2); // 每个复数需要两个32位值
        
        // 将输入数据转换为硬件格式 (交替的实部/虚部)
        for (const auto& complex_val : input) {
            // 使用IEEE-754单精度浮点表示
            uint32_t real_bits, imag_bits;
            memcpy(&real_bits, &complex_val.real(), sizeof(real_bits));
            memcpy(&imag_bits, &complex_val.imag(), sizeof(imag_bits));
            
            data_buffer.push_back(real_bits);
            data_buffer.push_back(imag_bits);
        }
        
        // 分配DMA内存并复制数据 (简化实现)
        // 在实际系统中,这里应该使用正确的DMA API
        void* dma_buffer = allocate_dma_buffer(data_buffer.size() * sizeof(uint32_t));
        if (!dma_buffer) {
            last_error_ = "分配DMA缓冲区失败";
            return std::vector<std::complex<float>>();
        }
        
        // 复制数据到DMA缓冲区
        memcpy(dma_buffer, data_buffer.data(), data_buffer.size() * sizeof(uint32_t));
        
        // 获取DMA缓冲区物理地址
        uint64_t dma_phys_addr = get_physical_address(dma_buffer);
        
        // 配置数据地址
        ip_core_->write_register(FFT_REG_DATA_ADDR, static_cast<uint32_t>(dma_phys_addr));
        
        // 设置FFT模式 (正向或逆向)
        uint32_t control = FFT_CTRL_START;
        if (inverse) {
            control |= FFT_CTRL_INVERSE;
        }
        
        // 启动FFT计算
        ip_core_->write_register(FFT_REG_CONTROL, control);
        
        // 等待计算完成
        if (!ip_core_->wait_for_bit_set(FFT_REG_STATUS, FFT_STATUS_DONE, 5000)) {
            last_error_ = "FFT计算超时";
            free_dma_buffer(dma_buffer);
            return std::vector<std::complex<float>>();
        }
        
        // 检查是否有错误
        uint32_t status = ip_core_->read_register(FFT_REG_STATUS);
        if (status & FFT_STATUS_ERROR) {
            last_error_ = "FFT计算出错";
            free_dma_buffer(dma_buffer);
            return std::vector<std::complex<float>>();
        }
        
        // 清除状态标志
        ip_core_->write_register(FFT_REG_STATUS, 0);
        
        // 从DMA缓冲区读取结果
        memcpy(data_buffer.data(), dma_buffer, data_buffer.size() * sizeof(uint32_t));
        
        // 释放DMA缓冲区
        free_dma_buffer(dma_buffer);
        
        // 将硬件格式转换回复数向量
        std::vector<std::complex<float>> result;
        result.reserve(size);
        
        for (size_t i = 0; i < data_buffer.size(); i += 2) {
            float real, imag;
            uint32_t real_bits = data_buffer[i];
            uint32_t imag_bits = data_buffer[i + 1];
            
            memcpy(&real, &real_bits, sizeof(real));
            memcpy(&imag, &imag_bits, sizeof(imag));
            
            result.push_back(std::complex<float>(real, imag));
        }
        
        return result;
    }
    
    // 软件FFT实现 (Cooley-Tukey算法)
    std::vector<std::complex<float>> execute_software(
        const std::vector<std::complex<float>>& input,
        bool inverse) {
        
        size_t n = input.size();
        
        // 如果只有一个元素,直接返回
        if (n <= 1) {
            return input;
        }
        
        // 创建结果向量
        std::vector<std::complex<float>> result = input;
        
        // 位反转排序
        size_t j = 0;
        for (size_t i = 0; i < n - 1; i++) {
            if (i < j) {
                std::swap(result[i], result[j]);
            }
            size_t k = n / 2;
            while (k <= j) {
                j -= k;
                k /= 2;
            }
            j += k;
        }
        
        // 蝶形计算
        for (size_t len = 2; len <= n; len *= 2) {
            float angle = (inverse ? 2.0f : -2.0f) * M_PI / len;
            std::complex<float> wm(cos(angle), sin(angle));
            
            for (size_t i = 0; i < n; i += len) {
                std::complex<float> w(1.0f, 0.0f);
                
                for (size_t j = 0; j < len / 2; j++) {
                    std::complex<float> u = result[i + j];
                    std::complex<float> t = w * result[i + j + len / 2];
                    
                    result[i + j] = u + t;
                    result[i + j + len / 2] = u - t;
                    
                    w *= wm;
                }
            }
        }
        
        // 如果是IFFT,需要除以n
        if (inverse) {
            for (auto& val : result) {
                val /= static_cast<float>(n);
            }
        }
        
        return result;
    }
    
    // DMA缓冲区分配 (简化实现)
    void* allocate_dma_buffer(size_t size) {
        // 在实际系统中,这里应该使用正确的DMA缓冲区分配API
        return malloc(size);
    }
    
    void free_dma_buffer(void* buffer) {
        free(buffer);
    }
    
    uint64_t get_physical_address(void* virtual_address) {
        // 在实际系统中,这里需要使用平台特定方法获取物理地址
        // 这里仅作为示例,直接返回虚拟地址值
        return reinterpret_cast<uint64_t>(virtual_address);
    }
    
private:
    std::shared_ptr<CustomIP> ip_core_;  // IP核对象
    bool initialized_;                    // 初始化标志
    std::string last_error_;              // 最后一个错误消息
};

// FFTAccelerator的外部实现,委托给FFTAcceleratorImpl

FFTAccelerator::FFTAccelerator(std::shared_ptr<CustomIP> ip_core)
    : impl_(new FFTAcceleratorImpl(ip_core)) {
}

FFTAccelerator::~FFTAccelerator() = default;

bool FFTAccelerator::initialize() {
    return impl_->initialize();
}

std::vector<std::complex<float>> FFTAccelerator::execute(
    const std::vector<std::complex<float>>& input,
    bool inverse,
    bool useHardware) {
    
    return impl_->execute(input, inverse, useHardware);
}

std::string FFTAccelerator::get_last_error() const {
    return impl_->get_last_error();
}

bool FFTAccelerator::benchmark(uint32_t fft_size, uint32_t iterations) {
    return impl_->benchmark(fft_size, iterations);
}

} // namespace hw_accel

3. 嵌入式系统与外设通信

3.1 UART/RS-232 通信实现

c

/**
 * uart.h - UART/RS232 通信接口
 *
 * 提供基本的串口通信功能
 */

#ifndef UART_H
#define UART_H

#include <stdint.h>

// 波特率定义
typedef enum {
    UART_BAUD_9600 = 9600,
    UART_BAUD_19200 = 19200,
    UART_BAUD_38400 = 38400,
    UART_BAUD_57600 = 57600,
    UART_BAUD_115200 = 115200,
    UART_BAUD_230400 = 230400,
    UART_BAUD_460800 = 460800,
    UART_BAUD_921600 = 921600
} UartBaudRate;

// 数据位定义
typedef enum {
    UART_DATA_BITS_7 = 7,
    UART_DATA_BITS_8 = 8,
    UART_DATA_BITS_9 = 9
} UartDataBits;

// 停止位定义
typedef enum {
    UART_STOP_BITS_1 = 0,
    UART_STOP_BITS_2 = 1
} UartStopBits;

// 校验位定义
typedef enum {
    UART_PARITY_NONE = 0,
    UART_PARITY_ODD = 1,
    UART_PARITY_EVEN = 2
} UartParity;

// 流控制定义
typedef enum {
    UART_FLOW_CONTROL_NONE = 0,
    UART_FLOW_CONTROL_RTS_CTS = 1,
    UART_FLOW_CONTROL_XON_XOFF = 2
} UartFlowControl;

// UART配置结构体
typedef struct {
    UartBaudRate baudRate;
    UartDataBits dataBits;
    UartStopBits stopBits;
    UartParity parity;
    UartFlowControl flowControl;
} UartConfig;

// UART句柄
typedef struct UartHandle* UartHandle_t;

/**
 * 打开UART设备
 *
 * @param deviceName 设备名称 (如"/dev/ttyS0"或"COM1")
 * @param config UART配置参数
 * @return UART句柄,失败返回NULL
 */
UartHandle_t uart_open(const char* deviceName, const UartConfig* config);

/**
 * 关闭UART设备
 *
 * @param handle UART句柄
 * @return 0表示成功,非0表示失败
 */
int uart_close(UartHandle_t handle);

/**
 * 发送数据
 *
 * @param handle UART句柄
 * @param data 数据缓冲区
 * @param size 数据大小
 * @return 实际发送的字节数,小于0表示错误
 */
int uart_send(UartHandle_t handle, const uint8_t* data, int size);

/**
 * 接收数据
 *
 * @param handle UART句柄
 * @param data 数据缓冲区
 * @param size 最大接收数据大小
 * @param timeout_ms 超时时间(毫秒),0表示非阻塞,负数表示一直等待
 * @return 实际接收的字节数,小于0表示错误
 */
int uart_receive(UartHandle_t handle, uint8_t* data, int size, int timeout_ms);

/**
 * 清空接收缓冲区
 *
 * @param handle UART句柄
 * @return 0表示成功,非0表示失败
 */
int uart_flush_rx(UartHandle_t handle);

/**
 * 清空发送缓冲区
 *
 * @param handle UART句柄
 * @return 0表示成功,非0表示失败
 */
int uart_flush_tx(UartHandle_t handle);

/**
 * 获取最后一个错误消息
 *
 * @return 错误消息字符串
 */
const char* uart_get_last_error(void);

/**
 * 设置接收超时
 *
 * @param handle UART句柄
 * @param timeout_ms 读取超时(毫秒)
 * @return 0表示成功,非0表示失败
 */
int uart_set_timeout(UartHandle_t handle, int timeout_ms);

/**
 * 获取接收缓冲区中可用数据量
 *
 * @param handle UART句柄
 * @return 可用数据量,小于0表示错误
 */
int uart_bytes_available(UartHandle_t handle);

#endif /* UART_H */

c

/**
 * uart.c - UART/RS232 通信接口实现 (基于POSIX)
 *
 * 提供跨平台的串口通信实现
 */

#include "uart.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#ifdef _WIN32
    // Windows平台
    #include <windows.h>
    #define SERIALCOM_HANDLE HANDLE
#else
    // POSIX平台 (Linux, macOS, etc.)
    #include <unistd.h>
    #include <fcntl.h>
    #include <termios.h>
    #include <sys/select.h>
    #include <sys/ioctl.h>
    #define SERIALCOM_HANDLE int
#endif

// 定义UART句柄结构体
struct UartHandle {
    SERIALCOM_HANDLE fd;          // 文件描述符/句柄
    char deviceName[64];          // 设备名称
    UartConfig config;            // UART配置
    int timeout_ms;               // 读取超时(毫秒)
};

// 最后一个错误消息
static char lastErrorMessage[256] = {0};

// 设置最后一个错误消息
static void set_last_error(const char* format, ...) {
    va_list args;
    va_start(args, format);
    vsnprintf(lastErrorMessage, sizeof(lastErrorMessage), format, args);
    va_end(args);
}

#ifdef _WIN32
// Windows平台特定的UART配置函数
static int configure_uart_win32(UartHandle_t handle) {
    DCB dcb = {0};
    COMMTIMEOUTS timeouts = {0};
    
    dcb.DCBlength = sizeof(DCB);
    
    // 获取当前配置
    if (!GetCommState(handle->fd, &dcb)) {
        set_last_error("GetCommState失败: %d", GetLastError());
        return -1;
    }
    
    // 设置波特率
    dcb.BaudRate = handle->config.baudRate;
    
    // 设置数据位
    dcb.ByteSize = handle->config.dataBits;
    
    // 设置停止位
    if (handle->config.stopBits == UART_STOP_BITS_1) {
        dcb.StopBits = ONESTOPBIT;
    } else {
        dcb.StopBits = TWOSTOPBITS;
    }
    
    // 设置校验位
    switch (handle->config.parity) {
        case UART_PARITY_NONE:
            dcb.Parity = NOPARITY;
            break;
        case UART_PARITY_ODD:
            dcb.Parity = ODDPARITY;
            break;
        case UART_PARITY_EVEN:
            dcb.Parity = EVENPARITY;
            break;
        default:
            dcb.Parity = NOPARITY;
            break;
    }
    
    // 设置流控制
    dcb.fOutX = FALSE;
    dcb.fInX = FALSE;
    dcb.fRtsControl = RTS_CONTROL_DISABLE;
    dcb.fDtrControl = DTR_CONTROL_DISABLE;
    
    if (handle->config.flowControl == UART_FLOW_CONTROL_RTS_CTS) {
        dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
        dcb.fOutxCtsFlow = TRUE;
    } else if (handle->config.flowControl == UART_FLOW_CONTROL_XON_XOFF) {
        dcb.fOutX = TRUE;
        dcb.fInX = TRUE;
    }
    
    // 更新配置
    if (!SetCommState(handle->fd, &dcb)) {
        set_last_error("SetCommState失败: %d", GetLastError());
        return -1;
    }
    
    // 设置超时
    timeouts.ReadIntervalTimeout = MAXDWORD;
    timeouts.ReadTotalTimeoutMultiplier = 0;
    timeouts.ReadTotalTimeoutConstant = 0;
    timeouts.WriteTotalTimeoutMultiplier = 0;
    timeouts.WriteTotalTimeoutConstant = 0;
    
    if (!SetCommTimeouts(handle->fd, &timeouts)) {
        set_last_error("SetCommTimeouts失败: %d", GetLastError());
        return -1;
    }
    
    return 0;
}
#else
// POSIX平台特定的UART配置函数
static int configure_uart_posix(UartHandle_t handle) {
    struct termios tty;
    memset(&tty, 0, sizeof(tty));
    
    // 获取当前配置
    if (tcgetattr(handle->fd, &tty) != 0) {
        set_last_error("tcgetattr失败: %s", strerror(errno));
        return -1;
    }
    
    // 设置基本配置
    tty.c_cflag |= (CLOCAL | CREAD);    // 忽略调制解调器状态,启用接收
    tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 禁用规范模式,禁用回显,禁用信号
    tty.c_oflag &= ~OPOST;              // 禁用输出处理
    tty.c_iflag &= ~(IXON | IXOFF | IXANY); // 禁用软件流控制
    
    // 设置波特率
    speed_t baudRate;
    switch (handle->config.baudRate) {
        case UART_BAUD_9600:   baudRate = B9600;   break;
        case UART_BAUD_19200:  baudRate = B19200;  break;
        case UART_BAUD_38400:  baudRate = B38400;  break;
        case UART_BAUD_57600:  baudRate = B57600;  break;
        case UART_BAUD_115200: baudRate = B115200; break;
        case UART_BAUD_230400: baudRate = B230400; break;
        #ifdef B460800
        case UART_BAUD_460800: baudRate = B460800; break;
        #endif
        #ifdef B921600
        case UART_BAUD_921600: baudRate = B921600; break;
        #endif
        default:
            set_last_error("不支持的波特率: %d", handle->config.baudRate);
            return -1;
    }
    
    cfsetospeed(&tty, baudRate);
    cfsetispeed(&tty, baudRate);
    
    // 设置数据位
    tty.c_cflag &= ~CSIZE;
    switch (handle->config.dataBits) {
        case UART_DATA_BITS_7:
            tty.c_cflag |= CS7;
            break;
        case UART_DATA_BITS_8:
            tty.c_cflag |= CS8;
            break;
        default:
            set_last_error("不支持的数据位: %d", handle->config.dataBits);
            return -1;
    }
    
    // 设置停止位
    if (handle->config.stopBits == UART_STOP_BITS_2) {
        tty.c_cflag |= CSTOPB;
    } else {
        tty.c_cflag &= ~CSTOPB;
    }
    
    // 设置校验位
    switch (handle->config.parity) {
        case UART_PARITY_NONE:
            tty.c_cflag &= ~PARENB;
            break;
        case UART_PARITY_ODD:
            tty.c_cflag |= PARENB;
            tty.c_cflag |= PARODD;
            break;
        case UART_PARITY_EVEN:
            tty.c_cflag |= PARENB;
            tty.c_cflag &= ~PARODD;
            break;
        default:
            tty.c_cflag &= ~PARENB;
            break;
    }
    
    // 设置流控制
    if (handle->config.flowControl == UART_FLOW_CONTROL_RTS_CTS) {
        #ifdef CRTSCTS
        tty.c_cflag |= CRTSCTS;
        #else
        set_last_error("平台不支持硬件流控制");
        return -1;
        #endif
    } else if (handle->config.flowControl == UART_FLOW_CONTROL_XON_XOFF) {
        tty.c_iflag |= (IXON | IXOFF);
    }
    
    // 设置超时和最小读取字符数
    tty.c_cc[VMIN] = 0;   // 最小字符数
    tty.c_cc[VTIME] = 0;  // 超时 (0表示非阻塞)
    
    // 清空缓冲区并应用新配置
    tcflush(handle->fd, TCIOFLUSH);
    if (tcsetattr(handle->fd, TCSANOW, &tty) != 0) {
        set_last_error("tcsetattr失败: %s", strerror(errno));
        return -1;
    }
    
    return 0;
}
#endif

// 打开UART设备
UartHandle_t uart_open(const char* deviceName, const UartConfig* config) {
    if (!deviceName || !config) {
        set_last_error("无效的参数");
        return NULL;
    }
    
    // 分配句柄
    UartHandle_t handle = (UartHandle_t)malloc(sizeof(struct UartHandle));
    if (!handle) {
        set_last_error("内存分配失败");
        return NULL;
    }
    
    // 初始化句柄
    memset(handle, 0, sizeof(struct UartHandle));
    strncpy(handle->deviceName, deviceName, sizeof(handle->deviceName) - 1);
    memcpy(&handle->config, config, sizeof(UartConfig));
    handle->timeout_ms = -1; // 默认无限等待
    
#ifdef _WIN32
    // Windows平台打开串口
    char fullPath[80];
    snprintf(fullPath, sizeof(fullPath), "\\\\.\\%s", deviceName);
    
    handle->fd = CreateFileA(
        fullPath,
        GENERIC_READ | GENERIC_WRITE,
        0,                // 不共享
        NULL,             // 默认安全属性
        OPEN_EXISTING,    // 打开现有设备
        0,                // 非重叠I/O
        NULL              // 模板文件
    );
    
    if (handle->fd == INVALID_HANDLE_VALUE) {
        set_last_error("无法打开串口设备 %s: 错误码 %d", deviceName, GetLastError());
        free(handle);
        return NULL;
    }
    
    // 配置UART
    if (configure_uart_win32(handle) != 0) {
        CloseHandle(handle->fd);
        free(handle);
        return NULL;
    }
#else
    // POSIX平台打开串口
    handle->fd = open(deviceName, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (handle->fd < 0) {
        set_last_error("无法打开串口设备 %s: %s", deviceName, strerror(errno));
        free(handle);
        return NULL;
    }
    
    // 配置UART
    if (configure_uart_posix(handle) != 0) {
        close(handle->fd);
        free(handle);
        return NULL;
    }
#endif
    
    return handle;
}

// 关闭UART设备
int uart_close(UartHandle_t handle) {
    if (!handle) {
        set_last_error("无效的句柄");
        return -1;
    }
    
#ifdef _WIN32
    CloseHandle(handle->fd);
#else
    close(handle->fd);
#endif
    
    free(handle);
    return 0;
}

// 发送数据
int uart_send(UartHandle_t handle, const uint8_t* data, int size) {
    if (!handle || !data || size <= 0) {
        set_last_error("无效的参数");
        return -1;
    }
    
#ifdef _WIN32
    DWORD bytesWritten = 0;
    if (!WriteFile(handle->fd, data, size, &bytesWritten, NULL)) {
        set_last_error("写入失败: %d", GetLastError());
        return -1;
    }
    return bytesWritten;
#else
    ssize_t bytesWritten = write(handle->fd, data, size);
    if (bytesWritten < 0) {
        set_last_error("写入失败: %s", strerror(errno));
        return -1;
    }
    return bytesWritten;
#endif
}

// 接收数据
int uart_receive(UartHandle_t handle, uint8_t* data, int size, int timeout_ms) {
    if (!handle || !data || size <= 0) {
        set_last_error("无效的参数");
        return -1;
    }
    
#ifdef _WIN32
    DWORD bytesRead = 0;
    COMMTIMEOUTS timeouts = {0};
    
    // 设置超时
    if (timeout_ms >= 0) {
        timeouts.ReadIntervalTimeout = MAXDWORD;
        timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
        timeouts.ReadTotalTimeoutConstant = timeout_ms;
    } else {
        // 无限等待
        timeouts.ReadIntervalTimeout = 0;
        timeouts.ReadTotalTimeoutMultiplier = 0;
        timeouts.ReadTotalTimeoutConstant = 0;
    }
    
    if (!SetCommTimeouts(handle->fd, &timeouts)) {
        set_last_error("设置超时失败: %d", GetLastError());
        return -1;
    }
    
    if (!ReadFile(handle->fd, data, size, &bytesRead, NULL)) {
        DWORD error = GetLastError();
        if (error != ERROR_TIMEOUT) {
            set_last_error("读取失败: %d", error);
            return -1;
        }
        return 0; // 超时
    }
    
    return bytesRead;
#else
    fd_set readfds;
    struct timeval tv;
    
    FD_ZERO(&readfds);
    FD_SET(handle->fd, &readfds);
    
    if (timeout_ms >= 0) {
        tv.tv_sec = timeout_ms / 1000;
        tv.tv_usec = (timeout_ms % 1000) * 1000;
    }
    
    // 等待数据可读或超时
    int ret = select(handle->fd + 1, &readfds, NULL, NULL, 
                     (timeout_ms >= 0) ? &tv : NULL);
    
    if (ret < 0) {
        set_last_error("select失败: %s", strerror(errno));
        return -1;
    } else if (ret == 0) {
        // 超时
        return 0;
    }
    
    // 读取数据
    ssize_t bytesRead = read(handle->fd, data, size);
    if (bytesRead < 0) {
        set_last_error("读取失败: %s", strerror(errno));
        return -1;
    }
    
    return bytesRead;
#endif
}

// 清空接收缓冲区
int uart_flush_rx(UartHandle_t handle) {
    if (!handle) {
        set_last_error("无效的句柄");
        return -1;
    }
    
#ifdef _WIN32
    if (!PurgeComm(handle->fd, PURGE_RXCLEAR)) {
        set_last_error("清空接收缓冲区失败: %d", GetLastError());
        return -1;
    }
#else
    if (tcflush(handle->fd, TCIFLUSH) != 0) {
        set_last_error("清空接收缓冲区失败: %s", strerror(errno));
        return -1;
    }
#endif
    
    return 0;
}

// 清空发送缓冲区
int uart_flush_tx(UartHandle_t handle) {
    if (!handle) {
        set_last_error("无效的句柄");
        return -1;
    }
    
#ifdef _WIN32
    if (!PurgeComm(handle->fd, PURGE_TXCLEAR)) {
        set_last_error("清空发送缓冲区失败: %d", GetLastError());
        return -1;
    }
#else
    if (tcflush(handle->fd, TCOFLUSH) != 0) {
        set_last_error("清空发送缓冲区失败: %s", strerror(errno));
        return -1;
    }
#endif
    
    return 0;
}

// 获取最后一个错误消息
const char* uart_get_last_error(void) {
    return lastErrorMessage;
}

// 设置接收超时
int uart_set_timeout(UartHandle_t handle, int timeout_ms) {
    if (!handle) {
        set_last_error("无效的句柄");
        return -1;
    }
    
    handle->timeout_ms = timeout_ms;
    
#ifdef _WIN32
    COMMTIMEOUTS timeouts = {0};
    
    // 设置超时
    if (timeout_ms >= 0) {
        timeouts.ReadIntervalTimeout = MAXDWORD;
        timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
        timeouts.ReadTotalTimeoutConstant = timeout_ms;
    } else {
        // 无限等待
        timeouts.ReadIntervalTimeout = 0;
        timeouts.ReadTotalTimeoutMultiplier = 0;
        timeouts.ReadTotalTimeoutConstant = 0;
    }
    
    if (!SetCommTimeouts(handle->fd, &timeouts)) {
        set_last_error("设置超时失败: %d", GetLastError());
        return -1;
    }
#else
    struct termios tty;
    
    if (tcgetattr(handle->fd, &tty) != 0) {
        set_last_error("tcgetattr失败: %s", strerror(errno));
        return -1;
    }
    
    if (timeout_ms >= 0) {
        // 设置字符超时 (VTIME以1/10秒为单位)
        tty.c_cc[VMIN] = 0;
        tty.c_cc[VTIME] = (timeout_ms / 100) & 0xFF;
    } else {
        // 无限等待
        tty.c_cc[VMIN] = 1;
        tty.c_cc[VTIME] = 0;
    }
    
    if (tcsetattr(handle->fd, TCSANOW, &tty) != 0) {
        set_last_error("tcsetattr失败: %s", strerror(errno));
        return -1;
    }
#endif
    
    return 0;
}

// 获取接收缓冲区中可用数据量
int uart_bytes_available(UartHandle_t handle) {
    if (!handle) {
        set_last_error("无效的句柄");
        return -1;
    }
    
#ifdef _WIN32
    COMSTAT status;
    DWORD errors;
    
    if (!ClearCommError(handle->fd, &errors, &status)) {
        set_last_error("ClearCommError失败: %d", GetLastError());
        return -1;
    }
    
    return status.cbInQue;
#else
    int bytes_available = 0;
    if (ioctl(handle->fd, FIONREAD, &bytes_available) < 0) {
        set_last_error("ioctl失败: %s", strerror(errno));
        return -1;
    }
    
    return bytes_available;
#endif
}

3.2 I2C设备通信实现

c

/**
 * i2c.h - I2C通信接口
 *
 * 提供与I2C设备通信的功能
 */

#ifndef I2C_H
#define I2C_H

#include <stdint.h>

// I2C句柄
typedef struct I2cHandle* I2cHandle_t;

/**
 * 打开I2C设备
 *
 * @param deviceName 设备名称 (如"/dev/i2c-1")
 * @return I2C句柄,失败返回NULL
 */
I2cHandle_t i2c_open(const char* deviceName);

/**
 * 关闭I2C设备
 *
 * @param handle I2C句柄
 * @return 0表示成功,非0表示失败
 */
int i2c_close(I2cHandle_t handle);

/**
 * 设置I2C从设备地址
 *
 * @param handle I2C句柄
 * @param address 7位或10位设备地址
 * @param is10bit 是否为10位地址 (0=7位地址,1=10位地址)
 * @return 0表示成功,非0表示失败
 */
int i2c_set_slave_address(I2cHandle_t handle, uint16_t address, int is10bit);

/**
 * 写入数据到I2C设备
 *
 * @param handle I2C句柄
 * @param data 数据缓冲区
 * @param size 数据大小
 * @return 实际写入的字节数,小于0表示错误
 */
int i2c_write(I2cHandle_t handle, const uint8_t* data, int size);

/**
 * 从I2C设备读取数据
 *
 * @param handle I2C句柄
 * @param data 数据缓冲区
 * @param size 最大读取数据大小
 * @return 实际读取的字节数,小于0表示错误
 */
int i2c_read(I2cHandle_t handle, uint8_t* data, int size);

/**
 * 写入寄存器(8位寄存器地址)
 *
 * @param handle I2C句柄
 * @param reg_addr 寄存器地址
 * @param data 数据缓冲区
 * @param size 数据大小
 * @return 实际写入的字节数(不包括寄存器地址),小于0表示错误
 */
int i2c_write_reg8(I2cHandle_t handle, uint8_t reg_addr, const uint8_t* data, int size);

/**
 * 读取寄存器(8位寄存器地址)
 *
 * @param handle I2C句柄
 * @param reg_addr 寄存器地址
 * @param data 数据缓冲区
 * @param size 最大读取数据大小
 * @return 实际读取的字节数,小于0表示错误
 */
int i2c_read_reg8(I2cHandle_t handle, uint8_t reg_addr, uint8_t* data, int size);

/**
 * 写入寄存器(16位寄存器地址)
 *
 * @param handle I2C句柄
 * @param reg_addr 寄存器地址
 * @param data 数据缓冲区
 * @param size 数据大小
 * @return 实际写入的字节数(不包括寄存器地址),小于0表示错误
 */
int i2c_write_reg16(I2cHandle_t handle, uint16_t reg_addr, const uint8_t* data, int size);

/**
 * 读取寄存器(16位寄存器地址)
 *
 * @param handle I2C句柄
 * @param reg_addr 寄存器地址
 * @param data 数据缓冲区
 * @param size 最大读取数据大小
 * @return 实际读取的字节数,小于0表示错误
 */
int i2c_read_reg16(I2cHandle_t handle, uint16_t reg_addr, uint8_t* data, int size);

/**
 * 设置I2C传输超时
 * 
 * @param handle I2C句柄
 * @param timeout_ms 超时时间(毫秒)
 * @return 0表示成功,非0表示失败
 */
int i2c_set_timeout(I2cHandle_t handle, int timeout_ms);

/**
 * 获取最后一个错误消息
 *
 * @return 错误消息字符串
 */
const char* i2c_get_last_error(void);

#endif /* I2C_H */

c

/**
 * i2c.c - I2C通信接口实现 (基于Linux I2C驱动)
 *
 * 提供与I2C设备通信的功能
 */

#include "i2c.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdarg.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

// 定义I2C句柄结构体
struct I2cHandle {
    int fd;                // 文件描述符
    char deviceName[64];   // 设备名称
    uint16_t slaveAddress; // 从设备地址
    int is10bit;           // 是否为10位地址
    int timeout_ms;        // 超时时间(毫秒)
};

// 最后一个错误消息
static char lastErrorMessage[256] = {0};

// 设置最后一个错误消息
static void set_last_error(const char* format, ...) {
    va_list args;
    va_start(args, format);
    vsnprintf(lastErrorMessage, sizeof(lastErrorMessage), format, args);
    va_end(args);
}

// 执行I2C传输
static int i2c_transfer(I2cHandle_t handle, struct i2c_msg* msgs, int num_msgs) {
    struct i2c_rdwr_ioctl_data msgset;
    
    if (!handle || !msgs || num_msgs <= 0) {
        set_last_error("无效的参数");
        return -1;
    }
    
    msgset.msgs = msgs;
    msgset.nmsgs = num_msgs;
    
    if (ioctl(handle->fd, I2C_RDWR, &msgset) < 0) {
        set_last_error("I2C传输失败: %s", strerror(errno));
        return -1;
    }
    
    return 0;
}

// 打开I2C设备
I2cHandle_t i2c_open(const char* deviceName) {
    if (!deviceName) {
        set_last_error("设备名称为空");
        return NULL;
    }
    
    // 分配句柄
    I2cHandle_t handle = (I2cHandle_t)malloc(sizeof(struct I2cHandle));
    if (!handle) {
        set_last_error("内存分配失败");
        return NULL;
    }
    
    // 初始化句柄
    memset(handle, 0, sizeof(struct I2cHandle));
    strncpy(handle->deviceName, deviceName, sizeof(handle->deviceName) - 1);
    handle->timeout_ms = 1000; // 默认超时1秒
    
    // 打开I2C设备
    handle->fd = open(deviceName, O_RDWR);
    if (handle->fd < 0) {
        set_last_error("无法打开I2C设备 %s: %s", deviceName, strerror(errno));
        free(handle);
        return NULL;
    }
    
    return handle;
}

// 关闭I2C设备
int i2c_close(I2cHandle_t handle) {
    if (!handle) {
        set_last_error("无效的句柄");
        return -1;
    }
    
    if (handle->fd >= 0) {
        close(handle->fd);
    }
    
    free(handle);
    return 0;
}

// 设置I2C从设备地址
int i2c_set_slave_address(I2cHandle_t handle, uint16_t address, int is10bit) {
    if (!handle) {
        set_last_error("无效的句柄");
        return -1;
    }
    
    handle->slaveAddress = address;
    handle->is10bit = is10bit;
    
    unsigned long flag = is10bit ? I2C_M_TEN : 0;
    
    // 尝试使用旧的IOCTL设置从设备地址
    if (ioctl(handle->fd, I2C_SLAVE, address) < 0 &&
        ioctl(handle->fd, I2C_SLAVE_FORCE, address) < 0) {
        // 如果失败,可能不支持常规的方式,或者地址冲突
        // 这没有问题,因为我们将使用I2C_RDWR来指定目标地址
    }
    
    return 0;
}

// 写入数据到I2C设备
int i2c_write(I2cHandle_t handle, const uint8_t* data, int size) {
    if (!handle || !data || size <= 0) {
        set_last_error("无效的参数");
        return -1;
    }
    
    struct i2c_msg msgs[1];
    
    // 设置写消息
    msgs[0].addr = handle->slaveAddress;
    msgs[0].flags = handle->is10bit ? I2C_M_TEN : 0;
    msgs[0].len = size;
    msgs[0].buf = (uint8_t*)data;
    
    if (i2c_transfer(handle, msgs, 1) < 0) {
        return -1;
    }
    
    return size;
}

// 从I2C设备读取数据
int i2c_read(I2cHandle_t handle, uint8_t* data, int size) {
    if (!handle || !data || size <= 0) {
        set_last_error("无效的参数");
        return -1;
    }
    
    struct i2c_msg msgs[1];
    
    // 设置读消息
    msgs[0].addr = handle->slaveAddress;
    msgs[0].flags = I2C_M_RD | (handle->is10bit ? I2C_M_TEN : 0);
    msgs[0].len = size;
    msgs[0].buf = data;
    
    if (i2c_transfer(handle, msgs, 1) < 0) {
        return -1;
    }
    
    return size;
}

// 写入寄存器(8位寄存器地址)
int i2c_write_reg8(I2cHandle_t handle, uint8_t reg_addr, const uint8_t* data, int size) {
    if (!handle || !data || size <= 0) {
        set_last_error("无效的参数");
        return -1;
    }
    
    // 分配缓冲区包含寄存器地址和数据
    uint8_t* buffer = (uint8_t*)malloc(size + 1);
    if (!buffer) {
        set_last_error("内存分配失败");
        return -1;
    }
    
    // 填充缓冲区
    buffer[0] = reg_addr;
    memcpy(buffer + 1, data, size);
    
    struct i2c_msg msgs[1];
    
    // 设置写消息
    msgs[0].addr = handle->slaveAddress;
    msgs[0].flags = handle->is10bit ? I2C_M_TEN : 0;
    msgs[0].len = size + 1;
    msgs[0].buf = buffer;
    
    int result = i2c_transfer(handle, msgs, 1);
    free(buffer);
    
    if (result < 0) {
        return -1;
    }
    
    return size;
}

// 读取寄存器(8位寄存器地址)
int i2c_read_reg8(I2cHandle_t handle, uint8_t reg_addr, uint8_t* data, int size) {
    if (!handle || !data || size <= 0) {
        set_last_error("无效的参数");
        return -1;
    }
    
    struct i2c_msg msgs[2];
    
    // 设置写消息(寄存器地址)
    msgs[0].addr = handle->slaveAddress;
    msgs[0].flags = handle->is10bit ? I2C_M_TEN : 0;
    msgs[0].len = 1;
    msgs[0].buf = &reg_addr;
    
    // 设置读消息(数据)
    msgs[1].addr = handle->slaveAddress;
    msgs[1].flags = I2C_M_RD | (handle->is10bit ? I2C_M_TEN : 0);
    msgs[1].len = size;
    msgs[1].buf = data;
    
    if (i2c_transfer(handle, msgs, 2) < 0) {
        return -1;
    }
    
    return size;
}

// 写入寄存器(16位寄存器地址)
int i2c_write_reg16(I2cHandle_t handle, uint16_t reg_addr, const uint8_t* data, int size) {
    if (!handle || !data || size <= 0) {
        set_last_error("无效的参数");
        return -1;
    }
    
    // 分配缓冲区包含寄存器地址和数据
    uint8_t* buffer = (uint8_t*)malloc(size + 2);
    if (!buffer) {
        set_last_error("内存分配失败");
        return -1;
    }
    
    // 填充缓冲区 (寄存器地址高字节在前)
    buffer[0] = (reg_addr >> 8) & 0xFF;
    buffer[1] = reg_addr & 0xFF;
    memcpy(buffer + 2, data, size);
    
    struct i2c_msg msgs[1];
    
    // 设置写消息
    msgs[0].addr = handle->slaveAddress;
    msgs[0].flags = handle->is10bit ? I2C_M_TEN : 0;
    msgs[0].len = size + 2;
    msgs[0].buf = buffer;
    
    int result = i2c_transfer(handle, msgs, 1);
    free(buffer);
    
    if (result < 0) {
        return -1;
    }
    
    return size;
}

// 读取寄存器(16位寄存器地址)
int i2c_read_reg16(I2cHandle_t handle, uint16_t reg_addr, uint8_t* data, int size) {
    if (!handle || !data || size <= 0) {
        set_last_error("无效的参数");
        return -1;
    }
    
    uint8_t reg_addr_buf[2];
    reg_addr_buf[0] = (reg_addr >> 8) & 0xFF;
    reg_addr_buf[1] = reg_addr & 0xFF;
    
    struct i2c_msg msgs[2];
    
    // 设置写消息(寄存器地址)
    msgs[0].addr = handle->slaveAddress;
    msgs[0].flags = handle->is10bit ? I2C_M_TEN : 0;
    msgs[0].len = 2;
    msgs[0].buf = reg_addr_buf;
    
    // 设置读消息(数据)
    msgs[1].addr = handle->slaveAddress;
    msgs[1].flags = I2C_M_RD | (handle->is10bit ? I2C_M_TEN : 0);
    msgs[1].len = size;
    msgs[1].buf = data;
    
    if (i2c_transfer(handle, msgs, 2) < 0) {
        return -1;
    }
    
    return size;
}

// 设置I2C传输超时
int i2c_set_timeout(I2cHandle_t handle, int timeout_ms) {
    if (!handle) {
        set_last_error("无效的句柄");
        return -1;
    }
    
    handle->timeout_ms = timeout_ms;
    
    // Linux I2C-dev驱动不直接支持超时设置
    // 我们可以使用非阻塞模式和select超时,但这需要扩展更多代码
    // 在这里,我们只是保存超时值以供将来可能的实现使用
    
    return 0;
}

// 获取最后一个错误消息
const char* i2c_get_last_error(void) {
    return lastErrorMessage;
}

3.3 CAN总线通信

c

/**
 * can.h - CAN总线通信接口
 *
 * 提供与CAN总线设备通信的基本功能
 */

#ifndef CAN_H
#define CAN_H

#include <stdint.h>

// CAN帧结构体
typedef struct {
    uint32_t id;               // CAN标识符
    uint8_t is_extended;       // 是否扩展帧(0=标准11位ID,1=扩展29位ID)
    uint8_t is_remote;         // 是否远程帧(0=数据帧, 1=远程帧)
    uint8_t is_error;          // 是否错误帧(0=正常帧, 1=错误帧)
    uint8_t dlc;               // 数据长度(0-8)
    uint8_t data[8];           // 数据字节
    uint64_t timestamp;        // 时间戳(微秒)
} CanFrame;

// CAN滤波器结构体
typedef struct {
    uint32_t id;               // 滤波器ID
    uint32_t mask;             // 滤波器掩码
    uint8_t is_extended;       // 是否扩展帧格式
} CanFilter;

// CAN句柄
typedef struct CanHandle* CanHandle_t;

/**
 * 打开CAN设备
 *
 * @param interface_name 接口名称 (如"can0")
 * @param bitrate CAN波特率 (如125000, 250000, 500000, 1000000)
 * @return CAN句柄,失败返回NULL
 */
CanHandle_t can_open(const char* interface_name, uint32_t bitrate);

/**
 * 关闭CAN设备
 *
 * @param handle CAN句柄
 * @return 0表示成功,非0表示失败
 */
int can_close(CanHandle_t handle);

/**
 * 开始CAN通信
 *
 * @param handle CAN句柄
 * @return 0表示成功,非0表示失败
 */
int can_start(CanHandle_t handle);

/**
 * 停止CAN通信
 *
 * @param handle CAN句柄
 * @return 0表示成功,非0表示失败
 */
int can_stop(CanHandle_t handle);

/**
 * 发送CAN帧
 *
 * @param handle CAN句柄
 * @param frame 要发送的CAN帧
 * @return 0表示成功,非0表示失败
 */
int can_send(CanHandle_t handle, const CanFrame* frame);

/**
 * 接收CAN帧
 *
 * @param handle CAN句柄
 * @param frame 接收到的CAN帧
 * @param timeout_ms 超时时间(毫秒),0表示非阻塞,负数表示一直等待
 * @return 0表示成功,1表示超时,负数表示错误
 */
int can_receive(CanHandle_t handle, CanFrame* frame, int timeout_ms);

/**
 * 设置CAN滤波器
 *
 * @param handle CAN句柄
 * @param filters 滤波器数组
 * @param num_filters 滤波器数量
 * @return 0表示成功,非0表示失败
 */
int can_set_filters(CanHandle_t handle, const CanFilter* filters, int num_filters);

/**
 * 获取CAN总线状态
 *
 * @param handle CAN句柄
 * @param tx_error 发送错误计数器
 * @param rx_error 接收错误计数器
 * @param bus_status 总线状态(0=正常, 1=警告, 2=被动错误, 3=总线关闭)
 * @return 0表示成功,非0表示失败
 */
int can_get_status(CanHandle_t handle, uint8_t* tx_error, uint8_t* rx_error, uint8_t* bus_status);

/**
 * 设置CAN总线的比特率
 *
 * @param handle CAN句柄
 * @param bitrate 比特率(bps)
 * @return 0表示成功,非0表示失败
 */
int can_set_bitrate(CanHandle_t handle, uint32_t bitrate);

/**
 * 获取最后一个错误消息
 *
 * @return 错误消息字符串
 */
const char* can_get_last_error(void);

#endif /* CAN_H */

c

/**
 * can.c - CAN总线通信接口实现 (基于SocketCAN)
 *
 * 提供与CAN总线设备通信的基本功能
 */

#include "can.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdarg.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <linux/can/error.h>
#include <fcntl.h>

// 定义CAN句柄结构体
struct CanHandle {
    int socket;                 // CAN套接字
    char interface_name[32];    // 接口名称
    struct sockaddr_can addr;   // 套接字地址
    struct ifreq ifr;           // 接口请求
    uint32_t bitrate;           // 比特率
    int is_started;             // 是否已启动
};

// 最后一个错误消息
static char lastErrorMessage[256] = {0};

// 设置最后一个错误消息
static void set_last_error(const char* format, ...) {
    va_list args;
    va_start(args, format);
    vsnprintf(lastErrorMessage, sizeof(lastErrorMessage), format, args);
    va_end(args);
}

// 打开CAN设备
CanHandle_t can_open(const char* interface_name, uint32_t bitrate) {
    if (!interface_name) {
        set_last_error("接口名称为空");
        return NULL;
    }
    
    // 分配句柄
    CanHandle_t handle = (CanHandle_t)malloc(sizeof(struct CanHandle));
    if (!handle) {
        set_last_error("内存分配失败");
        return NULL;
    }
    
    // 初始化句柄
    memset(handle, 0, sizeof(struct CanHandle));
    strncpy(handle->interface_name, interface_name, sizeof(handle->interface_name) - 1);
    handle->bitrate = bitrate;
    handle->is_started = 0;
    
    // 创建原始CAN套接字
    handle->socket = socket(PF_CAN, SOCK_RAW, CAN_RAW);
    if (handle->socket < 0) {
        set_last_error("创建CAN套接字失败: %s", strerror(errno));
        free(handle);
        return NULL;
    }
    
    // 获取接口索引
    strncpy(handle->ifr.ifr_name, interface_name, IFNAMSIZ - 1);
    if (ioctl(handle->socket, SIOCGIFINDEX, &handle->ifr) < 0) {
        set_last_error("获取接口索引失败: %s", strerror(errno));
        close(handle->socket);
        free(handle);
        return NULL;
    }
    
    // 设置地址
    memset(&handle->addr, 0, sizeof(struct sockaddr_can));
    handle->addr.can_family = AF_CAN;
    handle->addr.can_ifindex = handle->ifr.ifr_ifindex;
    
    // 设置非阻塞模式
    int flags = fcntl(handle->socket, F_GETFL, 0);
    if (flags < 0) {
        set_last_error("获取套接字标志失败: %s", strerror(errno));
        close(handle->socket);
        free(handle);
        return NULL;
    }
    
    if (fcntl(handle->socket, F_SETFL, flags | O_NONBLOCK) < 0) {
        set_last_error("设置非阻塞模式失败: %s", strerror(errno));
        close(handle->socket);
        free(handle);
        return NULL;
    }
    
    // 启用接收错误帧
    int recv_err_frames = 1;
    if (setsockopt(handle->socket, SOL_CAN_RAW, CAN_RAW_ERR_FILTER,
                   &recv_err_frames, sizeof(recv_err_frames)) < 0) {
        set_last_error("启用错误帧接收失败: %s", strerror(errno));
        close(handle->socket);
        free(handle);
        return NULL;
    }
    
    // 设置比特率 (这通常需要使用ip命令或定制驱动程序,这里只是保存值)
    handle->bitrate = bitrate;
    
    return handle;
}

// 关闭CAN设备
int can_close(CanHandle_t handle) {
    if (!handle) {
        set_last_error("无效的句柄");
        return -1;
    }
    
    if (handle->is_started) {
        can_stop(handle);
    }
    
    if (handle->socket >= 0) {
        close(handle->socket);
    }
    
    free(handle);
    return 0;
}

// 开始CAN通信
int can_start(CanHandle_t handle) {
    if (!handle) {
        set_last_error("无效的句柄");
        return -1;
    }
    
    if (handle->is_started) {
        return 0; // 已经启动
    }
    
    // 绑定套接字到CAN接口
    if (bind(handle->socket, (struct sockaddr*)&handle->addr, sizeof(handle->addr)) < 0) {
        set_last_error("绑定套接字失败: %s", strerror(errno));
        return -1;
    }
    
    handle->is_started = 1;
    return 0;
}

// 停止CAN通信
int can_stop(CanHandle_t handle) {
    if (!handle) {
        set_last_error("无效的句柄");
        return -1;
    }
    
    if (!handle->is_started) {
        return 0; // 已经停止
    }
    
    // 关闭并重新打开套接字
    close(handle->socket);
    
    handle->socket = socket(PF_CAN, SOCK_RAW, CAN_RAW);
    if (handle->socket < 0) {
        set_last_error("重新创建CAN套接字失败: %s", strerror(errno));
        handle->is_started = 0;
        return -1;
    }
    
    // 重新设置非阻塞模式
    int flags = fcntl(handle->socket, F_GETFL, 0);
    if (flags >= 0) {
        fcntl(handle->socket, F_SETFL, flags | O_NONBLOCK);
    }
    
    // 重新启用接收错误帧
    int recv_err_frames = 1;
    setsockopt(handle->socket, SOL_CAN_RAW, CAN_RAW_ERR_FILTER,
               &recv_err_frames, sizeof(recv_err_frames));
    
    handle->is_started = 0;
    return 0;
}

// 发送CAN帧
int can_send(CanHandle_t handle, const CanFrame* frame) {
    if (!handle || !frame) {
        set_last_error("无效的参数");
        return -1;
    }
    
    if (!handle->is_started) {
        set_last_error("CAN接口未启动");
        return -1;
    }
    
    // 检查数据长度
    if (frame->dlc > 8) {
        set_last_error("无效的数据长度: %d", frame->dlc);
        return -1;
    }
    
    // 准备CAN帧
    struct can_frame can_frame;
    memset(&can_frame, 0, sizeof(struct can_frame));
    
    // 设置ID和标志
    if (frame->is_extended) {
        can_frame.can_id = frame->id | CAN_EFF_FLAG;
    } else {
        can_frame.can_id = frame->id & CAN_SFF_MASK;
    }
    
    if (frame->is_remote) {
        can_frame.can_id |= CAN_RTR_FLAG;
    }
    
    if (frame->is_error) {
        can_frame.can_id |= CAN_ERR_FLAG;
    }
    
    // 设置数据长度和数据
    can_frame.can_dlc = frame->dlc;
    memcpy(can_frame.data, frame->data, frame->dlc);
    
    // 发送帧
    ssize_t nbytes = write(handle->socket, &can_frame, sizeof(struct can_frame));
    if (nbytes != sizeof(struct can_frame)) {
        set_last_error("发送CAN帧失败: %s", strerror(errno));
        return -1;
    }
    
    return 0;
}

// 接收CAN帧
int can_receive(CanHandle_t handle, CanFrame* frame, int timeout_ms) {
    if (!handle || !frame) {
        set_last_error("无效的参数");
        return -1;
    }
    
    if (!handle->is_started) {
        set_last_error("CAN接口未启动");
        return -1;
    }
    
    // 准备select超时
    fd_set readfds;
    struct timeval tv, *tvp;
    
    FD_ZERO(&readfds);
    FD_SET(handle->socket, &readfds);
    
    if (timeout_ms >= 0) {
        tv.tv_sec = timeout_ms / 1000;
        tv.tv_usec = (timeout_ms % 1000) * 1000;
        tvp = &tv;
    } else {
        // 无限等待
        tvp = NULL;
    }
    
    // 等待数据可读
    int ret = select(handle->socket + 1, &readfds, NULL, NULL, tvp);
    if (ret < 0) {
        set_last_error("select失败: %s", strerror(errno));
        return -1;
    } else if (ret == 0) {
        // 超时
        return 1;
    }
    
    // 读取CAN帧
    struct can_frame can_frame;
    struct timeval timestamp;
    
    ssize_t nbytes = read(handle->socket, &can_frame, sizeof(struct can_frame));
    if (nbytes < 0) {
        set_last_error("读取CAN帧失败: %s", strerror(errno));
        return -1;
    }
    
    if (nbytes < (ssize_t)sizeof(struct can_frame)) {
        set_last_error("接收到不完整的CAN帧");
        return -1;
    }
    
    // 获取时间戳
    ioctl(handle->socket, SIOCGSTAMP, &timestamp);
    
    // 填充输出帧
    if (can_frame.can_id & CAN_EFF_FLAG) {
        frame->id = can_frame.can_id & CAN_EFF_MASK;
        frame->is_extended = 1;
    } else {
        frame->id = can_frame.can_id & CAN_SFF_MASK;
        frame->is_extended = 0;
    }
    
    frame->is_remote = (can_frame.can_id & CAN_RTR_FLAG) ? 1 : 0;
    frame->is_error = (can_frame.can_id & CAN_ERR_FLAG) ? 1 : 0;
    frame->dlc = can_frame.can_dlc;
    memcpy(frame->data, can_frame.data, can_frame.can_dlc);
    
    // 设置时间戳 (微秒)
    frame->timestamp = (uint64_t)timestamp.tv_sec * 1000000 + timestamp.tv_usec;
    
    return 0;
}

// 设置CAN滤波器
int can_set_filters(CanHandle_t handle, const CanFilter* filters, int num_filters) {
    if (!handle || (!filters && num_filters > 0)) {
        set_last_error("无效的参数");
        return -1;
    }
    
    // 如果没有滤波器,则接收所有帧
    if (num_filters == 0) {
        struct can_filter rfilter[1];
        rfilter[0].can_id = 0;
        rfilter[0].can_mask = 0;
        
        if (setsockopt(handle->socket, SOL_CAN_RAW, CAN_RAW_FILTER,
                       &rfilter, sizeof(rfilter)) < 0) {
            set_last_error("设置CAN滤波器失败: %s", strerror(errno));
            return -1;
        }
        
        return 0;
    }
    
    // 设置自定义滤波器
    struct can_filter* rfilters = (struct can_filter*)malloc(
                                   num_filters * sizeof(struct can_filter));
    if (!rfilters) {
        set_last_error("内存分配失败");
        return -1;
    }
    
    for (int i = 0; i < num_filters; i++) {
        if (filters[i].is_extended) {
            rfilters[i].can_id = filters[i].id | CAN_EFF_FLAG;
            rfilters[i].can_mask = filters[i].mask | CAN_EFF_FLAG;
        } else {
            rfilters[i].can_id = filters[i].id & CAN_SFF_MASK;
            rfilters[i].can_mask = filters[i].mask & CAN_SFF_MASK;
        }
    }
    
    if (setsockopt(handle->socket, SOL_CAN_RAW, CAN_RAW_FILTER,
                   rfilters, num_filters * sizeof(struct can_filter)) < 0) {
        set_last_error("设置CAN滤波器失败: %s", strerror(errno));
        free(rfilters);
        return -1;
    }
    
    free(rfilters);
    return 0;
}

// 获取CAN总线状态
int can_get_status(CanHandle_t handle, uint8_t* tx_error, uint8_t* rx_error, uint8_t* bus_status) {
    if (!handle || !tx_error || !rx_error || !bus_status) {
        set_last_error("无效的参数");
        return -1;
    }
    
    if (!handle->is_started) {
        set_last_error("CAN接口未启动");
        return -1;
    }
    
    // 获取接口状态
    struct ifreq ifr;
    struct can_berr_counter berr;
    
    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, handle->interface_name, IFNAMSIZ - 1);
    
    // 获取错误计数器
    ifr.ifr_data = (void*)&berr;
    if (ioctl(handle->socket, SIOCGCANBSTATS, &ifr) < 0) {
        // 如果不支持SIOCGCANBSTATS,尝试其他方法
        *tx_error = 0;
        *rx_error = 0;
        *bus_status = 0;
        return 0;
    }
    
    *tx_error = berr.txerr;
    *rx_error = berr.rxerr;
    
    // 确定总线状态
    if (*tx_error >= 255 || *rx_error >= 255) {
        *bus_status = 3; // 总线关闭
    } else if (*tx_error >= 128 || *rx_error >= 128) {
        *bus_status = 2; // 被动错误
    } else if (*tx_error >= 96 || *rx_error >= 96) {
        *bus_status = 1; // 警告
    } else {
        *bus_status = 0; // 正常
    }
    
    return 0;
}

// 设置CAN总线的比特率
int can_set_bitrate(CanHandle_t handle, uint32_t bitrate) {
    if (!handle) {
        set_last_error("无效的句柄");
        return -1;
    }
    
    // 在Linux环境中,通常需要使用ip命令设置CAN接口参数
    // 例如: ip link set can0 type can bitrate 500000
    // 这里我们只保存比特率值,需要通过外部命令实际设置接口
    
    char command[128];
    snprintf(command, sizeof(command),
             "ip link set %s down && ip link set %s type can bitrate %u && ip link set %s up",
             handle->interface_name, handle->interface_name, bitrate, handle->interface_name);
    
    int result = system(command);
    if (result != 0) {
        set_last_error("设置比特率失败: 命令返回 %d", result);
        return -1;
    }
    
    handle->bitrate = bitrate;
    return 0;
}

// 获取最后一个错误消息
const char* can_get_last_error(void) {
    return lastErrorMessage;
}

3.4 SPI 设备通信实例

c

/**
 * spi_device.h - SPI设备通信接口
 * 
 * 基于C语言的SPI通信接口,支持Linux/Unix
 */

#ifndef SPI_DEVICE_H
#define SPI_DEVICE_H

#include <stdint.h>

// SPI传输模式
typedef enum {
    SPI_MODE_0 = 0,  // CPOL=0, CPHA=0
    SPI_MODE_1 = 1,  // CPOL=0, CPHA=1
    SPI_MODE_2 = 2,  // CPOL=1, CPHA=0
    SPI_MODE_3 = 3   // CPOL=1, CPHA=1
} SpiMode;

// SPI设备句柄
typedef struct SpiDevice* SpiDevice_t;

/**
 * 打开SPI设备
 * 
 * @param device_path 设备路径 (例如 "/dev/spidev0.0")
 * @param mode SPI模式 (0-3)
 * @param speed_hz 时钟频率 (Hz)
 * @param bits_per_word 每个字的位数 (通常为8)
 * @param lsb_first 是否LSB优先 (0=MSB, 1=LSB)
 * @return SPI设备句柄,失败返回NULL
 */
SpiDevice_t spi_open(const char* device_path, SpiMode mode, 
                     uint32_t speed_hz, uint8_t bits_per_word, 
                     int lsb_first);

/**
 * 关闭SPI设备
 * 
 * @param device SPI设备句柄
 */
void spi_close(SpiDevice_t device);

/**
 * 执行SPI全双工传输
 * 
 * @param device SPI设备句柄
 * @param tx_buffer 发送缓冲区
 * @param rx_buffer 接收缓冲区
 * @param length 缓冲区长度
 * @return 成功返回0,失败返回负数
 */
int spi_transfer(SpiDevice_t device, const uint8_t* tx_buffer, 
                 uint8_t* rx_buffer, size_t length);

/**
 * 执行SPI发送操作 (无接收)
 * 
 * @param device SPI设备句柄
 * @param buffer 发送缓冲区
 * @param length 数据长度
 * @return 成功返回0,失败返回负数
 */
int spi_write(SpiDevice_t device, const uint8_t* buffer, size_t length);

/**
 * 执行SPI接收操作 (发送0)
 * 
 * @param device SPI设备句柄
 * @param buffer 接收缓冲区
 * @param length 数据长度
 * @return 成功返回0,失败返回负数
 */
int spi_read(SpiDevice_t device, uint8_t* buffer, size_t length);

/**
 * 设置SPI模式
 * 
 * @param device SPI设备句柄
 * @param mode SPI模式 (0-3)
 * @return 成功返回0,失败返回负数
 */
int spi_set_mode(SpiDevice_t device, SpiMode mode);

/**
 * 设置SPI时钟频率
 * 
 * @param device SPI设备句柄
 * @param speed_hz 时钟频率 (Hz)
 * @return 成功返回0,失败返回负数
 */
int spi_set_speed(SpiDevice_t device, uint32_t speed_hz);

/**
 * 设置SPI每个字的位数
 * 
 * @param device SPI设备句柄
 * @param bits_per_word 每个字的位数 (通常为8)
 * @return 成功返回0,失败返回负数
 */
int spi_set_bits_per_word(SpiDevice_t device, uint8_t bits_per_word);

/**
 * 设置SPI位序
 * 
 * @param device SPI设备句柄
 * @param lsb_first 是否LSB优先 (0=MSB, 1=LSB)
 * @return 成功返回0,失败返回负数
 */
int spi_set_bit_order(SpiDevice_t device, int lsb_first);

/**
 * 获取最后的错误消息
 * 
 * @return 错误消息字符串
 */
const char* spi_get_error(void);

#endif /* SPI_DEVICE_H */

c

/**
 * spi_device.c - SPI设备通信接口实现
 * 
 * 基于Linux SPI设备驱动的实现
 */

#include "spi_device.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>

// 最大错误消息长度
#define MAX_ERROR_MSG_LEN 256

// SPI设备结构体
struct SpiDevice {
    int fd;                  // 文件描述符
    uint32_t speed_hz;       // 速度 (Hz)
    uint8_t bits_per_word;   // 每个字的位数
    uint8_t mode;            // SPI模式
    uint8_t lsb_first;       // LSB优先标志
    char device_path[64];    // 设备路径
};

// 全局错误消息
static char error_message[MAX_ERROR_MSG_LEN] = {0};

// 设置错误消息
static void set_error(const char* format, ...) {
    va_list args;
    va_start(args, format);
    vsnprintf(error_message, MAX_ERROR_MSG_LEN - 1, format, args);
    va_end(args);
}

// 打开SPI设备
SpiDevice_t spi_open(const char* device_path, SpiMode mode, 
                     uint32_t speed_hz, uint8_t bits_per_word, 
                     int lsb_first) {
    // 参数检查
    if (!device_path) {
        set_error("设备路径为空");
        return NULL;
    }
    
    // 分配设备结构体
    SpiDevice_t device = (SpiDevice_t)malloc(sizeof(struct SpiDevice));
    if (!device) {
        set_error("内存分配失败");
        return NULL;
    }
    
    // 初始化结构体
    memset(device, 0, sizeof(struct SpiDevice));
    strncpy(device->device_path, device_path, sizeof(device->device_path) - 1);
    device->speed_hz = speed_hz;
    device->bits_per_word = bits_per_word;
    device->mode = (uint8_t)mode;
    device->lsb_first = lsb_first ? 1 : 0;
    
    // 打开SPI设备
    device->fd = open(device_path, O_RDWR);
    if (device->fd < 0) {
        set_error("无法打开SPI设备 '%s': %s", device_path, strerror(errno));
        free(device);
        return NULL;
    }
    
    // 配置SPI模式
    uint8_t spi_mode = device->mode;
    if (device->lsb_first) {
        spi_mode |= SPI_LSB_FIRST;
    }
    
    if (ioctl(device->fd, SPI_IOC_WR_MODE, &spi_mode) < 0) {
        set_error("设置SPI模式失败: %s", strerror(errno));
        close(device->fd);
        free(device);
        return NULL;
    }
    
    // 配置位数
    if (ioctl(device->fd, SPI_IOC_WR_BITS_PER_WORD, &device->bits_per_word) < 0) {
        set_error("设置SPI位数失败: %s", strerror(errno));
        close(device->fd);
        free(device);
        return NULL;
    }
    
    // 配置速度
    if (ioctl(device->fd, SPI_IOC_WR_MAX_SPEED_HZ, &device->speed_hz) < 0) {
        set_error("设置SPI速度失败: %s", strerror(errno));
        close(device->fd);
        free(device);
        return NULL;
    }
    
    return device;
}

// 关闭SPI设备
void spi_close(SpiDevice_t device) {
    if (device) {
        if (device->fd >= 0) {
            close(device->fd);
        }
        free(device);
    }
}

// 执行SPI全双工传输
int spi_transfer(SpiDevice_t device, const uint8_t* tx_buffer, 
                 uint8_t* rx_buffer, size_t length) {
    if (!device || !tx_buffer || !rx_buffer || length == 0) {
        set_error("无效的参数");
        return -1;
    }
    
    // 创建传输结构
    struct spi_ioc_transfer tr = {
        .tx_buf = (unsigned long)tx_buffer,
        .rx_buf = (unsigned long)rx_buffer,
        .len = length,
        .speed_hz = device->speed_hz,
        .delay_usecs = 0,
        .bits_per_word = device->bits_per_word,
    };
    
    // 执行传输
    int ret = ioctl(device->fd, SPI_IOC_MESSAGE(1), &tr);
    if (ret < 0) {
        set_error("SPI传输失败: %s", strerror(errno));
        return -2;
    }
    
    return 0;
}

// 执行SPI发送操作 (无接收)
int spi_write(SpiDevice_t device, const uint8_t* buffer, size_t length) {
    if (!device || !buffer || length == 0) {
        set_error("无效的参数");
        return -1;
    }
    
    // 分配临时接收缓冲区
    uint8_t* rx_buffer = (uint8_t*)malloc(length);
    if (!rx_buffer) {
        set_error("内存分配失败");
        return -3;
    }
    
    // 执行传输
    int ret = spi_transfer(device, buffer, rx_buffer, length);
    
    // 释放临时缓冲区
    free(rx_buffer);
    
    return ret;
}

// 执行SPI接收操作 (发送0)
int spi_read(SpiDevice_t device, uint8_t* buffer, size_t length) {
    if (!device || !buffer || length == 0) {
        set_error("无效的参数");
        return -1;
    }
    
    // 分配临时发送缓冲区
    uint8_t* tx_buffer = (uint8_t*)malloc(length);
    if (!tx_buffer) {
        set_error("内存分配失败");
        return -3;
    }
    
    // 填充发送缓冲区为0
    memset(tx_buffer, 0, length);
    
    // 执行传输
    int ret = spi_transfer(device, tx_buffer, buffer, length);
    
    // 释放临时缓冲区
    free(tx_buffer);
    
    return ret;
}

// 设置SPI模式
int spi_set_mode(SpiDevice_t device, SpiMode mode) {
    if (!device) {
        set_error("无效的设备句柄");
        return -1;
    }
    
    // 构建SPI模式标志
    uint8_t spi_mode = (uint8_t)mode;
    if (device->lsb_first) {
        spi_mode |= SPI_LSB_FIRST;
    }
    
    // 设置模式
    if (ioctl(device->fd, SPI_IOC_WR_MODE, &spi_mode) < 0) {
        set_error("设置SPI模式失败: %s", strerror(errno));
        return -2;
    }
    
    // 更新设备结构
    device->mode = (uint8_t)mode;
    
    return 0;
}

// 设置SPI时钟频率
int spi_set_speed(SpiDevice_t device, uint32_t speed_hz) {
    if (!device) {
        set_error("无效的设备句柄");
        return -1;
    }
    
    // 设置速度
    if (ioctl(device->fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed_hz) < 0) {
        set_error("设置SPI速度失败: %s", strerror(errno));
        return -2;
    }
    
    // 更新设备结构
    device->speed_hz = speed_hz;
    
    return 0;
}

// 设置SPI每个字的位数
int spi_set_bits_per_word(SpiDevice_t device, uint8_t bits_per_word) {
    if (!device) {
        set_error("无效的设备句柄");
        return -1;
    }
    
    // 设置位数
    if (ioctl(device->fd, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word) < 0) {
        set_error("设置SPI位数失败: %s", strerror(errno));
        return -2;
    }
    
    // 更新设备结构
    device->bits_per_word = bits_per_word;
    
    return 0;
}

// 设置SPI位序
int spi_set_bit_order(SpiDevice_t device, int lsb_first) {
    if (!device) {
        set_error("无效的设备句柄");
        return -1;
    }
    
    // 构建新的模式标志
    uint8_t spi_mode = device->mode;
    if (lsb_first) {
        spi_mode |= SPI_LSB_FIRST;
    } else {
        spi_mode &= ~SPI_LSB_FIRST;
    }
    
    // 设置模式
    if (ioctl(device->fd, SPI_IOC_WR_MODE, &spi_mode) < 0) {
        set_error("设置SPI位序失败: %s", strerror(errno));
        return -2;
    }
    
    // 更新设备结构
    device->lsb_first = lsb_first ? 1 : 0;
    
    return 0;
}

// 获取最后的错误消息
const char* spi_get_error(void) {
    return error_message;
}

4. 综合应用示例

4.1 嵌入式传感器数据采集系统

c

/**
 * sensor_system.h - 嵌入式传感器数据采集系统接口
 * 
 * 硬件协同设计示例:软件与传感器硬件接口的协同设计
 */

#ifndef SENSOR_SYSTEM_H
#define SENSOR_SYSTEM_H

#include <stdint.h>
#include <time.h>

// 传感器类型定义
typedef enum {
    SENSOR_TYPE_TEMPERATURE = 0,
    SENSOR_TYPE_HUMIDITY = 1,
    SENSOR_TYPE_PRESSURE = 2,
    SENSOR_TYPE_ACCEL = 3,
    SENSOR_TYPE_GYRO = 4,
    SENSOR_TYPE_MAGNETIC = 5,
    SENSOR_TYPE_LIGHT = 6,
    SENSOR_TYPE_PROXIMITY = 7,
    SENSOR_TYPE_GAS = 8,
    SENSOR_TYPE_COUNT  // 总数
} SensorType;

// 传感器数据结构体
typedef struct {
    SensorType type;      // 传感器类型
    uint32_t sensor_id;   // 传感器ID
    double value[3];      // 传感器值 (最多3个轴)
    uint8_t value_count;  // 实际值的数量
    struct timespec timestamp; // 时间戳
} SensorData;

// 传感器配置结构体
typedef struct {
    uint32_t sample_rate;   // 采样率 (Hz)
    uint32_t range;         // 量程
    uint32_t resolution;    // 分辨率
    uint8_t enabled;        // 启用标志
} SensorConfig;

// 系统配置结构体
typedef struct {
    uint8_t use_i2c;       // 使用I2C接口
    uint8_t use_spi;       // 使用SPI接口
    char i2c_device[64];   // I2C设备路径
    char spi_device[64];   // SPI设备路径
    uint32_t i2c_addr;     // I2C设备地址
    uint32_t spi_speed;    // SPI时钟速度
    uint8_t log_enabled;   // 启用日志
    char log_file[128];    // 日志文件路径
} SystemConfig;

// 传感器系统句柄
typedef struct SensorSystem* SensorSystem_t;

/**
 * 初始化传感器系统
 * 
 * @param config 系统配置
 * @return 传感器系统句柄,失败返回NULL
 */
SensorSystem_t sensor_system_init(const SystemConfig* config);

/**
 * 关闭传感器系统
 * 
 * @param system 传感器系统句柄
 */
void sensor_system_close(SensorSystem_t system);

/**
 * 添加传感器
 * 
 * @param system 传感器系统句柄
 * @param type 传感器类型
 * @param config 传感器配置
 * @return 成功返回传感器ID,失败返回-1
 */
int sensor_system_add_sensor(SensorSystem_t system, SensorType type, 
                          const SensorConfig* config);

/**
 * 配置传感器
 * 
 * @param system 传感器系统句柄
 * @param sensor_id 传感器ID
 * @param config 传感器配置
 * @return 成功返回0,失败返回负值
 */
int sensor_system_configure_sensor(SensorSystem_t system, uint32_t sensor_id, 
                                const SensorConfig* config);

/**
 * 启用传感器
 * 
 * @param system 传感器系统句柄
 * @param sensor_id 传感器ID
 * @param enabled 1=启用,0=禁用
 * @return 成功返回0,失败返回负值
 */
int sensor_system_enable_sensor(SensorSystem_t system, uint32_t sensor_id, 
                             uint8_t enabled);

/**
 * 读取传感器数据
 * 
 * @param system 传感器系统句柄
 * @param sensor_id 传感器ID
 * @param data 传感器数据输出缓冲区
 * @return 成功返回0,失败返回负值
 */
int sensor_system_read_sensor(SensorSystem_t system, uint32_t sensor_id, 
                           SensorData* data);

/**
 * 启动数据采集
 * 
 * @param system 传感器系统句柄
 * @return 成功返回0,失败返回负值
 */
int sensor_system_start_acquisition(SensorSystem_t system);

/**
 * 停止数据采集
 * 
 * @param system 传感器系统句柄
 * @return 成功返回0,失败返回负值
 */
int sensor_system_stop_acquisition(SensorSystem_t system);

/**
 * 设置数据回调函数
 * 
 * @param system 传感器系统句柄
 * @param callback 回调函数指针
 * @param user_data 用户数据
 * @return 成功返回0,失败返回负值
 */
int sensor_system_set_data_callback(SensorSystem_t system, 
                                 void (*callback)(const SensorData* data, void* user_data),
                                 void* user_data);

/**
 * 获取最后的错误消息
 * 
 * @return 错误消息字符串
 */
const char* sensor_system_get_error(void);

/**
 * 获取传感器数量
 * 
 * @param system 传感器系统句柄
 * @return 传感器数量
 */
uint32_t sensor_system_get_sensor_count(SensorSystem_t system);

/**
 * 获取系统状态
 * 
 * @param system 传感器系统句柄
 * @param is_running 运行状态标志
 * @param active_sensors 活动传感器数量
 * @param sample_rate 当前平均采样率
 * @return 成功返回0,失败返回负值
 */
int sensor_system_get_status(SensorSystem_t system, uint8_t* is_running, 
                          uint32_t* active_sensors, double* sample_rate);

#endif /* SENSOR_SYSTEM_H */

c

/**
 * sensor_system.c - 嵌入式传感器数据采集系统实现
 * 
 * 硬件协同设计示例:软件与传感器硬件接口的协同设计
 */

#include "sensor_system.h"
#include "i2c.h"
#include "spi_device.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include <stdarg.h>

// 最大错误消息长度
#define MAX_ERROR_MSG_LEN 256

// 最大传感器数量
#define MAX_SENSORS 32

// 传感器设备结构体
typedef struct {
    SensorType type;        // 传感器类型
    uint32_t sensor_id;     // 传感器ID
    SensorConfig config;    // 传感器配置
    uint8_t is_i2c;         // 是否使用I2C接口
    uint8_t i2c_addr;       // I2C设备地址
    uint8_t reg_addr;       // 寄存器地址
    uint8_t active;         // 激活标志
} SensorDevice;

// 传感器系统结构体
struct SensorSystem {
    SystemConfig config;                    // 系统配置
    I2cHandle_t i2c_handle;                // I2C句柄
    SpiDevice_t spi_handle;                // SPI句柄
    SensorDevice sensors[MAX_SENSORS];     // 传感器设备数组
    uint32_t sensor_count;                 // 传感器数量
    uint8_t is_running;                    // 运行标志
    pthread_t acquisition_thread;          // 采集线程
    pthread_mutex_t lock;                  // 互斥锁
    void (*data_callback)(const SensorData* data, void* user_data); // 数据回调
    void* callback_user_data;              // 回调用户数据
    FILE* log_file;                        // 日志文件
};

// 全局错误消息
static char error_message[MAX_ERROR_MSG_LEN] = {0};

// 设置错误消息
static void set_error(const char* format, ...) {
    va_list args;
    va_start(args, format);
    vsnprintf(error_message, MAX_ERROR_MSG_LEN - 1, format, args);
    va_end(args);
}

// 写日志
static void write_log(SensorSystem_t system, const char* format, ...) {
    if (!system || !system->config.log_enabled || !system->log_file) {
        return;
    }
    
    // 获取当前时间
    time_t now;
    struct tm timeinfo;
    char timestamp[64];
    
    time(&now);
    localtime_r(&now, &timeinfo);
    strftime(timestamp, sizeof(timestamp), "[%Y-%m-%d %H:%M:%S] ", &timeinfo);
    
    // 写入时间戳
    fputs(timestamp, system->log_file);
    
    // 写入日志消息
    va_list args;
    va_start(args, format);
    vfprintf(system->log_file, format, args);
    va_end(args);
    
    // 写入换行并刷新
    fputs("\n", system->log_file);
    fflush(system->log_file);
}

// 数据采集线程函数
static void* acquisition_thread_func(void* arg) {
    SensorSystem_t system = (SensorSystem_t)arg;
    SensorData data;
    
    write_log(system, "数据采集线程启动");
    
    while (system->is_running) {
        // 获取当前时间
        clock_gettime(CLOCK_REALTIME, &data.timestamp);
        
        // 遍历所有传感器
        for (uint32_t i = 0; i < system->sensor_count; i++) {
            // 如果传感器已激活
            if (system->sensors[i].active) {
                // 读取传感器数据
                if (sensor_system_read_sensor(system, system->sensors[i].sensor_id, &data) == 0) {
                    // 调用回调函数
                    if (system->data_callback) {
                        system->data_callback(&data, system->callback_user_data);
                    }
                    
                    // 记录日志
                    if (system->config.log_enabled && system->log_file) {
                        write_log(system, "传感器 %u 数据: 类型=%d, 值=[%.3f, %.3f, %.3f]",
                                 data.sensor_id, data.type,
                                 data.value[0], data.value[1], data.value[2]);
                    }
                }
            }
        }
        
        // 简单延时 (实际应用中应该使用更精确的定时机制)
        usleep(10000);  // 10ms
    }
    
    write_log(system, "数据采集线程停止");
    return NULL;
}

// 读取I2C传感器数据
static int read_i2c_sensor(SensorSystem_t system, SensorDevice* sensor, SensorData* data) {
    if (!system || !sensor || !data || !system->i2c_handle) {
        set_error("无效的参数");
        return -1;
    }
    
    // 设置I2C从设备地址
    if (i2c_set_slave_address(system->i2c_handle, sensor->i2c_addr, 0) != 0) {
        set_error("设置I2C从设备地址失败");
        return -2;
    }
    
    // 根据传感器类型确定要读取的数据大小
    uint8_t data_size = 2;  // 默认读取2字节
    
    switch (sensor->type) {
        case SENSOR_TYPE_TEMPERATURE:
        case SENSOR_TYPE_HUMIDITY:
        case SENSOR_TYPE_PRESSURE:
        case SENSOR_TYPE_LIGHT:
        case SENSOR_TYPE_PROXIMITY:
        case SENSOR_TYPE_GAS:
            data_size = 2;  // 单值传感器通常为2字节
            data->value_count = 1;
            break;
            
        case SENSOR_TYPE_ACCEL:
        case SENSOR_TYPE_GYRO:
        case SENSOR_TYPE_MAGNETIC:
            data_size = 6;  // 3轴传感器通常为6字节(每轴2字节)
            data->value_count = 3;
            break;
            
        default:
            set_error("不支持的传感器类型: %d", sensor->type);
            return -3;
    }
    
    // 分配读取缓冲区
    uint8_t* buffer = (uint8_t*)malloc(data_size);
    if (!buffer) {
        set_error("内存分配失败");
        return -4;
    }
    
    // 从I2C设备读取数据
    int ret = i2c_read_reg8(system->i2c_handle, sensor->reg_addr, buffer, data_size);
    if (ret < 0) {
        set_error("I2C读取失败: %s", i2c_get_last_error());
        free(buffer);
        return -5;
    }
    
    // 解析数据
    if (data->value_count == 1) {
        // 单值传感器
        int16_t raw_value = (buffer[0] << 8) | buffer[1];
        
        // 根据传感器类型进行转换
        switch (sensor->type) {
            case SENSOR_TYPE_TEMPERATURE:
                // 假设温度传感器: raw / 16.0 度
                data->value[0] = raw_value / 16.0;
                break;
                
            case SENSOR_TYPE_HUMIDITY:
                // 假设湿度传感器: raw / 10.0 %
                data->value[0] = raw_value / 10.0;
                break;
                
            case SENSOR_TYPE_PRESSURE:
                // 假设压力传感器: raw * 0.1 hPa
                data->value[0] = raw_value * 0.1;
                break;
                
            case SENSOR_TYPE_LIGHT:
                // 假设光传感器: raw lux
                data->value[0] = raw_value;
                break;
                
            case SENSOR_TYPE_PROXIMITY:
                // 假设接近传感器: raw mm
                data->value[0] = raw_value;
                break;
                
            case SENSOR_TYPE_GAS:
                // 假设气体传感器: raw ppm
                data->value[0] = raw_value;
                break;
                
            default:
                data->value[0] = raw_value;
        }
    } else if (data->value_count == 3) {
        // 3轴传感器
        int16_t raw_x = (buffer[0] << 8) | buffer[1];
        int16_t raw_y = (buffer[2] << 8) | buffer[3];
        int16_t raw_z = (buffer[4] << 8) | buffer[5];
        
        // 根据传感器类型进行转换
        switch (sensor->type) {
            case SENSOR_TYPE_ACCEL:
                // 假设加速度传感器: raw * 0.001 g
                data->value[0] = raw_x * 0.001;
                data->value[1] = raw_y * 0.001;
                data->value[2] = raw_z * 0.001;
                break;
                
            case SENSOR_TYPE_GYRO:
                // 假设陀螺仪传感器: raw * 0.01 deg/s
                data->value[0] = raw_x * 0.01;
                data->value[1] = raw_y * 0.01;
                data->value[2] = raw_z * 0.01;
                break;
                
            case SENSOR_TYPE_MAGNETIC:
                // 假设磁力计传感器: raw * 0.1 uT
                data->value[0] = raw_x * 0.1;
                data->value[1] = raw_y * 0.1;
                data->value[2] = raw_z * 0.1;
                break;
                
            default:
                data->value[0] = raw_x;
                data->value[1] = raw_y;
                data->value[2] = raw_z;
        }
    }
    
    // 设置传感器类型和ID
    data->type = sensor->type;
    data->sensor_id = sensor->sensor_id;
    
    // 释放缓冲区
    free(buffer);
    
    return 0;
}

// 读取SPI传感器数据
static int read_spi_sensor(SensorSystem_t system, SensorDevice* sensor, SensorData* data) {
    if (!system || !sensor || !data || !system->spi_handle) {
        set_error("无效的参数");
        return -1;
    }
    
    // 根据传感器类型确定要读取的数据大小
    uint8_t data_size = 2;  // 默认读取2字节
    
    switch (sensor->type) {
        case SENSOR_TYPE_TEMPERATURE:
        case SENSOR_


c

        case SENSOR_TYPE_HUMIDITY:
        case SENSOR_TYPE_PRESSURE:
        case SENSOR_TYPE_LIGHT:
        case SENSOR_TYPE_PROXIMITY:
        case SENSOR_TYPE_GAS:
            data_size = 2;  // 单值传感器通常为2字节
            data->value_count = 1;
            break;
            
        case SENSOR_TYPE_ACCEL:
        case SENSOR_TYPE_GYRO:
        case SENSOR_TYPE_MAGNETIC:
            data_size = 6;  // 3轴传感器通常为6字节(每轴2字节)
            data->value_count = 3;
            break;
            
        default:
            set_error("不支持的传感器类型: %d", sensor->type);
            return -3;
    }
    
    // 分配读取缓冲区
    uint8_t* rx_buffer = (uint8_t*)malloc(data_size + 1);  // +1用于寄存器地址
    uint8_t* tx_buffer = (uint8_t*)malloc(data_size + 1);
    
    if (!rx_buffer || !tx_buffer) {
        set_error("内存分配失败");
        if (rx_buffer) free(rx_buffer);
        if (tx_buffer) free(tx_buffer);
        return -4;
    }
    
    // 设置寄存器地址(读取命令)
    tx_buffer[0] = sensor->reg_addr | 0x80;  // 最高位设为1表示读操作
    memset(tx_buffer + 1, 0, data_size);     // 填充0
    
    // 通过SPI传输
    int ret = spi_transfer(system->spi_handle, tx_buffer, rx_buffer, data_size + 1);
    if (ret < 0) {
        set_error("SPI传输失败: %s", spi_get_error());
        free(rx_buffer);
        free(tx_buffer);
        return -5;
    }
    
    // 解析数据(跳过第一个字节,它是寄存器地址)
    if (data->value_count == 1) {
        // 单值传感器
        int16_t raw_value = (rx_buffer[1] << 8) | rx_buffer[2];
        
        // 根据传感器类型进行转换
        switch (sensor->type) {
            case SENSOR_TYPE_TEMPERATURE:
                // 假设温度传感器: raw / 16.0 度
                data->value[0] = raw_value / 16.0;
                break;
                
            case SENSOR_TYPE_HUMIDITY:
                // 假设湿度传感器: raw / 10.0 %
                data->value[0] = raw_value / 10.0;
                break;
                
            case SENSOR_TYPE_PRESSURE:
                // 假设压力传感器: raw * 0.1 hPa
                data->value[0] = raw_value * 0.1;
                break;
                
            case SENSOR_TYPE_LIGHT:
                // 假设光传感器: raw lux
                data->value[0] = raw_value;
                break;
                
            case SENSOR_TYPE_PROXIMITY:
                // 假设接近传感器: raw mm
                data->value[0] = raw_value;
                break;
                
            case SENSOR_TYPE_GAS:
                // 假设气体传感器: raw ppm
                data->value[0] = raw_value;
                break;
                
            default:
                data->value[0] = raw_value;
        }
    } else if (data->value_count == 3) {
        // 3轴传感器
        int16_t raw_x = (rx_buffer[1] << 8) | rx_buffer[2];
        int16_t raw_y = (rx_buffer[3] << 8) | rx_buffer[4];
        int16_t raw_z = (rx_buffer[5] << 8) | rx_buffer[6];
        
        // 根据传感器类型进行转换
        switch (sensor->type) {
            case SENSOR_TYPE_ACCEL:
                // 假设加速度传感器: raw * 0.001 g
                data->value[0] = raw_x * 0.001;
                data->value[1] = raw_y * 0.001;
                data->value[2] = raw_z * 0.001;
                break;
                
            case SENSOR_TYPE_GYRO:
                // 假设陀螺仪传感器: raw * 0.01 deg/s
                data->value[0] = raw_x * 0.01;
                data->value[1] = raw_y * 0.01;
                data->value[2] = raw_z * 0.01;
                break;
                
            case SENSOR_TYPE_MAGNETIC:
                // 假设磁力计传感器: raw * 0.1 uT
                data->value[0] = raw_x * 0.1;
                data->value[1] = raw_y * 0.1;
                data->value[2] = raw_z * 0.1;
                break;
                
            default:
                data->value[0] = raw_x;
                data->value[1] = raw_y;
                data->value[2] = raw_z;
        }
    }
    
    // 设置传感器类型和ID
    data->type = sensor->type;
    data->sensor_id = sensor->sensor_id;
    
    // 释放缓冲区
    free(rx_buffer);
    free(tx_buffer);
    
    return 0;
}

// 初始化传感器系统
SensorSystem_t sensor_system_init(const SystemConfig* config) {
    if (!config) {
        set_error("无效的系统配置");
        return NULL;
    }
    
    // 分配系统结构体
    SensorSystem_t system = (SensorSystem_t)malloc(sizeof(struct SensorSystem));
    if (!system) {
        set_error("内存分配失败");
        return NULL;
    }
    
    // 初始化结构体
    memset(system, 0, sizeof(struct SensorSystem));
    memcpy(&system->config, config, sizeof(SystemConfig));
    
    // 初始化互斥锁
    if (pthread_mutex_init(&system->lock, NULL) != 0) {
        set_error("初始化互斥锁失败");
        free(system);
        return NULL;
    }
    
    // 打开I2C设备(如果需要)
    if (config->use_i2c) {
        system->i2c_handle = i2c_open(config->i2c_device);
        if (!system->i2c_handle) {
            set_error("打开I2C设备失败: %s", i2c_get_last_error());
            pthread_mutex_destroy(&system->lock);
            free(system);
            return NULL;
        }
    }
    
    // 打开SPI设备(如果需要)
    if (config->use_spi) {
        system->spi_handle = spi_open(config->spi_device, SPI_MODE_0, 
                                     config->spi_speed, 8, 0);
        if (!system->spi_handle) {
            set_error("打开SPI设备失败: %s", spi_get_error());
            if (system->i2c_handle) {
                i2c_close(system->i2c_handle);
            }
            pthread_mutex_destroy(&system->lock);
            free(system);
            return NULL;
        }
    }
    
    // 打开日志文件(如果需要)
    if (config->log_enabled && config->log_file[0] != '\0') {
        system->log_file = fopen(config->log_file, "a");
        if (!system->log_file) {
            set_error("打开日志文件失败: %s", strerror(errno));
            // 不将此视为致命错误,继续初始化
        }
    }
    
    // 写入初始日志
    write_log(system, "传感器系统初始化");
    
    return system;
}

// 关闭传感器系统
void sensor_system_close(SensorSystem_t system) {
    if (!system) {
        return;
    }
    
    // 确保停止采集
    if (system->is_running) {
        sensor_system_stop_acquisition(system);
    }
    
    // 写入关闭日志
    write_log(system, "传感器系统关闭");
    
    // 关闭日志文件
    if (system->log_file) {
        fclose(system->log_file);
        system->log_file = NULL;
    }
    
    // 关闭I2C设备
    if (system->i2c_handle) {
        i2c_close(system->i2c_handle);
        system->i2c_handle = NULL;
    }
    
    // 关闭SPI设备
    if (system->spi_handle) {
        spi_close(system->spi_handle);
        system->spi_handle = NULL;
    }
    
    // 销毁互斥锁
    pthread_mutex_destroy(&system->lock);
    
    // 释放系统结构体
    free(system);
}

// 添加传感器
int sensor_system_add_sensor(SensorSystem_t system, SensorType type, 
                          const SensorConfig* config) {
    if (!system || !config) {
        set_error("无效的参数");
        return -1;
    }
    
    pthread_mutex_lock(&system->lock);
    
    // 检查是否已达到最大传感器数量
    if (system->sensor_count >= MAX_SENSORS) {
        pthread_mutex_unlock(&system->lock);
        set_error("已达到最大传感器数量 (%d)", MAX_SENSORS);
        return -2;
    }
    
    // 添加新传感器
    SensorDevice* sensor = &system->sensors[system->sensor_count];
    sensor->type = type;
    sensor->sensor_id = system->sensor_count;
    memcpy(&sensor->config, config, sizeof(SensorConfig));
    
    // 设置接口类型
    if (system->config.use_i2c) {
        sensor->is_i2c = 1;
        sensor->i2c_addr = (uint8_t)system->config.i2c_addr;
    } else {
        sensor->is_i2c = 0;
    }
    
    // 设置默认寄存器地址(根据传感器类型)
    switch (type) {
        case SENSOR_TYPE_TEMPERATURE:
            sensor->reg_addr = 0x00;
            break;
        case SENSOR_TYPE_HUMIDITY:
            sensor->reg_addr = 0x01;
            break;
        case SENSOR_TYPE_PRESSURE:
            sensor->reg_addr = 0x02;
            break;
        case SENSOR_TYPE_ACCEL:
            sensor->reg_addr = 0x10;
            break;
        case SENSOR_TYPE_GYRO:
            sensor->reg_addr = 0x20;
            break;
        case SENSOR_TYPE_MAGNETIC:
            sensor->reg_addr = 0x30;
            break;
        case SENSOR_TYPE_LIGHT:
            sensor->reg_addr = 0x40;
            break;
        case SENSOR_TYPE_PROXIMITY:
            sensor->reg_addr = 0x50;
            break;
        case SENSOR_TYPE_GAS:
            sensor->reg_addr = 0x60;
            break;
        default:
            sensor->reg_addr = 0x00;
    }
    
    // 设置激活状态
    sensor->active = config->enabled;
    
    // 更新传感器计数
    uint32_t sensor_id = system->sensor_count;
    system->sensor_count++;
    
    pthread_mutex_unlock(&system->lock);
    
    // 写入日志
    write_log(system, "添加传感器: ID=%u, 类型=%d, 启用=%d",
             sensor_id, type, config->enabled);
    
    return sensor_id;
}

// 配置传感器
int sensor_system_configure_sensor(SensorSystem_t system, uint32_t sensor_id, 
                                const SensorConfig* config) {
    if (!system || !config) {
        set_error("无效的参数");
        return -1;
    }
    
    pthread_mutex_lock(&system->lock);
    
    // 检查传感器ID是否有效
    if (sensor_id >= system->sensor_count) {
        pthread_mutex_unlock(&system->lock);
        set_error("无效的传感器ID: %u", sensor_id);
        return -2;
    }
    
    // 更新传感器配置
    memcpy(&system->sensors[sensor_id].config, config, sizeof(SensorConfig));
    
    // 更新激活状态
    system->sensors[sensor_id].active = config->enabled;
    
    pthread_mutex_unlock(&system->lock);
    
    // 写入日志
    write_log(system, "配置传感器: ID=%u, 启用=%d, 采样率=%u",
             sensor_id, config->enabled, config->sample_rate);
    
    return 0;
}

// 启用传感器
int sensor_system_enable_sensor(SensorSystem_t system, uint32_t sensor_id, 
                             uint8_t enabled) {
    if (!system) {
        set_error("无效的系统句柄");
        return -1;
    }
    
    pthread_mutex_lock(&system->lock);
    
    // 检查传感器ID是否有效
    if (sensor_id >= system->sensor_count) {
        pthread_mutex_unlock(&system->lock);
        set_error("无效的传感器ID: %u", sensor_id);
        return -2;
    }
    
    // 更新激活状态
    system->sensors[sensor_id].active = enabled ? 1 : 0;
    system->sensors[sensor_id].config.enabled = enabled ? 1 : 0;
    
    pthread_mutex_unlock(&system->lock);
    
    // 写入日志
    write_log(system, "%s传感器: ID=%u", enabled ? "启用" : "禁用", sensor_id);
    
    return 0;
}

// 读取传感器数据
int sensor_system_read_sensor(SensorSystem_t system, uint32_t sensor_id, 
                           SensorData* data) {
    if (!system || !data) {
        set_error("无效的参数");
        return -1;
    }
    
    pthread_mutex_lock(&system->lock);
    
    // 检查传感器ID是否有效
    if (sensor_id >= system->sensor_count) {
        pthread_mutex_unlock(&system->lock);
        set_error("无效的传感器ID: %u", sensor_id);
        return -2;
    }
    
    // 获取传感器引用
    SensorDevice* sensor = &system->sensors[sensor_id];
    
    // 确保传感器处于激活状态
    if (!sensor->active) {
        pthread_mutex_unlock(&system->lock);
        set_error("传感器未激活: %u", sensor_id);
        return -3;
    }
    
    // 根据接口类型读取传感器数据
    int ret;
    if (sensor->is_i2c) {
        ret = read_i2c_sensor(system, sensor, data);
    } else {
        ret = read_spi_sensor(system, sensor, data);
    }
    
    pthread_mutex_unlock(&system->lock);
    
    return ret;
}

// 启动数据采集
int sensor_system_start_acquisition(SensorSystem_t system) {
    if (!system) {
        set_error("无效的系统句柄");
        return -1;
    }
    
    pthread_mutex_lock(&system->lock);
    
    // 检查是否已经在运行
    if (system->is_running) {
        pthread_mutex_unlock(&system->lock);
        set_error("数据采集已经在运行");
        return -2;
    }
    
    // 检查是否有激活的传感器
    int has_active_sensor = 0;
    for (uint32_t i = 0; i < system->sensor_count; i++) {
        if (system->sensors[i].active) {
            has_active_sensor = 1;
            break;
        }
    }
    
    if (!has_active_sensor) {
        pthread_mutex_unlock(&system->lock);
        set_error("没有激活的传感器");
        return -3;
    }
    
    // 设置运行标志
    system->is_running = 1;
    
    // 创建采集线程
    int ret = pthread_create(&system->acquisition_thread, NULL, 
                            acquisition_thread_func, system);
    if (ret != 0) {
        system->is_running = 0;
        pthread_mutex_unlock(&system->lock);
        set_error("创建采集线程失败: %s", strerror(ret));
        return -4;
    }
    
    pthread_mutex_unlock(&system->lock);
    
    // 写入日志
    write_log(system, "启动数据采集");
    
    return 0;
}

// 停止数据采集
int sensor_system_stop_acquisition(SensorSystem_t system) {
    if (!system) {
        set_error("无效的系统句柄");
        return -1;
    }
    
    pthread_mutex_lock(&system->lock);
    
    // 检查是否正在运行
    if (!system->is_running) {
        pthread_mutex_unlock(&system->lock);
        set_error("数据采集未在运行");
        return -2;
    }
    
    // 清除运行标志
    system->is_running = 0;
    
    // 保存线程ID
    pthread_t thread_id = system->acquisition_thread;
    
    pthread_mutex_unlock(&system->lock);
    
    // 等待线程结束
    pthread_join(thread_id, NULL);
    
    // 写入日志
    write_log(system, "停止数据采集");
    
    return 0;
}

// 设置数据回调函数
int sensor_system_set_data_callback(SensorSystem_t system, 
                                 void (*callback)(const SensorData* data, void* user_data),
                                 void* user_data) {
    if (!system) {
        set_error("无效的系统句柄");
        return -1;
    }
    
    pthread_mutex_lock(&system->lock);
    
    // 更新回调函数和用户数据
    system->data_callback = callback;
    system->callback_user_data = user_data;
    
    pthread_mutex_unlock(&system->lock);
    
    // 写入日志
    write_log(system, "设置数据回调函数: %p", callback);
    
    return 0;
}

// 获取最后的错误消息
const char* sensor_system_get_error(void) {
    return error_message;
}

// 获取传感器数量
uint32_t sensor_system_get_sensor_count(SensorSystem_t system) {
    if (!system) {
        return 0;
    }
    
    return system->sensor_count;
}

// 获取系统状态
int sensor_system_get_status(SensorSystem_t system, uint8_t* is_running, 
                          uint32_t* active_sensors, double* sample_rate) {
    if (!system) {
        set_error("无效的系统句柄");
        return -1;
    }
    
    pthread_mutex_lock(&system->lock);
    
    // 获取运行状态
    if (is_running) {
        *is_running = system->is_running;
    }
    
    // 计算激活的传感器数量
    if (active_sensors) {
        *active_sensors = 0;
        for (uint32_t i = 0; i < system->sensor_count; i++) {
            if (system->sensors[i].active) {
                (*active_sensors)++;
            }
        }
    }
    
    // 计算平均采样率
    if (sample_rate) {
        *sample_rate = 0.0;
        uint32_t count = 0;
        
        for (uint32_t i = 0; i < system->sensor_count; i++) {
            if (system->sensors[i].active) {
                *sample_rate += system->sensors[i].config.sample_rate;
                count++;
            }
        }
        
        if (count > 0) {
            *sample_rate /= count;
        }
    }
    
    pthread_mutex_unlock(&system->lock);
    
    return 0;
}

4.2 电机控制系统

cpp

/**
 * motor_control.h - 电机控制系统接口
 * 
 * 硬件协同设计示例:软件与电机驱动硬件的协同设计
 */

#ifndef MOTOR_CONTROL_H
#define MOTOR_CONTROL_H

#include <cstdint>
#include <string>
#include <vector>
#include <memory>

namespace motor_control {

// 前向声明
class MotorControllerImpl;

// 电机类型
enum class MotorType {
    DC,             // 直流电机
    BLDC,           // 无刷直流电机
    STEPPER,        // 步进电机
    SERVO           // 伺服电机
};

// 电机控制模式
enum class ControlMode {
    POSITION,       // 位置控制
    VELOCITY,       // 速度控制
    TORQUE,         // 力矩控制
    OPEN_LOOP       // 开环控制
};

// 电机配置结构体
struct MotorConfig {
    std::string name;         // 电机名称
    MotorType type;           // 电机类型
    double max_velocity;      // 最大速度 (rpm)
    double max_acceleration;  // 最大加速度 (rpm/s)
    double max_torque;        // 最大力矩 (Nm)
    double gear_ratio;        // 齿轮比
    bool reverse_direction;   // 反向标志
    
    // 特定电机类型配置
    union {
        struct {
            double max_current;      // 最大电流 (A)
        } dc;
        
        struct {
            uint8_t pole_pairs;      // 极对数
            bool hall_sensors;       // 是否使用霍尔传感器
        } bldc;
        
        struct {
            uint32_t steps_per_rev;  // 每转步数
            uint8_t microstepping;   // 微步细分
        } stepper;
        
        struct {
            double min_angle;        // 最小角度 (度)
            double max_angle;        // 最大角度 (度)
            double center_angle;     // 中心角度 (度)
        } servo;
    };
};

// PID控制器参数
struct PIDParams {
    double kp;   // 比例系数
    double ki;   // 积分系数
    double kd;   // 微分系数
    double ff;   // 前馈系数
    double imax; // 积分限幅
};

// 电机状态
struct MotorStatus {
    double position;        // 位置 (取决于电机类型: 度/弧度/步)
    double velocity;        // 速度 (rpm)
    double current;         // 电流 (A)
    double voltage;         // 电压 (V)
    double temperature;     // 温度 (°C)
    bool is_moving;         // 是否运动中
    bool is_calibrated;     // 是否已校准
    bool error_state;       // 错误状态
    uint32_t error_code;    // 错误代码
    ControlMode mode;       // 当前控制模式
};

/**
 * 电机控制器类
 */
class MotorController {
public:
    /**
     * 构造函数
     * 
     * @param interface_name 接口名称 (如 "/dev/ttyUSB0", "can0")
     * @param interface_type 接口类型 (如 "uart", "can", "spi")
     */
    MotorController(const std::string& interface_name, 
                   const std::string& interface_type);
    
    /**
     * 析构函数
     */
    ~MotorController();
    
    /**
     * 初始化电机控制器
     * 
     * @return 成功返回true,失败返回false
     */
    bool initialize();
    
    /**
     * 添加电机
     * 
     * @param config 电机配置
     * @return 成功返回电机ID,失败返回-1
     */
    int add_motor(const MotorConfig& config);
    
    /**
     * 配置电机
     * 
     * @param motor_id 电机ID
     * @param config 电机配置
     * @return 成功返回true,失败返回false
     */
    bool configure_motor(int motor_id, const MotorConfig& config);
    
    /**
     * 设置PID参数
     * 
     * @param motor_id 电机ID
     * @param mode 控制模式
     * @param params PID参数
     * @return 成功返回true,失败返回false
     */
    bool set_pid_params(int motor_id, ControlMode mode, const PIDParams& params);
    
    /**
     * 设置电机模式
     * 
     * @param motor_id 电机ID
     * @param mode 控制模式
     * @return 成功返回true,失败返回false
     */
    bool set_motor_mode(int motor_id, ControlMode mode);
    
    /**
     * 使能/禁用电机
     * 
     * @param motor_id 电机ID
     * @param enable 使能标志
     * @return 成功返回true,失败返回false
     */
    bool enable_motor(int motor_id, bool enable);
    
    /**
     * 设置位置目标
     * 
     * @param motor_id 电机ID
     * @param position 目标位置
     * @param velocity_limit 可选的速度限制
     * @param acceleration_limit 可选的加速度限制
     * @return 成功返回true,失败返回false
     */
    bool set_position(int motor_id, double position, 
                     double velocity_limit = 0, 
                     double acceleration_limit = 0);
    
    /**
     * 设置速度目标
     * 
     * @param motor_id 电机ID
     * @param velocity 目标速度 (rpm)
     * @param acceleration_limit 可选的加速度限制
     * @return 成功返回true,失败返回false
     */
    bool set_velocity(int motor_id, double velocity, 
                     double acceleration_limit = 0);
    
    /**
     * 设置力矩目标
     * 
     * @param motor_id 电机ID
     * @param torque 目标力矩 (Nm)
     * @return 成功返回true,失败返回false
     */
    bool set_torque(int motor_id, double torque);
    
    /**
     * 设置开环输出
     * 
     * @param motor_id 电机ID
     * @param duty_cycle 占空比 (-1.0 to 1.0)
     * @return 成功返回true,失败返回false
     */
    bool set_duty_cycle(int motor_id, double duty_cycle);
    
    /**
     * 获取电机状态
     * 
     * @param motor_id 电机ID
     * @return 电机状态结构体
     */
    MotorStatus get_motor_status(int motor_id);
    
    /**
     * 校准电机
     * 
     * @param motor_id 电机ID
     * @return 成功返回true,失败返回false
     */
    bool calibrate_motor(int motor_id);
    
    /**
     * 停止电机
     * 
     * @param motor_id 电机ID
     * @param emergency 是否紧急停止
     * @return 成功返回true,失败返回false
     */
    bool stop_motor(int motor_id, bool emergency = false);
    
    /**
     * 停止所有电机
     * 
     * @param emergency 是否紧急停止
     * @return 成功返回true,失败返回false
     */
    bool stop_all_motors(bool emergency = false);
    
    /**
     * 获取最后的错误消息
     * 
     * @return 错误消息
     */
    std::string get_last_error() const;
    
    /**
     * 获取电机数量
     * 
     * @return 电机数量
     */
    int get_motor_count() const;
    
private:
    // 私有实现 (PIMPL模式)
    std::unique_ptr<MotorControllerImpl> impl_;
    
    // 禁止拷贝和赋值
    MotorController(const MotorController&) = delete;
    MotorController& operator=(const MotorController&) = delete;
};

} // namespace motor_control

#endif /* MOTOR_CONTROL_H */

cpp

/**
 * motor_control.cpp - 电机控制系统实现
 *
 * 硬件协同设计示例:软件与电机驱动硬件的协同设计
 */

#include "motor_control.h"
#include <cstring>
#include <thread>
#include <chrono>
#include <mutex>
#include <algorithm>
#include <cmath>
#include <fstream>
#include <sstream>
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <net/if.h>
#include <sys/socket.h>
#include <sys/types.h>

namespace motor_control {

// 最大电机数量
constexpr int MAX_MOTORS = 16;

// 电机结构体
struct Motor {
    MotorConfig config;           // 电机配置
    MotorStatus status;           // 电机状态
    PIDParams pid_position;       // 位置PID参数
    PIDParams pid_velocity;       // 速度PID参数
    PIDParams pid_torque;         // 力矩PID参数
    
    // 目标值
    double target_position;       // 目标位置
    double target_velocity;       // 目标速度
    double target_torque;         // 目标力矩
    double target_duty_cycle;     // 目标占空比
    
    // 限制
    double velocity_limit;        // 速度限制
    double acceleration_limit;    // 加速度限制
    
    // 状态
    bool is_enabled;              // 是否使能
    bool is_configured;           // 是否已配置
};

// PID控制器结构体
class PIDController {
public:
    PIDController() {
        reset();
    }
    
    void configure(const PIDParams& params) {
        kp = params.kp;
        ki = params.ki;
        kd = params.kd;
        ff = params.ff;
        imax = params.imax;
        reset();
    }
    
    void reset() {
        previous_error = 0.0;
        integral = 0.0;
        last_time = std::chrono::steady_clock::now();
    }
    
    double update(double setpoint, double process_variable) {
        auto now = std::chrono::steady_clock::now();
        std::chrono::duration<double> time_diff = now - last_time;
        double dt = time_diff.count();
        
        // 防止dt过小导致不稳定
        if (dt < 0.001) {
            dt = 0.001;
        }
        
        // 计算误差
        double error = setpoint - process_variable;
        
        // 微分项 (使用误差变化率)
        double derivative = 0.0;
        if (dt > 0) {
            derivative = (error - previous_error) / dt;
        }
        
        // 积分项 (使用误差累积)
        integral += error * dt;
        
        // 积分限幅
        if (imax > 0) {
            integral = std::min(std::max(integral, -imax), imax);
        }
        
        // PID输出
        double output = kp * error + ki * integral + kd * derivative + ff * setpoint;
        
        // 更新状态
        previous_error = error;
        last_time = now;
        
        return output;
    }
    
private:
    double kp = 0.0;
    double ki = 0.0;
    double kd = 0.0;
    double ff = 0.0;
    double imax = 0.0;
    double previous_error = 0.0;
    double integral = 0.0;
    std::chrono::steady_clock::time_point last_time;
};

// 电机控制器实现类
class MotorControllerImpl {
public:
    MotorControllerImpl(const std::string& interface_name, 
                       const std::string& interface_type) 
        : interface_name_(interface_name),
          interface_type_(interface_type),
          initialized_(false),
          running_(false),
          motor_count_(0),
          fd_(-1)
    {
        // 初始化电机数组
        for (int i = 0; i < MAX_MOTORS; i++) {
            motors_[i] = {};
            motors_[i].is_configured = false;
            motors_[i].is_enabled = false;
            
            // 设置默认PID参数
            motors_[i].pid_position = {0.1, 0.01, 0.001, 0.0, 10.0};
            motors_[i].pid_velocity = {0.01, 0.001, 0.0, 0.0, 10.0};
            motors_[i].pid_torque = {0.5, 0.05, 0.0, 0.0, 10.0};
            
            // 创建PID控制器
            position_controllers_[i].configure(motors_[i].pid_position);
            velocity_controllers_[i].configure(motors_[i].pid_velocity);
            torque_controllers_[i].configure(motors_[i].pid_torque);
        }
    }
    
    ~MotorControllerImpl() {
        // 停止控制线程
        if (running_) {
            running_ = false;
            if (control_thread_.joinable()) {
                control_thread_.join();
            }
        }
        
        // 关闭接口
        if (fd_ >= 0) {
            close(fd_);
            fd_ = -1;
        }
    }
    
    bool initialize() {
        // 检查是否已初始化
        if (initialized_) {
            last_error_ = "已经初始化";
            return false;
        }
        
        // 根据接口类型打开相应设备
        if (interface_type_ == "uart" || interface_type_ == "serial") {
            if (!open_uart_interface()) {
                return false;
            }
        } else if (interface_type_ == "can") {
            if (!open_can_interface()) {
                return false;
            }
        } else if (interface_type_ == "spi") {
            if (!open_spi_interface()) {
                return false;
            }
        } else {
            last_error_ = "不支持的接口类型: " + interface_type_;
            return false;
        }
        
        // 启动控制线程
        running_ = true;
        control_thread_ = std::thread(&MotorControllerImpl::control_loop, this);
        
        initialized_ = true;
        return true;
    }
    
    int add_motor(const MotorConfig& config) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 检查是否已初始化
        if (!initialized_) {
            last_error_ = "控制器未初始化";
            return -1;
        }
        
        // 检查是否已达到最大电机数量
        if (motor_count_ >= MAX_MOTORS) {
            last_error_ = "已达到最大电机数量";
            return -1;
        }
        
        // 查找是否已存在同名电机
        for (int i = 0; i < motor_count_; i++) {
            if (motors_[i].config.name == config.name) {
                last_error_ = "电机名称已存在: " + config.name;
                return -1;
            }
        }
        
        // 添加新电机
        int motor_id = motor_count_;
        motors_[motor_id].config = config;
        motors_[motor_id].is_configured = true;
        
        // 初始化状态
        motors_[motor_id].status.position = 0.0;
        motors_[motor_id].status.velocity = 0.0;
        motors_[motor_id].status.current = 0.0;
        motors_[motor_id].status.voltage = 0.0;
        motors_[motor_id].status.temperature = 0.0;
        motors_[motor_id].status.is_moving = false;
        motors_[motor_id].status.is_calibrated = false;
        motors_[motor_id].status.error_state = false;
        motors_[motor_id].status.error_code = 0;
        motors_[motor_id].status.mode = ControlMode::POSITION;
        
        // 初始化目标值
        motors_[motor_id].target_position = 0.0;
        motors_[motor_id].target_velocity = 0.0;
        motors_[motor_id].target_torque = 0.0;
        motors_[motor_id].target_duty_cycle = 0.0;
        
        // 初始化限制
        motors_[motor_id].velocity_limit = config.max_velocity;
        motors_[motor_id].acceleration_limit = config.max_acceleration;
        
        // 增加电机计数
        motor_count_++;
        
        return motor_id;
    }
    
    bool configure_motor(int motor_id, const MotorConfig& config) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 检查电机ID是否有效
        if (motor_id < 0 || motor_id >= motor_count_ || !motors_[motor_id].is_configured) {
            last_error_ = "无效的电机ID: " + std::to_string(motor_id);
            return false;
        }
        
        // 保存旧配置的一些值
        bool was_enabled = motors_[motor_id].is_enabled;
        ControlMode old_mode = motors_[motor_id].status.mode;
        
        // 更新配置
        motors_[motor_id].config = config;
        
        // 恢复状态
        motors_[motor_id].is_enabled = was_enabled;
        motors_[motor_id].status.mode = old_mode;
        
        // 设置限制
        motors_[motor_id].velocity_limit = config.max_velocity;
        motors_[motor_id].acceleration_limit = config.max_acceleration;
        
        return true;
    }
    
    bool set_pid_params(int motor_id, ControlMode mode, const PIDParams& params) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 检查电机ID是否有效
        if (motor_id < 0 || motor_id >= motor_count_ || !motors_[motor_id].is_configured) {
            last_error_ = "无效的电机ID: " + std::to_string(motor_id);
            return false;
        }
        
        // 根据模式更新PID参数
        switch (mode) {
            case ControlMode::POSITION:
                motors_[motor_id].pid_position = params;
                position_controllers_[motor_id].configure(params);
                break;
                
            case ControlMode::VELOCITY:
                motors_[motor_id].pid_velocity = params;
                velocity_controllers_[motor_id].configure(params);
                break;
                
            case ControlMode::TORQUE:
                motors_[motor_id].pid_torque = params;
                torque_controllers_[motor_id].configure(params);
                break;
                
            default:
                last_error_ = "不支持开环模式的PID参数";
                return false;
        }
        
        return true;
    }
    
    bool set_motor_mode(int motor_id, ControlMode mode) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 检查电机ID是否有效
        if (motor_id < 0 || motor_id >= motor_count_ || !motors_[motor_id].is_configured) {
            last_error_ = "无效的电机ID: " + std::to_string(motor_id);
            return false;
        }
        
        // 检查模式是否支持
        if (mode == ControlMode::POSITION && motors_[motor_id].config.type == MotorType::DC) {
            last_error_ = "直流电机不支持位置控制模式";
            return false;
        }
        
        // 更新模式
        motors_[motor_id].status.mode = mode;
        
        // 根据电机类型进行特定处理
        switch (motors_[motor_id].config.type) {
            case MotorType::DC:
                // 重置PID控制器
                if (mode == ControlMode::VELOCITY) {
                    velocity_controllers_[motor_id].reset();
                } else if (mode == ControlMode::TORQUE) {
                    torque_controllers_[motor_id].reset();
                }
                break;
                
            case MotorType::BLDC:
                // 重置所有PID控制器
                position_controllers_[motor_id].reset();
                velocity_controllers_[motor_id].reset();
                torque_controllers_[motor_id].reset();
                break;
                
            case MotorType::STEPPER:
                // 步进电机特殊处理
                if (mode == ControlMode::TORQUE) {
                    last_error_ = "步进电机不支持力矩控制模式";
                    return false;
                }
                break;
                
            case MotorType::SERVO:
                // 伺服电机仅支持位置控制
                if (mode != ControlMode::POSITION) {
                    last_error_ = "伺服电机仅支持位置控制模式";
                    return false;
                }
                break;
        }
        
        return true;
    }
    
    bool enable_motor(int motor_id, bool enable) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 检查电机ID是否有效
        if (motor_id < 0 || motor_id >= motor_count_ || !motors_[motor_id].is_configured) {
            last_error_ = "无效的电机ID: " + std::to_string(motor_id);
            return false;
        }
        
        // 更新使能状态
        motors_[motor_id].is_enabled = enable;
        
        // 如果禁用,重置控制器和目标值
        if (!enable) {
            position_controllers_[motor_id].reset();
            velocity_controllers_[motor_id].reset();
            torque_controllers_[motor_id].reset();
            
            motors_[motor_id].target_duty_cycle = 0.0;
        }
        
        // 发送使能命令到硬件
        uint8_t command_buffer[8] = {0};
        command_buffer[0] = enable ? 0x01 : 0x00;  // 使能命令
        command_buffer[1] = (uint8_t)motor_id;     // 电机ID
        
        bool result = send_command(command_buffer, sizeof(command_buffer));
        if (!result) {
            last_error_ = "发送使能命令失败";
            return false;
        }
        
        return true;
    }
    
    bool set_position(int motor_id, double position, 
                    double velocity_limit, double acceleration_limit) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 检查电机ID是否有效
        if (motor_id < 0 || motor_id >= motor_count_ || !motors_[motor_id].is_configured) {
            last_error_ = "无效的电机ID: " + std::to_string(motor_id);
            return false;
        }
        
        // 检查电机是否使能
        if (!motors_[motor_id].is_enabled) {
            last_error_ = "电机未使能: " + std::to_string(motor_id);
            return false;
        }
        
        // 检查电机是否支持位置控制
        if (motors_[motor_id].config.type == MotorType::DC) {
            last_error_ = "直流电机不支持位置控制";
            return false;
        }
        
        // 对于伺服电机,检查位置是否在限制范围内
        if (motors_[motor_id].config.type == MotorType::SERVO) {
            double min_angle = motors_[motor_id].config.servo.min_angle;
            double max_angle = motors_[motor_id].config.servo.max_angle;
            
            if (position < min_angle || position > max_angle) {
                last_error_ = "位置超出伺服电机范围: " + 
                             std::to_string(position) + " [" + 
                             std::to_string(min_angle) + ", " + 
                             std::to_string(max_angle) + "]";
                return false;
            }
        }
        
        // 设置目标位置
        motors_[motor_id].target_position = position;
        
        // 设置速度和加速度限制(如果提供)
        if (velocity_limit > 0) {
            motors_[motor_id].velocity_limit = std::min(velocity_limit, 
                                                     motors_[motor_id].config.max_velocity);
        }
        
        if (acceleration_limit > 0) {
            motors_[motor_id].acceleration_limit = std::min(acceleration_limit, 
                                                         motors_[motor_id].config.max_acceleration);
        }
        
        // 设置控制模式为位置模式
        motors_[motor_id].status.mode = ControlMode::POSITION;
        
        // 发送位置命令到硬件
        uint8_t command_buffer[16] = {0};
        command_buffer[0] = 0x10;  // 位置控制命令
        command_buffer[1] = (uint8_t)motor_id;  // 电机ID
        
        // 编码位置值(4字节浮点数)
        float pos_float = static_cast<float>(position);
        std::memcpy(&command_buffer[2], &pos_float, sizeof(float));
        
        // 编码速度限制(4字节浮点数)
        float vel_float = static_cast<float>(motors_[motor_id].velocity_limit);
        std::memcpy(&command_buffer[6], &vel_float, sizeof(float));
        
        // 编码加速度限制(4字节浮点数)
        float acc_float = static_cast<float>(motors_[motor_id].acceleration_limit);
        std::memcpy(&command_buffer[10], &acc_float, sizeof(float));
        
        bool result = send_command(command_buffer, sizeof(command_buffer));
        if (!result) {
            last_error_ = "发送位置命令失败";
            return false;
        }
        
        return true;
    }
    
    bool set_velocity(int motor_id, double velocity, double acceleration_limit) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 检查电机ID是否有效
        if (motor_id < 0 || motor_id >= motor_count_ || !motors_[motor_id].is_configured) {
            last_error_ = "无效的电机ID: " + std::to_string(motor_id);
            return false;
        }
        
        // 检查电机是否使能
        if (!motors_[motor_id].is_enabled) {
            last_error_ = "电机未使能: " + std::to_string(motor_id);
            return false;
        }
        
        // 检查电机是否为伺服电机(不支持速度控制)
        if (motors_[motor_id].config.type == MotorType::SERVO) {
            last_error_ = "伺服电机不支持速度控制";
            return false;
        }
        
        // 限制速度
        velocity = std::min(std::max(velocity, -motors_[motor_id].config.max_velocity), 
                           motors_[motor_id].config.max_velocity);
        
        // 方向反转处理
        if (motors_[motor_id].config.reverse_direction) {
            velocity = -velocity;
        }
        
        // 设置目标速度
        motors_[motor_id].target_velocity = velocity;
        
        // 设置加速度限制(如果提供)
        if (acceleration_limit > 0) {
            motors_[motor_id].acceleration_limit = std::min(acceleration_limit, 
                                                         motors_[motor_id].config.max_acceleration);
        }
        
        // 设置控制模式为速度模式
        motors_[motor_id].status.mode = ControlMode::VELOCITY;
        
        // 发送速度命令到硬件
        uint8_t command_buffer[12] = {0};
        command_buffer[0] = 0x20;  // 速度控制命令
        command_buffer[1] = (uint8_t)motor_id;  // 电机ID
        
        // 编码速度值(4字节浮点数)
        float vel_float = static_cast<float>(velocity);
        std::memcpy(&command_buffer[2], &vel_float, sizeof(float));
        
        // 编码加速度限制(4字节浮点数)
        float acc_float = static_cast<float>(motors_[motor_id].acceleration_limit);
        std::memcpy(&command_buffer[6], &acc_float, sizeof(float));
        
        bool result = send_command(command_buffer, sizeof(command_buffer));
        if (!result) {
            last_error_ = "发送速度命令失败";
            return false;
        }
        
        return true;
    }
    
    bool set_torque(int motor_id, double torque) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 检查电机ID是否有效
        if (motor_id < 0 || motor_id >= motor_count_ || !motors_[motor_id].is_configured) {
            last_error_ = "无效的电机ID: " + std::to_string(motor_id);
            return false;
        }
        
        // 检查电机是否使能
        if (!motors_[motor_id].is_enabled) {
            last_error_ = "电机未使能: " + std::to_string(motor_id);
            return false;
        }
        
        // 检查电机类型是否支持力矩控制
        if (motors_[motor_id].config.type == MotorType::STEPPER ||
            motors_[motor_id].config.type == MotorType::SERVO) {
            last_error_ = "电机类型不支持力矩控制";
            return false;
        }
        
        // 限制力矩
        torque = std::min(std::max(torque, -motors_[motor_id].config.max_torque), 
                          motors_[motor_id].config.max_torque);
        
        // 方向反转处理
        if (motors_[motor_id].config.reverse_direction) {
            torque = -torque;
        }
        
        // 设置目标力矩
        motors_[motor_id].target_torque = torque;
        
        // 设置控制模式为力矩模式
        motors_[motor_id].status.mode = ControlMode::TORQUE;
        
        // 发送力矩命令到硬件
        uint8_t command_buffer[8] = {0};
        command_buffer[0] = 0x30;  // 力矩控制命令
        command_buffer[1] = (uint8_t)motor_id;  // 电机ID
        
        // 编码力矩值(4字节浮点数)
        float torque_float = static_cast<float>(torque);
        std::memcpy(&command_buffer[2], &torque_float, sizeof(float));
        
        bool result = send_command(command_buffer, sizeof(command_buffer));
        if (!result) {
            last_error_ = "发送力矩命令失败";
            return false;
        }
        
        return true;
    }
    
    bool set_duty_cycle(int motor_id, double duty_cycle) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 检查电机ID是否有效
        if (motor_id < 0 || motor_id >= motor_count_ || !motors_[motor_id].is_configured) {
            last_error_ = "无效的电机ID: " + std::to_string(motor_id);
            return false;
        }
        
        // 检查电机是否使能
        if (!motors_[motor_id].is_enabled) {
            last_error_ = "电机未使能: " + std::to_string(motor_id);
            return false;
        }
        
        // 限制占空比
        duty_cycle = std::min(std::max(duty_cycle, -1.0), 1.0);
        
        // 方向反转处理
        if (motors_[motor_id].config.reverse_direction) {
            duty_cycle = -duty_cycle;
        }
        
        // 设置目标占空比
        motors_[motor_id].target_duty_cycle = duty_cycle;
        
        // 设置控制模式为开环模式
        motors_[motor_id].status.mode = ControlMode::OPEN_LOOP;
        
        // 发送占空比命令到硬件
        uint8_t command_buffer[8] = {0};
        command_buffer[0] = 0x40;  // 开环控制命令
        command_buffer[1] = (uint8_t)motor_id;  // 电机ID
        
        // 编码占空比值(4字节浮点数)
        float duty_float = static_cast<float>(duty_cycle);
        std::memcpy(&command_buffer[2], &duty_float, sizeof(float));
        
        bool result = send_command(command_buffer, sizeof(command_buffer));
        if (!result) {
            last_error_ = "发送占空比命令失败";
            return false;
        }
        
        return true;
    }
    
    MotorStatus get_motor_status(int motor_id) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 检查电机ID是否有效
        if (motor_id < 0 || motor_id >= motor_count_ || !motors_[motor_id].is_configured) {
            last_error_ = "无效的电机ID: " + std::to_string(motor_id);
            MotorStatus empty_status = {};
            empty_status.error_state = true;
            empty_status.error_code = 0xFFFF;
            return empty_status;
        }
        
        // 返回状态副本
        return motors_[motor_id].status;
    }
    
    bool calibrate_motor(int motor_id) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 检查电机ID是否有效
        if (motor_id < 0 || motor_id >= motor_count_ || !motors_[motor_id].is_configured) {
            last_error_ = "无效的电机ID: " + std::to_string(motor_id);
            return false;
        }
        
        // 发送校准命令到硬件
        uint8_t command_buffer[8] = {0};
        command_buffer[0] = 0xA0;  // 校准命令
        command_buffer[1] = (uint8_t)motor_id;  // 电机ID
        
        bool result = send_command(command_buffer, sizeof(command_buffer));
        if (!result) {
            last_error_ = "发送校准命令失败";
            return false;
        }
        
        // 更新校准状态
        motors_[motor_id].status.is_calibrated = true;
        
        return true;
    }
    
    bool stop_motor(int motor_id, bool emergency) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 检查电机ID是否有效
        if (motor_id < 0 || motor_id >= motor_count_ || !motors_[motor_id].is_configured) {
            last_error_ = "无效的电机ID: " + std::to_string(motor_id);
            return false;
        }
        
        // 发送停止命令到硬件
        uint8_t command_buffer[8] = {0};
        command_buffer[0] = emergency ? 0xF0 : 0xF1;  // 紧急停止或正常停止
        command_buffer[1] = (uint8_t)motor_id;  // 电机ID
        
        bool result = send_command(command_buffer, sizeof(command_buffer));
        if (!result) {
            last_error_ = "发送停止命令失败";
            return false;
        }
        
        // 更新电机状态
        motors_[motor_id].target_velocity = 0.0;
        motors_[motor_id].target_torque = 0.0;
        motors_[motor_id].target_duty_cycle = 0.0;
        motors_[motor_id].status.is_moving = false;
        
        // 如果是紧急停止,则禁用电机
        if (emergency) {
            motors_[motor_id].is_enabled = false;
        }
        
        return true;
    }
    
    bool stop_all_motors(bool emergency) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 发送停止所有电机命令到硬件
        uint8_t command_buffer[8] = {0};
        command_buffer[0] = emergency ? 0xFC : 0xFD;  // 紧急停止所有或正常停止所有
        
        bool result = send_command(command_buffer, sizeof(command_buffer));
        if (!result) {
            last_error_ = "发送停止所有电机命令失败";
            return false;
        }
        
        // 更新所有电机状态
        for (int i = 0; i < motor_count_; i++) {
            if (motors_[i].is_configured) {
                motors_[i].target_velocity = 0.0;
                motors_[i].target_torque = 0.0;
                motors_[i].target_duty_cycle = 0.0;
                motors_[i].status.is_moving = false;
                
                // 如果是紧急停止,则禁用电机
                if (emergency) {
                    motors_[i].is_enabled = false;
                }
            }
        }
        
        return true;
    }
    
    std::string get_last_error() const {
        return last_error_;
    }
    
    int get_motor_count() const {
        return motor_count_;
    }
    
private:
    // 控制循环线程函数
    void control_loop() {
        while (running_) {
            // 更新电机状态
            update_motor_status();
            
            // 执行控制逻辑
            for (int i = 0; i < motor_count_; i++) {
                if (motors_[i].is_configured && motors_[i].is_enabled) {
                    update_motor_control(i);
                }
            }
            
            // 控制周期 (1000 Hz)
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
        }
    }
    
    // 更新电机状态
    void update_motor_status() {
        std::lock_guard<std::mutex> lock(mutex_);
        
        // 接收状态数据
        uint8_t buffer[64] = {0};
        int bytes_read = receive_data(buffer, sizeof(buffer));
        
        if (bytes_read > 0) {
            // 解析状态数据
            parse_status_data(buffer, bytes_read);
        }
    }
    
    // 解析状态数据
    void parse_status_data(const uint8_t* data, int size) {
        // 检查数据有效性
        if (size < 2) {
            return;
        }
        
        // 根据命令类型解析数据
        uint8_t cmd_type = data[0];
        
        if (cmd_type == 0x80) {  // 电机状态数据
            // 检查数据大小
            if (size < 18) {
                return;
            }
            
            // 获取电机ID
            uint8_t motor_id = data[1];
            
            // 检查ID是否有效
            if (motor_id >= motor_count_ || !motors_[motor_id].is_configured) {
                return;
            }
            
            // 解析状态数据
            float position, velocity, current, voltage, temperature;
            
            // 位置 (字节2-5)
            std::memcpy(&position, &data[2], sizeof(float));
            
            // 速度 (字节6-9)
            std::memcpy(&velocity, &data[6], sizeof(float));
            
            // 电流 (字节10-13)
            std::memcpy(&current, &data[10], sizeof(float));
            
            // 电压 (字节14-17)
            std::memcpy(&voltage, &data[14], sizeof(float));
            
            // 温度 (字节18-21)
            if (size >= 22) {
                std::memcpy(&temperature, &data[18], sizeof(float));
            } else {
                temperature = 0.0f;
            }
            
            // 其他状态标志 (字节22)
            uint8_t flags = 0;
            if (size >= 23) {
                flags = data[22];
            }
            
            // 更新电机状态
            motors_[motor_id].status.position = position;
            motors_[motor_id].status.velocity = velocity;
            motors_[motor_id].status.current = current;
            motors_[motor_id].status.voltage = voltage;
            motors_[motor_id].status.temperature = temperature;
            
            // 解析状态标志
            motors_[motor_id].status.is_moving = (flags & 0x01) != 0;
            motors_[motor_id].status.is_calibrated = (flags & 0x02) != 0;
            motors_[motor_id].status.error_state = (flags & 0x04) != 0;
            
            // 错误代码 (字节23-24)
            if (size >= 25 && motors_[motor_id].status.error_state) {
                motors_[motor_id].status.error_code = (data[23] << 8) | data[24];
            } else {
                motors_[motor_id].status.error_code = 0;
            }
        }
    }
    
    // 更新电机控制
    void update_motor_control(int motor_id) {
        // 根据控制模式执行控制逻辑
        switch (motors_[motor_id].status.mode) {
            case ControlMode::POSITION:
                update_position_control(motor_id);
                break;
                
            case ControlMode::VELOCITY:
                update_velocity_control(motor_id);
                break;
                
            case ControlMode::TORQUE:
                update_torque_control(motor_id);
                break;
                
            case ControlMode::OPEN_LOOP:
                // 开环控制由set_duty_cycle直接处理
                break;
        }
    }
    
    // 位置控制逻辑
    void update_position_control(int motor_id) {
        // 获取当前位置和目标位置
        double current_position = motors_[motor_id].status.position;
        double target_position = motors_[motor_id].target_position;
        
        // 计算位置误差
        double position_error = target_position - current_position;
        
        // 检查是否在位置容差范围内
        const double position_tolerance = 0.01;  // 位置容差
        if (std::abs(position_error) < position_tolerance) {
            // 已到达目标位置
            motors_[motor_id].status.is_moving = false;
            return;
        }
        
        // 计算位置控制器输出(目标速度)
        double target_velocity = position_controllers_[motor_id].update(
            target_position, current_position);
        
        // 限制速度
        target_velocity = std::min(std::max(target_velocity, -motors_[motor_id].velocity_limit), 
                                 motors_[motor_id].velocity_limit);
        
        // 更新目标速度
        motors_[motor_id].target_velocity = target_velocity;
        
        // 继续执行速度控制
        update_velocity_control(motor_id);
    }
    
    // 速度控制逻辑
    void update_velocity_control(int motor_id) {
        // 获取当前速度和目标速度
        double current_velocity = motors_[motor_id].status.velocity;
        double target_velocity = motors_[motor_id].target_velocity;
        
        // 计算速度误差
        double velocity_error = target_velocity - current_velocity;
        
        // 检查是否在速度容差范围内
        const double velocity_tolerance = 0.1;  // 速度容差
        if (std::abs(velocity_error) < velocity_tolerance && 
            motors_[motor_id].status.mode == ControlMode::VELOCITY) {
            // 已达到目标速度
            motors_[motor_id].status.is_moving = (std::abs(target_velocity) > velocity_tolerance);
        } else {
            // 未达到目标速度
            motors_[motor_id].status.is_moving = true;
        }
        
        // 计算速度控制器输出(目标力矩)
        double target_torque = velocity_controllers_[motor_id].update(
            target_velocity, current_velocity);
        
        // 限制力矩
        target_torque = std::min(std::max(target_torque, -motors_[motor_id].config.max_torque), 
                               motors_[motor_id].config.max_torque);
        
        // 更新目标力矩
        motors_[motor_id].target_torque = target_torque;
        
        // 继续执行力矩控制
        update_torque_control(motor_id);
    }
    
    // 力矩控制逻辑
    void update_torque_control(int motor_id) {
        // 获取当前力矩和目标力矩
        double current_torque = motors_[motor_id].status.current * 0.1;  // 假设电流与力矩成正比
        double target_torque = motors_[motor_id].target_torque;
        
        // 计算力矩控制器输出(目标占空比)
        double target_duty_cycle = torque_controllers_[motor_id].update(
            target_torque, current_torque);
        
        // 限制占空比
        target_duty_cycle = std::min(std::max(target_duty_cycle, -1.0), 1.0);
        
        // 更新目标占空比
        motors_[motor_id].target_duty_cycle = target_duty_cycle;
        
        // 发送占空比命令到硬件
        uint8_t command_buffer[8] = {0};
        command_buffer[0] = 0x40;  // 开环控制命令
        command_buffer[1] = (uint8_t)motor_id;  // 电机ID
        
        // 编码占空比值(4字节浮点数)
        float duty_float = static_cast<float>(target_duty_cycle);
        std::memcpy(&command_buffer[2], &duty_float, sizeof(float));
        
        send_command(command_buffer, sizeof(command_buffer));
    }
    
    // 打开UART接口
    bool open_uart_interface() {
        // 打开串口设备
        fd_ = open(interface_name_.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
        if (fd_ < 0) {
            last_error_ = "无法打开串口设备: " + interface_name_ + " - " + strerror(errno);
            return false;
        }
        
        // 配置串口参数
        struct termios tty;
        memset(&tty, 0, sizeof(tty));
        
        // 获取当前配置
        if (tcgetattr(fd_, &tty) != 0) {
            last_error_ = "获取串口参数失败: " + std::string(strerror(errno));
            close(fd_);
            fd_ = -1;
            return false;
        }
        
        // 设置波特率
        cfsetospeed(&tty, B115200);
        cfsetispeed(&tty, B115200);
        
        // 设置控制模式
        tty.c_cflag |= (CLOCAL | CREAD);    // 忽略调制解调器控制线
        tty.c_cflag &= ~CSIZE;              // 清除位大小标志
        tty.c_cflag |= CS8;                 // 8位数据位
        tty.c_cflag &= ~PARENB;             // 无奇偶校验
        tty.c_cflag &= ~CSTOPB;             // 1个停止位
        tty.c_cflag &= ~CRTSCTS;            // 禁用硬件流控制
        
        // 设置输入模式
        tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
        
        // 设置输出模式
        tty.c_oflag &= ~OPOST;
        
        // 设置本地模式
        tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
        
        // 设置超时
        tty.c_cc[VMIN] = 0;    // 非阻塞读
        tty.c_cc[VTIME] = 1;   // 100ms超时
        
        // 应用设置
        if (tcsetattr(fd_, TCSANOW, &tty) != 0) {
            last_error_ = "设置串口参数失败: " + std::string(strerror(errno));
            close(fd_);
            fd_ = -1;
            return false;
        }
        
        // 清空缓冲区
        tcflush(fd_, TCIOFLUSH);
        
        return true;
    }
    
    // 打开CAN接口
    bool open_can_interface() {
        // 创建套接字
        fd_ = socket(PF_CAN, SOCK_RAW, CAN_RAW);
        if (fd_ < 0) {
            last_error_ = "无法创建CAN套接字: " + std::string(strerror(errno));
            return false;
        }
        
        // 指定CAN接口
        struct ifreq ifr;
        strcpy(ifr.ifr_name, interface_name_.c_str());
        if (ioctl(fd_, SIOCGIFINDEX, &ifr) < 0) {
            last_error_ = "无法获取CAN接口索引: " + std::string(strerror(errno));
            close(fd_);
            fd_ = -1;
            return false;
        }
        
        // 绑定套接字
        struct sockaddr_can addr;
        addr.can_family = AF_CAN;
        addr.can_ifindex = ifr.ifr_ifindex;
        
        if (bind(fd_, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
            last_error_ = "无法绑定CAN套接字: " + std::string(strerror(errno));
            close(fd_);
            fd_ = -1;
            return false;
        }
        
        // 设置非阻塞模式
        int flags = fcntl(fd_, F_GETFL, 0);
        if (flags < 0) {
            last_error_ = "无法获取套接字标志: " + std::string(strerror(errno));
            close(fd_);
            fd_ = -1;
            return false;
        }
        
        if (fcntl(fd_, F_SETFL, flags | O_NONBLOCK) < 0) {
            last_error_ = "无法设置非阻塞模式: " + std::string(strerror(errno));
            close(fd_);
            fd_ = -1;
            return false;
        }
        
        return true;
    }
    
    // 打开SPI接口
    bool open_spi_interface() {
        // SPI接口需要用户自行实现,这里仅占位
        last_error_ = "SPI接口尚未实现";
        return false;
    }
    
    // 发送命令
    bool send_command(const uint8_t* data, size_t size) {
        if (fd_ < 0) {
            last_error_ = "设备未打开";
            return false;
        }
        
        if (interface_type_ == "uart" || interface_type_ == "serial") {
            // 发送UART数据
            ssize_t bytes_written = write(fd_, data, size);
            if (bytes_written < static_cast<ssize_t>(size)) {
                last_error_ = "UART发送失败: " + std::string(strerror(errno));
                return false;
            }
            
            // 刷新输出缓冲区
            tcdrain(fd_);
            
        } else if (interface_type_ == "can") {
            // 检查数据大小(CAN帧有限制)
            if (size > 8) {
                last_error_ = "CAN数据过大";
                return false;
            }
            
            // 准备CAN帧
            struct can_frame frame;
            memset(&frame, 0, sizeof(frame));
            
            // 设置ID(假设使用标准ID)
            frame.can_id = 0x100;  // 基本ID
            
            // 设置数据长度
            frame.can_dlc = size;
            
            // 复制数据
            memcpy(frame.data, data, size);
            
            // 发送CAN帧
            ssize_t bytes_written = write(fd_, &frame, sizeof(frame));
            if (bytes_written < static_cast<ssize_t>(sizeof(frame))) {
                last_error_ = "CAN发送失败: " + std::string(strerror(errno));
                return false;
            }
            
        } else if (interface_type_ == "spi") {
            // SPI发送需要用户自行实现
            last_error_ = "SPI接口尚未实现";
            return false;
        }
        
        return true;
    }
    
    // 接收数据
    int receive_data(uint8_t* buffer, size_t max_size) {
        if (fd_ < 0) {
            last_error_ = "设备未打开";
            return -1;
        }
        
        if (interface_type_ == "uart" || interface_type_ == "serial") {
            // 从UART接收数据
            ssize_t bytes_read = read(fd_, buffer, max_size);
            if (bytes_read < 0) {
                if (errno == EAGAIN || errno == EWOULDBLOCK) {
                    // 无数据可读
                    return 0;
                }
                
                last_error_ = "UART接收失败: " + std::string(strerror(errno));
                return -1;
            }
            
            return bytes_read;
            
        } else if (interface_type_ == "can") {
            // 接收CAN帧
            struct can_frame frame;
            memset(&frame, 0, sizeof(frame));
            
            ssize_t bytes_read = read(fd_, &frame, sizeof(frame));
            if (bytes_read < 0) {
                if (errno == EAGAIN || errno == EWOULDBLOCK) {
                    // 无数据可读
                    return 0;
                }
                
                last_error_ = "CAN接收失败: " + std::string(strerror(errno));
                return -1;
            }
            
            if (bytes_read != sizeof(frame)) {
                last_error_ = "接收到不完整的CAN帧";
                return -1;
            }
            
            // 检查数据大小
            if (frame.can_dlc > max_size) {
                last_error_ = "接收缓冲区太小";
                return -1;
            }
            
            // 复制数据
            memcpy(buffer, frame.data, frame.can_dlc);
            
            return frame.can_dlc;
            
        } else if (interface_type_ == "spi") {
            // SPI接收需要用户自行实现
            last_error_ = "SPI接口尚未实现";
            return -1;
        }
        
        return 0;
    }
    
private:
    std::string interface_name_;          // 接口名称
    std::string interface_type_;          // 接口类型
    bool initialized_;                    // 初始化标志
    bool running_;                        // 运行标志
    int motor_count_;                     // 电机数量
    int fd_;                              // 文件描述符
    std::string last_error_;              // 最后一个错误消息
    
    Motor motors_[MAX_MOTORS];            // 电机数组
    PIDController position_controllers_[MAX_MOTORS];  // 位置PID控制器
    PIDController velocity_controllers_[MAX_MOTORS];  // 速度PID控制器
    PIDController torque_controllers_[MAX_MOTORS];    // 力矩PID控制器
    
    std::thread control_thread_;          // 控制线程
    std::mutex mutex_;                    // 互斥锁
};

// MotorController 类方法的实现,委托给 MotorControllerImpl

MotorController::MotorController(const std::string& interface_name, 
                               const std::string& interface_type)
    : impl_(new MotorControllerImpl(interface_name, interface_type)) {
}

MotorController::~MotorController() = default;

bool MotorController::initialize() {
    return impl_->initialize();
}

int MotorController::add_motor(const MotorConfig& config) {
    return impl_->add_motor(config);
}

bool MotorController::configure_motor(int motor_id, const MotorConfig& config) {
    return impl_->configure_motor(motor_id, config);
}

bool MotorController::set_pid_params(int motor_id, ControlMode mode, const PIDParams& params) {
    return impl_->set_pid_params(motor_id, mode, params);
}

bool MotorController::set_motor_mode(int motor_id, ControlMode mode) {
    return impl_->set_motor_mode(motor_id, mode);
}

bool MotorController::enable_motor(int motor_id, bool enable) {
    return impl_->enable_motor(motor_id, enable);
}

bool MotorController::set_position(int motor_id, double position, 
                                double velocity_limit, 
                                double acceleration_limit) {
    return impl_->set_position(motor_id, position, velocity_limit, acceleration_limit);
}

bool MotorController::set_velocity(int motor_id, double velocity, 
                                double acceleration_limit) {
    return impl_->set_velocity(motor_id, velocity, acceleration_limit);
}

bool MotorController::set_torque(int motor_id, double torque) {
    return impl_->set_torque(motor_id, torque);
}

bool MotorController::set_duty_cycle(int motor_id, double duty_cycle) {
    return impl_->set_duty_cycle(motor_id, duty_cycle);
}

MotorStatus MotorController::get_motor_status(int motor_id) {
    return impl_->get_motor_status(motor_id);
}

bool MotorController::calibrate_motor(int motor_id) {
    return impl_->calibrate_motor(motor_id);
}

bool MotorController::stop_motor(int motor_id, bool emergency) {
    return impl_->stop_motor(motor_id, emergency);
}

bool MotorController::stop_all_motors(bool emergency) {
    return impl_->stop_all_motors(emergency);
}

std::string MotorController::get_last_error() const {
    return impl_->get_last_error();
}

int MotorController::get_motor_count() const {
    return impl_->get_motor_count();
}

} // namespace motor_control

5. 结语

以上代码示例展示了通过 C/C++ 与硬件协同设计的多种实现方式,涵盖了从底层驱动到应用层的各个方面。这些实例可以作为硬件协同设计的参考,开发者可以根据自己的具体需求进行修改和扩展。

关键实践要点:

  1. 硬件抽象层:通过标准接口封装底层硬件,提供统一的编程模型
  2. 内存映射I/O:直接操作硬件寄存器进行高效控制
  3. 多线程处理:使用线程分离数据采集、处理和控制逻辑
  4. 错误处理:完善的错误检查和报告机制
  5. 跨平台考虑:尽可能使用标准库和跨平台API

这些示例演示了软件如何与硬件紧密协作,共同实现系统功能。实际应用中,可能需要根据具体硬件规格进行适当调整。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小宝哥Code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值