diff --git "a/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\343\200\220RSOC25\343\200\221Day14\350\257\276\347\250\213\347\254\224\350\256\260\357\274\232\345\206\257\345\256\276/dev_text.c" "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\343\200\220RSOC25\343\200\221Day14\350\257\276\347\250\213\347\254\224\350\256\260\357\274\232\345\206\257\345\256\276/dev_text.c" new file mode 100644 index 0000000000000000000000000000000000000000..59ab8a1d0041ccde1eab2f16bbafe99af5d3b9eb --- /dev/null +++ "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\343\200\220RSOC25\343\200\221Day14\350\257\276\347\250\213\347\254\224\350\256\260\357\274\232\345\206\257\345\256\276/dev_text.c" @@ -0,0 +1,19 @@ +#include +#include + +static int rt_dev_test_init(void) +{ + rt_device_t dev_test =rt_device_create(RT_Device_Class_Char,0); + + if(dev_test == RT_NULL) + { + rt_kprintf("Failed to create test device\n"); + return -RT_ERROR; + } + if(rt_device_register(dev_test,"testdeV",RT_DEVICE_FLAG_RDWR) !=RT_EOK) + { + rt_kprintf("Failed to register test device\n"); + return -RT_ERROR; + } + return RT_EOK; +} \ No newline at end of file diff --git "a/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\343\200\220RSOC25\343\200\221Day14\350\257\276\347\250\213\347\254\224\350\256\260\357\274\232\345\206\257\345\256\276/\344\273\243\347\240\201.c" "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\343\200\220RSOC25\343\200\221Day14\350\257\276\347\250\213\347\254\224\350\256\260\357\274\232\345\206\257\345\256\276/\344\273\243\347\240\201.c" new file mode 100644 index 0000000000000000000000000000000000000000..444fcb9d5d36a1cec6f52d47f8ac7ddda5e75fe6 --- /dev/null +++ "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\343\200\220RSOC25\343\200\221Day14\350\257\276\347\250\213\347\254\224\350\256\260\357\274\232\345\206\257\345\256\276/\344\273\243\347\240\201.c" @@ -0,0 +1,178 @@ +from abc import ABC, abstractmethod +from enum import Enum +from typing import Dict, List, Optional, Any + +# 设备状态枚举 +class DeviceState(Enum): + OFFLINE = 0 + READY = 1 + ERROR = 2 + +# 设备驱动基类 +class DeviceDriver(ABC): + def __init__(self, device_id: str, device_type: str): + self.device_id = device_id + self.device_type = device_type + self.state = DeviceState.OFFLINE + self.config = {} + + @abstractmethod + def open(self) -> bool: + """初始化并打开设备""" + pass + + @abstractmethod + def close(self) -> bool: + """关闭设备并释放资源""" + pass + + @abstractmethod + def read(self, command: str, **kwargs) -> Optional[Any]: + """从设备读取数据""" + pass + + @abstractmethod + def write(self, command: str, data: Any, **kwargs) -> bool: + """向设备写入数据""" + pass + + def get_state(self) -> DeviceState: + """获取设备当前状态""" + return self.state + + def configure(self, config: Dict) -> None: + """配置设备参数""" + self.config.update(config) + +# 设备驱动管理器 +class DeviceDriverManager: + def __init__(self): + self._drivers: Dict[str, DeviceDriver] = {} + + def register_driver(self, driver: DeviceDriver) -> bool: + """注册设备驱动""" + if driver.device_id in self._drivers: + return False + self._drivers[driver.device_id] = driver + return True + + def unregister_driver(self, device_id: str) -> bool: + """注销设备驱动""" + if device_id not in self._drivers: + return False + driver = self._drivers[device_id] + if driver.get_state() != DeviceState.OFFLINE: + driver.close() + del self._drivers[device_id] + return True + + def get_driver(self, device_id: str) -> Optional[DeviceDriver]: + """获取设备驱动""" + return self._drivers.get(device_id) + + def list_devices(self) -> List[str]: + """列出所有已注册的设备ID""" + return list(self._drivers.keys()) + +# 示例:LED设备驱动 +class LEDDriver(DeviceDriver): + def __init__(self, device_id: str): + super().__init__(device_id, "led") + self._is_on = False + + def open(self) -> bool: + print(f"Opening LED device: {self.device_id}") + self.state = DeviceState.READY + return True + + def close(self) -> bool: + print(f"Closing LED device: {self.device_id}") + self._is_on = False + self.state = DeviceState.OFFLINE + return True + + def read(self, command: str, **kwargs) -> Optional[Any]: + if command == "status": + return "on" if self._is_on else "off" + elif command == "brightness": + return kwargs.get("default_brightness", 100) if self._is_on else 0 + return None + + def write(self, command: str, data: Any, **kwargs) -> bool: + if command == "set_state": + if isinstance(data, bool): + self._is_on = data + print(f"LED {self.device_id} state set to: {data}") + return True + elif isinstance(data, str): + self._is_on = data.lower() == "on" + print(f"LED {self.device_id} state set to: {self._is_on}") + return True + return False + +# 示例:温度传感器驱动 +class TemperatureSensorDriver(DeviceDriver): + def __init__(self, device_id: str, min_temp: float = -40.0, max_temp: float = 85.0): + super().__init__(device_id, "temperature_sensor") + self.min_temp = min_temp + self.max_temp = max_temp + self._current_temp = 25.0 + + def open(self) -> bool: + print(f"Opening temperature sensor: {self.device_id}") + self.state = DeviceState.READY + return True + + def close(self) -> bool: + print(f"Closing temperature sensor: {self.device_id}") + self.state = DeviceState.OFFLINE + return True + + def read(self, command: str, **kwargs) -> Optional[Any]: + if command == "temperature": + # 模拟温度轻微波动 + import random + self._current_temp += random.uniform(-0.5, 0.5) + self._current_temp = max(self.min_temp, min(self.max_temp, self._current_temp)) + return round(self._current_temp, 2) + elif command == "range": + return (self.min_temp, self.max_temp) + return None + + def write(self, command: str, data: Any, **kwargs) -> bool: + if command == "calibrate": + print(f"Calibrating temperature sensor {self.device_id} with offset: {data}") + return True + return False + +# 使用示例 +if __name__ == "__main__": + # 创建驱动管理器 + manager = DeviceDriverManager() + + # 创建并注册设备驱动 + led = LEDDriver("led1") + temp_sensor = TemperatureSensorDriver("temp1") + + manager.register_driver(led) + manager.register_driver(temp_sensor) + + # 打开设备 + led.open() + temp_sensor.open() + + # 操作设备 + led.write("set_state", True) + print(f"LED status: {led.read('status')}") + + for _ in range(3): + temp = temp_sensor.read("temperature") + print(f"Current temperature: {temp}°C") + + # 关闭设备 + led.close() + temp_sensor.close() + + # 注销驱动 + manager.unregister_driver("led1") + manager.unregister_driver("temp1") \ No newline at end of file diff --git "a/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\343\200\220RSOC25\343\200\221Day14\350\257\276\347\250\213\347\254\224\350\256\260\357\274\232\345\206\257\345\256\276/\347\254\224\350\256\260.md" "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\343\200\220RSOC25\343\200\221Day14\350\257\276\347\250\213\347\254\224\350\256\260\357\274\232\345\206\257\345\256\276/\347\254\224\350\256\260.md" new file mode 100644 index 0000000000000000000000000000000000000000..6427465c6dd7cdd402c03040fecf188bd2e59ad9 --- /dev/null +++ "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\343\200\220RSOC25\343\200\221Day14\350\257\276\347\250\213\347\254\224\350\256\260\357\274\232\345\206\257\345\256\276/\347\254\224\350\256\260.md" @@ -0,0 +1,46 @@ +# 【RSOC25】Day1 课程笔记:冯宾 + +`字符设备和块设备的特点与区别`: + +`字符设备`:提供连续的数据流,应用程序可以顺序读取,通常`不支持随机存取`。相反此类设备支持按`字节/字符`来读写数据。举例来说,键盘、串口、调制解调器都是典型的字符设备 + +`块设备`:应用程序可以`随机访问`设备数据,程序可自行确定读取数据的位置。硬盘、软盘、CD-ROM驱动器和闪存都是典型的块设备,应用程序可以寻址磁盘上的任何位置,并由此读取数据。此外,数据的读写只能以`块(通常是512B)的倍数`进行。与字符设备不同,块设备并不支持基于字符的寻址。 + +这两种类型的设备的根本区别在于它们是否可以被随机访问。字符设备只能总结一下,顺序读取,块设备可以随机读取。 + +`访问 I/0 设备` + +应用程序通过IO设备管理接口来访问硬件设备,当设备驱动实现后,应用程序就可以访问该硬件。I/O设备管理接口与I/0设备的操作方法的映射关系下图所示 + +`为什么要对设备分类` + +·MSH可以重定向到任意的字符设备上,例如将lcd模拟成字符设备,就可以将打印输出到LCD上,或者是实现一套空字符设备,将msh重定向到这里。 + +Fatfs文件系统依赖块设备驱动,我们将SD卡读写实现成块设备,但是也可以用ram来模拟块设备驱动, + +·不同的组件和应用会依赖不同的设备,对设备进行分类,可以做到对一类设备同样的控制 + +`数据接收回调` + +当硬件设备收到数据时,可以通过如下函数回调另一个函数来设置数据接收指示,通知上层应用线程有数据到达 + +在应用程序调用rt_device_write()入数据时,如果底层硬件能够支持自动发送,那么上层应用可以设置一个回调函数。这个回调函数会在底层硬件数据发送完成后(例如DMA传送完成或 FIFO已经写入完毕产生完成中断时)调用。 + +`GPIO概念与原理` + +芯片上的引脚一般分为4类:电源、时钟、控制与 I/O,I/0 口在使用模式上又分为 General Purpose lnput Output(通用输入/输出),简称GPIO,与功能复用I/O(如SPI/I2C/UART等)。 + +大多数MCU的引脚都不止一个功能。不同引脚内部结构不一样,拥有的功能也不一样。可以通过不同的配置,切换引脚的实际功能通用 I/O 口主要特性如下: + +`可编程控制中断`--中断触发模式可配置,一般有下图所示5种中断触发模式: + +上升沿触发:用于检测无抖动的上升沿 + +下降沿触发:用于检测无抖动的下降沿 + +高电平触发:用于检测高电平状态 + +低电平触发:用于检测低电平状态 + +双边沿触发:用于检测无抖动的双边沿 +