Compare commits

...

15 Commits
main ... 联网

772 changed files with 78887 additions and 10840 deletions

283
.config
View File

@ -4,10 +4,126 @@ CONFIG_BOARD_STM32F407_SPARK=y
#
# RT-Thread Kernel
#
#
# klibc options
#
#
# rt_vsnprintf options
#
# CONFIG_RT_KLIBC_USING_LIBC_VSNPRINTF is not set
CONFIG_RT_KLIBC_USING_VSNPRINTF_LONGLONG=y
CONFIG_RT_KLIBC_USING_VSNPRINTF_STANDARD=y
CONFIG_RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS=y
CONFIG_RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS=y
CONFIG_RT_KLIBC_USING_VSNPRINTF_WRITEBACK_SPECIFIER=y
CONFIG_RT_KLIBC_USING_VSNPRINTF_CHECK_NUL_IN_FORMAT_SPECIFIER=y
# CONFIG_RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS is not set
CONFIG_RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE=32
CONFIG_RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE=32
CONFIG_RT_KLIBC_USING_VSNPRINTF_FLOAT_PRECISION=6
CONFIG_RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL=9
CONFIG_RT_KLIBC_USING_VSNPRINTF_LOG10_TAYLOR_TERMS=4
# end of rt_vsnprintf options
#
# rt_vsscanf options
#
# CONFIG_RT_KLIBC_USING_LIBC_VSSCANF is not set
# end of rt_vsscanf options
#
# rt_memset options
#
# CONFIG_RT_KLIBC_USING_USER_MEMSET is not set
# CONFIG_RT_KLIBC_USING_LIBC_MEMSET is not set
# CONFIG_RT_KLIBC_USING_TINY_MEMSET is not set
# end of rt_memset options
#
# rt_memcpy options
#
# CONFIG_RT_KLIBC_USING_USER_MEMCPY is not set
# CONFIG_RT_KLIBC_USING_LIBC_MEMCPY is not set
# CONFIG_RT_KLIBC_USING_TINY_MEMCPY is not set
# end of rt_memcpy options
#
# rt_memmove options
#
# CONFIG_RT_KLIBC_USING_USER_MEMMOVE is not set
# CONFIG_RT_KLIBC_USING_LIBC_MEMMOVE is not set
# end of rt_memmove options
#
# rt_memcmp options
#
# CONFIG_RT_KLIBC_USING_USER_MEMCMP is not set
# CONFIG_RT_KLIBC_USING_LIBC_MEMCMP is not set
# end of rt_memcmp options
#
# rt_strstr options
#
# CONFIG_RT_KLIBC_USING_USER_STRSTR is not set
# CONFIG_RT_KLIBC_USING_LIBC_STRSTR is not set
# end of rt_strstr options
#
# rt_strcasecmp options
#
# CONFIG_RT_KLIBC_USING_USER_STRCASECMP is not set
# end of rt_strcasecmp options
#
# rt_strncpy options
#
# CONFIG_RT_KLIBC_USING_USER_STRNCPY is not set
# CONFIG_RT_KLIBC_USING_LIBC_STRNCPY is not set
# end of rt_strncpy options
#
# rt_strcpy options
#
# CONFIG_RT_KLIBC_USING_USER_STRCPY is not set
# CONFIG_RT_KLIBC_USING_LIBC_STRCPY is not set
# end of rt_strcpy options
#
# rt_strncmp options
#
# CONFIG_RT_KLIBC_USING_USER_STRNCMP is not set
# CONFIG_RT_KLIBC_USING_LIBC_STRNCMP is not set
# end of rt_strncmp options
#
# rt_strcmp options
#
# CONFIG_RT_KLIBC_USING_USER_STRCMP is not set
# CONFIG_RT_KLIBC_USING_LIBC_STRCMP is not set
# end of rt_strcmp options
#
# rt_strlen options
#
# CONFIG_RT_KLIBC_USING_USER_STRLEN is not set
# CONFIG_RT_KLIBC_USING_LIBC_STRLEN is not set
# end of rt_strlen options
#
# rt_strnlen options
#
# CONFIG_RT_KLIBC_USING_USER_STRNLEN is not set
# end of rt_strnlen options
# CONFIG_RT_UTEST_TC_USING_KLIBC is not set
# end of klibc options
CONFIG_RT_NAME_MAX=8
# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
# CONFIG_RT_USING_SMART is not set
# CONFIG_RT_USING_NANO is not set
# CONFIG_RT_USING_SMART is not set
# CONFIG_RT_USING_AMP is not set
# CONFIG_RT_USING_SMP is not set
CONFIG_RT_CPUS_NR=1
@ -17,6 +133,7 @@ CONFIG_RT_THREAD_PRIORITY_32=y
# CONFIG_RT_THREAD_PRIORITY_256 is not set
CONFIG_RT_THREAD_PRIORITY_MAX=32
CONFIG_RT_TICK_PER_SECOND=1000
CONFIG_RT_USING_OVERFLOW_CHECK=y
CONFIG_RT_USING_HOOK=y
CONFIG_RT_HOOK_USING_FUNC_PTR=y
# CONFIG_RT_USING_HOOKLIST is not set
@ -30,25 +147,17 @@ CONFIG_RT_TIMER_THREAD_STACK_SIZE=512
# CONFIG_RT_USING_CPU_USAGE_TRACER is not set
#
# kservice optimization
# kservice options
#
# CONFIG_RT_USING_TINY_FFS is not set
# end of kservice optimization
#
# klibc optimization
#
# CONFIG_RT_KLIBC_USING_STDLIB is not set
# CONFIG_RT_KLIBC_USING_TINY_SIZE is not set
# CONFIG_RT_KLIBC_USING_PRINTF_LONGLONG is not set
# end of klibc optimization
# end of kservice options
CONFIG_RT_USING_DEBUG=y
CONFIG_RT_DEBUGING_ASSERT=y
CONFIG_RT_DEBUGING_COLOR=y
CONFIG_RT_DEBUGING_CONTEXT=y
# CONFIG_RT_DEBUGING_AUTO_INIT is not set
CONFIG_RT_USING_OVERFLOW_CHECK=y
# CONFIG_RT_USING_CI_ACTION is not set
#
# Inter-Thread communication
@ -83,7 +192,6 @@ CONFIG_RT_USING_DEVICE=y
# CONFIG_RT_USING_DEVICE_OPS is not set
# CONFIG_RT_USING_INTERRUPT_INFO is not set
# CONFIG_RT_USING_THREADSAFE_PRINTF is not set
# CONFIG_RT_USING_SCHED_THREAD_CTX is not set
CONFIG_RT_USING_CONSOLE=y
CONFIG_RT_CONSOLEBUF_SIZE=128
CONFIG_RT_CONSOLE_DEVICE_NAME="uart1"
@ -172,8 +280,7 @@ CONFIG_RT_USING_DFS_ROMFS=y
# end of DFS: device virtual file system
CONFIG_RT_USING_FAL=y
CONFIG_FAL_DEBUG_CONFIG=y
CONFIG_FAL_DEBUG=1
CONFIG_FAL_USING_DEBUG=y
CONFIG_FAL_PART_HAS_TABLE_CFG=y
CONFIG_FAL_USING_SFUD_PORT=y
CONFIG_FAL_USING_NOR_FLASH_DEV_NAME="norflash0"
@ -189,10 +296,10 @@ CONFIG_RT_USING_SYSTEM_WORKQUEUE=y
CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048
CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23
CONFIG_RT_USING_SERIAL=y
CONFIG_RT_USING_SERIAL_V1=y
# CONFIG_RT_USING_SERIAL_V2 is not set
# CONFIG_RT_USING_SERIAL_V1 is not set
CONFIG_RT_USING_SERIAL_V2=y
CONFIG_RT_SERIAL_USING_DMA=y
CONFIG_RT_SERIAL_RB_BUFSZ=64
# CONFIG_RT_USING_SERIAL_BYPASS is not set
# CONFIG_RT_USING_CAN is not set
# CONFIG_RT_USING_CPUTIME is not set
CONFIG_RT_USING_I2C=y
@ -201,6 +308,7 @@ CONFIG_RT_USING_I2C_BITOPS=y
# CONFIG_RT_I2C_BITOPS_DEBUG is not set
# CONFIG_RT_USING_SOFT_I2C is not set
# CONFIG_RT_USING_PHY is not set
# CONFIG_RT_USING_PHY_V2 is not set
CONFIG_RT_USING_ADC=y
# CONFIG_RT_USING_DAC is not set
# CONFIG_RT_USING_NULL is not set
@ -222,6 +330,7 @@ CONFIG_RT_MMCSD_STACK_SIZE=1024
CONFIG_RT_MMCSD_THREAD_PREORITY=22
CONFIG_RT_MMCSD_MAX_PARTITION=16
# CONFIG_RT_SDIO_DEBUG is not set
# CONFIG_RT_USING_SDHCI is not set
CONFIG_RT_USING_SPI=y
# CONFIG_RT_USING_SPI_BITOPS is not set
# CONFIG_RT_USING_QSPI is not set
@ -270,6 +379,15 @@ CONFIG_RT_WLAN_WORKQUEUE_THREAD_NAME="wlan"
CONFIG_RT_WLAN_WORKQUEUE_THREAD_SIZE=2048
CONFIG_RT_WLAN_WORKQUEUE_THREAD_PRIO=15
# CONFIG_RT_WLAN_DEBUG is not set
CONFIG_RT_USING_BLK=y
#
# Partition Types
#
CONFIG_RT_BLK_PARTITION_DFS=y
CONFIG_RT_BLK_PARTITION_EFI=y
# end of Partition Types
# CONFIG_RT_USING_VIRTIO is not set
CONFIG_RT_USING_PIN=y
# CONFIG_RT_USING_KTIME is not set
@ -355,6 +473,7 @@ CONFIG_NETDEV_USING_IFCONFIG=y
CONFIG_NETDEV_USING_PING=y
CONFIG_NETDEV_USING_NETSTAT=y
CONFIG_NETDEV_USING_AUTO_DEFAULT=y
# CONFIG_NETDEV_USING_LINK_STATUS_CALLBACK is not set
# CONFIG_NETDEV_USING_IPV6 is not set
CONFIG_NETDEV_IPV4=1
CONFIG_NETDEV_IPV6=0
@ -418,8 +537,17 @@ CONFIG_LWIP_NETIF_LOOPBACK=0
# CONFIG_RT_LWIP_USING_HW_CHECKSUM is not set
CONFIG_RT_LWIP_USING_PING=y
# CONFIG_LWIP_USING_DHCPD is not set
# CONFIG_RT_LWIP_ENABLE_USER_HOOKS is not set
# CONFIG_RT_LWIP_DEBUG is not set
# CONFIG_RT_USING_AT is not set
CONFIG_RT_USING_AT=y
CONFIG_AT_DEBUG=y
# CONFIG_AT_USING_SERVER is not set
CONFIG_AT_USING_CLIENT=y
CONFIG_AT_CLIENT_NUM_MAX=1
# CONFIG_AT_USING_SOCKET is not set
CONFIG_AT_USING_CLI=y
CONFIG_AT_PRINT_RAW_CMD=y
CONFIG_AT_SW_VERSION_NUM=0x10301
# end of Network
#
@ -548,6 +676,9 @@ CONFIG_PKG_USING_RW007_V210=y
CONFIG_PKG_RW007_VER="v2.1.0"
# CONFIG_RW007_NOT_USE_EXAMPLE_DRIVERS is not set
CONFIG_RW007_USING_STM32_DRIVERS=y
# CONFIG_RW007_USING_BLE is not set
# CONFIG_RW007_USING_POWERSWITCH_EXAMPLE is not set
# CONFIG_RW007_USING_SPI_TEST is not set
CONFIG_RW007_SPI_MAX_HZ=30000000
CONFIG_RW007_SPI_BUS_NAME="spi2"
CONFIG_RW007_CS_PIN=90
@ -737,6 +868,8 @@ CONFIG_PKG_ALI_IOTKIT_VER_NUM=0x30002
# CONFIG_PKG_USING_MATTER_ADAPTATION_LAYER is not set
# CONFIG_PKG_USING_LHC_MODBUS is not set
# CONFIG_PKG_USING_QMODBUS is not set
# CONFIG_PKG_USING_PNET is not set
# CONFIG_PKG_USING_OPENER is not set
# end of IoT - internet of things
#
@ -773,6 +906,11 @@ CONFIG_PKG_CJSON_VER="v1.7.17"
# CONFIG_PKG_USING_JSMN is not set
# CONFIG_PKG_USING_AGILE_JSMN is not set
# CONFIG_PKG_USING_PARSON is not set
CONFIG_PKG_USING_RYAN_JSON=y
CONFIG_PKG_RYAN_JSON_PATH="/packages/language/JSON/RyanJson"
CONFIG_PKG_USING_RYAN_JSON_LATEST_VERSION=y
CONFIG_PKG_RYAN_JSON_VER="latest"
CONFIG_PKG_RYAN_JSON_VER_NUM=0xfff
# end of JSON: JavaScript Object Notation, a lightweight data-interchange format
#
@ -883,6 +1021,8 @@ CONFIG_PKG_VCONSOLE_VER="latest"
# CONFIG_PKG_USING_VOFA_PLUS is not set
# CONFIG_PKG_USING_RT_TRACE is not set
# CONFIG_PKG_USING_ZDEBUG is not set
# CONFIG_PKG_USING_RVBACKTRACE is not set
# CONFIG_PKG_USING_HPATCHLITE is not set
# end of tools packages
#
@ -894,26 +1034,6 @@ CONFIG_PKG_VCONSOLE_VER="latest"
#
# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
CONFIG_PKG_USING_RT_VSNPRINTF_FULL=y
CONFIG_PKG_RT_VSNPRINTF_FULL_PATH="/packages/system/enhanced-kservice/rt_vsnprintf_full"
CONFIG_PKG_VSNPRINTF_SUPPORT_DECIMAL_SPECIFIERS=y
CONFIG_PKG_VSNPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS=y
CONFIG_PKG_VSNPRINTF_SUPPORT_WRITEBACK_SPECIFIER=y
CONFIG_PKG_VSNPRINTF_SUPPORT_LONG_LONG=y
CONFIG_PKG_VSNPRINTF_CHECK_FOR_NUL_IN_FORMAT_SPECIFIER=y
# CONFIG_PKG_VSNPRINTF_SUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS is not set
CONFIG_PKG_VSNPRINTF_INTEGER_BUFFER_SIZE=32
CONFIG_PKG_VSNPRINTF_DECIMAL_BUFFER_SIZE=32
CONFIG_PKG_VSNPRINTF_DEFAULT_FLOAT_PRECISION=6
CONFIG_PKG_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL=9
CONFIG_PKG_VSNPRINTF_LOG10_TAYLOR_TERMS=4
# CONFIG_RT_VSNPRINTF_FULL_REPLACING_SPRINTF is not set
# CONFIG_RT_VSNPRINTF_FULL_REPLACING_SNPRINTF is not set
# CONFIG_RT_VSNPRINTF_FULL_REPLACING_PRINTF is not set
# CONFIG_RT_VSNPRINTF_FULL_REPLACING_VSPRINTF is not set
# CONFIG_RT_VSNPRINTF_FULL_REPLACING_VSNPRINTF is not set
CONFIG_PKG_USING_RT_VSNPRINTF_FULL_LATEST_VERSION=y
CONFIG_PKG_RT_VSNPRINTF_FULL_VER="latest"
# end of enhanced kernel services
# CONFIG_PKG_USING_AUNITY is not set
@ -931,7 +1051,6 @@ CONFIG_PKG_RT_VSNPRINTF_FULL_VER="latest"
#
# CONFIG_PKG_USING_CMSIS_5 is not set
# CONFIG_PKG_USING_CMSIS_CORE is not set
# CONFIG_PKG_USING_CMSIS_DSP is not set
# CONFIG_PKG_USING_CMSIS_NN is not set
# CONFIG_PKG_USING_CMSIS_RTOS1 is not set
# CONFIG_PKG_USING_CMSIS_RTOS2 is not set
@ -960,6 +1079,7 @@ CONFIG_PKG_PERF_COUNTER_PATH="/packages/system/perf_counter"
CONFIG_PKG_USING_PERF_COUNTER_V2241=y
# CONFIG_PKG_USING_PERF_COUNTER_LATEST_VERSION is not set
CONFIG_PKG_PERF_COUNTER_VER="v2.2.4.1"
CONFIG_FAL_DEBUG_CONFIG=y
# CONFIG_PKG_USING_FILEX is not set
# CONFIG_PKG_USING_LEVELX is not set
# CONFIG_PKG_USING_FLASHDB is not set
@ -988,7 +1108,6 @@ CONFIG_PKG_PERF_COUNTER_VER="v2.2.4.1"
# CONFIG_PKG_USING_ARM_2D is not set
# CONFIG_PKG_USING_MCUBOOT is not set
# CONFIG_PKG_USING_TINYUSB is not set
# CONFIG_PKG_USING_CHERRYUSB is not set
# CONFIG_PKG_USING_KMULTI_RTIMER is not set
# CONFIG_PKG_USING_TFDB is not set
# CONFIG_PKG_USING_QPC is not set
@ -996,10 +1115,13 @@ CONFIG_PKG_PERF_COUNTER_VER="v2.2.4.1"
# CONFIG_PKG_USING_FLASH_BLOB is not set
# CONFIG_PKG_USING_MLIBC is not set
# CONFIG_PKG_USING_TASK_MSG_BUS is not set
# CONFIG_PKG_USING_UART_FRAMEWORK is not set
# CONFIG_PKG_USING_SFDB is not set
# CONFIG_PKG_USING_RTP is not set
# CONFIG_PKG_USING_REB is not set
# CONFIG_PKG_USING_RMP is not set
# CONFIG_PKG_USING_R_RHEALSTONE is not set
# CONFIG_PKG_USING_HEARTBEAT is not set
# end of system packages
#
@ -1013,6 +1135,8 @@ CONFIG_PKG_PERF_COUNTER_VER="v2.2.4.1"
#
# STM32 HAL & SDK Drivers
#
# CONFIG_PKG_USING_STM32F4_HAL_DRIVER is not set
# CONFIG_PKG_USING_STM32F4_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_STM32L4_HAL_DRIVER is not set
# CONFIG_PKG_USING_STM32L4_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_STM32WB55_SDK is not set
@ -1049,6 +1173,43 @@ CONFIG_SDIO_MAX_FREQ=1000000
# CONFIG_PKG_USING_NRF5X_SDK is not set
# CONFIG_PKG_USING_NRFX is not set
# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
# CONFIG_PKG_USING_MM32 is not set
#
# WCH HAL & SDK Drivers
#
# CONFIG_PKG_USING_CH32V20x_SDK is not set
# CONFIG_PKG_USING_CH32V307_SDK is not set
# end of WCH HAL & SDK Drivers
#
# AT32 HAL & SDK Drivers
#
# CONFIG_PKG_USING_AT32A403A_HAL_DRIVER is not set
# CONFIG_PKG_USING_AT32A403A_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_AT32A423_HAL_DRIVER is not set
# CONFIG_PKG_USING_AT32A423_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_AT32F45x_HAL_DRIVER is not set
# CONFIG_PKG_USING_AT32F45x_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_AT32F402_405_HAL_DRIVER is not set
# CONFIG_PKG_USING_AT32F402_405_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_AT32F403A_407_HAL_DRIVER is not set
# CONFIG_PKG_USING_AT32F403A_407_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_AT32F413_HAL_DRIVER is not set
# CONFIG_PKG_USING_AT32F413_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_AT32F415_HAL_DRIVER is not set
# CONFIG_PKG_USING_AT32F415_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_AT32F421_HAL_DRIVER is not set
# CONFIG_PKG_USING_AT32F421_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_AT32F423_HAL_DRIVER is not set
# CONFIG_PKG_USING_AT32F423_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_AT32F425_HAL_DRIVER is not set
# CONFIG_PKG_USING_AT32F425_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_AT32F435_437_HAL_DRIVER is not set
# CONFIG_PKG_USING_AT32F435_437_CMSIS_DRIVER is not set
# CONFIG_PKG_USING_AT32M412_416_HAL_DRIVER is not set
# CONFIG_PKG_USING_AT32M412_416_CMSIS_DRIVER is not set
# end of AT32 HAL & SDK Drivers
# end of HAL & SDK Drivers
#
@ -1072,9 +1233,11 @@ CONFIG_SDIO_MAX_FREQ=1000000
# CONFIG_PKG_USING_MPU6XXX is not set
CONFIG_PKG_USING_AHT10=y
CONFIG_PKG_AHT10_PATH="/packages/peripherals/sensors/aht10"
# CONFIG_AHT10_USING_SOFT_FILTER is not set
# CONFIG_AHT10_USING_SENSOR_DEVICE is not set
# CONFIG_PKG_AHT10_USING_SOFT_FILTER is not set
# CONFIG_PKG_AHT10_USING_SENSOR_V2 is not set
# CONFIG_PKG_USING_AHT10_SAMPLE is not set
CONFIG_PKG_USING_AHT10_LATEST_VERSION=y
# CONFIG_PKG_USING_AHT10_V300 is not set
# CONFIG_PKG_USING_AHT10_V210 is not set
CONFIG_PKG_AHT10_VER="latest"
CONFIG_PKG_USING_AP3216C=y
@ -1105,8 +1268,10 @@ CONFIG_PKG_AP3216C_VER="latest"
# CONFIG_PKG_USING_PMSXX is not set
# CONFIG_PKG_USING_RT3020 is not set
# CONFIG_PKG_USING_MLX90632 is not set
# CONFIG_PKG_USING_MLX90382 is not set
# CONFIG_PKG_USING_MLX90393 is not set
# CONFIG_PKG_USING_MLX90392 is not set
# CONFIG_PKG_USING_MLX90394 is not set
# CONFIG_PKG_USING_MLX90397 is not set
# CONFIG_PKG_USING_MS5611 is not set
# CONFIG_PKG_USING_MAX31865 is not set
@ -1136,6 +1301,7 @@ CONFIG_PKG_USING_ICM20608_LATEST_VERSION=y
CONFIG_PKG_ICM20608_VER="latest"
# CONFIG_PKG_USING_PAJ7620 is not set
# CONFIG_PKG_USING_STHS34PF80 is not set
# CONFIG_PKG_USING_P3T1755 is not set
# end of sensors drivers
#
@ -1242,6 +1408,10 @@ CONFIG_PKG_INFRARED_VER="v0.1.1"
# CONFIG_PKG_USING_SYSTEM_RUN_LED is not set
# CONFIG_PKG_USING_BT_MX01 is not set
# CONFIG_PKG_USING_RGPOWER is not set
# CONFIG_PKG_USING_BT_MX02 is not set
# CONFIG_PKG_USING_GC9A01 is not set
# CONFIG_PKG_USING_IK485 is not set
# CONFIG_PKG_USING_SERVO is not set
# CONFIG_PKG_USING_SPI_TOOLS is not set
# end of peripheral libraries and drivers
@ -1258,6 +1428,7 @@ CONFIG_PKG_INFRARED_VER="v0.1.1"
# CONFIG_PKG_USING_QUEST is not set
# CONFIG_PKG_USING_NAXOS is not set
# CONFIG_PKG_USING_R_TINYMAIX is not set
# CONFIG_PKG_USING_LLMCHAT is not set
# end of AI packages
#
@ -1269,6 +1440,7 @@ CONFIG_PKG_INFRARED_VER="v0.1.1"
# CONFIG_PKG_USING_UKAL is not set
# CONFIG_PKG_USING_DIGITALCTRL is not set
# CONFIG_PKG_USING_KISSFFT is not set
# CONFIG_PKG_USING_CMSIS_DSP is not set
# end of Signal Processing and Control Algorithm Packages
#
@ -1299,7 +1471,6 @@ CONFIG_KERNEL_SAMPLES_USING_EVENT=y
CONFIG_KERNEL_SAMPLES_USING_MESSAGEQUEUE=y
# CONFIG_KERNEL_SAMPLES_USING_TIMER is not set
# CONFIG_KERNEL_SAMPLES_USING_HEAP is not set
# CONFIG_KERNEL_SAMPLES_USING_MEMHEAP is not set
# CONFIG_KERNEL_SAMPLES_USING_MEMPOOL is not set
# CONFIG_KERNEL_SAMPLES_USING_IDLEHOOK is not set
# CONFIG_KERNEL_SAMPLES_USING_SIGNAL is not set
@ -1358,6 +1529,7 @@ CONFIG_PKG_FLEXIBLE_BUTTON_VER="v1.0.0"
# CONFIG_PKG_USING_KI is not set
# CONFIG_PKG_USING_ARMv7M_DWT is not set
# CONFIG_PKG_USING_CRCLIB is not set
# CONFIG_PKG_USING_LIBCRC is not set
# CONFIG_PKG_USING_LWGPS is not set
# CONFIG_PKG_USING_STATE_MACHINE is not set
# CONFIG_PKG_USING_DESIGN_PATTERN is not set
@ -1369,6 +1541,7 @@ CONFIG_PKG_FLEXIBLE_BUTTON_VER="v1.0.0"
# CONFIG_PKG_USING_QPARAM is not set
# CONFIG_PKG_USING_CorevMCU_CLI is not set
# CONFIG_PKG_USING_GET_IRQ_PRIORITY is not set
# CONFIG_PKG_USING_DRMP is not set
# end of miscellaneous packages
#
@ -1382,6 +1555,7 @@ CONFIG_PKG_FLEXIBLE_BUTTON_VER="v1.0.0"
# CONFIG_PKG_USING_ARDUINO_MSGQ_C_CPP_DEMO is not set
# CONFIG_PKG_USING_ARDUINO_SKETCH_LOADER_DEMO is not set
# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set
# CONFIG_PKG_USING_ARDUINO_RTDUINO_SENSORFUSION_SHIELD is not set
# CONFIG_PKG_USING_ARDUINO_NINEINONE_SENSOR_SHIELD is not set
# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set
# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set
@ -1660,23 +1834,38 @@ CONFIG_BSP_USING_UART=y
CONFIG_BSP_USING_UART1=y
# CONFIG_BSP_UART1_RX_USING_DMA is not set
# CONFIG_BSP_UART1_TX_USING_DMA is not set
CONFIG_BSP_UART1_TX_BUFSIZE=0
CONFIG_BSP_UART1_RX_BUFSIZE=256
CONFIG_BSP_USING_UART2=y
# CONFIG_BSP_UART2_RX_USING_DMA is not set
# CONFIG_BSP_UART2_TX_USING_DMA is not set
CONFIG_BSP_UART2_TX_BUFSIZE=0
CONFIG_BSP_UART2_RX_BUFSIZE=256
CONFIG_BSP_USING_UART3=y
# CONFIG_BSP_UART3_RX_USING_DMA is not set
# CONFIG_BSP_UART3_TX_USING_DMA is not set
CONFIG_BSP_UART3_RX_USING_DMA=y
CONFIG_BSP_UART3_TX_USING_DMA=y
CONFIG_BSP_UART3_TX_BUFSIZE=0
CONFIG_BSP_UART3_RX_BUFSIZE=256
# CONFIG_BSP_USING_UART4 is not set
CONFIG_BSP_UART4_TX_BUFSIZE=0
CONFIG_BSP_UART4_RX_BUFSIZE=256
# CONFIG_BSP_USING_UART5 is not set
CONFIG_BSP_UART5_TX_BUFSIZE=0
CONFIG_BSP_UART5_RX_BUFSIZE=256
CONFIG_BSP_USING_UART6=y
# CONFIG_BSP_UART6_RX_USING_DMA is not set
# CONFIG_BSP_UART6_TX_USING_DMA is not set
CONFIG_BSP_UART6_TX_BUFSIZE=0
CONFIG_BSP_UART6_RX_BUFSIZE=256
CONFIG_BSP_USING_TIM=y
CONFIG_BSP_USING_TIM11=y
CONFIG_BSP_USING_TIM13=y
CONFIG_BSP_USING_TIM14=y
CONFIG_BSP_USING_PWM=y
# CONFIG_BSP_USING_PWM1 is not set
CONFIG_BSP_USING_PWM1=y
CONFIG_BSP_USING_PWM1_CH1=y
# CONFIG_BSP_USING_PWM1_CH2 is not set
# CONFIG_BSP_USING_PWM1_CH3 is not set
# CONFIG_BSP_USING_PWM2 is not set
CONFIG_BSP_USING_PWM3=y
CONFIG_BSP_USING_PWM3_CH2=y

View File

@ -379,10 +379,12 @@
"__llvm__=1"
],
"intelliSenseMode": "gcc-arm",
"compilerPath": "d:/Develop/env2/tools/gnu_gcc/arm_gcc/mingw/bin/arm-none-eabi-gcc",
"compilerPath": "d:/DevTools/env2/tools/gnu_gcc/arm_gcc/mingw/bin/arm-none-eabi-gcc",
"cStandard": "c99",
"cppStandard": "c++11",
"compileCommands": "build/compile_commands.json",
"compileCommands": [
"build/compile_commands.json"
],
"includePath": [
"d:\\components\\drivers\\include",
"d:\\Develop\\libraries\\HAL_Drivers\\drivers\\config",

View File

@ -20,3 +20,25 @@
[info] Log at : 2025/1/18|00:50:06|GMT+0800
[info] Log at : 2025/2/3|17:47:00|GMT+0800
[info] Log at : 2025/2/11|20:47:29|GMT+0800
[info] Log at : 2025/2/13|18:00:08|GMT+0800
[info] Log at : 2025/2/16|09:16:38|GMT+0800
[info] Log at : 2025/2/18|16:29:01|GMT+0800
[info] Log at : 2025/3/5|20:26:51|GMT+0800
[info] Log at : 2025/3/10|21:09:20|GMT+0800
[info] Log at : 2025/3/14|07:53:16|GMT+0800
[info] Log at : 2025/3/15|11:13:19|GMT+0800
[info] Log at : 2025/3/17|22:39:47|GMT+0800
[info] Log at : 2025/3/18|21:14:31|GMT+0800

34
.vscode/launch.json vendored
View File

@ -1,32 +1,20 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "rt-spark-openocd",
// "cwd": "${workspaceFolder}",
"executable": "${workspaceRoot}/rt-thread.elf",
"request": "launch",
"name": "调试_pyocd",
"type": "cortex-debug",
"runToEntryPoint": "main",
"targetId": "STM32F407ZG",
"cwd": "${workspaceRoot}",
"request": "launch",
"cwd": "${workspaceRoot}",
"servertype": "pyocd",
"configFiles": [
"interface/stlink-v2.cfg",
"target/stm32f4x.cfg"
],
"armToolchainPath": "d:/Develop/env2/tools/gnu_gcc/arm_gcc/mingw/bin",
"gdbPath": "d:/Develop/env2/tools/gnu_gcc/arm_gcc/mingw/bin/arm-none-eabi-gdb.exe",
"serverpath": "d:\\Develop\\env2\\.venv\\Scripts\\pyocd",
"svdFile": "${workspaceRoot}/chip/STM32F407.svd",
"cmsisPack": "${workspaceRoot}/chip/Keil.STM32F4xx_DFP.2.17.1.pack",
// "cortex-debug.openocdPath": "d:/Develop/OpenOCD/bin/openocd.exe"
"serverpath": "d:\\DevTools\\env2\\.venv\\Scripts\\pyocd.exe",
"executable": "${workspaceRoot}/rt-thread.elf",
"targetId": "stm32f407vg",
"svdFile": "${workspaceRoot}/.vscode/STM32F407.svd",
"armToolchainPath": "d:/DevTools/env2/tools/gnu_gcc/arm_gcc/mingw/bin/",
"gdbPath": "d:\\DevTools\\env2\\tools\\gnu_gcc\\arm_gcc\\mingw\\bin\\arm-none-eabi-gdb.exe",
// "showDevDebugOutput": "raw" ,
}
]
}

529
.vscode/project.json vendored Normal file
View File

@ -0,0 +1,529 @@
{
"RT-Thread": "D:\\Develop\\SumProject\\rt-thread",
"Groups": [
{
"name": "aht10",
"path": "packages\\aht10-latest",
"files": [
"packages\\aht10-latest\\src\\aht10.c",
"packages\\aht10-latest\\SConscript"
]
},
{
"name": "ali-iotkit",
"path": "packages\\ali-iotkit-v3.0.2",
"files": [
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\infra\\infra_log.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\mqtt\\impl\\MQTTUnsubscribeClient.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\infra\\infra_cjson.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\dm_api.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_sign\\dev_sign_mqtt.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\infra\\infra_compat.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\infra\\infra_defs.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\dm_log_report.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\mqtt\\mqtt_api.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\infra\\infra_string.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\dm_message.c",
"packages\\ali-iotkit-v3.0.2\\ports\\rtthread\\HAL_TCP_rtthread.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\iotx_cm_mqtt.c",
"packages\\ali-iotkit-v3.0.2\\ports\\wrapper.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\dm_msg_process.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\dm_cota.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\dm_ipc.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\mqtt\\impl\\MQTTDeserializePublish.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\infra\\infra_prt_nwk_payload.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\impl_linkkit.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\infra\\infra_report.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\client\\dm_client_adapter.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\infra\\infra_timer.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\infra\\infra_net.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\mqtt\\impl\\MQTTSubscribeClient.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\mqtt\\impl\\MQTTPacket.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\dm_ota.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\dm_fota.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\mqtt\\impl\\MQTTConnectClient.c",
"packages\\ali-iotkit-v3.0.2\\ports\\rtthread\\HAL_UDP_rtthread.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\infra\\infra_sha256.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\dm_opt.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\mqtt\\impl\\iotx_mqtt_client.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\mqtt\\impl\\MQTTSerializePublish.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\dm_manager.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\dm_utils.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\client\\dm_client.c",
"packages\\ali-iotkit-v3.0.2\\ports\\rtthread\\HAL_OS_rtthread.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\iotx_cm.c",
"packages\\ali-iotkit-v3.0.2\\iotkit-embedded\\src\\dev_model\\dm_message_cache.c",
"packages\\ali-iotkit-v3.0.2\\SConscript"
]
},
{
"name": "ap3216c",
"path": "packages\\ap3216c-latest",
"files": [
"packages\\ap3216c-latest\\ap3216c.c",
"packages\\ap3216c-latest\\SConscript"
]
},
{
"name": "Applications",
"path": "applications",
"files": [
"applications\\sim.c",
"applications\\app_lcd.c",
"applications\\sensor.c",
"applications\\mysnake.c",
"applications\\test_drv_example.c",
"applications\\pin_irq_example.c",
"applications\\init.c",
"applications\\myproject.c",
"applications\\my_func.c",
"applications\\status.c",
"applications\\assistant.c",
"applications\\main.c",
"applications\\mytest.c",
"applications\\motor.c",
"applications\\AHT10.c",
"applications\\myinfrared.c",
"applications\\SConscript"
]
},
{
"name": "AT",
"path": "rt-thread\\components\\net\\at",
"files": [
"rt-thread\\components\\net\\at\\src\\at_cli.c",
"rt-thread\\components\\net\\at\\src\\at_client.c",
"rt-thread\\components\\net\\at\\src\\at_utils.c",
"rt-thread\\components\\net\\at\\SConscript"
]
},
{
"name": "cJSON",
"path": "packages\\cJSON-v1.7.17",
"files": [
"packages\\cJSON-v1.7.17\\cJSON.c",
"packages\\cJSON-v1.7.17\\cJSON_Utils.c",
"packages\\cJSON-v1.7.17\\SConscript"
]
},
{
"name": "Compiler",
"path": "rt-thread\\components\\libc\\compilers\\common",
"files": [
"rt-thread\\components\\libc\\compilers\\common\\cctype.c",
"rt-thread\\components\\libc\\compilers\\common\\cstdlib.c",
"rt-thread\\components\\libc\\compilers\\common\\cstring.c",
"rt-thread\\components\\libc\\compilers\\common\\ctime.c",
"rt-thread\\components\\libc\\compilers\\common\\cunistd.c",
"rt-thread\\components\\libc\\compilers\\common\\cwchar.c",
"rt-thread\\components\\libc\\compilers\\newlib\\syscalls.c",
"rt-thread\\components\\libc\\compilers\\common\\SConscript"
]
},
{
"name": "CPP",
"path": "rt-thread\\components\\libc\\cplusplus",
"files": [
"rt-thread\\components\\libc\\cplusplus\\cxx_crt_init.c",
"rt-thread\\components\\libc\\cplusplus\\cxx_crt.cpp",
"rt-thread\\components\\libc\\cplusplus\\SConscript"
]
},
{
"name": "DeviceDrivers",
"path": "rt-thread\\components\\drivers\\block",
"files": [
"rt-thread\\components\\drivers\\block\\blk.c",
"rt-thread\\components\\drivers\\block\\blk_dev.c",
"rt-thread\\components\\drivers\\block\\blk_dfs.c",
"rt-thread\\components\\drivers\\block\\blk_partition.c",
"rt-thread\\components\\drivers\\block\\partitions\\dfs.c",
"rt-thread\\components\\drivers\\block\\partitions\\efi.c",
"rt-thread\\components\\drivers\\core\\device.c",
"rt-thread\\components\\drivers\\hwtimer\\hwtimer.c",
"rt-thread\\components\\drivers\\i2c\\dev_i2c_bit_ops.c",
"rt-thread\\components\\drivers\\i2c\\dev_i2c_core.c",
"rt-thread\\components\\drivers\\i2c\\dev_i2c_dev.c",
"rt-thread\\components\\drivers\\ipc\\completion_comm.c",
"rt-thread\\components\\drivers\\ipc\\completion_up.c",
"rt-thread\\components\\drivers\\ipc\\condvar.c",
"rt-thread\\components\\drivers\\ipc\\dataqueue.c",
"rt-thread\\components\\drivers\\ipc\\pipe.c",
"rt-thread\\components\\drivers\\ipc\\ringblk_buf.c",
"rt-thread\\components\\drivers\\ipc\\ringbuffer.c",
"rt-thread\\components\\drivers\\ipc\\waitqueue.c",
"rt-thread\\components\\drivers\\ipc\\workqueue.c",
"rt-thread\\components\\drivers\\misc\\adc.c",
"rt-thread\\components\\drivers\\misc\\rt_drv_pwm.c",
"rt-thread\\components\\drivers\\pin\\dev_pin.c",
"rt-thread\\components\\drivers\\rtc\\dev_rtc.c",
"rt-thread\\components\\drivers\\rtc\\dev_soft_rtc.c",
"rt-thread\\components\\drivers\\sdio\\dev_block.c",
"rt-thread\\components\\drivers\\sdio\\dev_mmc.c",
"rt-thread\\components\\drivers\\sdio\\dev_mmcsd_core.c",
"rt-thread\\components\\drivers\\sdio\\dev_sd.c",
"rt-thread\\components\\drivers\\sdio\\dev_sdio.c",
"rt-thread\\components\\drivers\\sensor\\v1\\sensor.c",
"rt-thread\\components\\drivers\\sensor\\v1\\sensor_cmd.c",
"rt-thread\\components\\drivers\\serial\\dev_serial_v2.c",
"rt-thread\\components\\drivers\\spi\\dev_spi.c",
"rt-thread\\components\\drivers\\spi\\dev_spi_core.c",
"rt-thread\\components\\drivers\\spi\\dev_spi_flash_sfud.c",
"rt-thread\\components\\drivers\\spi\\sfud\\src\\sfud.c",
"rt-thread\\components\\drivers\\spi\\sfud\\src\\sfud_sfdp.c",
"rt-thread\\components\\drivers\\wlan\\dev_wlan.c",
"rt-thread\\components\\drivers\\wlan\\dev_wlan_cfg.c",
"rt-thread\\components\\drivers\\wlan\\dev_wlan_cmd.c",
"rt-thread\\components\\drivers\\wlan\\dev_wlan_lwip.c",
"rt-thread\\components\\drivers\\wlan\\dev_wlan_mgnt.c",
"rt-thread\\components\\drivers\\wlan\\dev_wlan_prot.c",
"rt-thread\\components\\drivers\\wlan\\dev_wlan_workqueue.c",
"rt-thread\\components\\drivers\\block\\SConscript"
]
},
{
"name": "Drivers",
"path": "board",
"files": [
"board\\CubeMX_Config\\Src\\stm32f4xx_hal_msp.c",
"board\\board.c",
"board\\ports\\drv_filesystem.c",
"board\\ports\\fal\\fal_spi_flash_sfud_port.c",
"board\\ports\\lcd\\drv_lcd.c",
"board\\ports\\led_matrix\\drv_matrix_led.c",
"board\\ports\\spi_flash_init.c",
"board\\startup_stm32f407xx.s",
"libraries\\HAL_Drivers\\drivers\\drv_adc.c",
"libraries\\HAL_Drivers\\drivers\\drv_flash\\drv_flash_f4.c",
"libraries\\HAL_Drivers\\drivers\\drv_gpio.c",
"libraries\\HAL_Drivers\\drivers\\drv_pwm.c",
"libraries\\HAL_Drivers\\drivers\\drv_sdio.c",
"libraries\\HAL_Drivers\\drivers\\drv_soft_i2c.c",
"libraries\\HAL_Drivers\\drivers\\drv_spi.c",
"libraries\\HAL_Drivers\\drivers\\drv_test.c",
"libraries\\HAL_Drivers\\drivers\\drv_tim.c",
"libraries\\HAL_Drivers\\drivers\\drv_usart_v2.c",
"libraries\\HAL_Drivers\\drivers\\drv_usbd.c",
"libraries\\HAL_Drivers\\drv_common.c",
"board\\SConscript"
]
},
{
"name": "Fal",
"path": "rt-thread\\components\\fal",
"files": [
"rt-thread\\components\\fal\\src\\fal_flash.c",
"rt-thread\\components\\fal\\src\\fal_rtt.c",
"rt-thread\\components\\fal\\src\\fal.c",
"rt-thread\\components\\fal\\src\\fal_partition.c",
"rt-thread\\components\\fal\\samples\\porting\\fal_flash_sfud_port.c",
"rt-thread\\components\\fal\\SConscript"
]
},
{
"name": "Filesystem",
"path": "rt-thread\\components\\dfs\\dfs_v1",
"files": [
"rt-thread\\components\\dfs\\dfs_v1\\filesystems\\devfs\\devfs.c",
"rt-thread\\components\\dfs\\dfs_v1\\filesystems\\elmfat\\dfs_elm.c",
"rt-thread\\components\\dfs\\dfs_v1\\filesystems\\elmfat\\ff.c",
"rt-thread\\components\\dfs\\dfs_v1\\filesystems\\elmfat\\ffunicode.c",
"rt-thread\\components\\dfs\\dfs_v1\\filesystems\\romfs\\dfs_romfs.c",
"rt-thread\\components\\dfs\\dfs_v1\\src\\dfs.c",
"rt-thread\\components\\dfs\\dfs_v1\\src\\dfs_file.c",
"rt-thread\\components\\dfs\\dfs_v1\\src\\dfs_fs.c",
"rt-thread\\components\\dfs\\dfs_v1\\src\\dfs_posix.c",
"rt-thread\\components\\dfs\\dfs_v1\\SConscript"
]
},
{
"name": "Finsh",
"path": "rt-thread\\components\\finsh",
"files": [
"rt-thread\\components\\finsh\\msh_parse.c",
"rt-thread\\components\\finsh\\msh.c",
"rt-thread\\components\\finsh\\msh_file.c",
"rt-thread\\components\\finsh\\shell.c",
"rt-thread\\components\\finsh\\cmd.c",
"rt-thread\\components\\finsh\\SConscript"
]
},
{
"name": "flex_button",
"path": "packages\\FlexibleButton-v1.0.0",
"files": [
"packages\\FlexibleButton-v1.0.0\\flexible_button.c",
"packages\\FlexibleButton-v1.0.0\\SConscript"
]
},
{
"name": "icm20608",
"path": "packages\\icm20608-latest",
"files": [
"packages\\icm20608-latest\\icm20608.c",
"packages\\icm20608-latest\\SConscript"
]
},
{
"name": "Infrared_frame",
"path": "packages\\infrared-v0.1.1",
"files": [
"packages\\infrared-v0.1.1\\src\\nec_decoder.c",
"packages\\infrared-v0.1.1\\src\\infrared.c",
"packages\\infrared-v0.1.1\\src\\drv_infrared.c",
"packages\\infrared-v0.1.1\\SConscript"
]
},
{
"name": "Kernel",
"path": ".",
"files": [
"rt-thread\\src\\clock.c",
"rt-thread\\src\\components.c",
"rt-thread\\src\\cpu_up.c",
"rt-thread\\src\\defunct.c",
"rt-thread\\src\\idle.c",
"rt-thread\\src\\ipc.c",
"rt-thread\\src\\irq.c",
"rt-thread\\src\\kservice.c",
"rt-thread\\src\\mem.c",
"rt-thread\\src\\mempool.c",
"rt-thread\\src\\object.c",
"rt-thread\\src\\scheduler_comm.c",
"rt-thread\\src\\scheduler_up.c",
"rt-thread\\src\\thread.c",
"rt-thread\\src\\timer.c",
".\\SConscript"
]
},
{
"name": "kernel-samples",
"path": "packages\\kernel_samples-latest\\en",
"files": [
"packages\\kernel_samples-latest\\en\\event_sample.c",
"packages\\kernel_samples-latest\\en\\thread_sample.c",
"packages\\kernel_samples-latest\\en\\semaphore_sample.c",
"packages\\kernel_samples-latest\\en\\mutex_sample.c",
"packages\\kernel_samples-latest\\en\\msgq_sample.c",
"packages\\kernel_samples-latest\\en\\mailbox_sample.c",
"packages\\kernel_samples-latest\\en\\SConscript"
]
},
{
"name": "klibc",
"path": "rt-thread\\src\\klibc",
"files": [
"rt-thread\\src\\klibc\\kstdio.c",
"rt-thread\\src\\klibc\\rt_vsnprintf_std.c",
"rt-thread\\src\\klibc\\kerrno.c",
"rt-thread\\src\\klibc\\rt_vsscanf.c",
"rt-thread\\src\\klibc\\kstring.c",
"rt-thread\\src\\klibc\\SConscript"
]
},
{
"name": "Legacy",
"path": "rt-thread\\components\\legacy",
"files": [
"rt-thread\\components\\legacy\\ipc\\workqueue_legacy.c",
"rt-thread\\components\\legacy\\SConscript"
]
},
{
"name": "libcpu",
"path": "rt-thread\\libcpu\\arm\\common",
"files": [
"rt-thread\\libcpu\\arm\\common\\atomic_arm.c",
"rt-thread\\libcpu\\arm\\common\\div0.c",
"rt-thread\\libcpu\\arm\\common\\showmem.c",
"rt-thread\\libcpu\\arm\\cortex-m4\\context_gcc.S",
"rt-thread\\libcpu\\arm\\cortex-m4\\cpuport.c",
"rt-thread\\libcpu\\arm\\common\\SConscript"
]
},
{
"name": "Libraries",
"path": "libraries\\STM32F4xx_HAL",
"files": [
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_lptim.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_cortex.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_cec.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_adc_ex.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_uart.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_sram.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_tim_ex.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_dma_ex.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_usart.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_pcd.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_ll_fsmc.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_flash_ex.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_tim.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_ll_fmc.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_pwr_ex.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_gpio.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_rcc_ex.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_i2c_ex.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_pcd_ex.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_hcd.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_rtc.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_cryp_ex.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_adc.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_qspi.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_flash_ramfunc.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_ll_usb.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_pwr.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_sd.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_i2c.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_crc.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_rcc.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_rtc_ex.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_ll_sdmmc.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_spi.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_flash.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_rng.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_cryp.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_dma.c",
"libraries\\STM32F4xx_HAL\\STM32F4xx_HAL_Driver\\Src\\stm32f4xx_hal_pccard.c",
"libraries\\STM32F4xx_HAL\\CMSIS\\Device\\ST\\STM32F4xx\\Source\\Templates\\system_stm32f4xx.c",
"libraries\\STM32F4xx_HAL\\SConscript"
]
},
{
"name": "lwIP",
"path": "rt-thread\\components\\net\\lwip\\lwip-2.0.3",
"files": [
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\api\\api_lib.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\api\\api_msg.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\api\\err.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\api\\netbuf.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\api\\netdb.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\api\\netifapi.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\api\\sockets.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\api\\tcpip.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\apps\\ping\\ping.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\def.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\dns.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\inet_chksum.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\init.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\ip.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\ipv4\\autoip.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\ipv4\\dhcp.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\ipv4\\etharp.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\ipv4\\icmp.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\ipv4\\igmp.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\ipv4\\ip4.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\ipv4\\ip4_addr.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\ipv4\\ip4_frag.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\memp.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\netif.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\pbuf.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\raw.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\stats.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\sys.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\tcp.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\tcp_in.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\tcp_out.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\timeouts.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\core\\udp.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\netif\\ethernet.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\src\\netif\\lowpan6.c",
"rt-thread\\components\\net\\lwip\\port\\ethernetif.c",
"rt-thread\\components\\net\\lwip\\port\\sys_arch.c",
"rt-thread\\components\\net\\lwip\\lwip-2.0.3\\SConscript"
]
},
{
"name": "NetUtils",
"path": "packages\\netutils-latest\\ntp",
"files": [
"packages\\netutils-latest\\ntp\\ntp.c",
"packages\\netutils-latest\\ntp\\SConscript"
]
},
{
"name": "perf_counter",
"path": "packages\\perf_counter-v2.2.4.1",
"files": [
"packages\\perf_counter-v2.2.4.1\\perf_counter.c",
"packages\\perf_counter-v2.2.4.1\\os\\perf_os_patch_rt_thread.c",
"packages\\perf_counter-v2.2.4.1\\SConscript"
]
},
{
"name": "POSIX",
"path": "rt-thread\\components\\libc\\posix\\io\\epoll",
"files": [
"rt-thread\\components\\libc\\posix\\io\\poll\\poll.c",
"rt-thread\\components\\libc\\posix\\io\\poll\\select.c",
"rt-thread\\components\\libc\\posix\\io\\epoll\\SConscript"
]
},
{
"name": "RS485_port",
"path": "board\\ports\\rs485",
"files": [
"board\\ports\\rs485\\drv_rs485.c",
"board\\ports\\rs485\\SConscript"
]
},
{
"name": "rt_usbd",
"path": "rt-thread\\components\\legacy\\usb\\usbdevice",
"files": [
"rt-thread\\components\\legacy\\usb\\usbdevice\\core\\usbdevice.c",
"rt-thread\\components\\legacy\\usb\\usbdevice\\core\\usbdevice_core.c",
"rt-thread\\components\\legacy\\usb\\usbdevice\\class\\cdc_vcom.c",
"rt-thread\\components\\legacy\\usb\\usbdevice\\SConscript"
]
},
{
"name": "rw007",
"path": "packages\\rw007-v2.1.0",
"files": [
"packages\\rw007-v2.1.0\\example\\rw007_stm32_port.c",
"packages\\rw007-v2.1.0\\src\\spi_wifi_rw007.c",
"packages\\rw007-v2.1.0\\SConscript"
]
},
{
"name": "RyanJson",
"path": "packages\\RyanJson-latest",
"files": [
"packages\\RyanJson-latest\\RyanJson\\RyanJson.c",
"packages\\RyanJson-latest\\SConscript"
]
},
{
"name": "SAL",
"path": "rt-thread\\components\\net\\netdev",
"files": [
"rt-thread\\components\\net\\netdev\\src\\netdev.c",
"rt-thread\\components\\net\\netdev\\src\\netdev_ipaddr.c",
"rt-thread\\components\\net\\sal\\dfs_net\\dfs_net.c",
"rt-thread\\components\\net\\sal\\impl\\af_inet_lwip.c",
"rt-thread\\components\\net\\sal\\socket\\net_netdb.c",
"rt-thread\\components\\net\\sal\\socket\\net_sockets.c",
"rt-thread\\components\\net\\sal\\src\\sal_socket.c",
"rt-thread\\components\\net\\netdev\\SConscript"
]
},
{
"name": "Utilities",
"path": "rt-thread\\components\\utilities\\ulog",
"files": [
"rt-thread\\components\\utilities\\ulog\\backend\\console_be.c",
"rt-thread\\components\\utilities\\ulog\\ulog.c",
"rt-thread\\components\\utilities\\ulog\\SConscript"
]
},
{
"name": "vconsole",
"path": "packages\\vconsole-latest",
"files": [
"packages\\vconsole-latest\\vconsole.c",
"packages\\vconsole-latest\\SConscript"
]
}
]
}

19
.vscode/settings.json vendored
View File

@ -27,7 +27,24 @@
"rgb.h": "c",
"main.h": "c",
"indicator_led.h": "c",
"drv_matrix_led.h": "c"
"drv_matrix_led.h": "c",
"init.h": "c",
"string.h": "c",
"at.h": "c",
"ADC.C": "cpp",
"PM2.5.C": "cpp",
"sensor.h": "c",
"status.h": "c",
"optional": "c",
"ostream": "c",
"ratio": "c",
"system_error": "c",
"array": "c",
"functional": "c",
"tuple": "c",
"type_traits": "c",
"utility": "c",
"random": "c"
},
// "cortex-debug.openocdPath": "d:/Develop/"
}

138
.vscode/tasks.json vendored
View File

@ -9,18 +9,39 @@
"args": [
"/d",
"/c",
"d:\\Develop\\env2\\tools\\bin\\env-init.bat && "
"d:\\DevTools\\env2\\tools\\bin\\env-init.bat && "
]
}
},
},
"tasks": [
{
"label": "更新软件包",
"type": "shell",
"command": "call ${workspaceFolder}\\tools\\pkgs_update.bat",
"problemMatcher": []
},
// {
// "label": "更新软件包",
// "type": "shell",
// "command": "call ${workspaceFolder}\\tools\\pkgs_update.bat",
// "problemMatcher": []
// },
// {
// "label": "MenuConfig",
// "type": "shell",
// "command": "start",
// "args": [
// "cmd.exe",
// "/d",
// "/c call ${workspaceFolder}\\tools\\mc.bat "
// ],
// "problemMatcher": []
// },
// {
// "label": "MenuConfig -s",
// "type": "shell",
// "command": "start",
// "args": [
// "cmd.exe",
// "/d /c call menuconfig -s"
// ],
// "problemMatcher": []
// },
{
"label": "PyConfig",
"type": "shell",
@ -34,7 +55,11 @@
"args": [
"-j8"
],
"options": {},
"options": {
"env": {
"MCU": "STM32F407ZG"
}
},
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
@ -50,15 +75,11 @@
"message": 5
}
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "编译(j1)",
"type": "shell",
"command": "scons",
"command": "${workspaceFolder}\\tools\\build-stm32.bat",
"args": [
"-j1"
],
@ -78,49 +99,6 @@
}
}
},
{
"label": "编译下载(j1)",
"type": "shell",
"command": "scons -j1 && copy /z ${workspaceFolder}\\rtthread.bin f:\\",
"args": [],
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"label": "编译下载(j8)",
"type": "shell",
// "command": "scons -j8 && pyocd flash -t stm32l431rctx ${workspaceFolder}/rt-thread.elf",
"command": "scons -j8 && copy /z ${workspaceFolder}\\rtthread.bin f:\\",
"args": [],
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"label": "清理",
"type": "shell",
@ -128,16 +106,6 @@
"args": [],
"problemMatcher": []
},
{
"label": "下载固件(pyocd)",
"type": "shell",
// "command": "pyocd flash -t stm32l431rctx ${workspaceFolder}/rt-thread.elf",
"command": "copy /z ${workspaceFolder}/rtthread.bin f:\\",
"args": [],
"args": [],
"problemMatcher": []
},
{
"label": "更新 C/C++ 路径",
"type": "shell",
@ -146,10 +114,9 @@
"problemMatcher": []
},
{
"label": "全部编译(j1)",
"label": "编译(j1)下载",
"type": "shell",
"command": "scons -c && cd ${workspaceFolder} && rm -fv *.elf *.hex *.bin *.map && scons -j1",
"args": [],
"command": "scons -j1 &&pyocd load -M under-reset -t stm32f407zg ${workspaceFolder}/rt-thread.elf",
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
@ -167,10 +134,9 @@
}
},
{
"label": "全部编译(j8)",
"label": "编译(j8)下载",
"type": "shell",
"command": "scons -c && cd ${workspaceFolder} && rm -fv *.elf *.hex *.bin *.map && scons -j8",
"args": [],
"command": "scons -j8 &&pyocd load -M under-reset -t stm32f407zg ${workspaceFolder}/rt-thread.elf",
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
@ -188,26 +154,18 @@
}
},
{
"label": "全部编译下载(j8)",
"label": "下载固件(pyocd)",
"type": "shell",
// "command": "scons -c && cd ${workspaceFolder} && rm -fv *.elf *.hex *.bin *.map && scons -j8 && pyocd flash -t stm32l431rctx ${workspaceFolder}/rt-thread.elf",
"command": "scons -c && cd ${workspaceFolder} && rm -fv *.elf *.hex *.bin *.map && scons -j8 && copy /z ${workspaceFolder}/rtthread.bin f:\\",
"command": "pyocd load -M under-reset -t stm32f407zg ${workspaceFolder}/rt-thread.elf",
"args": [],
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
"problemMatcher": []
},
{
"label": "重启(pyocd)",
"type": "shell",
"command": "pyocd reset -t stm32f407zg",
"args": [],
"problemMatcher": []
},
]
}

View File

@ -1,3 +1,16 @@
### 接线
#### 语音助手
* TX:PD8 (STM32板子上的,要 RX to TX)
* RX:PD9 (STM32板子上的,要 RX to TX)
#### ADC传感器
* pm25 PA1
* PM2.5 LED PG5
* 空气质量 PA5
* 压力 PA6
#### LED小灯
* PE12
# 红外遥控贪吃蛇/显示+上传温度等数据
![简略教程封面](/my_picture/简略教程封面.jpg)

163
applications/assistant.c Normal file
View File

@ -0,0 +1,163 @@
/*
* DMA 使
* uart_dma_sample
* uart_dma_sample uart1
* 使使
* "hello RT-Thread!"
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "status.h"
#define SAMPLE_UART_NAME "uart3" /* 串口设备名称 */
#define LOG_TAG "assistant"
#define DBG_LVL DBG_LOG
// #define DBG_LVL DBG_INFO
#define USE_LOG1
#define USE_LOG2
#define USE_LOG3
// #define USE_LOG4
#define USE_LOG5
// #define USE_LOG6
// #define USE_LOG_D
#include "logn.h"
/* 串口接收消息结构 */
struct rx_msg
{
rt_device_t dev;
rt_size_t size;
};
/* 串口设备句柄 */
static rt_device_t serial;
/* 消息队列控制块 */
static struct rt_messagequeue rx_mq;
/* 接收数据回调函数 */
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
struct rx_msg msg;
rt_err_t result;
msg.dev = dev;
msg.size = size;
result = rt_mq_send(&rx_mq, &msg, sizeof(msg));
if (result == -RT_EFULL)
{
/* 消息队列满 */
rt_kprintf("message queue full\n");
}
return result;
}
void assist_control(char *rx_buffer)
{
LOG3("assist_control CMD:%s",rx_buffer);
if (rt_strstr(rx_buffer, "cc")!=RT_NULL||rt_strstr(rx_buffer, "3")!=RT_NULL)
{
fan_status=1;
fan_on();
rt_kprintf("加大抽风\n");
}
else if (rt_strstr(rx_buffer, "dd")!=RT_NULL||rt_strstr(rx_buffer, "4")!=RT_NULL)
{
fan_status=0;
fan_off();
rt_kprintf("关闭抽风\n");
}
else if (rt_strstr(rx_buffer, "ee")!=RT_NULL||rt_strstr(rx_buffer, "1")!=RT_NULL)
{
light_status=1;
light_on();
rt_kprintf("开灯\n");
}
else if (rt_strstr(rx_buffer, "ff")!=RT_NULL||rt_strstr(rx_buffer, "2")!=RT_NULL)
{
light_status=0;
light_off();
rt_kprintf("关灯\n");
}
else if (rt_strstr(rx_buffer, "bb")!=RT_NULL||rt_strstr(rx_buffer, "2")!=RT_NULL)
{
beep_on();
}
}
static void serial_thread_entry(void *parameter)
{
struct rx_msg msg;
rt_err_t result;
rt_uint32_t rx_length;
static char rx_buffer[BSP_UART3_RX_BUFSIZE + 1];
while (1)
{
rt_memset(&msg, 0, sizeof(msg));
/* 从消息队列中读取消息 */
result = rt_mq_recv(&rx_mq, &msg, sizeof(msg), RT_WAITING_FOREVER);
if (result > 0)
{
/* 从串口读取数据 */
rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size);
rx_buffer[rx_length] = '\0';
assist_control(rx_buffer);
/* 打印数据 */
rt_kprintf("%s\n", rx_buffer);
}
}
}
void serial_send(char *str)
{
rt_device_write(serial, 0, str, (sizeof(str) - 1));
}
int aiv_init(void)
{
LOG5("VOICE assistant START");
rt_err_t ret = RT_EOK;
char uart_name[RT_NAME_MAX];
static char msg_pool[256];
char str[] = "hello RT-Thread!\r\n";
rt_strcpy(uart_name, SAMPLE_UART_NAME);
/* 查找串口设备 */
serial = rt_device_find(uart_name);
if (!serial)
{
rt_kprintf("find %s failed!\n", uart_name);
return RT_ERROR;
}
/* 初始化消息队列 */
rt_mq_init(&rx_mq, "rx_mq",
msg_pool, /* 存放消息的缓冲区 */
sizeof(struct rx_msg), /* 一条消息的最大长度 */
sizeof(msg_pool), /* 存放消息的缓冲区大小 */
RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */
/* 以 DMA 接收及轮询发送方式打开串口设备 */
rt_device_open(serial, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
/* 设置接收回调函数 */
rt_device_set_rx_indicate(serial, uart_input);
/* 发送字符串 */
// rt_device_write(serial, 0, str, (sizeof(str) - 1));
/* 创建 serial 线程 */
rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);
/* 创建成功则启动线程 */
if (thread != RT_NULL)
{
rt_thread_startup(thread);
}
else
{
ret = RT_ERROR;
}
return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(aiv_init, siri start);

2
applications/assistant.h Normal file
View File

@ -0,0 +1,2 @@
void serial_send(char *str);
void assist_control(char *rx_buffer);

View File

@ -1,10 +1,13 @@
#include "sim.h"
#include "sensor.h"
#include <rtthread.h>
#include <rthw.h>
#include <wlan_mgnt.h>
#include <wlan_cfg.h>
#include <wlan_prot.h>
#include <dev_wlan_mgnt.h>
#include <dev_wlan_cfg.h>
#include <dev_wlan_prot.h>
#include <ap3216c.h>
#include "my_func.h"
#include "status.h"
static int board_init(void)
{
@ -47,17 +50,42 @@ static int app_init(void)
}
INIT_APP_EXPORT(app_init);
// extern int wifi_join(int argc, char *argv[]);
extern int aiv_init(void);
extern int mot_init(void);
extern int last_stop;
int main_init(void)
{
char str[] = "wifi join Dong abcd07691234";
my_round(20);
system(str);
// rt_thread_mdelay(18000);
// char *argv[] = {"wifi", "join", "Dong", "abcd07691234"};
// wifi_join(4, argv);
// char *ssid = "Dong";
// char *key = "abcd07691234";
// rt_wlan_connect(ssid, key);
return 0;
sim_dev_init();
ath_init();
wla_init();
// if (wlan_connected == RT_EOK)
// {
// last_stop = 1;
// mqt_init();
// }
ap3_init();
inf_init();
cdc_init();
tst_init(); // 不知道为什么不能在mqtt_init()之前,不然报错
serial_init();
mot_init();
aiv_init();
sensor_init();
status_init();
// led_init();
}
MSH_CMD_EXPORT_ALIAS(main_init, myproject, run my project);

218
applications/logn.h Normal file
View File

@ -0,0 +1,218 @@
#ifndef __LOGN_H___
#define __LOGN_H___
#ifdef __cplusplus
extern "C"
{
#endif
#define LOGN_PRINTF(...) rt_kprintf(__VA_ARGS__)
#if defined(RT_USING_ULOG)
#include <ulog.h>
#else
#define LOG_LVL_ERROR 0
#define LOG_LVL_WARNING 1
#define LOG_LVL_INFO 2
#define LOG_LVL_DBG 3
#ifdef LOG_TAG
#undef DBG_TAG
#define DBG_TAG LOG_TAG
#else
#define LOG_TAG DGB_TAG
#endif // LOG_TAG
#ifdef RT_DEBUG
#ifdef LOG_LVL
#undef DBG_LVL
#define DBG_LVL LOG_LVL
#else
#define LOG_LVL DBG_LVL
#endif // LOG_LVL
#include <rtdbg.h>
#else
#define LOGN_ENABLE
#endif // RT_DEBUG
#endif // !RT_USING_ULOG
#if (LOG_LVL < LOG_LVL_DBG)
#define LOG0(fmt, ...)
#define LOG1(fmt, ...)
#define LOG2(fmt, ...)
#define LOG3(fmt, ...)
#define LOG4(fmt, ...)
#define LOG5(fmt, ...)
#define LOG6(fmt, ...)
#define LOG7(fmt, ...)
#define LOG10(fmt, ...)
#define LOG11(fmt, ...)
#define LOG12(fmt, ...)
#define LOG13(fmt, ...)
#define LOG14(fmt, ...)
#define LOG15(fmt, ...)
#define LOG16(fmt, ...)
#define LOG17(fmt, ...)
#else
/**
* CSI(Control Sequence Introducer/Initiator) sign
* more information on https://en.wikipedia.org/wiki/ANSI_escape_code
*/
#define CSI_START "\033["
#define CSI_END "\033[0m"
/* output log front color */
#define F_BLACK "30m"
#define F_RED "31m"
#define F_GREEN "32m"
#define F_YELLOW "33m"
#define F_BLUE "34m"
#define F_MAGENTA "35m"
#define F_CYAN "36m"
#define F_WHITE "37m"
/* output log backgroup color */
#define B_BLACK "40m"
#define B_RED "41m"
#define B_GREEN "42m"
#define B_YELLOW "43m"
#define B_BLUE "44m"
#define B_MAGENTA "45m"
#define B_CYAN "46m"
#define B_WHITE "47m"
// 亮前景色
#define F_GRAY "90m"
#define F_B_BLACK "90m"
#define F_B_RED "91m"
#define F_B_GREEN "92m"
#define F_B_YELLOW "93m"
#define F_B_BLUE "94m"
#define F_B_MAGENTA "95m"
#define F_B_CYAN "96m"
#define F_B_WHITE "97m"
// 亮背景色
#define B_GRAY "100m"
#define B_B_BLACK "100m"
#define B_B_RED "101m"
#define B_B_GREEN "102m"
#define B_B_YELLOW "103m"
#define B_B_BLUE "104m"
#define B_B_MAGENTA "105m"
#define B_B_CYAN "106m"
#define B_B_WHITE "107m"
#define SET_COLOR(c, s) CSI_START c s CSI_END
#ifdef RT_USING_ULOG
#define logn_line(color_n, fmt, ...) ulog_d(LOG_TAG, SET_COLOR(color_n, fmt), ##__VA_ARGS__)
#else // !RT_USING_ULOG
#if (DBG_LEVEL >= DBG_LOG || defined(LOGN_ENABLE))
#ifndef RT_DEBUG
#define dbg_log_line(lvl, color_n, fmt, ...) LOGN_PRINTF(SET_COLOR(color_n, lvl) fmt "\n", ##__VA_ARGS__);
#endif // !RT_DEBUG
#define logn_line(color_n, fmt, ...) dbg_log_line("N", 0, SET_COLOR(color_n, fmt), ##__VA_ARGS__)
#else // !(DBG_LEVEL >= DBG_LOG)
#define logn_line(...)
#endif // (DBG_LEVEL >= DBG_LOG)
#endif // RT_USING_ULOG
#ifdef USE_LOG0
#define LOG0(fmt, ...) logn_line("30;100m", fmt, ##__VA_ARGS__)
#else
#define LOG0(fmt, ...)
#endif // USE_LOG0
#ifdef USE_LOG1
#define LOG1(fmt, ...) logn_line(F_RED, fmt, ##__VA_ARGS__)
#else
#define LOG1(fmt, ...)
#endif // USE_LOG1
#ifdef USE_LOG2
#define LOG2(fmt, ...) logn_line(F_GREEN, fmt, ##__VA_ARGS__)
#else
#define LOG2(fmt, ...)
#endif // USE_LOG2
#ifdef USE_LOG3
#define LOG3(fmt, ...) logn_line(F_YELLOW, fmt, ##__VA_ARGS__)
#else
#define LOG3(fmt, ...)
#endif // USE_LOG3
#ifdef USE_LOG4
#define LOG4(fmt, ...) logn_line(F_BLUE, fmt, ##__VA_ARGS__)
#else
#define LOG4(fmt, ...)
#endif // USE_LOG4
#ifdef USE_LOG5
#define LOG5(fmt, ...) logn_line(F_MAGENTA, fmt, ##__VA_ARGS__)
#else
#define LOG5(fmt, ...)
#endif // USE_LOG5
#ifdef USE_LOG6
#define LOG6(fmt, ...) logn_line(F_CYAN, fmt, ##__VA_ARGS__)
#else
#define LOG6(fmt, ...)
#endif // USE_LOG6
#ifdef USE_LOG7
#define LOG7(fmt, ...) logn_line(F_WHITE, fmt, ##__VA_ARGS__)
#else
#define LOG7(fmt, ...)
#endif // USE_LOG7
#ifdef USE_LOG10
#define LOG10(fmt, ...) logn_line(F_GRAY, fmt, ##__VA_ARGS__)
#else
#define LOG10(fmt, ...)
#endif // USE_LOG10
#ifdef USE_LOG11
#define LOG11(fmt, ...) logn_line(F_B_RED, fmt, ##__VA_ARGS__)
#else
#define LOG11(fmt, ...)
#endif // USE_LOG11
#ifdef USE_LOG12
#define LOG12(fmt, ...) logn_line(F_B_GREEN, fmt, ##__VA_ARGS__)
#else
#define LOG12(fmt, ...)
#endif // USE_LOG12
#ifdef USE_LOG13
#define LOG13(fmt, ...) logn_line(F_B_YELLOW, fmt, ##__VA_ARGS__)
#else
#define LOG13(fmt, ...)
#endif // USE_LOG13
#ifdef USE_LOG14
#define LOG14(fmt, ...) logn_line(F_B_BLUE, fmt, ##__VA_ARGS__)
#else
#define LOG14(fmt, ...)
#endif // USE_LOG14
#ifdef USE_LOG15
#define LOG15(fmt, ...) logn_line(F_B_MAGENTA, fmt, ##__VA_ARGS__)
#else
#define LOG15(fmt, ...)
#endif // USE_LOG15
#ifdef USE_LOG16
#define LOG16(fmt, ...) logn_line(F_B_CYAN, fmt, ##__VA_ARGS__)
#else
#define LOG16(fmt, ...)
#endif // USE_LOG16
#ifdef USE_LOG17
#define LOG17(fmt, ...) logn_line(F_B_WHITE, fmt, ##__VA_ARGS__)
#else
#define LOG17(fmt, ...)
#endif // USE_LOG17
#ifndef USE_LOG_D
#undef LOG_D
#define LOG_D(...)
#endif // USE_LOG_D
#endif
#define IS_USE_LOGN(n) ((defined(USE_LOG##n)) && (LOG_LVL >= LOG_LVL_DBG))
#ifdef __cplusplus
}
#endif
#endif // !__LOGN_H___

View File

@ -39,9 +39,9 @@ int main(void)
system("snake");
// rt_wlan_config_autoreconnect(RT_TRUE);
// rt_wlan_connect("Dong", "abcd07691234");
rt_wlan_connect("as", "88888888");
rt_wlan_connect("as", "88888888");
system("myproject");
// rt_wlan_connect("as", "07691234");
// wlan_connected=rt_wlan_connect("as", "07691234");
// system("myproject");
// system("mqtt");
mytime();

119
applications/motor.c Normal file
View File

@ -0,0 +1,119 @@
#include <rtthread.h>
#include <rtdevice.h>
#include <drv_gpio.h>
#define LOG_TAG "app.robot"
#define LOG_LVL LOG_LVL_DBG
// #define LOG_LVL LOG_LVL_INFO
#define USE_LOG1
#define USE_LOG2
#define USE_LOG3
#define USE_LOG4
#define USE_LOG5
#define USE_LOG6
#define USE_LOG7
#define USE_LOG12
#define USE_LOG_D
#include "logn.h"
#define MOTOR_PWM_DEV_NAME "pwm1"
#define MOTOR_PWM_DEV_CHANNEL 1
#define MOTOR2_PWM_DEV_NAME "pwm1"
#define MOTOR2_PWM_DEV_CHANNEL 1
struct rt_device_pwm *motor_dev; // pwm设备句柄
rt_uint32_t period = 100000000; // 单位us 向左6位变毫秒 10s
// rt_uint32_t pulse = 1000000;
#define PIN_MOTOR2 GET_PIN(B, 2)
int motor1=PIN_HIGH;
/**
* @brief (num)%
*
* @param num (0~100).
*
*/
void motor_speed(int num)
{
rt_pwm_set(motor_dev, MOTOR_PWM_DEV_CHANNEL, period, (100-num)/ 100 * period );
rt_pin_write(PIN_MOTOR2, num>0?PIN_LOW:PIN_HIGH);
}
int mot_init(void)
{
rt_pin_mode(PIN_MOTOR2, PIN_MODE_OUTPUT);
rt_pin_write(PIN_MOTOR2, PIN_HIGH);
motor_dev = (struct rt_device_pwm *)rt_device_find(MOTOR_PWM_DEV_NAME);
if (motor_dev == RT_NULL)
{
rt_kprintf("motor run failed! can't find %s device!\n", MOTOR_PWM_DEV_NAME);
return RT_ERROR;
}
/* 设置PWM周期和脉冲宽度默认值 */
motor_speed(0);
rt_pwm_enable(motor_dev, MOTOR_PWM_DEV_CHANNEL);
LOG1("motor init success!");
}
void motor_set(int argc, char **argv)
{
// if(motor1== PIN_HIGH)
// {
// rt_pin_write(PIN_MOTOR1, PIN_LOW);
// motor1=PIN_LOW;
// }
// else
// {
// rt_pin_write(PIN_MOTOR1, PIN_HIGH);
// motor1=PIN_HIGH;
// }
if (argc == 2)
{
motor_speed(atoi(argv[1]));
}
LOG5("motor speed:%d",atoi(argv[1]));
}
MSH_CMD_EXPORT_ALIAS(motor_set,motor, motor_set speed 0~100);
// struct rt_device_pwm *motor_dev; // pwm设备句柄
// rt_uint32_t period2 = 10000000; // 单位us 向左6位变毫秒 10ms2
// /**
// * @brief 电机速度控制(num)%
// *
// * @param num 百分比数字(0~100).
// *
// */
// void motor2_speed(int num)
// {
// rt_pwm_set(motor_dev, MOTOR2_PWM_DEV_CHANNEL, period2, num * period2 / 100);
// }
// int mo2_init(void)
// {
// motor_dev = (struct rt_device_pwm *)rt_device_find(MOTOR2_PWM_DEV_NAME);
// if (motor_dev == RT_NULL)
// {
// rt_kprintf("motor2 run failed! can't find %s device!\n", MOTOR2_PWM_DEV_NAME);
// return RT_ERROR;
// }
// /* 设置PWM周期和脉冲宽度默认值 */
// motor_speed(0);
// }
// void motor2_set(int argc, char **argv)
// {
// if (argc == 2)
// {
// motor2_speed(atoi(argv[1]));
// }
// LOG5("motor2 speed:%d",atoi(argv[1]));
// }
// MSH_CMD_EXPORT_ALIAS(motor2_set,motor2, motor2_set speed 0~100);

2
applications/motor.h Normal file
View File

@ -0,0 +1,2 @@
void motor_speed(int num);
int mot_init(void);

View File

@ -10,6 +10,7 @@
//串口
rt_device_t serial;
char str[] = "forward\n";
int wlan_connected=RT_FALSE;
extern char tmp[];
void lcd_black(int x, int y)

View File

@ -9,6 +9,8 @@
//串口
extern rt_device_t serial;
extern char str[];
extern int wlan_connected;
extern float Humi, Temp;
void mytime();
void greattime();
@ -19,12 +21,12 @@ void lcd_black(int x, int y);
void lcd_white(int x, int y);
void snake_address(int x, int y, int r, const rt_uint16_t da);
// typedef int QDataType;
// typedef struct QListNode
// {
// QDataType data;
// struct QListNode* next;
// } QueueNode;
void ath_init(void);
void wla_init(void);
void serial_init(void);
void mqt_init(void);
int ap3_init(void);
void snk_init(void);
void cdc_init(void);
void inf_init(void);
void tst_init(void);

View File

@ -37,7 +37,7 @@ void snake_compare(rt_uint8_t key, rt_uint8_t repeat)
const char *str ="forward\n";
// rt_strncpy(str,"forward\n",10);
// *str = ;
rt_device_write(serial, 0, str, rt_strlen(str));
//rt_device_write(serial, 0, str, rt_strlen(str));
LOG_I("str=%s",str);
}
@ -49,7 +49,7 @@ void snake_compare(rt_uint8_t key, rt_uint8_t repeat)
// *str = "left\n";
const char *str = "left\n";
// rt_strncpy(str,"left\n",10);
rt_device_write(serial, 0, str, rt_strlen(str));
//rt_device_write(serial, 0, str, rt_strlen(str));
LOG_I("str=%s",str);
}
@ -60,7 +60,7 @@ void snake_compare(rt_uint8_t key, rt_uint8_t repeat)
rt_atomic_store(&now_direction, 2);
const char *str = "back\n";
// rt_strncpy(str,"back\n",10);
rt_device_write(serial, 0, str, rt_strlen(str));
//rt_device_write(serial, 0, str, rt_strlen(str));
LOG_I("str=%s",str);
}
@ -71,7 +71,7 @@ void snake_compare(rt_uint8_t key, rt_uint8_t repeat)
rt_atomic_store(&now_direction, 3);
// rt_strncpy(str,"right\n",10);
const char *str = "right\n";
rt_device_write(serial, 0, str, rt_strlen(str));
//rt_device_write(serial, 0, str, rt_strlen(str));
LOG_I("str=%s",str);
}
// 加速
@ -79,21 +79,21 @@ void snake_compare(rt_uint8_t key, rt_uint8_t repeat)
{
const char *str = "Speedup";
rt_device_write(serial, 0, str, rt_strlen(str));
//rt_device_write(serial, 0, str, rt_strlen(str));
}
// 加速
if (rt_strcmp(tmp, "28") == 0 )
{
const char *str = "Speeddown";
rt_device_write(serial, 0, str, rt_strlen(str));
//rt_device_write(serial, 0, str, rt_strlen(str));
}
// 加速
if (rt_strcmp(tmp, "A8") == 0 )
{
const char *str = "Toggle";
rt_device_write(serial, 0, str, rt_strlen(str));
//rt_device_write(serial, 0, str, rt_strlen(str));
}
// 菜单(切换页面)
@ -113,7 +113,7 @@ void snake_compare(rt_uint8_t key, rt_uint8_t repeat)
const char *str = "OK\n";
// rt_strncpy(str,"OK\n",10);
LOG_I("str=%s",str);
rt_device_write(serial, 0, str, rt_strlen(str));
//rt_device_write(serial, 0, str, rt_strlen(str));
if (page_chosen == 4&& page_stop == 0)
{
// rt_event_send(&my_event, EVENT_MQTT_ENABLE);

View File

@ -15,8 +15,10 @@
#include "infrared.h"
#include <ulog.h>
#include "my_func.h"
#include "indicator_led.h"
#include "sensor.h"
#include "assistant.h"
#include "cJSON.h"
#include "RyanJson.h"
#define THREAD_PRIORITY 25
#define THREAD_STACK_SIZE 4096
#define THREAD_TIMESLICE 5
@ -30,6 +32,7 @@ rt_thread_t Test_Thread = RT_NULL;
rt_thread_t CDC_Thread = RT_NULL;
rt_thread_t Serial_Thread = RT_NULL;
rt_thread_t LED_Thread = RT_NULL;
rt_thread_t wlan_connect_tid = RT_NULL;
char DEMO_PRODUCT_KEY[IOTX_PRODUCT_KEY_LEN + 1] = {0};
char DEMO_DEVICE_NAME[IOTX_DEVICE_NAME_LEN + 1] = {0};
@ -44,6 +47,9 @@ int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN]);
uint64_t HAL_UptimeMs(void);
int HAL_Snprintf(char *str, const int len, const char *fmt, ...);
#define WLAN_NAME "as"
#define WLAN_PASSWORD "07691234"
// 定义接受文件内容的缓冲区
char buffer[1026] = {};
char tmp[1026];
@ -52,7 +58,8 @@ rt_atomic_t page_chosen = 1;
rt_atomic_t page_first = 1;
rt_atomic_t page_stop = 0;
rt_atomic_t last_stop = 0;
rt_atomic_t mqtt_enable = 0;
rt_atomic_t last_connect_status = -RT_ERROR;
rt_atomic_t mqtt_enable = 1;
void *pclient = NULL;
@ -114,6 +121,14 @@ static void example_message_arrive(void *pcontext, void *pclient, iotx_mqtt_even
EXAMPLE_TRACE("Topic : %.*s", topic_info->topic_len, topic_info->ptopic);
EXAMPLE_TRACE("Payload: %.*s", topic_info->payload_len, topic_info->payload);
EXAMPLE_TRACE("\n");
char str_tmp[32];
RyanJson_t jsonRoot = RyanJsonParse(topic_info->payload);
int cmdkey= RyanJsonGetIntValue(RyanJsonGetObjectByKey(jsonRoot, "KEY"));
rt_sprintf(str_tmp, "%d", cmdkey);
assist_control(str_tmp);
break;
default:
break;
@ -167,9 +182,12 @@ void show_lcd()
{
lcd_y = 10;
easy_show_lcd("Temperature:", Temp);
easy_show_lcd("Humidity:", Humi);
easy_show_lcd("Brightness:(lux)", brightness);
easy_show_lcd("Ps data:", (float)ps_data);
easy_show_lcd("Air quality:", ADC_air);
easy_show_lcd("PM2.5:", ADC_PM25);
easy_show_lcd("Pressure:",ADC_pressure);
// easy_show_lcd("Humidity:", Humi);
// easy_show_lcd("Brightness:(lux)", brightness);
// easy_show_lcd("Ps data:", (float)ps_data);
// lcd_show_string(10, plus_lcd_y(10), 24, "Temperature:");
// rt_sprintf(tmp, "%f", Temp);
// lcd_show_string(10, plus_lcd_y(24), 32, tmp);
@ -257,24 +275,42 @@ void tmp_payload(void)
my_round(20);
page_first = 0;
}
if (!mqtt_enable)
if (!wlan_connected)
{
lcd_show_string(240 / 2 - 24 * 2, 240 / 2 + 12, 32, "disable");
if (last_stop)
{
last_stop = 0;
IOT_MQTT_Destroy(&pclient);
rt_thread_delete(MQTT_Thread);
}
lcd_show_string(240 / 2 - 24 * 2, 240 / 2 + 12, 32, "disconnect");
// if (last_stop)
// {
// last_stop = 0;
// IOT_MQTT_Destroy(&pclient);
// rt_thread_delete(MQTT_Thread);
// }
}
else
{
lcd_show_string(240 / 2 - 24 * 2, 240 / 2 + 12, 32, "enable ");
if (mqtt_enable && !last_stop)
{
last_stop = 1;
mqt_init();
}
lcd_show_string(240 / 2 - 24 * 2, 240 / 2 + 12, 32, "connected ");
// if (mqtt_enable && !last_stop && wlan_connected == RT_EOK)
// {
// last_stop = 1;
// mqt_init();
// }
// if (wlan_connected == RT_EOK)
// {
// lcd_show_string(240 / 2 - 24 * 2, 240 / 2 + 12 + 32, 32, "connect");
// // if (last_connect_status != RT_EOK)
// // {
// // mqt_init();
// // }
// }
// else
// {
// lcd_show_string(240 / 2 - 24 * 2, 240 / 2 + 12 + 32, 32, "disconnect");
// // if (last_connect_status == RT_EOK)
// // {
// // IOT_MQTT_Destroy(&pclient);
// // rt_thread_delete(MQTT_Thread);
// // }
// }
// last_connect_status = wlan_connected;
}
}
if (ps_data > 1022)
@ -287,7 +323,7 @@ void tmp_payload(void)
page_chosen = (page_chosen % PAGE_MAX) + 1;
page_first = 1;
}
rt_sprintf(tmp, "{\"params\":{\"temperature\":%.2f,\"humidity\":%.2f,\"LightLux\":%.2f,\"Psdata\":%d,\"Snakelen\":%d}}", Temp, Humi, brightness, ps_data, snake_len);
rt_sprintf(tmp, "{\"params\":{\"temperature\":%.2f,\"humidity\":%.2f,\"LightLux\":%.2f,\"Psdata\":%d,\"Snakelen\":%d,\"Air\":%.2f,\"Pressure\":%.2f,\"PM25\":%.2f}}", Temp, Humi, brightness, ps_data, snake_len,ADC_air,ADC_pressure,ADC_PM25);
return;
}
void test_lcd()
@ -304,18 +340,12 @@ void test_lcd()
MSH_CMD_EXPORT(test_lcd, run my project);
static int example_publish(void *handle)
{
// tmp_payload();
int res = 0;
const char *fmt = "/sys/%s/%s/thing/event/property/post";
// /k1lyriw1yGj/${deviceName}/user/get
char *topic = NULL;
int topic_len = 0;
char *payload = tmp;
// strcpy(payload,tmp_payload());
// rt_kprintf("payload:%s\n",payload);
topic_len = rt_strlen(fmt) + rt_strlen(DEMO_PRODUCT_KEY) + rt_strlen(DEMO_DEVICE_NAME) + 1;
// topic = HAL_Malloc(topic_len);
topic = rt_malloc(topic_len);
if (topic == NULL)
{
@ -323,14 +353,12 @@ static int example_publish(void *handle)
return -1;
}
memset(topic, 0, topic_len);
// HAL_Snprintf(topic, topic_len, fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);
rt_snprintf(topic, topic_len, fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);
res = IOT_MQTT_Publish_Simple(0, topic, IOTX_MQTT_QOS0, payload, rt_strlen(payload));
if (res < 0)
{
EXAMPLE_TRACE("publish failed, res = %d", res);
// HAL_Free(topic);
rt_free(topic);
return -1;
}
@ -377,7 +405,7 @@ static void mqtt_example_main(void *parameter)
while (1)
{
if (0 == loop_cnt % 20)
if (0 == loop_cnt % 5)
{
example_publish(pclient);
}
@ -408,7 +436,41 @@ void cdc_entry(void *parameter)
rt_thread_mdelay(500);
}
}
void wlan_connect_thread(void *parameter)
{
(void *)parameter;
wlan_connected=RT_FALSE;
rt_wlan_connect(WLAN_NAME,WLAN_PASSWORD);
rt_wlan_connect(WLAN_NAME,WLAN_PASSWORD);
// while(rt_wlan_connect(WLAN_NAME,WLAN_PASSWORD)!= RT_EOK)
// {
// rt_thread_mdelay(2000);
// }
rt_wlan_config_autoreconnect(RT_TRUE);
while (1)
{
if (rt_wlan_is_connected() == RT_TRUE)
{
// if(!wlan_connected)
{
wlan_connected = RT_TRUE;
// rt_wlan_connect(WLAN_NAME,WLAN_PASSWORD);
rt_thread_mdelay(5000);
mqt_init();
}
}
// else
// {
// if(wlan_connected)
// {
// wlan_connected = RT_FALSE;
// IOT_MQTT_Destroy(&pclient);
// rt_thread_delete(MQTT_Thread);
// }
// }
rt_thread_mdelay(5000);
}
}
// /* 用于接收消息的信号量 */
// static struct rt_semaphore rx_sem;
// /* 接收数据回调函数 */
@ -422,20 +484,20 @@ void cdc_entry(void *parameter)
static void serial_thread_entry(void *parameter)
{
serial = RT_NULL;
char buf[] = "hello rt-thread!\r\n";
serial = rt_device_find("uart3");
// serial = RT_NULL;
// char buf[] = "hello rt-thread!\r\n";
// serial = rt_device_find("uart3");
if (serial)
rt_device_open(serial, RT_DEVICE_FLAG_RDWR);
else
return;
// if (serial)
// rt_device_open(serial, RT_DEVICE_FLAG_RDWR);
// else
// return;
while (1)
{
rt_device_write(serial, 0, buf, rt_strlen(buf));
rt_thread_mdelay(500);
}
// while (1)
// {
// rt_device_write(serial, 0, buf, rt_strlen(buf));
// rt_thread_mdelay(500);
// }
// char ch[105];
// while (1)
@ -462,6 +524,20 @@ void ath_init(void)
return;
}
}
void wla_init(void)
{
wlan_connect_tid = rt_thread_create("wlanas", wlan_connect_thread, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (wlan_connect_tid != RT_NULL)
{
rt_thread_startup(wlan_connect_tid);
}
else
{
rt_kprintf("wlan_connect_thread Create Failed!\n");
}
}
MSH_CMD_EXPORT_ALIAS(wla_init, wla_init, "Infrared");
void serial_init(void)
{
// // 初始化设备
@ -505,7 +581,7 @@ void serial_init(void)
}
void mqt_init(void)
{
MQTT_Thread = rt_thread_create("MTQQ_Thread", mqtt_example_main, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
MQTT_Thread = rt_thread_create("MQTT_Thread", mqtt_example_main, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (MQTT_Thread != RT_NULL)
{
@ -591,6 +667,45 @@ void tst_init(void)
}
}
MSH_CMD_EXPORT_ALIAS(tst_init, no_mqtt, "Infrared");
// extern int aiv_init(void);
// extern int mot_init(void);
// // extern int last_stop;
// int main_init(void)
// {
// my_round(20);
// sim_dev_init();
// ath_init();
// wla_init();
// if (wlan_connected == RT_EOK)
// {
// last_stop = 1;
// mqt_init();
// }
// ap3_init();
// inf_init();
// cdc_init();
// tst_init(); // 不知道为什么不能在mqtt_init()之前,不然报错
// serial_init();
// mot_init();
// aiv_init();
// // sensor_init();
// led_init();
// }
// void evn_init(void)
// {
// if(rt_event_create("my_event2", RT_IPC_FLAG_FIFO) != RT_EOK)
@ -598,27 +713,3 @@ MSH_CMD_EXPORT_ALIAS(tst_init, no_mqtt, "Infrared");
// rt_kprintf("Create Event Failed!\n");
// }
// }
void my_project(void)
{
// /* 选择 NEC 解码器 */
// ir_select_decoder("nec");
// evn_init();
ath_init();
// mqt_init();
ap3_init();
inf_init();
cdc_init();
tst_init(); // 不知道为什么不能在mqtt_init()之前,不然报错
serial_init();
led_init();
}
MSH_CMD_EXPORT_ALIAS(my_project, myproject, run my project);

198
applications/sensor.c Normal file
View File

@ -0,0 +1,198 @@
#define ADC_DEV_NAME "adc1" /* ADC 设备名称 */
#define ADC_CHANNEL_AIR 5 /* ADC 通道 */
#define ADC_CHANNEL_PM25 1 /* ADC 通道 */
#define ADC_CHANNEL_PRESS 6 /* ADC 通道 */
#define REFER_VOLTAGE 330 /* 参考电压 3.3V,数据精度乘以100保留2位小数*/
#define CONVERT_BITS (1 << 12) /* 转换位数为12位 */
#include <rtthread.h>
#include <rtdevice.h>
#include <drv_gpio.h>
#include "status.h"
#include "math.h"
#include "my_func.h"
rt_thread_t Sensor_Thread = RT_NULL;
#define THREAD_PRIORITY 25
#define THREAD_STACK_SIZE 4096
#define THREAD_TIMESLICE 5
#define PM25_READ_TIMES 20
#define GPIO_PIN GET_PIN(G, 5)
#define LOG_TAG "sensor"
#define DBG_LVL DBG_LOG
// #define DBG_LVL DBG_INFO
#define USE_LOG1
#define USE_LOG2
#define USE_LOG3
// #define USE_LOG4
#define USE_LOG5
// #define USE_LOG6
// #define USE_LOG_D
#include "logn.h"
float ADC_air;
float ADC_PM25;
float ADC_pressure;
#define MQ2_READ_TIMES 10
float Air_Read()
{
rt_adc_device_t adc_dev; /* ADC 设备句柄 */
rt_uint32_t value, vol;
/* 查找设备 */
adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
/* 使能设备 */
rt_adc_enable(adc_dev, ADC_CHANNEL_AIR);
/* 读取采样值 */
value = rt_adc_read(adc_dev, ADC_CHANNEL_AIR);
return value;
}
float MQ2_GetData_PPM(void)
{
float tempData = 0;
for (uint8_t i = 0; i < MQ2_READ_TIMES; i++)
{
tempData += Air_Read();
;
rt_thread_mdelay(5);
;
}
tempData /= MQ2_READ_TIMES;
float Vol = (tempData * 5 / 4096);
float RS = (5 - Vol) / (Vol * 0.5);
float R0 = 6.64;
float ppm = pow(11.5428 * R0 / RS, 0.6549f);
return ppm;
}
float PM25_Read()
{
rt_adc_device_t adc_dev; /* ADC 设备句柄 */
rt_uint32_t value, vol;
/* 查找设备 */
adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
/* 使能设备 */
rt_adc_enable(adc_dev, ADC_CHANNEL_PM25);
/* 读取采样值 */
value = rt_adc_read(adc_dev, ADC_CHANNEL_PM25);
return value;
}
float Pressure_Read()
{
rt_adc_device_t adc_dev; /* ADC 设备句柄 */
rt_uint32_t value, vol;
/* 查找设备 */
adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
/* 使能设备 */
rt_adc_enable(adc_dev, ADC_CHANNEL_PRESS);
/* 读取采样值 */
value = rt_adc_read(adc_dev, ADC_CHANNEL_PRESS);
return value;
}
float PM25_GetData(void)
{
int ADCVal;
int dustVal = 0;
float Voltage;
rt_pin_write(GPIO_PIN, PIN_HIGH); // 置1 开启内部LED
rt_hw_us_delay(280);
ADCVal = PM25_Read();
rt_hw_us_delay(25);
rt_pin_write(GPIO_PIN, PIN_LOW); // 置0 关闭内部LED
rt_hw_us_delay(9680); // 需要脉宽比0.32ms/10ms的PWM信号驱动传感器中的LED
Voltage = 3.3f * ADCVal / 4096.f * 2; // 获得AO输出口的电压值
dustVal = (0.17 * Voltage - 0.1) * 1000; // 乘以1000单位换成ug/m3//
if (dustVal < 0)
dustVal = 0; // 限位//
if (dustVal > 500)
dustVal = 500;
return dustVal;
}
/**
* @brief
* @param
* @retval
*/
float Get_PM25_Average_Data(void)
{
float temp_val = 0;
float t;
for (t = 0; t < PM25_READ_TIMES; t++) // #define PM25_READ_TIMES 20 定义读取次数,读这么多次,然后取平均值
{
temp_val += PM25_GetData(); // 读取ADC值
rt_thread_mdelay(5);
}
temp_val /= PM25_READ_TIMES; // 得到平均值
return temp_val; // 返回算出的ADC平均值
}
int warning_range(char *str, float value, float min, float max)
{
if (value < min)
{
LOG5("%s's value:%f is too low\n", str, value);
danger_status();
return 1;
}
else if (value > max)
{
LOG5("%s's value:%f is too high\n", str, value);
danger_status();
return 1;
}
return 0;
}
int cnt_warning = 0;
static void sensor_thread(void *parameter)
{
while (1)
{
ADC_air = MQ2_GetData_PPM(); // 空气质量传感器数值 0-4095 表示从差到优秀
ADC_PM25 = Get_PM25_Average_Data(); // PM2.5传感器数值0-500 表示从优秀到查差
ADC_pressure = Pressure_Read(); // 压力传感器数值 0-4095 表示从差到优秀
// LOG5("ADC_air:%f,ADC_PM25:%f,ADC_pressure:%f", ADC_air, ADC_PM25, ADC_pressure);
cnt_warning = 0;
cnt_warning += warning_range("air", ADC_air, 0, 4095);
cnt_warning += warning_range("PM25", ADC_PM25, 0, 500);
cnt_warning += warning_range("pressure", ADC_pressure, 3500, 4095);
cnt_warning+= warning_range("temperature", Temp, 0, 50);
if (cnt_warning == 0)
{
normal_status();
}
rt_thread_mdelay(500);
}
}
void sensor_init(void)
{
Sensor_Thread = rt_thread_create("sensor", sensor_thread, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (Sensor_Thread != RT_NULL)
{
rt_thread_startup(Sensor_Thread);
}
else
{
rt_kprintf("Sensor_Thread Create Failed!\n");
}
}
// MSH_CMD_EXPORT_ALIAS(sensor_init, sensor, run my sensors);

7
applications/sensor.h Normal file
View File

@ -0,0 +1,7 @@
void sensor_init(void);
extern float ADC_air;
extern float ADC_PM25;
extern float ADC_pressure;
extern int cnt_warning;

162
applications/sim.c Normal file
View File

@ -0,0 +1,162 @@
#include "at.h"
#include "board.h"
#include "drv_gpio.h"
#include "rtatomic.h"
#include "rtthread.h"
#include <rtdevice.h>
#include <stdbool.h>
#include <stdlib.h>
#define LOG_TAG "sim"
#define DBG_LVL DBG_LOG
// #define DBG_LVL DBG_INFO
#define USE_LOG1
#define USE_LOG2
#define USE_LOG3
// #define USE_LOG4
#define USE_LOG5
// #define USE_LOG6
// #define USE_LOG_D
#include "logn.h"
#define AT_UART_NAME "uart2"
static at_client_t at_client;
#define AT_SEND_CMD(cmd, resp) \
do \
{ \
rc = RT_EOK; \
if (at_obj_exec_cmd((at_client), (resp), (cmd)) < 0) \
{ \
rc = -RT_ERROR; \
goto __exit; \
} \
} while (0)
rt_err_t sim_call(char *phonenum)
{
rt_err_t rc = RT_EOK;
at_response_t resp = NULL;
resp = at_create_resp(256, 1, 5 * RT_TICK_PER_SECOND);
if (!resp)
{
LOG_E("No memory for AT response structure!");
return -RT_ENOMEM;
}
char at_str[32];
rt_snprintf(at_str, sizeof(at_str), "ATD%s;", phonenum);
AT_SEND_CMD(at_str, resp);
__exit:
if (resp)
{
at_delete_resp(resp);
}
return rc;
}
int cmd_at_send(int argc, char**argv)
{
rt_err_t rc = RT_EOK;
at_response_t resp = NULL;
resp = at_create_resp(256, 1, 5 * RT_TICK_PER_SECOND);
if (!resp)
{
LOG_E("No memory for AT response structure!");
return -RT_ENOMEM;
}
char at_str[128];
AT_SEND_CMD(argv[1], resp);
LOG5("%s",at_resp_get_line(resp, 1));
LOG5("%s",at_resp_get_line(resp, 2));
__exit:
if (resp)
{
at_delete_resp(resp);
}
return rc;
}
MSH_CMD_EXPORT_ALIAS(cmd_at_send, AT_SEND, send AT command);
static void urc_hang_up_handler(struct at_client *client, const char *buf, size_t len)
{
(void)client;
LOG3("The call was hung up.");
}
static void urc_ok_handler(struct at_client *client, const char *buf, size_t len)
{
(void)client;
LOG3("at receive OK.");
}
static void urc_error_handler(struct at_client *client, const char *buf, size_t len)
{
(void)client;
LOG3("at receive ERROR.");
}
static struct at_urc urc_table[] = {
{"NO CARRIER", "\r\n", urc_hang_up_handler},
{"OK", "\r\n", urc_ok_handler},
{"ERROR", "\r\n", urc_error_handler},
};
rt_err_t sim_dev_init()
{
// cmd_mq = ((struct bt_global *)parameter)->cmd_mq;
// init pin
// rt_pin_mode(BT_RST_PIN, PIN_MODE_OUTPUT_OD);
// rt_pin_mode(BT_LINK_STATUS_PIN, PIN_MODE_INPUT);
// init cmd lock
// rt_mutex_init(&cmd_lock, "cmd_lock", RT_IPC_FLAG_FIFO);
// init at client
at_client_init(AT_UART_NAME, 128, 128);
at_client = at_client_get_first();
if (at_client)
{
/* step2修改串口配置参数 */
const struct serial_configure config = {
.baud_rate = BAUD_RATE_115200, // 修改波特率为 115200
.data_bits = DATA_BITS_8, // 数据位 8
.stop_bits = STOP_BITS_1, // 停止位 1
.parity = PARITY_NONE, // 无奇偶校验位
.bit_order = BIT_ORDER_LSB, // 小端模式
.flowcontrol = RT_SERIAL_FLOWCONTROL_NONE, // 无流控
.invert = NRZ_NORMAL, // NRZ 正常模式
#if defined(RT_USING_SERIAL_V1)
.bufsz = RT_SERIAL_RB_BUFSZ,
#elif defined(RT_USING_SERIAL_V2)
.rx_bufsz = BSP_UART2_RX_BUFSIZE, // 修改缓冲区 rx buff size 为 128
.tx_bufsz = BSP_UART2_TX_BUFSIZE, // 修改缓冲区 tx buff size 为 128
#endif // RT_USING_SERIAL_Vx
};
/* step3控制串口设备。通过控制接口传入命令控制字与控制参数 */
rt_device_control(at_client->device, RT_DEVICE_CTRL_CONFIG, (void *)&config);
/* 添加多种 URC 数据至 URC 列表中,当接收到同时匹配 URC 前缀和后缀的数据,执行
* URC
*/
at_set_urc_table(urc_table, sizeof(urc_table) / sizeof(urc_table[0]));
LOG_I("sim initialization success");
return RT_EOK;
}
else
{
LOG_E("sim initialization failed");
return -RT_ERROR;
}
}

3
applications/sim.h Normal file
View File

@ -0,0 +1,3 @@
#include "rtthread.h"
rt_err_t sim_dev_init();
rt_err_t sim_call(char *phonenum);

140
applications/status.c Normal file
View File

@ -0,0 +1,140 @@
#include <rtthread.h>
#include <rtdevice.h>
#include <drv_gpio.h>
#include <assistant.h>
#include <sim.h>
#include <motor.h>
#include "sensor.h"
#include "status.h"
struct rt_event robot_event; // 机器人的控制事件
#define THREAD_PRIORITY 25
#define THREAD_STACK_SIZE 4096
#define THREAD_TIMESLICE 5
#define LOG_TAG "status"
#define DBG_LVL DBG_LOG
// #define DBG_LVL DBG_INFO
#define USE_LOG1
#define USE_LOG2
#define USE_LOG3
// #define USE_LOG4
#define USE_LOG5
// #define USE_LOG6
// #define USE_LOG_D
#include "logn.h"
/* 配置 LED 灯引脚 */
#define PIN_LED_B GET_PIN(E, 12)
#define LED_ON PIN_HIGH
#define LED_OFF PIN_LOW
/* 配置蜂鸣器引脚 */
#define PIN_BEEP GET_PIN(B, 0) // PA1: BEEP --> BEEP (PB1)
int light_status = 0;
int fan_status = 0;
void fan_on(void)
{
fan_status = 1;
LOG3("fan on!");
motor_speed(100);
}
void fan_off(void)
{
fan_status = 0;
// LOG3("fan off!");
motor_speed(0);
}
void light_on(void)
{
LOG3("light on!");
rt_pin_mode(PIN_LED_B, PIN_MODE_OUTPUT);
rt_pin_write(PIN_LED_B, LED_ON);
}
void light_off(void)
{
// LOG3("light off!");
rt_pin_mode(PIN_LED_B, PIN_MODE_OUTPUT);
rt_pin_write(PIN_LED_B, LED_OFF);
}
void beep_on(void)
{
rt_pin_mode(PIN_BEEP, PIN_MODE_OUTPUT);
rt_pin_write(PIN_BEEP, PIN_HIGH);
rt_thread_mdelay(100);
}
MSH_CMD_EXPORT_ALIAS(beep_on, beep, show beep_on);
void beep_off(void)
{
rt_pin_mode(PIN_BEEP, PIN_MODE_OUTPUT);
rt_pin_write(PIN_BEEP, PIN_LOW);
}
MSH_CMD_EXPORT_ALIAS(beep_off, P2, show beep_off);
void danger_status(void)
{
rt_event_send(&robot_event, EVENT_DELAY);
char *str = "aa";
serial_send(str);
sim_call("17318112360");
fan_on();
light_on();
// LED_BreathMore(0,LED_NUM-1,LED_RED);
}
MSH_CMD_EXPORT_ALIAS(danger_status, danger, show danger_status);
void normal_status(void)
{
if (fan_status == 0)
fan_off();
if (light_status == 0)
light_off();
beep_off();
// LED_SetMore(0,LED_NUM-1,LEDI_OFF);
}
void collect_entry(void *parameter)
{
while (1)
{
if (rt_event_recv(&robot_event, EVENT_DELAY, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
RT_WAITING_FOREVER, NULL) == RT_EOK)
{
rt_thread_mdelay(10000);
if(cnt_warning>0)
{
beep_on();
}
}
}
}
int status_init(void)
{
rt_err_t result;
rt_thread_t collect_tid;
result = rt_event_init(&robot_event, "robotE", RT_IPC_FLAG_PRIO);
if (result != RT_EOK)
{
rt_kprintf("init robot_event failed.\n");
return -1;
}
collect_tid = rt_thread_create("collecT", collect_entry, NULL, 2048, 12, 10);
if (collect_tid)
{
rt_thread_startup(collect_tid);
}
else
{
LOG_E("create collect thread failed!");
return -RT_ENOMEM;
}
return RT_EOK;
}

14
applications/status.h Normal file
View File

@ -0,0 +1,14 @@
void danger_status(void);
void normal_status(void);
void fan_on(void);
void fan_off(void);
void light_on(void);
void light_off(void);
void beep_on(void);
void beep_off(void);
int status_init(void);
extern int light_status;
extern int fan_status ;
#define EVENT_DELAY (1 << 3)

View File

@ -52,61 +52,65 @@ Mcu.Pin11=PA1
Mcu.Pin12=PA2
Mcu.Pin13=PA3
Mcu.Pin14=PA4
Mcu.Pin15=PA7
Mcu.Pin16=PB1
Mcu.Pin17=PE7
Mcu.Pin18=PE8
Mcu.Pin19=PE9
Mcu.Pin15=PA5
Mcu.Pin16=PA6
Mcu.Pin17=PA7
Mcu.Pin18=PE7
Mcu.Pin19=PE8
Mcu.Pin2=PF4
Mcu.Pin20=PE10
Mcu.Pin21=PE11
Mcu.Pin22=PE13
Mcu.Pin23=PB10
Mcu.Pin24=PB11
Mcu.Pin25=PB13
Mcu.Pin26=PD8
Mcu.Pin27=PD9
Mcu.Pin28=PD12
Mcu.Pin29=PD13
Mcu.Pin20=PE9
Mcu.Pin21=PE10
Mcu.Pin22=PE11
Mcu.Pin23=PE13
Mcu.Pin24=PE14
Mcu.Pin25=PB10
Mcu.Pin26=PB11
Mcu.Pin27=PB13
Mcu.Pin28=PD8
Mcu.Pin29=PD9
Mcu.Pin3=PF5
Mcu.Pin30=PD14
Mcu.Pin31=PD15
Mcu.Pin32=PC8
Mcu.Pin33=PC9
Mcu.Pin34=PA9
Mcu.Pin35=PA10
Mcu.Pin36=PA11
Mcu.Pin37=PA12
Mcu.Pin38=PA13
Mcu.Pin39=PA14
Mcu.Pin30=PD12
Mcu.Pin31=PD13
Mcu.Pin32=PD14
Mcu.Pin33=PD15
Mcu.Pin34=PC8
Mcu.Pin35=PC9
Mcu.Pin36=PA8
Mcu.Pin37=PA9
Mcu.Pin38=PA10
Mcu.Pin39=PA11
Mcu.Pin4=PF6
Mcu.Pin40=PC10
Mcu.Pin41=PC11
Mcu.Pin42=PC12
Mcu.Pin43=PD0
Mcu.Pin44=PD1
Mcu.Pin45=PD2
Mcu.Pin46=PD4
Mcu.Pin47=PD5
Mcu.Pin48=PG10
Mcu.Pin49=PG11
Mcu.Pin40=PA12
Mcu.Pin41=PA13
Mcu.Pin42=PA14
Mcu.Pin43=PC10
Mcu.Pin44=PC11
Mcu.Pin45=PC12
Mcu.Pin46=PD0
Mcu.Pin47=PD1
Mcu.Pin48=PD2
Mcu.Pin49=PD4
Mcu.Pin5=PF7
Mcu.Pin50=PG13
Mcu.Pin51=PG14
Mcu.Pin52=VP_IWDG_VS_IWDG
Mcu.Pin53=VP_RTC_VS_RTC_Activate
Mcu.Pin54=VP_SYS_VS_Systick
Mcu.Pin55=VP_TIM1_VS_ClockSourceINT
Mcu.Pin56=VP_TIM2_VS_ClockSourceINT
Mcu.Pin57=VP_TIM3_VS_ClockSourceINT
Mcu.Pin58=VP_TIM11_VS_ClockSourceINT
Mcu.Pin59=VP_TIM13_VS_ClockSourceINT
Mcu.Pin50=PD5
Mcu.Pin51=PG10
Mcu.Pin52=PG11
Mcu.Pin53=PG13
Mcu.Pin54=PG14
Mcu.Pin55=PB7
Mcu.Pin56=VP_IWDG_VS_IWDG
Mcu.Pin57=VP_RTC_VS_RTC_Activate
Mcu.Pin58=VP_SYS_VS_Systick
Mcu.Pin59=VP_TIM1_VS_ClockSourceINT
Mcu.Pin6=PF9
Mcu.Pin60=VP_TIM14_VS_ClockSourceINT
Mcu.Pin60=VP_TIM2_VS_ClockSourceINT
Mcu.Pin61=VP_TIM3_VS_ClockSourceINT
Mcu.Pin62=VP_TIM11_VS_ClockSourceINT
Mcu.Pin63=VP_TIM13_VS_ClockSourceINT
Mcu.Pin64=VP_TIM14_VS_ClockSourceINT
Mcu.Pin7=PH0-OSC_IN
Mcu.Pin8=PH1-OSC_OUT
Mcu.Pin9=PC2
Mcu.PinsNb=61
Mcu.PinsNb=65
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F407ZGTx
@ -145,16 +149,23 @@ PA3.Locked=true
PA3.Mode=Asynchronous
PA3.Signal=USART2_RX
PA4.Signal=COMP_DAC1_group
PA5.Locked=true
PA5.Signal=ADCx_IN5
PA6.Locked=true
PA6.Signal=ADCx_IN6
PA7.Signal=S_TIM3_CH2
PA8.Locked=true
PA8.Signal=S_TIM1_CH1
PA9.GPIOParameters=GPIO_PuPd
PA9.GPIO_PuPd=GPIO_PULLUP
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
PB1.Signal=S_TIM3_CH4
PB10.Signal=S_TIM2_CH3
PB11.Signal=S_TIM2_CH4
PB13.Mode=Full_Duplex_Master
PB13.Signal=SPI2_SCK
PB7.Locked=true
PB7.Signal=S_TIM4_CH2
PC10.Mode=SD_4_bits_Wide_bus
PC10.Signal=SDIO_D2
PC11.Mode=SD_4_bits_Wide_bus
@ -191,6 +202,10 @@ PE10.Signal=FSMC_D7_DA7
PE11.Locked=true
PE11.Signal=S_TIM1_CH2
PE13.Signal=S_TIM1_CH3
PE14.GPIOParameters=GPIO_Label
PE14.GPIO_Label=PM25LED
PE14.Locked=true
PE14.Signal=S_TIM1_CH4
PE7.Signal=FSMC_D4_DA4
PE8.Signal=FSMC_D5_DA5
PE9.Signal=FSMC_D6_DA6
@ -287,6 +302,10 @@ RCC.VCOOutputFreq_Value=336000000
RCC.VcooutputI2S=192000000
SH.ADCx_IN1.0=ADC1_IN1,IN1
SH.ADCx_IN1.ConfNb=1
SH.ADCx_IN5.0=ADC1_IN5,IN5
SH.ADCx_IN5.ConfNb=1
SH.ADCx_IN6.0=ADC1_IN6,IN6
SH.ADCx_IN6.ConfNb=1
SH.COMP_DAC1_group.0=DAC_OUT1,DAC_OUT1
SH.COMP_DAC1_group.ConfNb=1
SH.FSMC_A18.0=FSMC_A18,A18_1
@ -313,45 +332,51 @@ SH.FSMC_NWE.0=FSMC_NWE,Lcd1
SH.FSMC_NWE.ConfNb=1
SH.S_TIM14_CH1.0=TIM14_CH1,PWM Generation1 CH1
SH.S_TIM14_CH1.ConfNb=1
SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1
SH.S_TIM1_CH1.ConfNb=1
SH.S_TIM1_CH2.0=TIM1_CH2,PWM Generation2 CH2
SH.S_TIM1_CH2.ConfNb=1
SH.S_TIM1_CH3.0=TIM1_CH3,PWM Generation3 CH3
SH.S_TIM1_CH3.ConfNb=1
SH.S_TIM1_CH4.0=TIM1_CH4,PWM Generation4 CH4
SH.S_TIM1_CH4.ConfNb=1
SH.S_TIM2_CH3.0=TIM2_CH3,PWM Generation3 CH3
SH.S_TIM2_CH3.ConfNb=1
SH.S_TIM2_CH4.0=TIM2_CH4,PWM Generation4 CH4
SH.S_TIM2_CH4.ConfNb=1
SH.S_TIM3_CH2.0=TIM3_CH2,PWM Generation2 CH2
SH.S_TIM3_CH2.ConfNb=1
SH.S_TIM3_CH4.0=TIM3_CH4,PWM Generation4 CH4
SH.S_TIM3_CH4.ConfNb=1
SH.S_TIM4_CH1.0=TIM4_CH1,PWM Generation1 CH1
SH.S_TIM4_CH1.ConfNb=1
SH.S_TIM4_CH2.0=TIM4_CH2,PWM Generation2 CH2
SH.S_TIM4_CH2.ConfNb=1
SPI2.CalculateBaudRate=21.0 MBits/s
SPI2.Direction=SPI_DIRECTION_2LINES
SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate
SPI2.Mode=SPI_MODE_MASTER
SPI2.VirtualType=VM_MASTER
TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM1.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM1.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM1.IPParameters=Channel-PWM Generation2 CH2,Channel-PWM Generation3 CH3
TIM1.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
TIM1.IPParameters=Channel-PWM Generation2 CH2,Channel-PWM Generation3 CH3,Channel-PWM Generation4 CH4,Channel-PWM Generation1 CH1
TIM14.Channel=TIM_CHANNEL_1
TIM14.IPParameters=Channel
TIM2.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM2.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
TIM2.IPParameters=Channel-PWM Generation3 CH3,Channel-PWM Generation4 CH4
TIM3.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM3.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
TIM3.IPParameters=Channel-PWM Generation4 CH4,Channel-PWM Generation2 CH2,Pulse-PWM Generation2 CH2,Period
TIM3.IPParameters=Channel-PWM Generation2 CH2,Pulse-PWM Generation2 CH2,Period
TIM3.Period=210
TIM3.Pulse-PWM\ Generation2\ CH2=0
TIM4.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM4.IPParameters=Channel-PWM Generation1 CH1
TIM4.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM4.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2
USART1.IPParameters=VirtualMode
USART1.VirtualMode=VM_ASYNC
USART2.IPParameters=VirtualMode
USART2.VirtualMode=VM_ASYNC
USART3.BaudRate=9600
USART3.BaudRate=115200
USART3.IPParameters=VirtualMode,BaudRate
USART3.VirtualMode=VM_ASYNC
USB_OTG_FS.IPParameters=VirtualMode

View File

@ -73,13 +73,15 @@ extern "C" {
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
/* Exported functions prototypes ---------------------------------------------*/
// void Error_Handler(void);
void Error_Handler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
#define PM25LED_Pin GPIO_PIN_14
#define PM25LED_GPIO_Port GPIOE
/* USER CODE BEGIN Private defines */

View File

@ -549,6 +549,10 @@ static void MX_TIM1_Init(void)
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
@ -557,6 +561,10 @@ static void MX_TIM1_Init(void)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
@ -690,10 +698,6 @@ static void MX_TIM3_Init(void)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM3_Init 2 */
/* USER CODE END TIM3_Init 2 */
@ -743,6 +747,10 @@ static void MX_TIM4_Init(void)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM4_Init 2 */
/* USER CODE END TIM4_Init 2 */
@ -940,7 +948,7 @@ static void MX_USART3_UART_Init(void)
/* USER CODE END USART3_Init 1 */
huart3.Instance = USART3;
huart3.Init.BaudRate = 9600;
huart3.Init.BaudRate = 115200;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
@ -1008,8 +1016,8 @@ static void MX_GPIO_Init(void)
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
@ -1086,16 +1094,16 @@ static void MX_FSMC_Init(void)
* @brief This function is executed in case of error occurrence.
* @retval None
*/
// void Error_Handler(void)
// {
// /* USER CODE BEGIN Error_Handler_Debug */
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
// // /* User can add his own implementation to report the HAL error return state */
// // __disable_irq();
// // while (1)
// // {
// // }
// /* USER CODE END Error_Handler_Debug */
// }
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**

View File

@ -121,8 +121,10 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
__HAL_RCC_GPIOA_CLK_ENABLE();
/**ADC1 GPIO Configuration
PA1 ------> ADC1_IN1
PA5 ------> ADC1_IN5
PA6 ------> ADC1_IN6
*/
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_5|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
@ -176,8 +178,10 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
/**ADC1 GPIO Configuration
PA1 ------> ADC1_IN1
PA5 ------> ADC1_IN5
PA6 ------> ADC1_IN6
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1|GPIO_PIN_5|GPIO_PIN_6);
/* USER CODE BEGIN ADC1_MspDeInit 1 */
@ -597,17 +601,27 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
/* USER CODE END TIM1_MspPostInit 0 */
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**TIM1 GPIO Configuration
PE11 ------> TIM1_CH2
PE13 ------> TIM1_CH3
PE14 ------> TIM1_CH4
PA8 ------> TIM1_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_13;
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_13|PM25LED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN TIM1_MspPostInit 1 */
/* USER CODE END TIM1_MspPostInit 1 */
@ -641,10 +655,8 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
/* USER CODE END TIM3_MspPostInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**TIM3 GPIO Configuration
PA7 ------> TIM3_CH2
PB1 ------> TIM3_CH4
*/
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
@ -653,13 +665,6 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN TIM3_MspPostInit 1 */
/* USER CODE END TIM3_MspPostInit 1 */
@ -671,8 +676,10 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
/* USER CODE END TIM4_MspPostInit 0 */
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**TIM4 GPIO Configuration
PD12 ------> TIM4_CH1
PB7 ------> TIM4_CH2
*/
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
@ -681,6 +688,13 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN TIM4_MspPostInit 1 */
/* USER CODE END TIM4_MspPostInit 1 */

View File

@ -299,6 +299,20 @@ menu "On-chip Peripheral Drivers"
depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA
default n
config BSP_UART1_TX_BUFSIZE
int "Set UART1 TX buffer size"
range 0 65535
depends on RT_USING_SERIAL_V2
default 0
config BSP_UART1_RX_BUFSIZE
int "Set UART1 RX buffer size"
range 64 65535
depends on RT_USING_SERIAL_V2
default 256
config BSP_USING_UART2
bool "Enable UART2"
default n
@ -313,6 +327,18 @@ menu "On-chip Peripheral Drivers"
depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA
default n
config BSP_UART2_TX_BUFSIZE
int "Set UART2 TX buffer size"
range 0 65535
depends on RT_USING_SERIAL_V2
default 0
config BSP_UART2_RX_BUFSIZE
int "Set UART2 RX buffer size"
range 64 65535
depends on RT_USING_SERIAL_V2
default 256
config BSP_USING_UART3
bool "Enable UART3"
default n
@ -327,6 +353,18 @@ menu "On-chip Peripheral Drivers"
depends on BSP_USING_UART3 && RT_SERIAL_USING_DMA
default n
config BSP_UART3_TX_BUFSIZE
int "Set UART3 TX buffer size"
range 0 65535
depends on RT_USING_SERIAL_V2
default 0
config BSP_UART3_RX_BUFSIZE
int "Set UART3 RX buffer size"
range 64 65535
depends on RT_USING_SERIAL_V2
default 256
config BSP_USING_UART4
bool "Enable UART4"
default n
@ -340,6 +378,19 @@ menu "On-chip Peripheral Drivers"
bool "Enable UART4 TX DMA"
depends on BSP_USING_UART4 && RT_SERIAL_USING_DMA
default n
config BSP_UART4_TX_BUFSIZE
int "Set UART4 TX buffer size"
range 0 65535
depends on RT_USING_SERIAL_V2
default 0
config BSP_UART4_RX_BUFSIZE
int "Set UART4 RX buffer size"
range 64 65535
depends on RT_USING_SERIAL_V2
default 256
config BSP_USING_UART5
bool "Enable UART5"
@ -355,6 +406,18 @@ menu "On-chip Peripheral Drivers"
depends on BSP_USING_UART5 && RT_SERIAL_USING_DMA
default n
config BSP_UART5_TX_BUFSIZE
int "Set UART5 TX buffer size"
range 0 65535
depends on RT_USING_SERIAL_V2
default 0
config BSP_UART5_RX_BUFSIZE
int "Set UART5 RX buffer size"
range 64 65535
depends on RT_USING_SERIAL_V2
default 256
config BSP_USING_UART6
bool "Enable UART6"
default n
@ -368,6 +431,19 @@ menu "On-chip Peripheral Drivers"
bool "Enable UART6 TX DMA"
depends on BSP_USING_UART6 && RT_SERIAL_USING_DMA
default n
config BSP_UART6_TX_BUFSIZE
int "Set UART6 TX buffer size"
range 0 65535
depends on RT_USING_SERIAL_V2
default 0
config BSP_UART6_RX_BUFSIZE
int "Set UART6 RX buffer size"
range 64 65535
depends on RT_USING_SERIAL_V2
default 256
endif
menuconfig BSP_USING_TIM
@ -397,6 +473,9 @@ menu "On-chip Peripheral Drivers"
bool "Enable timer1 output PWM"
default n
if BSP_USING_PWM1
config BSP_USING_PWM1_CH1
bool "Enable PWM1 channel1"
default n
config BSP_USING_PWM1_CH2
bool "Enable PWM1 channel2"
default n

View File

@ -12,7 +12,7 @@
#include <sfud.h>
#ifdef RT_USING_SFUD
#include <spi_flash_sfud.h>
#include <dev_spi_flash_sfud.h>
#endif
static int init(void);

View File

@ -50,12 +50,24 @@ const RGBColor_TypeDef LED_GREEN = {255, 0, 0};
const RGBColor_TypeDef LED_RED = {0, 255, 0};
const RGBColor_TypeDef LED_BLUE = {0, 0, 255};
const RGBColor_TypeDef LED_WHITE = {255, 255, 255};
const RGBColor_TypeDef LT_RED = {0, 32, 0};
const RGBColor_TypeDef LT_GREEN = {32, 0, 0};
const RGBColor_TypeDef LT_BLUE = {0, 0, 32};
const RGBColor_TypeDef LT_WHITE = {16, 16, 16};
const RGBColor_TypeDef LT_PURPLE = {0,32,32};
const RGBColor_TypeDef LT_YELLOW = {256/8, 256/8, 0};
const RGBColor_TypeDef LLT_RED = {0, 8, 0};
const RGBColor_TypeDef LLT_GREEN = {8, 0, 0};
const RGBColor_TypeDef LLT_BLUE = {0, 0, 8};
const RGBColor_TypeDef LLT_WHITE = {4, 4, 4};
const RGBColor_TypeDef LLT_PURPLE = {0,8,8};
const RGBColor_TypeDef LLT_YELLOW = {8, 8, 0};
const RGBColor_TypeDef LEDI_OFF = {0, 0, 0};
const RGBColor_TypeDef LEDI_ON = {255, 255, 255};
// 灯颜色缓存

View File

@ -15,11 +15,27 @@ typedef struct RGBColor_TypeDef
// // 灯闪烁颜色缓存
// extern RGBColor_TypeDef LED_Blink_Color[LED_NUM] = {0};
extern const RGBColor_TypeDef LED_DARK;
extern const RGBColor_TypeDef LED_GREEN;
extern const RGBColor_TypeDef LED_RED;
extern const RGBColor_TypeDef LED_BLUE;
extern const RGBColor_TypeDef LED_WHITE;
extern const RGBColor_TypeDef LED_DARK ;
extern const RGBColor_TypeDef LED_GREEN;
extern const RGBColor_TypeDef LED_RED ;
extern const RGBColor_TypeDef LED_BLUE ;
extern const RGBColor_TypeDef LED_WHITE ;
extern const RGBColor_TypeDef LT_RED ;
extern const RGBColor_TypeDef LT_GREEN ;
extern const RGBColor_TypeDef LT_BLUE ;
extern const RGBColor_TypeDef LT_WHITE ;
extern const RGBColor_TypeDef LT_PURPLE;
extern const RGBColor_TypeDef LT_YELLOW;
extern const RGBColor_TypeDef LLT_RED ;
extern const RGBColor_TypeDef LLT_GREEN;
extern const RGBColor_TypeDef LLT_BLUE ;
extern const RGBColor_TypeDef LLT_WHITE;
extern const RGBColor_TypeDef LLT_PURPLE;
extern const RGBColor_TypeDef LLT_YELLOW;
extern const RGBColor_TypeDef LEDI_OFF ;
extern const RGBColor_TypeDef LEDI_ON ;
extern void Set_LEDColor(uint16_t LedId, RGBColor_TypeDef Color);
extern void RGB_Reflash(void);

View File

@ -9,8 +9,8 @@
*/
#include <rtthread.h>
#include "spi_flash.h"
#include "spi_flash_sfud.h"
#include "dev_spi_flash.h"
#include "dev_spi_flash_sfud.h"
#include <drv_spi.h>
#include <drv_gpio.h>

View File

@ -15,7 +15,7 @@
#ifdef BSP_USING_PWM
#include "drv_config.h"
#include "drv_tim.h"
#include <drivers/rt_drv_pwm.h>
#include <drivers/dev_pwm.h>
//#define DRV_DEBUG
#define LOG_TAG "drv.pwm"

View File

@ -17,8 +17,8 @@
#include <drv_common.h>
#include "drv_dma.h"
#include <string.h>
#include <drivers/mmcsd_core.h>
#include <drivers/sdio.h>
#include <drivers/dev_mmcsd_core.h>
#include <drivers/dev_sdio.h>
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4)
#define SDCARD_INSTANCE_TYPE SDIO_TypeDef

View File

@ -1,180 +0,0 @@
# 红外遥控贪吃蛇/显示+上传温度等数据到云平台
**梁浚超** 导师:**李镇鸿**
![简略教程封面](/my_picture/简略教程封面.jpg)
[成果展示视频链接(new)(https://www.bilibili.com/video/BV1VqeceTEts) ](https://www.bilibili.com/video/BV1VqeceTEts)
[简略教程视频链接(https://www.bilibili.com/video/BV15uYqeME6t)](https://www.bilibili.com/video/BV15uYqeME6t)
[成果展示视频链接(https://www.bilibili.com/video/BV1x3YSesEcw)](https://www.bilibili.com/video/BV1x3YSesEcw)
## 主要内容
- [红外遥控贪吃蛇/显示+上传温度等数据到云平台](#红外遥控贪吃蛇显示上传温度等数据到云平台)
- [主要内容](#主要内容)
- [1. LCD显示温湿度等数据](#1-lcd显示温湿度等数据)
- [1.1 LCD显示字符串](#11-lcd显示字符串)
- [1.2 屏幕圆角](#12-屏幕圆角)
- [2. LCD贪吃蛇小游戏](#2-lcd贪吃蛇小游戏)
- [2.1 循环队列储存蛇身的坐标](#21-循环队列储存蛇身的坐标)
- [2.2 放弃使用bool记录地图](#22-放弃使用bool记录地图)
- [2.3 随机运动](#23-随机运动)
- [2.4 引入按键](#24-引入按键)
- [2.5 红外遥控](#25-红外遥控)
- [3. 红外遥控](#3-红外遥控)
- [3.1 填好对应的pin](#31-填好对应的pin)
- [3.2 找到合适的遥控器](#32-找到合适的遥控器)
- [3.3 基本操作](#33-基本操作)
- [3.4 导致LCD闪烁](#34-导致lcd闪烁)
- [4. 时间获取,显示](#4-时间获取显示)
- [5. 菜单切换](#5-菜单切换)
- [6. MQTT上传温湿度等数据到云平台](#6-mqtt上传温湿度等数据到云平台)
- [6.1 简单修改](#61-简单修改)
- [6.2 连接WiFi](#62-连接wifi)
- [6.3 阿里云平台查看数据](#63-阿里云平台查看数据)
- [光照强度](#光照强度)
- [接近感应](#接近感应)
- [蛇长](#蛇长)
- [湿度](#湿度)
- [温度](#温度)
- [6.4 开启关闭MQTT](#64-开启关闭mqtt)
- [展望](#展望)
- [感谢](#感谢)
## 1. LCD显示温湿度等数据
[成果展示视频链接1:10(new)(https://www.bilibili.com/video/BV1VqeceTEts) ](https://www.bilibili.com/video/BV1VqeceTEts)
![LCD显示](../my_picture/LCD数据.jpg)
### 1.1 LCD显示字符串
左上角是00 →x↓y
``` c
void easy_show_lcd(char *title, float Temp)
{
lcd_show_string(10, plus_lcd_y(24), 24, title);
rt_sprintf(tmp, "%f", Temp);
lcd_show_string(10, plus_lcd_y(32), 32, tmp);
}
```
### 1.2 屏幕圆角
勾股定理、⚪的公式
``` c
if ((newi * newi + newj * newj) > (r * r))
{
lcd_black(i, j);
}
```
## 2. LCD贪吃蛇小游戏
[视频展示](https://www.bilibili.com/video/BV1WHafe1EBh/?spm_id_from=333.999.0.0&vd_source=4ac343050490681bfc3be821b46a4a18)
### 2.1 循环队列储存蛇身的坐标
``` c
int snake_head = 2, snake_tail = 0; // 蛇头,蛇尾
new_head_x = (snake_list[snake_head][0] + snake_direction[now_direction][0] + SNAKE_MAX) % (SNAKE_MAX);
```
### 2.2 放弃使用bool记录地图
内存不够
### 2.3 随机运动
``` c
int snake_direction[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}}; // 上,左,下,右
```
![alt text](../my_picture/防止反向.jpg)
``` c
// 50%的概率保持当前方向
if (rand() % 100 < 50)
{
new_direction = rand() % 3;
now_direction = (now_direction + 3 + new_direction) % 4; // 防止反向、走回头路
}
```
### 2.4 引入按键
修改`now_direction`就可以了
### 2.5 红外遥控
## 3. 红外遥控
### 3.1 填好对应的pin
### 3.2 找到合适的遥控器
| 编号key| 功能 |
| :----: | :----: |
| 0x30| 上 |
| 0xE8 | 左 |
| 0xB0 | 下 |
| 0x68 | 右 |
| 0xFF | OK |
| 0x38 | 电源键 |
| 0xA8 | 静音 |
| 0x88 | 菜单 |
| 0x28 | 退出 |
### 3.3 基本操作
``` c
ir_select_decoder("nec");
infrared_read("nec", &infrared_data);
snake_compare(infrared_data.data.nec.key, infrared_data.data.nec.repeat);
rt_sprintf(tmp, "%02X", key);
```
### 3.4 导致LCD闪烁
[闪烁展示](https://www.bilibili.com/video/BV1frakeoEbc/?spm_id_from=333.999.0.0)
[问题解决](https://club.rt-thread.org/ask/article/23706daa8b2e9e55.html)
## 4. 时间获取,显示
![显示时间.jpg](../my_picture/显示时间.jpg)
[参考(https://blog.csdn.net/toopoo/article/details/113665077)](https://blog.csdn.net/toopoo/article/details/113665077)
``` c
void greattime()
{
time_t cur_time;
struct tm *info;
cur_time = ntp_get_time(RT_NULL);
info=localtime(&cur_time);
strftime(tmp, 80, "%Y-%m-%d", info);
lcd_show_string(40, 240/2-32-24, 32, tmp);
strftime(tmp, 80, "%H:%M:%S", info);
lcd_show_string(50, 240/2+24, 32, tmp);
if (cur_time)
{
rt_kprintf("NTP Server Time: %s", ctime((const time_t *)&cur_time));
}
}
```
## 5. 菜单切换
``` c
// 菜单(切换页面)
if (repeat == 0 && (rt_strcmp(tmp, "88") == 0 || rt_strcmp(tmp, "11") == 0))
{
page_chosen = (page_chosen % PAGE_MAX) + 1;
page_first = 1;
}
```
[展示1:51](https://www.bilibili.com/video/BV1VqeceTEts/?spm_id_from=333.999.0.0&vd_source=4ac343050490681bfc3be821b46a4a18)
## 6. MQTT上传温湿度等数据到云平台
### 6.1 简单修改
``` c
char tmp[];
rt_sprintf(tmp, "{\"params\":{\"temperature\":%.2f,\"humidity\":%.2f,\"LightLux\":%.2f,\"Psdata\":%d,\"Snakelen\":%d}}", Temp, Humi, brightness, ps_data, snake_len);
const char *fmt = "/sys/%s/%s/thing/event/property/post";
char *payload = tmp;
```
### 6.2 连接WiFi
``` c
rt_wlan_config_autoreconnect(RT_TRUE);
rt_wlan_connect("Dong", "abcd07691234");
system("myproject");
```
### 6.3 阿里云平台查看数据
#### 光照强度
![alt text](../my_picture/光照强度.png)
#### 接近感应
![alt text](../my_picture/接近感应.png)
#### 蛇长
![alt text](../my_picture/蛇长.png)
#### 湿度
![alt text](../my_picture/湿度.png)
#### 温度
![alt text](../my_picture/温度.png)
### 6.4 开启关闭MQTT
![开启mqtt图](../my_picture/成果展示封面.png)
``` c
IOT_MQTT_Destroy(&pclient);
```
#### 展望
LVGL,网页/小程序展示操作
## 感谢
RT-Thread和各位导师的指导

View File

@ -1,15 +0,0 @@
from building import *
import os
cwd = GetCurrentDir()
CPPPATH = [cwd]
src = Glob('*.c')
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
list = os.listdir(cwd)
for item in list:
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
group = group + SConscript(os.path.join(item, 'SConscript'))
Return('group')

View File

@ -1,85 +0,0 @@
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <icm20608.h>
#define LOG_TAG "icm.app"
#define LOG_LVL LOG_LVL_DBG
#include <ulog.h>
static void icm_thread_entry(void *parameter)
{
icm20608_device_t dev = RT_NULL;
const char *i2c_bus_name = "i2c2";
int count = 0;
rt_err_t result;
/* 初始化 icm20608 传感器 */
dev = icm20608_init(i2c_bus_name);
if (dev == RT_NULL)
{
LOG_E("The sensor initializes failure");
}
else
{
LOG_D("The sensor initializes success");
}
/* 对 icm20608 进行零值校准:采样 10 次,求取平均值作为零值 */
result = icm20608_calib_level(dev, 10);
if (result == RT_EOK)
{
LOG_D("The sensor calibrates success");
LOG_D("accel_offset: X%6d Y%6d Z%6d", dev->accel_offset.x, dev->accel_offset.y, dev->accel_offset.z);
LOG_D("gyro_offset : X%6d Y%6d Z%6d", dev->gyro_offset.x, dev->gyro_offset.y, dev->gyro_offset.z);
}
else
{
LOG_E("The sensor calibrates failure");
icm20608_deinit(dev);
}
while (count++ < 100)
{
rt_int16_t accel_x, accel_y, accel_z;
rt_int16_t gyros_x, gyros_y, gyros_z;
/* 读取三轴加速度 */
result = icm20608_get_accel(dev, &accel_x, &accel_y, &accel_z);
if (result == RT_EOK)
{
LOG_D("current accelerometer: accel_x%6d, accel_y%6d, accel_z%6d", accel_x, accel_y, accel_z);
}
else
{
LOG_E("The sensor does not work");
}
/* 读取三轴陀螺仪 */
result = icm20608_get_gyro(dev, &gyros_x, &gyros_y, &gyros_z);
if (result == RT_EOK)
{
LOG_D("current gyroscope : gyros_x%6d, gyros_y%6d, gyros_z%6d", gyros_x, gyros_y, gyros_z);
}
else
{
LOG_E("The sensor does not work");
break;
}
rt_thread_mdelay(1000);
}
}
static int icm_app(void)
{
rt_thread_t res = rt_thread_create("icm", icm_thread_entry, RT_NULL, 1024, 20, 50);
if(res == RT_NULL)
{
return -RT_ERROR;
}
rt_thread_startup(res);
return RT_EOK;
}
MSH_CMD_EXPORT(icm_app, icm_app);

View File

@ -1,230 +0,0 @@
#include "indicator_led.h"
#include "rtdevice.h"
#define ADC_DEV_NAME "adc1" /* ADC 设备名称 */
#define ADC_DEV_CHANNEL 5 /* ADC 通道 */
#define REFER_VOLTAGE 330 /* 参考电压 3.3V,数据精度乘以100保留2位小数*/
#define CONVERT_BITS (1 << 12) /* 转换位数为12位 */
#define LED_NUM 24 // LED灯珠个数
rt_thread_t led_blink_thread = RT_NULL;
rt_thread_t led_breath_thread = RT_NULL;
// 灯是否处于特定颜色还是闪烁状态
uint8_t LED_Blink_State[LED_NUM] = {LED_NOT_BLINKING};
// 呼吸灯是否开启
uint8_t LED_Breath_State = LED_BREATH_OFF;
// 灯闪烁颜色缓存
RGBColor_TypeDef LED_Blink_Color[LED_NUM] = {0};
const RGBColor_TypeDef LED_OFF = {0, 0, 0};
const RGBColor_TypeDef LED_ON = {255, 255, 255};
/**
* @brief LED的开关
* @param LedBreath_state / LED_BREATH_ON/LED_BREATH_OFF
*/
void LED_BreathTurn(uint8_t LedBreath_state)
{
LED_Breath_State = LedBreath_state;
// if (LedBreath_state == LED_BREATH_OFF)
// {
// // rt_thread_suspend(led_breath_thread);
// LED_SetMore(LED_BREATH_ID(1), LED_BREATH_ID(12), LED_OFF);
// }
// else if (LedBreath_state == LED_BREATH_ON)
// {
// // rt_thread_resume(led_breath_thread);
// }
}
/**
* @brief LED的颜色或开关
* @param LedId LED的序号(0~LED_NUM-1)
* @param Color / LED_RED,LED_BLUE,LED_OFF,LED_ON()
*/
void LED_Set(uint16_t LedId, RGBColor_TypeDef Color)
{
LedId=LED_CHARGE_ID(LedId);
LED_Blink_State[LedId] = 0;
Set_LEDColor(LedId, Color);
RGB_Reflash();
}
/**
* @brief LED的颜色或开关
* @param LedId_begin LED的序号(0~LED_NUM-1)
* @param LedId_end LED的序号(0~LED_NUM-1)
* @param Color / LED_RED,LED_BLUE,LED_OFF,LED_ON()
*/
void LED_SetMore(uint16_t LedId_begin, uint16_t LedId_end, RGBColor_TypeDef Color)
{
LedId_begin=LED_CHARGE_ID(LedId_begin);
LedId_end=LED_CHARGE_ID(LedId_end);
for (int LedId = LedId_begin; LedId <= LedId_end; LedId++)
{
LED_Blink_State[LedId] = 0;
Set_LEDColor(LedId, Color);
}
RGB_Reflash();
}
/**
* @brief LED的闪烁
* @param LedId LED的序号(0~LED_NUM-1)
* @param Color LED_RED,LED_BLUE
*/
void LED_Blink(uint16_t LedId, RGBColor_TypeDef Color)
{
LedId=LED_CHARGE_ID(LedId);
LED_Blink_State[LedId] = 1;
LED_Blink_Color[LedId] = Color;
}
/**
* @brief LED的闪烁
* @param LedId_begin LED的序号(0~LED_NUM-1)
* @param LedId_end LED的序号(0~LED_NUM-1)
* @param Color LED_RED,LED_BLUE
*/
void LED_BlinkMore(uint16_t LedId_begin, uint16_t LedId_end, RGBColor_TypeDef Color)
{
LedId_begin=LED_CHARGE_ID(LedId_begin);
LedId_end=LED_CHARGE_ID(LedId_end);
for (int LedId = LedId_begin; LedId <= LedId_end; LedId++)
{
LED_Blink_State[LedId] = 1;
LED_Blink_Color[LedId] = Color;
}
}
/**
* @brief 0.5s判断各盏灯是否要翻转
*/
void led_blink_entry(void *parameter)
{
uint8_t LED_Blink_ON = 1;
while (1)
{
for (int LedId = 0; LedId < LED_NUM; LedId++)
{
if (LED_Blink_State[LedId] == LED_IS_BLINKING)
{
if (LED_Blink_ON)
{
Set_LEDColor(LedId, LED_Blink_Color[LedId]);
}
else
{
Set_LEDColor(LedId, LED_OFF);
}
}
}
LED_Blink_ON = !LED_Blink_ON;
RGB_Reflash();
rt_thread_mdelay(500);
}
}
/**
* @brief
*/
void led_breath_entry(void *parameter)
{
int count = 0;
while (1)
{
for (int i = LED_BREATH_ID(1); i <= LED_BREATH_ID(12); i++)
{
if (LED_Breath_State==LED_BREATH_OFF)
{
rt_thread_mdelay(100);
i = LED_BREATH_ID(1);
continue;
}
switch (count)
{
case 0:
Set_LEDColor(i, LED_RED);
break;
case 1:
Set_LEDColor(i, LED_GREEN);
break;
case 2:
Set_LEDColor(i, LED_BLUE);
break;
default:
return;
break;
}
RGB_Reflash();
rt_thread_delay(40);
}
count = (count + 1) % 3;
}
}
#define BORAD_NOT_CORRECT 25
#define BORAD_CORRECT_VOL 250
/**
* @brief
*/
static int borad_check(void)
{
rt_adc_device_t adc_dev;
rt_uint32_t value, vol;
rt_err_t ret = RT_EOK;
/* 查找设备 */
adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
if (adc_dev == RT_NULL)
{
rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
return RT_ERROR;
}
/* 使能设备 */
ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);
/* 读取采样值 */
value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
/* 转换为对应电压值 */
vol = value * REFER_VOLTAGE / CONVERT_BITS;
if(vol>=BORAD_CORRECT_VOL)
{
rt_kprintf("NOT correct borad!\n");
rt_kprintf("the value is :%d \n", value);
rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);
return BORAD_NOT_CORRECT;
}
/* 关闭通道 */
ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL);
return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(borad_check, adc voltage convert sample);
/**
* @brief LED的初始化
*/
int led_init(void)
{
if (borad_check()==BORAD_NOT_CORRECT)
{
return 0;
}
led_blink_thread = rt_thread_create("led blink control thread", led_blink_entry, RT_NULL, 1024, 20, 20);
if (led_blink_thread == RT_NULL)
{
rt_kprintf("led blink control thread creat failed!\n");
return 0;
}
led_breath_thread = rt_thread_create("led breath control thread", led_breath_entry, RT_NULL, 1024, 20, 20);
if (led_breath_thread == RT_NULL)
{
rt_kprintf("led breath control thread creat failed!\n");
return 0;
}
rt_thread_mdelay(200); // avoid multi-thread on LED matrix transmit.
rt_thread_startup(led_blink_thread);
rt_thread_startup(led_breath_thread);
}

View File

@ -1,20 +0,0 @@
#include <rtthread.h>
#include <drv_matrix_led.h>
#define LED_IS_BLINKING 1
#define LED_NOT_BLINKING 0
#define LED_BREATH_ON 1
#define LED_BREATH_OFF 0
#define LED_CHARGE_ID(i) (i+12-1) //电源指示灯序号(1-12)
#define LED_BREATH_ID(i) (i-1) //呼吸灯序号(1-12)
extern void LED_Set(uint16_t LedId, RGBColor_TypeDef Color);
extern void LED_SetMore(uint16_t LedId_begin,uint16_t LedId_end, RGBColor_TypeDef Color);
extern void LED_Blink(uint16_t LedId, RGBColor_TypeDef Color);
extern void LED_BlinkMore(uint16_t LedId_begin, uint16_t LedId_end, RGBColor_TypeDef Color);
extern void LED_BreathTurn(uint8_t LedBreath_state);
extern int led_init(void);
extern const RGBColor_TypeDef LED_OFF;
extern const RGBColor_TypeDef LED_ON;

View File

@ -1,87 +0,0 @@
#include"indicator_led.h"
// #include "drv_matrix_led.h"
#include <stdlib.h>
void ledblinkm(int argc, char **argv){
int LedId_begin = atoi(argv[2]);
int LedId_end = atoi(argv[3]);
if(!rt_strcmp(argv[1],"RED"))
{
LED_BlinkMore(LedId_begin,LedId_end,LED_RED);
}
else if(!rt_strcmp(argv[1],"BLUE"))
{
LED_BlinkMore(LedId_begin,LedId_end,LED_BLUE);
}
}
MSH_CMD_EXPORT_ALIAS(ledblinkm,LEDB, "BLINKS LedId Color");
void ledbreath(int argc, char **argv){
LED_BreathTurn(atoi(argv[1]));
}
MSH_CMD_EXPORT_ALIAS(ledbreath,LEDBR, "BLINKS LedId Color");
void ledsetm(int argc, char **argv){
int LedId_begin = atoi(argv[2]);
int LedId_end = atoi(argv[3]);
if(!rt_strcmp(argv[1],"RED"))
{
LED_SetMore(LedId_begin,LedId_end,LED_RED);
}
else if(!rt_strcmp(argv[1],"BLUE"))
{
LED_SetMore(LedId_begin,LedId_end,LED_BLUE);
}
}
MSH_CMD_EXPORT_ALIAS(ledsetm,LEDS, "SETS LedId Color");
void ledblink(int argc, char **argv){
// if(argc < 2){
// const rt_uint8_t Buffer[] = "AT+NAME\r\n";
// rt_uint8_t len = rt_strlen((const char*)Buffer);
// rt_device_write(Project_uart_Device,0,Buffer,len);
// }else if(argc > 2){
// rt_kprintf("Only one parameter can be entered\r\n");
// }else{
// char Buffer[] = "AT+NAME";
// char* NewBuf = strcat(Buffer,argv[1]);
// NewBuf = strcat(NewBuf,"\r\n");
// rt_uint8_t len = rt_strlen((const char*)NewBuf);
// rt_device_write(Project_uart_Device,0,NewBuf,len);
// }
int LedId = atoi(argv[1]);
if(!rt_strcmp(argv[2],"RED"))
{
LED_Blink(LedId,LED_RED);
}
else if(!rt_strcmp(argv[2],"BLUE"))
{
LED_Blink(LedId,LED_BLUE);
}
}
MSH_CMD_EXPORT_ALIAS(ledblink,LED0, "BLINK LedId Color");
void ledset(int argc, char **argv){//设置/查询设备名称
// if(argc < 2){
// const rt_uint8_t Buffer[] = "AT+NAME\r\n";
// rt_uint8_t len = rt_strlen((const char*)Buffer);
// rt_device_write(Project_uart_Device,0,Buffer,len);
// }else if(argc > 2){
// rt_kprintf("Only one parameter can be entered\r\n");
// }else{
// char Buffer[] = "AT+NAME";
// char* NewBuf = strcat(Buffer,argv[1]);
// NewBuf = strcat(NewBuf,"\r\n");
// rt_uint8_t len = rt_strlen((const char*)NewBuf);
// rt_device_write(Project_uart_Device,0,NewBuf,len);
// }
int LedId = atoi(argv[1]);
if(!rt_strcmp(argv[2],"RED"))
{
LED_Set(LedId,LED_RED);
}
else if(!rt_strcmp(argv[2],"BLUE"))
{
LED_Set(LedId,LED_BLUE);
}
}
MSH_CMD_EXPORT_ALIAS(ledset,LED1, "BLINK LedId Color");

View File

@ -11,7 +11,8 @@
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/RT-Thread/rt-thread?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![GitHub pull-requests](https://img.shields.io/github/issues-pr/RT-Thread/rt-thread.svg)](https://github.com/RT-Thread/rt-thread/pulls)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](https://github.com/RT-Thread/rt-thread/pulls)
[![RT-Thread BSP Static Build Check](https://github.com/RT-Thread/rt-thread/actions/workflows/bsp_buildings.yml/badge.svg)](https://github.com/RT-Thread/rt-thread/actions/workflows/bsp_buildings.yml)
<a href="https://hellogithub.com/repository/5816fc3c1e714d109631ceb377538ca9" target="_blank"><img src="https://api.hellogithub.com/v1/widgets/recommend.svg?rid=5816fc3c1e714d109631ceb377538ca9&claim_uid=kVCe5FXIMGAjJfy" alt="FeaturedHelloGitHub" style="width: 100px; height: 20px;" width="250" height="54" /></a>
# RT-Thread
RT-Thread was born in 2006, it is an open source, neutral, and community-based real-time operating system (RTOS).

View File

@ -162,20 +162,32 @@ endif
bool "Using devfs for device objects"
default y
config RT_USING_DFS_ROMFS
if RT_USING_DFS_V1
config RT_USING_DFS_ISO9660
bool "Using ISO9660 filesystem"
depends on RT_USING_MEMHEAP
default n
endif
menuconfig RT_USING_DFS_ROMFS
bool "Enable ReadOnly file system on flash"
default n
config RT_USING_DFS_ROMFS_USER_ROOT
bool "Use user's romfs root"
depends on RT_USING_DFS_ROMFS
default n
if RT_USING_DFS_ROMFS
config RT_USING_DFS_ROMFS_USER_ROOT
bool "Use user's romfs root"
depends on RT_USING_DFS_V1
default n
endif
if RT_USING_SMART
config RT_USING_DFS_PTYFS
bool "Using Pseudo-Teletype Filesystem (UNIX98 PTY)"
depends on RT_USING_DFS_DEVFS
default y
config RT_USING_DFS_PROCFS
bool "Enable proc file system"
default n
endif
config RT_USING_DFS_CROMFS

View File

@ -1,4 +1,6 @@
from building import *
from gcc import *
import rtconfig
import os
# The set of source files associated with this SConscript file.
@ -6,6 +8,7 @@ src = []
cwd = GetCurrentDir()
CPPPATH = [cwd + "/include"]
group = []
LOCAL_CFLAGS = ''
if GetDepend('RT_USING_DFS') and not GetDepend('RT_USING_DFS_V2'):
src = ['src/dfs.c', 'src/dfs_file.c', 'src/dfs_fs.c']
@ -13,7 +16,12 @@ if GetDepend('RT_USING_DFS') and not GetDepend('RT_USING_DFS_V2'):
if GetDepend('DFS_USING_POSIX'):
src += ['src/dfs_posix.c']
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS'], CPPPATH = CPPPATH)
if rtconfig.PLATFORM in GetGCCLikePLATFORM():
LOCAL_CFLAGS += ' -std=c99'
elif rtconfig.PLATFORM in ['armcc']:
LOCAL_CFLAGS += ' --c99'
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS'], CPPPATH = CPPPATH, LOCAL_CFLAGS = LOCAL_CFLAGS)
# search in the file system implementation
list = os.listdir(cwd)

View File

@ -0,0 +1,11 @@
# RT-Thread building script for component
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_ISO9660'], CPPPATH = CPPPATH)
Return('group')

View File

@ -0,0 +1,698 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#include <rthw.h>
#include <rtthread.h>
#include <rtservice.h>
#define DBG_TAG "dfs.iso9660"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#include "dfs_iso9660.h"
#include <dfs.h>
#include <dfs_fs.h>
#include <dfs_file.h>
#include <posix/string.h>
#include <drivers/misc.h>
#include <drivers/byteorder.h>
#include <sys/time.h>
#define ISO9660_FSTYPE_DIR 0040000
#define ISO9660_FSTYPE_REG 0100000
#define ISO9660_FSTYPE_SYMLINK 0120000
#define ISO9660_FSTYPE_MASK 0170000
#define ISO9660_BLKSZ 2048
#define ISO9660_VOLDESC_BOOT 0
#define ISO9660_VOLDESC_PRIMARY 1
#define ISO9660_VOLDESC_SUPP 2
#define ISO9660_VOLDESC_PART 3
#define ISO9660_VOLDESC_END 255
rt_packed(struct iso9660_voldesc
{
rt_uint8_t type;
rt_uint8_t magic[5];
rt_uint8_t version;
});
rt_packed(struct iso9660_date2
{
rt_uint8_t year;
rt_uint8_t month;
rt_uint8_t day;
rt_uint8_t hour;
rt_uint8_t minute;
rt_uint8_t second;
rt_uint8_t offset;
});
/* Directory entry */
rt_packed(struct iso9660_dir
{
rt_uint8_t len;
rt_uint8_t ext_sectors;
rt_le32_t first_sector;
rt_le32_t first_sector_be;
rt_le32_t size;
rt_le32_t size_be;
struct iso9660_date2 mtime;
#define FLAG_TYPE_PLAIN 0
#define FLAG_TYPE_DIR 2
#define FLAG_TYPE 3
#define FLAG_MORE_EXTENTS 0x80
rt_uint8_t flags;
rt_uint8_t file_unit_size;
rt_uint8_t interleave_gap_size;
rt_le16_t vol_seq_num;
rt_le16_t vol_seq_num_be;
#define MAX_NAMELEN 255
rt_uint8_t namelen;
char name[0];
});
rt_packed(struct iso9660_date
{
rt_uint8_t year[4];
rt_uint8_t month[2];
rt_uint8_t day[2];
rt_uint8_t hour[2];
rt_uint8_t minute[2];
rt_uint8_t second[2];
rt_uint8_t hundredth[2];
rt_uint8_t offset;
});
/* Common volume descriptor */
rt_packed(struct iso9660_common_voldesc
{
struct iso9660_voldesc voldesc;
rt_uint8_t sysname[33];
rt_uint8_t volname[32];
rt_uint8_t unused2[8];
rt_le32_t vol_space_size_le;
rt_le32_t vol_space_size_be;
rt_uint8_t escape[32];
rt_le16_t vol_set_size_le;
rt_le16_t vol_set_size_be;
rt_le16_t vol_seq_num_le;
rt_le16_t vol_seq_num_be;
rt_le16_t logical_block_size_le;
rt_le16_t logical_block_size_be;
rt_le32_t path_table_size;
rt_le32_t path_table_size_be;
rt_le32_t path_table;
rt_le32_t path_table_be;
rt_uint8_t unused3[8];
struct iso9660_dir rootdir;
rt_uint8_t unused4[624];
struct iso9660_date created;
struct iso9660_date modified;
rt_uint8_t unused5[0 /* 1201 */];
});
struct iso9660
{
struct rt_device *dev;
rt_uint8_t joliet;
rt_uint8_t swap[ISO9660_BLKSZ];
struct iso9660_common_voldesc primary, supp;
};
struct iso9660_fd
{
struct iso9660 *iso;
struct iso9660_dir dirent;
};
struct iso9660_iterate
{
struct iso9660_fd *fd;
int i, index, count;
struct dirent *dirp;
};
static void iso9660_convert_string(char *dest, rt_uint16_t *src, int len)
{
/* UTF16 to ASCII */
len >>= 1;
for (int i = 0; i < len; ++i)
{
rt_uint16_t utf16 = rt_be16_to_cpu(*src++);
if (utf16 < 0x80)
{
*dest++ = (rt_uint8_t)utf16;
}
else
{
*dest++ = '?';
}
}
*dest = '\0';
}
static void iso9660_convert_lower(char *dest, rt_uint8_t *src, int len)
{
for (int i = 0; i < len; ++i, ++src)
{
if (*src >= 'A' && *src <= 'Z')
{
*dest++ = *src - ('A' - 'a');
}
else
{
*dest++ = *src;
}
}
*dest = '\0';
}
static time_t iso9660_convert_unixtime(struct iso9660_date *date)
{
struct tm tm;
tm.tm_sec = (date->second[0] - '0') * 10 + (date->second[1] - '0');
tm.tm_min = (date->minute[0] - '0') * 10 + (date->minute[1] - '0');
tm.tm_hour = (date->hour[0] - '0') * 10 + (date->hour[1] - '0');
tm.tm_mday = (date->day[0] - '0') * 10 + (date->day[1] - '0');
tm.tm_mon = (date->month[0] - '0') * 10 + (date->month[1] - '0');
tm.tm_year = (date->year[0] - '0') * 1000 + (date->year[1] - '0') * 100 +
(date->year[2] - '0') * 10 + (date->year[3] - '0');
tm.tm_wday = 0;
return mktime(&tm);
}
static time_t iso9660_convert_unixtime2(struct iso9660_date2 *date)
{
struct tm tm;
tm.tm_sec = date->second;
tm.tm_min = date->minute;
tm.tm_hour = date->hour;
tm.tm_mday = date->day;
tm.tm_mon = date->month;
tm.tm_year = date->year + 1900;
tm.tm_wday = 0;
return mktime(&tm);
}
static struct iso9660_fd *iso9660_lookup(struct iso9660 *iso, const char *path,
struct iso9660_iterate *it)
{
rt_uint32_t lba;
rt_size_t sz, len, namelen;
char sname[MAX_NAMELEN];
struct iso9660_fd *fd;
struct iso9660_dir *dirent;
if (it)
{
fd = it->fd;
iso = fd->iso;
dirent = &fd->dirent;
/* No next entry, always goon */
len = 1;
}
else
{
if (!(fd = rt_malloc(sizeof(*fd))))
{
return fd;
}
fd->iso = iso;
dirent = iso->joliet ? &iso->supp.rootdir : &iso->primary.rootdir;
if (!rt_strcmp(path, "/"))
{
rt_memcpy(&fd->dirent, dirent, sizeof(*dirent));
return fd;
}
/* Skip the first '/' */
++path;
len = strchrnul(path, '/') - path;
}
lba = rt_le32_to_cpu(dirent->first_sector);
if (rt_device_read(iso->dev, lba, iso->swap, 1) <= 0)
{
goto _fail;
}
dirent = (void *)iso->swap;
sz = 0;
do {
/* Ignore "." and ".." */
do {
rt_uint32_t dlen = rt_le32_to_cpu(dirent->len);
dirent = (void *)dirent + dlen;
sz += dlen;
if (ISO9660_BLKSZ - sz < sizeof(*dirent))
{
/* Sector end, goto the next sector */
if (rt_device_read(iso->dev, ++lba, iso->swap, 1) <= 0)
{
goto _fail;
}
dirent = (void *)iso->swap;
sz = 0;
}
if (rt_le32_to_cpu(dirent->first_sector) == 0)
{
/* Is end, no found. */
goto _fail;
}
} while (dirent->name[0] >> 1 == 0 && rt_le32_to_cpu(dirent->namelen) == 1);
namelen = rt_le32_to_cpu(dirent->namelen);
if (iso->joliet)
{
iso9660_convert_string(sname, (rt_uint16_t *)dirent->name, namelen);
}
else
{
if (!(rt_le32_to_cpu(dirent->flags) & FLAG_TYPE_DIR))
{
/* Remove ";1" */
namelen -= 2;
}
iso9660_convert_lower(sname, (rt_uint8_t *)dirent->name, namelen);
}
if (it)
{
if (it->i < it->index)
{
goto _next;
}
if ((rt_le32_to_cpu(dirent->flags) & FLAG_TYPE) == FLAG_TYPE_DIR)
{
it->dirp->d_type = DT_DIR;
}
else
{
it->dirp->d_type = DT_REG;
}
it->dirp->d_namlen = namelen;
rt_strncpy(it->dirp->d_name, sname, namelen);
it->dirp->d_name[namelen] = '\0';
it->dirp->d_reclen = (rt_uint16_t)sizeof(struct dirent);
++it->dirp;
_next:
++it->i;
if (it->i - it->index >= it->count)
{
/* Iterate end */
return RT_NULL;
}
/* No next entry */
continue;
}
if (!rt_strncmp(sname, path, len))
{
/* The end of path, found ok */
if (!path[len])
{
rt_memcpy(&fd->dirent, dirent, sizeof(*dirent));
return fd;
}
/* Next entry */
lba = rt_le32_to_cpu(dirent->first_sector);
if (rt_device_read(iso->dev, lba, iso->swap, 1) <= 0)
{
goto _fail;
}
dirent = (void *)iso->swap;
sz = 0;
path += len + 1;
len = strchrnul(path, '/') - path;
}
} while (len);
_fail:
if (!it)
{
rt_free(fd);
}
return RT_NULL;
}
static int dfs_iso9660_open(struct dfs_file *fd)
{
struct iso9660 *iso = fd->vnode->fs->data;
fd->vnode->data = iso9660_lookup(iso, fd->vnode->path, RT_NULL);
return fd->vnode->data ? 0 : -EINVAL;
}
static int dfs_iso9660_close(struct dfs_file *fd)
{
struct iso9660_fd *iso_fd = fd->vnode->data;
rt_free(iso_fd);
return 0;
}
static int dfs_iso9660_read(struct dfs_file *fd, void *buf, size_t count)
{
rt_uint32_t pos;
void *buf_ptr;
ssize_t read_blk, toread_blk;
size_t rcount = 0, remain, size;
struct iso9660_fd *iso_fd = fd->vnode->data;
struct iso9660 *iso = iso_fd->iso;
if (fd->pos + count > rt_le32_to_cpu(iso_fd->dirent.size))
{
count = rt_le32_to_cpu(iso_fd->dirent.size) - fd->pos;
}
pos = rt_le32_to_cpu(iso_fd->dirent.first_sector);
/* Align to a sector */
if (fd->pos)
{
pos += fd->pos / ISO9660_BLKSZ;
remain = fd->pos & (ISO9660_BLKSZ - 1);
if (rt_device_read(iso->dev, pos, iso->swap, 1) <= 0)
{
return -EIO;
}
size = rt_min_t(size_t, ISO9660_BLKSZ - remain, count);
rt_memcpy(buf, &iso->swap[remain], size);
rcount += size;
count -= size;
buf += size;
pos += 1;
fd->pos += size;
if (!count)
{
goto _end;
}
}
remain = count & (ISO9660_BLKSZ - 1);
count = rt_max_t(size_t, count / ISO9660_BLKSZ, 1);
while ((ssize_t)count > 0)
{
if (count == 1)
{
buf_ptr = iso->swap;
toread_blk = 1;
}
else
{
buf_ptr = buf;
toread_blk = count;
}
read_blk = rt_device_read(iso->dev, pos, buf_ptr, toread_blk);
if (read_blk <= 0)
{
return (int)read_blk;
}
if (count == 1)
{
size = remain;
rt_memcpy(buf, iso->swap, size);
}
else
{
size = read_blk * ISO9660_BLKSZ;
}
rcount += size;
count -= read_blk;
buf += size;
pos += read_blk;
fd->pos += size;
}
_end:
return rcount;
}
static off_t dfs_iso9660_lseek(struct dfs_file *fd, off_t offset)
{
int ret = -EIO;
if (offset <= fd->vnode->size)
{
fd->pos = offset;
ret = fd->pos;
}
return ret;
}
static int dfs_iso9660_getdents(struct dfs_file *fd, struct dirent *dirp, uint32_t count)
{
struct iso9660_iterate it;
struct iso9660_fd *iso_fd = fd->vnode->data;
count = (count / sizeof(struct dirent));
if (!count)
{
return -EINVAL;
}
it.fd = iso_fd;
it.i = 0;
it.index = fd->pos;
it.count = count;
it.dirp = dirp;
iso9660_lookup(RT_NULL, RT_NULL, &it);
count = it.i - it.index;
if (count > 0)
{
fd->pos += count;
}
count *= sizeof(struct dirent);
return count;
}
static const struct dfs_file_ops _iso9660_fops =
{
.open = dfs_iso9660_open,
.close = dfs_iso9660_close,
.read = dfs_iso9660_read,
.lseek = dfs_iso9660_lseek,
.getdents = dfs_iso9660_getdents,
};
static int dfs_iso9660_mount(struct dfs_filesystem *fs,
unsigned long rwflag, const void *data)
{
int err;
struct iso9660 *iso;
struct iso9660_voldesc *voldesc;
struct rt_device_blk_geometry geometry;
if (!(iso = rt_malloc(sizeof(*iso))))
{
return -RT_ENOMEM;
}
iso->dev = fs->dev_id;
rt_device_control(iso->dev, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
if (geometry.bytes_per_sector != ISO9660_BLKSZ)
{
LOG_E("%s: Logical block size = %d is not supported",
iso->dev->parent.name, geometry.bytes_per_sector);
err = -EINVAL;
goto _fail;
}
iso->primary.rootdir.first_sector = 0;
iso->supp.rootdir.first_sector = 0;
/* LBA 0-15 is the bootloader's information */
for (int lba = 16; ; ++lba)
{
if (rt_device_read(iso->dev, lba, &iso->swap, 1) <= 0)
{
err = -EIO;
goto _fail;
}
voldesc = (void *)iso->swap;
if (rt_strncmp((char *)voldesc->magic, "CD001", 5))
{
LOG_E("%s: Invalid magic \"%s\"", voldesc->magic);
err = -EINVAL;
goto _fail;
}
if (voldesc->type == ISO9660_VOLDESC_BOOT)
{
LOG_D("System Name: %s", ((struct iso9660_common_voldesc *)voldesc)->sysname);
LOG_D("Volume Name: %s", ((struct iso9660_common_voldesc *)voldesc)->volname);
}
else if (voldesc->type == ISO9660_VOLDESC_PRIMARY)
{
iso->joliet = 0;
rt_memcpy(&iso->primary, &iso->swap, sizeof(iso->primary));
}
else if (voldesc->type == ISO9660_VOLDESC_SUPP)
{
rt_memcpy(&iso->supp, &iso->swap, sizeof(iso->supp));
if (iso->supp.escape[0] == 0x25 && iso->supp.escape[1] == 0x2f)
{
if (iso->supp.escape[2] == 0x40)
{
iso->joliet = 1;
}
else if (iso->supp.escape[2] == 0x43)
{
iso->joliet = 2;
}
else if (iso->supp.escape[2] == 0x45)
{
iso->joliet = 3;
}
else
{
continue;
}
}
}
else if (voldesc->type == ISO9660_VOLDESC_PART)
{
LOG_D("System Name: %s", ((struct iso9660_common_voldesc *)voldesc)->sysname);
LOG_D("Volume Name: %s", ((struct iso9660_common_voldesc *)voldesc)->volname);
}
else if (voldesc->type == ISO9660_VOLDESC_END)
{
break;
}
}
if (!iso->primary.rootdir.first_sector || !iso->supp.rootdir.first_sector)
{
LOG_E("No primary or secondary partition found");
err = -EINVAL;
goto _fail;
}
fs->data = iso;
return 0;
_fail:
rt_free(iso);
return err;
}
static int dfs_iso9660_unmount(struct dfs_filesystem *fs)
{
struct iso9660 *iso = fs->data;
rt_free(iso);
return 0;
}
static int dfs_iso9660_stat(struct dfs_filesystem *fs,
const char *filename, struct stat *st)
{
struct iso9660 *iso = fs->data;
struct iso9660_fd *fd = iso9660_lookup(iso, filename, RT_NULL);
if (!fd)
{
return -EINVAL;
}
st->st_dev = 0;
st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
S_IWUSR | S_IWGRP | S_IWOTH;
if ((fd->dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR)
{
st->st_mode &= ~S_IFREG;
st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
}
st->st_atime = iso9660_convert_unixtime(iso->joliet ?
&iso->supp.created : &iso->primary.created);
st->st_mtime = iso9660_convert_unixtime2(&fd->dirent.mtime);
st->st_size = rt_le32_to_cpu(fd->dirent.size);
rt_free(fd);
return 0;
}
static const struct dfs_filesystem_ops _iso9660 =
{
.name = "iso9660",
.flags = DFS_FS_FLAG_DEFAULT,
.fops = &_iso9660_fops,
.mount = dfs_iso9660_mount,
.unmount = dfs_iso9660_unmount,
.stat = dfs_iso9660_stat,
};
int dfs_iso9660_init(void)
{
/* register iso9660 file system */
return dfs_register(&_iso9660);
}
INIT_COMPONENT_EXPORT(dfs_iso9660_init);

View File

@ -0,0 +1,16 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#ifndef __DFS_ISO9660_H__
#define __DFS_ISO9660_H__
int dfs_iso9660_init(void);
#endif /* __DFS_ISO9660_H__ */

View File

@ -92,7 +92,7 @@ struct ramfs_dirent *dfs_ramfs_lookup(struct dfs_ramfs *ramfs,
return NULL;
}
int dfs_ramfs_read(struct dfs_file *file, void *buf, size_t count)
ssize_t dfs_ramfs_read(struct dfs_file *file, void *buf, size_t count)
{
rt_size_t length;
struct ramfs_dirent *dirent;
@ -114,7 +114,7 @@ int dfs_ramfs_read(struct dfs_file *file, void *buf, size_t count)
return length;
}
int dfs_ramfs_write(struct dfs_file *fd, const void *buf, size_t count)
ssize_t dfs_ramfs_write(struct dfs_file *fd, const void *buf, size_t count)
{
struct ramfs_dirent *dirent;
struct dfs_ramfs *ramfs;
@ -151,7 +151,7 @@ int dfs_ramfs_write(struct dfs_file *fd, const void *buf, size_t count)
return count;
}
int dfs_ramfs_lseek(struct dfs_file *file, off_t offset)
off_t dfs_ramfs_lseek(struct dfs_file *file, off_t offset)
{
if (offset <= (off_t)file->vnode->size)
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@ -107,7 +107,8 @@ int dfs_init(void)
INIT_PREV_EXPORT(dfs_init);
/**
* this function will lock device file system.
* @brief this function will lock device file system.
* this lock (fslock) is used for protecting filesystem_operation_table and filesystem_table.
*
* @note please don't invoke it on ISR.
*/
@ -126,6 +127,12 @@ void dfs_lock(void)
}
}
/**
* @brief this function will lock file descriptors.
* this lock (fdlock) is used for protecting fd table (_fdtab).
*
* @note please don't invoke it on ISR.
*/
void dfs_file_lock(void)
{
rt_err_t result = -RT_EBUSY;
@ -142,7 +149,7 @@ void dfs_file_lock(void)
}
/**
* this function will lock device file system.
* @brief this function will unlock device file system.
*
* @note please don't invoke it on ISR.
*/
@ -151,33 +158,56 @@ void dfs_unlock(void)
rt_mutex_release(&fslock);
}
#ifdef DFS_USING_POSIX
/**
* @brief this function will unlock fd table.
*/
void dfs_file_unlock(void)
{
rt_mutex_release(&fdlock);
}
#ifdef DFS_USING_POSIX
/**
* @brief Expand the file descriptor table to accommodate a specific file descriptor.
*
* This function ensures that the file descriptor table in the given `dfs_fdtable` structure
* has sufficient capacity to include the specified file descriptor `fd`. If the table
* needs to be expanded, it reallocates memory and initializes new slots to `NULL`.
*
* @param fdt Pointer to the `dfs_fdtable` structure representing the file descriptor table.
* @param fd The file descriptor that the table must accommodate.
* @return int
* - The input file descriptor `fd` if it is within the current or newly expanded table's capacity.
* - `-1` if the requested file descriptor exceeds `DFS_FD_MAX` or memory allocation fails.
*/
static int fd_slot_expand(struct dfs_fdtable *fdt, int fd)
{
int nr;
int index;
struct dfs_file **fds = NULL;
/* If the file descriptor is already within the current capacity, no expansion is needed.*/
if (fd < fdt->maxfd)
{
return fd;
}
/* If the file descriptor exceeds the maximum allowable limit, return an error.*/
if (fd >= DFS_FD_MAX)
{
return -1;
}
/* Calculate the new capacity, rounding up to the nearest multiple of 4.*/
nr = ((fd + 4) & ~3);
/* Ensure the new capacity does not exceed the maximum limit.*/
if (nr > DFS_FD_MAX)
{
nr = DFS_FD_MAX;
}
/* Attempt to reallocate the file descriptor table to the new capacity.*/
fds = (struct dfs_file **)rt_realloc(fdt->fds, nr * sizeof(struct dfs_file *));
if (!fds)
{
@ -189,12 +219,23 @@ static int fd_slot_expand(struct dfs_fdtable *fdt, int fd)
{
fds[index] = NULL;
}
/* Update the file descriptor table and its capacity.*/
fdt->fds = fds;
fdt->maxfd = nr;
return fd;
}
/**
* @brief Allocate a file descriptor slot starting from a specified index.
*
* @param fdt fdt Pointer to the `dfs_fdtable` structure representing the file descriptor table.
* @param startfd The starting index for the search for an empty slot.
* @return int
* - The index of the first available slot if successful.
* - `-1` if no slot is available or if table expansion fails
*/
static int fd_slot_alloc(struct dfs_fdtable *fdt, int startfd)
{
int idx;
@ -219,6 +260,17 @@ static int fd_slot_alloc(struct dfs_fdtable *fdt, int startfd)
}
return idx;
}
/**
* @brief Allocate a new file descriptor and associate it with a newly allocated `struct dfs_file`.
*
* @param fdt Pointer to the `dfs_fdtable` structure representing the file descriptor table.
* @param startfd The starting index for searching an available file descriptor slot.
*
* @return
* - The index of the allocated file descriptor if successful.
* - `-1` if no slot is available or memory allocation fails.
*/
static int fd_alloc(struct dfs_fdtable *fdt, int startfd)
{
int idx;
@ -323,7 +375,11 @@ struct dfs_file *fd_get(int fd)
/**
* @ingroup Fd
*
* This function will put the file descriptor.
* @brief This function will release the file descriptor.
*
* This function releases a file descriptor slot in the file descriptor table, decrements reference
* counts, and cleans up resources associated with the `dfs_file` and `dfs_vnode` structures when applicable.
*
*/
void fdt_fd_release(struct dfs_fdtable* fdt, int fd)
{
@ -378,6 +434,20 @@ void fd_release(int fd)
fdt_fd_release(fdt, fd);
}
/**
* @brief Duplicates a file descriptor.
*
* This function duplicates an existing file descriptor (`oldfd`) and returns
* a new file descriptor that refers to the same underlying file object.
*
* @param oldfd The file descriptor to duplicate. It must be a valid file
* descriptor within the range of allocated descriptors.
*
* @return The new file descriptor if successful, or a negative value
* (e.g., -1) if an error occurs.
*
* @see sys_dup2()
*/
rt_err_t sys_dup(int oldfd)
{
int newfd = -1;
@ -470,6 +540,23 @@ int fd_is_open(const char *pathname)
return -1;
}
/**
* @brief Duplicates a file descriptor to a specified file descriptor.
*
* This function duplicates an existing file descriptor (`oldfd`) and assigns it
* to the specified file descriptor (`newfd`).
*
* @param oldfd The file descriptor to duplicate. It must be a valid and open file
* descriptor within the range of allocated descriptors.
* @param newfd The target file descriptor. If `newfd` is already in use, it will
* be closed before duplication. If `newfd` exceeds the current file
* descriptor table size, the table will be expanded to accommodate it.
*
* @return The value of `newfd` on success, or a negative value (e.g., -1) if an
* error occurs.
*
* @see sys_dup()
*/
rt_err_t sys_dup2(int oldfd, int newfd)
{
struct dfs_fdtable *fdt = NULL;
@ -550,6 +637,10 @@ static int fd_get_fd_index_form_fdt(struct dfs_fdtable *fdt, struct dfs_file *fi
return fd;
}
/**
* @brief get fd (index) by dfs file object.
*
*/
int fd_get_fd_index(struct dfs_file *file)
{
struct dfs_fdtable *fdt;
@ -558,6 +649,21 @@ int fd_get_fd_index(struct dfs_file *file)
return fd_get_fd_index_form_fdt(fdt, file);
}
/**
* @brief Associates a file descriptor with a file object.
*
* This function associates a given file descriptor (`fd`) with a specified
* file object (`file`) in the file descriptor table (`fdt`).
*
* @param fdt The file descriptor table to operate on. It must be a valid
* and initialized `dfs_fdtable` structure.
* @param fd The file descriptor to associate. It must be within the range
* of allocated file descriptors and currently unoccupied.
* @param file The file object to associate with the file descriptor. It must
* be a valid and initialized `dfs_file` structure.
*
* @return The value of `fd` on success, or -1 if an error occurs.
*/
int fd_associate(struct dfs_fdtable *fdt, int fd, struct dfs_file *file)
{
int retfd = -1;
@ -591,6 +697,10 @@ exit:
return retfd;
}
/**
* @brief initialize a dfs file object.
*
*/
void fd_init(struct dfs_file *fd)
{
if (fd)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@ -18,10 +18,12 @@
#define DFS_VNODE_HASH_NR 128
/*dfs vnode manager, for saving and searching vnodes.*/
struct dfs_vnode_mgr
{
struct rt_mutex lock;
rt_list_t head[DFS_VNODE_HASH_NR];
struct rt_mutex lock; /* mutex for protecting dfs vnode lists */
rt_list_t head[DFS_VNODE_HASH_NR]; /* a group of dfs vnode lists, the dfs vnode is inserted to one of the lists
according to path string's hash-value mod DFS_VNODE_HASH_NR. */
};
static struct dfs_vnode_mgr dfs_fm;
@ -36,6 +38,10 @@ void dfs_fm_unlock(void)
rt_mutex_release(&dfs_fm.lock);
}
/**
* @brief Initialize dfs vnode manager structure, including a lock and hash tables for vnode.
*
*/
void dfs_vnode_mgr_init(void)
{
int i = 0;
@ -47,6 +53,23 @@ void dfs_vnode_mgr_init(void)
}
}
/**
* @brief Initialize a DFS vnode structure.
*
* @param vnode Pointer to the DFS vnode structure to be initialized.
* The caller must ensure this is a valid, allocated structure.
* @param type The type of the vnode, representing its role or category (e.g., regular file, directory).
* @param fops Pointer to the file operations structure associated with this vnode.
* This structure defines the behavior of the vnode for operations such as open, read, write, etc.
* If `fops` is NULL, the vnode will have no associated file operations.
*
* @return 0 on success, or a negative error code on failure.
*
* @note The caller should ensure that:
* - The `vnode` pointer is valid and properly allocated.
* - The `fops` pointer (if not NULL) points to a valid `struct dfs_file_ops`
* instance, where all necessary function pointers are properly set.
*/
int dfs_vnode_init(struct dfs_vnode *vnode, int type, const struct dfs_file_ops *fops)
{
if (vnode)
@ -64,7 +87,7 @@ int dfs_vnode_init(struct dfs_vnode *vnode, int type, const struct dfs_file_ops
/* BKDR Hash Function */
static unsigned int bkdr_hash(const char *str)
{
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
unsigned int seed = 131; /* 31 131 1313 13131 131313 etc..*/
unsigned int hash = 0;
while (*str)
@ -75,6 +98,22 @@ static unsigned int bkdr_hash(const char *str)
return (hash % DFS_VNODE_HASH_NR);
}
/**
* @brief Find a DFS vnode by its path.
*
* This function searches for a vnode in the vnode hash table using the specified path.
* If found, it returns a pointer to the vnode and updates the hash head if required.
*
* @param path The file path to search for. This should be a valid null-terminated string.
* @param hash_head Pointer to a location where the hash table head associated with the vnode
* can be stored. This can be NULL if the hash head is not needed.
*
* @return Pointer to the DFS vnode if found, or NULL if no vnode matches the specified path.
*
* @note The caller must ensure that:
* - The `path` pointer is valid and points to a properly null-terminated string.
* - If `hash_head` is not NULL, it points to a valid location to store the hash head.
*/
static struct dfs_vnode *dfs_vnode_find(const char *path, rt_list_t **hash_head)
{
struct dfs_vnode *vnode = NULL;
@ -329,11 +368,12 @@ int dfs_file_close(struct dfs_file *fd)
}
/**
* this function will perform a io control on a file descriptor.
* this function will perform an io control on a file descriptor.
*
* @param fd the file descriptor.
* @param cmd the command to send to file descriptor.
* @param args the argument to send to file descriptor.
* - When `cmd` is `F_SETFL`, an additional integer argument specifies the new status flags.
*
* @return 0 on successful, -1 on failed.
*/
@ -846,7 +886,7 @@ void cat(const char *filename)
{
buffer[length] = '\0';
rt_device_t out_device = rt_console_get_device();
rt_device_write(out_device, 0, (void *)buffer, sizeof(buffer));
rt_device_write(out_device, 0, (void *)buffer, length);
}
} while (length > 0);
rt_kprintf("\n");
@ -1026,14 +1066,14 @@ void copy(const char *src, const char *dst)
flag |= FLAG_DST_IS_FILE;
}
//2. check status
/*2. check status*/
if ((flag & FLAG_SRC_IS_DIR) && (flag & FLAG_DST_IS_FILE))
{
rt_kprintf("cp faild, cp dir to file is not permitted!\n");
return ;
}
//3. do copy
/*3. do copy*/
if (flag & FLAG_SRC_IS_FILE)
{
if (flag & FLAG_DST_IS_DIR)
@ -1053,7 +1093,7 @@ void copy(const char *src, const char *dst)
copyfile(src, dst);
}
}
else //flag & FLAG_SRC_IS_DIR
else /*flag & FLAG_SRC_IS_DIR*/
{
if (flag & FLAG_DST_IS_DIR)
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@ -322,8 +322,8 @@ int dfs_mount(const char *device_name,
/* open device, but do not check the status of device */
if (dev_id != NULL)
{
if (rt_device_open(fs->dev_id,
RT_DEVICE_OFLAG_RDWR) != RT_EOK)
if (rt_device_open(fs->dev_id, RT_DEVICE_OFLAG_RDWR) != RT_EOK &&
rt_device_open(fs->dev_id, RT_DEVICE_OFLAG_RDONLY) != RT_EOK)
{
/* The underlying device has error, clear the entry. */
dfs_lock();
@ -529,7 +529,8 @@ int dfs_mount_device(rt_device_t dev)
{
int index = 0;
if(dev == RT_NULL) {
if(dev == RT_NULL)
{
rt_kprintf("the device is NULL to be mounted.\n");
return -RT_ERROR;
}
@ -538,7 +539,8 @@ int dfs_mount_device(rt_device_t dev)
{
if (mount_table[index].path == NULL) break;
if(strcmp(mount_table[index].device_name, dev->parent.name) == 0) {
if(strcmp(mount_table[index].device_name, dev->parent.name) == 0)
{
if (dfs_mount(mount_table[index].device_name,
mount_table[index].path,
mount_table[index].filesystemtype,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@ -28,7 +28,17 @@
* return a file descriptor according specified flags.
*
* @param file the path name of file.
* @param flags the file open flags.
* @param flags the file open flags. Common values include:
* - Access modes (mutually exclusive):
* - `O_RDONLY`: Open for read-only access.
* - `O_WRONLY`: Open for write-only access.
* - `O_RDWR`: Open for both reading and writing.
* - File status flags (can be combined with bitwise OR `|`):
* - `O_CREAT`: Create the file if it does not exist. Requires a `mode` argument.
* - `O_TRUNC`: Truncate the file to zero length if it already exists.
* - `O_APPEND`: Append writes to the end of the file.
* - `O_EXCL`: Ensure that `O_CREAT` creates the file exclusively.
* - Other platform-specific flags
*
* @return the non-negative integer on successful open, others for failed.
*/
@ -65,6 +75,22 @@ RTM_EXPORT(open);
#ifndef AT_FDCWD
#define AT_FDCWD (-100)
#endif
/**
* @brief Opens a file relative to a directory file descriptor.
*
* @param dirfd The file descriptor of the directory to base the relative path on.
* @param pathname The path to the file to be opened, relative to the directory specified by `dirfd`.
* Can be an absolute path (in which case `dirfd` is ignored).
* @param flags File access and status flags (e.g., `O_RDONLY`, `O_WRONLY`, `O_CREAT`).
*
* @return On success, returns a new file descriptor for the opened file.
* On failure, returns `-1` and sets `errno` to indicate the error.
*
* @note When using relative paths, ensure `dirfd` is a valid directory descriptor.
* When `pathname` is absolute, the `dirfd` argument is ignored.
*
*/
int openat(int dirfd, const char *path, int flag, ...)
{
struct dfs_file *d;
@ -241,14 +267,22 @@ ssize_t write(int fd, const void *buf, size_t len)
RTM_EXPORT(write);
/**
* this function is a POSIX compliant version, which will seek the offset for
* this function is a POSIX compliant version, which will Reposition the file offset for
* an open file descriptor.
*
* @param fd the file descriptor.
* @param offset the offset to be seeked.
* @param whence the directory of seek.
* The `lseek` function sets the file offset for the file descriptor `fd`
* to a new value, determined by the `offset` and `whence` parameters.
* It can be used to seek to specific positions in a file for reading or writing.
*
* @return the current read/write position in the file, or -1 on failed.
* @param fd the file descriptor.
* @param offset The offset, in bytes, to set the file position.
* The meaning of `offset` depends on the value of `whence`.
* @param whence the directive of seek. It can be one of:
* - `SEEK_SET`: Set the offset to `offset` bytes from the beginning of the file.
* - `SEEK_CUR`: Set the offset to its current location plus `offset` bytes.
* - `SEEK_END`: Set the offset to the size of the file plus `offset` bytes.
*
* @return the resulting read/write position in the file, or -1 on failed.
*/
off_t lseek(int fd, off_t offset, int whence)
{
@ -436,9 +470,15 @@ RTM_EXPORT(fsync);
* control functions on devices.
*
* @param fildes the file description
* @param cmd the specified command
* @param cmd the specified command, Common values include:
* - `F_DUPFD`: Duplicate a file descriptor.
* - `F_GETFD`: Get the file descriptor flags.
* - `F_SETFD`: Set the file descriptor flags.
* - `F_GETFL`: Get the file status flags.
* - `F_SETFL`: Set the file status flags.
* @param ... represents the additional information that is needed by this
* specific device to perform the requested function.
* specific device to perform the requested function. For example:
* - When `cmd` is `F_SETFL`, an additional integer argument specifies the new status flags.
*
* @return 0 on successful completion. Otherwise, -1 shall be returned and errno
* set to indicate the error.
@ -595,7 +635,7 @@ RTM_EXPORT(fstatfs);
* this function is a POSIX compliant version, which will make a directory
*
* @param path the directory path to be made.
* @param mode
* @param mode The permission mode for the new directory (unused here, can be set to 0).
*
* @return 0 on successful, others on failed.
*/

View File

@ -786,18 +786,18 @@ static ssize_t dfs_cromfs_read(struct dfs_file *file, void *buf, size_t count, o
rt_err_t result = RT_EOK;
file_info *fi = NULL;
cromfs_info *ci = NULL;
uint32_t length = 0;
ssize_t length = 0;
ci = (cromfs_info *)file->dentry->mnt->data;
fi = (file_info *)file->vnode->data;
if (count < file->vnode->size - *pos)
if ((off_t)count < (off_t)file->vnode->size - *pos)
{
length = count;
}
else
{
length = file->vnode->size - *pos;
length = (off_t)file->vnode->size - *pos;
}
if (length > 0)

View File

@ -11,6 +11,9 @@
#ifndef __DFS_CROMFS_H__
#define __DFS_CROMFS_H__
#include <stdint.h>
int dfs_cromfs_init(void);
uint8_t *cromfs_get_partition_data(uint32_t *len);
#endif /*__DFS_CROMFS_H__*/

View File

@ -77,6 +77,7 @@ static int dfs_devfs_open(struct dfs_file *file)
}
}
}
rt_free(device_name);
}
return ret;
@ -113,6 +114,29 @@ static int dfs_devfs_close(struct dfs_file *file)
return ret;
}
static rt_ubase_t _get_unit_shift(rt_device_t device)
{
rt_ubase_t shift = 0;
/**
* transfer unit size from POSIX RW(in bytes) to rt_device_R/W
* (block size for blk device, otherwise in bytes).
*/
if (device->type == RT_Device_Class_Block)
{
struct rt_device_blk_geometry geometry = {0};
/* default to 512 */
shift = 9;
if (!rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry))
{
shift = __rt_ffs(geometry.block_size) - 1;
}
}
return shift;
}
static ssize_t dfs_devfs_read(struct dfs_file *file, void *buf, size_t count, off_t *pos)
{
ssize_t ret = -RT_EIO;
@ -135,9 +159,14 @@ static ssize_t dfs_devfs_read(struct dfs_file *file, void *buf, size_t count, of
if (device->ops)
#endif /* RT_USING_POSIX_DEVIO */
{
/* read device data */
ret = rt_device_read(device, *pos, buf, count);
*pos += ret;
rt_ubase_t shift = _get_unit_shift(device);
ret = rt_device_read(device, *pos, buf, count >> shift);
if (ret > 0)
{
ret <<= shift;
*pos += ret;
}
}
}
@ -169,9 +198,15 @@ static ssize_t dfs_devfs_write(struct dfs_file *file, const void *buf, size_t co
if (device->ops)
#endif /* RT_USING_POSIX_DEVIO */
{
rt_ubase_t shift = _get_unit_shift(device);
/* read device data */
ret = rt_device_write(device, *pos, buf, count);
*pos += ret;
ret = rt_device_write(device, *pos, buf, count >> shift);
if (ret > 0)
{
ret <<= shift;
*pos += ret;
}
}
}
@ -265,7 +300,7 @@ static int dfs_devfs_flush(struct dfs_file *file)
static off_t dfs_devfs_lseek(struct dfs_file *file, off_t offset, int wherece)
{
off_t ret = 0;
off_t ret = -EPERM;
rt_device_t device;
RT_ASSERT(file != RT_NULL);
@ -408,16 +443,16 @@ mode_t dfs_devfs_device_to_mode(struct rt_device *device)
switch (device->type)
{
case RT_Device_Class_Char:
mode = S_IFCHR | 0777;
mode = S_IFCHR | 0666;
break;
case RT_Device_Class_Block:
mode = S_IFBLK | 0777;
mode = S_IFBLK | 0666;
break;
case RT_Device_Class_Pipe:
mode = S_IFIFO | 0777;
mode = S_IFIFO | 0666;
break;
default:
mode = S_IFCHR | 0777;
mode = S_IFCHR | 0666;
break;
}

View File

@ -18,6 +18,7 @@
#include <dfs_dentry.h>
#include <dfs_file.h>
#include <dfs_mnt.h>
#include <dfs_vfs.h>
#include <devfs.h>
#include <unistd.h>
@ -34,10 +35,9 @@ struct devtmpfs_file
char name[DIRENT_NAME_MAX]; /* file name */
rt_uint32_t type; /* file type */
rt_list_t subdirs; /* file subdir list */
rt_list_t sibling; /* file sibling list */
struct dfs_vfs_node node; /* file node in the devtmpfs */
struct devtmpfs_sb *sb; /* superblock ptr */
struct devtmpfs_sb *sb; /* superblock ptr */
rt_uint32_t mode;
char *link;
@ -48,7 +48,6 @@ struct devtmpfs_sb
rt_uint32_t magic; /* TMPFS_MAGIC */
struct devtmpfs_file root; /* root dir */
rt_size_t df_size; /* df size */
rt_list_t sibling; /* sb sibling list */
struct rt_spinlock lock; /* tmpfs lock */
};
@ -111,15 +110,13 @@ static int _get_subdir(const char *path, char *name)
#if 0
static int _free_subdir(struct devtmpfs_file *dfile)
{
struct devtmpfs_file *file;
rt_list_t *list, *temp_list;
struct devtmpfs_file *file, *tmp;
struct devtmpfs_sb *superblock;
RT_ASSERT(dfile->type == TMPFS_TYPE_DIR);
rt_list_for_each_safe(list, temp_list, &dfile->subdirs)
dfs_vfs_for_each_subnode(file, tmp, dfile, node)
{
file = rt_list_entry(list, struct devtmpfs_file, sibling);
if (file->type == TMPFS_TYPE_DIR)
{
_free_subdir(file);
@ -134,7 +131,7 @@ static int _free_subdir(struct devtmpfs_file *dfile)
RT_ASSERT(superblock);
rt_spin_lock(&superblock->lock);
rt_list_remove(&(file->sibling));
dfs_vfs_remove_node(&file->node);
rt_spin_unlock(&superblock->lock);
rt_free(file);
@ -152,14 +149,12 @@ static int devtmpfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void
{
superblock->df_size = sizeof(struct devtmpfs_sb);
superblock->magic = TMPFS_MAGIC;
rt_list_init(&superblock->sibling);
superblock->root.name[0] = '/';
superblock->root.sb = superblock;
superblock->root.type = TMPFS_TYPE_DIR;
superblock->root.mode = S_IFDIR | (S_IRUSR | S_IRGRP | S_IROTH) | (S_IXUSR | S_IXGRP | S_IXOTH);
rt_list_init(&superblock->root.sibling);
rt_list_init(&superblock->root.subdirs);
dfs_vfs_init_node(&superblock->root.node);
rt_spin_lock_init(&superblock->lock);
@ -193,8 +188,7 @@ static struct devtmpfs_file *devtmpfs_file_lookup(struct devtmpfs_sb *superblock
{
const char *subpath, *curpath, *filename = RT_NULL;
char subdir_name[DIRENT_NAME_MAX];
struct devtmpfs_file *file, *curfile;
rt_list_t *list;
struct devtmpfs_file *file, *curfile, *tmp;
subpath = path;
while (*subpath == '/' && *subpath)
@ -222,9 +216,8 @@ find_subpath:
rt_spin_lock(&superblock->lock);
rt_list_for_each(list, &curfile->subdirs)
dfs_vfs_for_each_subnode(file, tmp, curfile, node)
{
file = rt_list_entry(list, struct devtmpfs_file, sibling);
if (filename) /* find file */
{
if (rt_strcmp(file->name, filename) == 0)
@ -293,7 +286,9 @@ static int devtmpfs_stat(struct dfs_dentry *dentry, struct stat *st)
static int devtmpfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
{
struct devtmpfs_file *d_file;
rt_size_t index, end;
struct dirent *d;
struct devtmpfs_file *d_file, *n_file = RT_NULL, *tmp;
struct devtmpfs_sb *superblock;
RT_ASSERT(file);
@ -306,11 +301,6 @@ static int devtmpfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_
d_file = devtmpfs_file_lookup(superblock, file->dentry->pathname);
if (d_file)
{
rt_size_t index, end;
struct dirent *d;
struct devtmpfs_file *n_file;
rt_list_t *list;
/* make integer count */
count = (count / sizeof(struct dirent));
if (count == 0)
@ -322,12 +312,10 @@ static int devtmpfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_
index = 0;
count = 0;
rt_list_for_each(list, &d_file->subdirs)
dfs_vfs_for_each_subnode(n_file, tmp, d_file, node)
{
if (index >= (rt_size_t)file->fpos)
{
n_file = rt_list_entry(list, struct devtmpfs_file, sibling);
d = dirp + count;
if (n_file->type == TMPFS_TYPE_FILE)
{
@ -378,8 +366,7 @@ static int devtmpfs_symlink(struct dfs_dentry *parent_dentry, const char *target
strncpy(l_file->name, linkpath, DIRENT_NAME_MAX - 1);
rt_list_init(&(l_file->subdirs));
rt_list_init(&(l_file->sibling));
dfs_vfs_init_node(&l_file->node);
l_file->sb = superblock;
l_file->type = TMPFS_TYPE_FILE;
l_file->mode = p_file->mode;
@ -388,7 +375,7 @@ static int devtmpfs_symlink(struct dfs_dentry *parent_dentry, const char *target
l_file->link = rt_strdup(target);
rt_spin_lock(&superblock->lock);
rt_list_insert_after(&(p_file->subdirs), &(l_file->sibling));
dfs_vfs_append_node(&p_file->node, &l_file->node);
rt_spin_unlock(&superblock->lock);
}
}
@ -460,7 +447,7 @@ static int devtmpfs_unlink(struct dfs_dentry *dentry)
}
rt_spin_lock(&superblock->lock);
rt_list_remove(&(d_file->sibling));
dfs_vfs_remove_node(&d_file->node);
rt_spin_unlock(&superblock->lock);
rt_free(d_file);
@ -537,8 +524,7 @@ static struct dfs_vnode *devtmpfs_create_vnode(struct dfs_dentry *dentry, int ty
strncpy(d_file->name, file_name, DIRENT_NAME_MAX);
rt_list_init(&(d_file->subdirs));
rt_list_init(&(d_file->sibling));
dfs_vfs_init_node(&d_file->node);
d_file->sb = superblock;
vnode->nlink = 1;
@ -563,7 +549,7 @@ static struct dfs_vnode *devtmpfs_create_vnode(struct dfs_dentry *dentry, int ty
d_file->mode = vnode->mode;
rt_spin_lock(&superblock->lock);
rt_list_insert_after(&(p_file->subdirs), &(d_file->sibling));
dfs_vfs_append_node(&p_file->node, &d_file->node);
rt_spin_unlock(&superblock->lock);
}

View File

@ -0,0 +1,166 @@
# 进程文件系统 (procfs)
## 数据结构
```c
struct proc_dentry
{
rt_uint32_t mode;
rt_atomic_t ref_count;
struct proc_dentry *parent;
struct dfs_vfs_node node;
const struct dfs_file_ops *fops;
const struct proc_ops *ops;
char *name;
void *data;
};
```
```log
root { mode: S_IFDIR, ref_count: 1, parent: root, name: /, child->next: file1->node }
|
|—— file1 { mode: S_IFREG, ref_count: 1, parent: root, name: file1, node->next: link1->node }
|—— link1 { mode: S_IFLNK, ref_count: 1, parent: root, name: link1, data: fullpath, node->next: dir1->node }
|—— dir1 { mode: S_IFDIR, ref_count: 1, parent: root, name: dir1, node->next: file3->node, child->next: file2->node }
| |
| |—— dir2 { mode: S_IFDIR, ref_count: 1, parent: dir1, name: dir2, node->next: link2->node }
| |—— link2 { mode: S_IFLNK, ref_count: 1, parent: dir1, name: link2, data: fullpath, node->next: file2->node }
| |—— file2 { mode: S_IFREG, ref_count: 1, parent: dir1, name: file2 }
|
|—— file3 { mode: S_IFREG, ref_count: 1, parent: root, name: file3 }
```
## API 介绍
```c
struct proc_dentry *dfs_proc_find(const char *name);
struct proc_dentry *proc_mkdir_data(const char *name, mode_t mode, struct proc_dentry *parent,
const struct dfs_file_ops *fops, void *data);
struct proc_dentry *proc_mkdir_mode(const char *name, mode_t mode, struct proc_dentry *parent);
struct proc_dentry *proc_mkdir(const char *name, struct proc_dentry *parent);
struct proc_dentry *proc_create_data(const char *name, mode_t mode, struct proc_dentry *parent,
const struct dfs_file_ops *fops, void *data);
struct proc_dentry *proc_symlink(const char *name, struct proc_dentry *parent, const char *dest);
struct proc_dentry *proc_acquire(struct proc_dentry *dentry);
void proc_release(struct proc_dentry *dentry);
void proc_remove(struct proc_dentry *dentry);
```
- dfs_proc_find
查找指定节点,并返回节点数据指针
| 入参 | 说明 |
| ---- | ---------------------------------------------------- |
| name | 从 procfs 的 root 起始的完整路径,比如 “/dir1/file2” |
- proc_mkdir_data
创建一个目录,并返回节点数据指针
| 入参 | 说明 |
| ------ | ------------------------------------------------------------ |
| name | 从 procfs 的 root 起始的完整路径,比如 “/dir1/file2”<br />从 parent 起始的完整路径 |
| mode | 权限配置 |
| parent | 指定创建目录的起始节点 |
| fops | 文件操作接口配置 |
| data | 私有数据 |
- proc_mkdir_mode
创建一个目录,并返回节点数据指针
| 入参 | 说明 |
| ------ | ------------------------------------------------------------ |
| name | 从 procfs 的 root 起始的完整路径,比如 “/dir1/file2”<br />从 parent 起始的完整路径 |
| mode | 权限配置 |
| parent | 指定创建目录的起始节点 |
- proc_mkdir
创建一个目录,并返回节点数据指针
| 入参 | 说明 |
| ---- | ------------------------------------------------------------ |
| name | 从 procfs 的 root 起始的完整路径,比如 “/dir1/file2”<br />从 parent 起始的完整路径 |
| mode | 权限配置 |
- proc_create_data
创建一个文件,并返回节点数据指针
| 入参 | 说明 |
| ------ | ------------------------------------------------------------ |
| name | 从 procfs 的 root 起始的完整路径,比如 “/dir1/file2”<br />从 parent 起始的完整路径 |
| mode | 权限配置 |
| parent | 指定创建文件的起始节点 |
| fops | 文件操作接口配置 |
| data | 私有数据 |
- proc_symlink
创建一个符号链接,并返回节点数据指针
| 入参 | 说明 |
| ------ | ------------------------------------------------------------ |
| name | 从 procfs 的 root 起始的完整路径,比如 “/dir1/file2”<br />从 parent 起始的完整路径 |
| parent | 指定创建文件的起始节点 |
| dest | 链接的目标文件完整路径 |
- proc_acquire
引用一个节点,并返回节点数据指针
| 入参 | 说明 |
| ------ | -------------- |
| dentry | 需要引用的节点 |
- proc_release
释放一个节点
| 入参 | 说明 |
| ------ | -------------- |
| dentry | 需要释放的节点 |
- proc_remove
删除一个节点包含子节点
| 入参 | 说明 |
| ------ | -------------- |
| dentry | 需要删除的节点 |
## msh 调试命令
- proc_dump
遍历打印指定节点含子节点的信息(名称、引用计数),比如 `proc_dump /dir1` 或者 `proc_dump`
- proc_remove
删除指定节点含子节点,比如 `proc_remove /dir1` 或者 `proc_remove /file3`
- proc_symlink
创建一个符号链接,`proc_symlink /link3 /mnt`
- proc_echo
创建一个空文件,`proc_echo /file4`
- proc_mkdir
创建一个空目录,`proc_mkdir /dir3`
- proc_pid
创建一个 pid 目录,`proc_pid /101`

View File

@ -0,0 +1,11 @@
# RT-Thread building script for component
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_PROCFS'], CPPPATH = CPPPATH)
Return('group')

View File

@ -0,0 +1,733 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
/*
* This is the root in the proc tree..
*/
static struct proc_dentry _proc_root = {
.mode = S_IFDIR | (S_IRUSR | S_IRGRP | S_IROTH) | (S_IXUSR | S_IXGRP | S_IXOTH),
.ref_count = 1,
.parent = &_proc_root,
.node.sibling = RT_LIST_OBJECT_INIT(_proc_root.node.sibling),
.node.subnode = RT_LIST_OBJECT_INIT(_proc_root.node.subnode),
.fops = RT_NULL,
.name = "/",
.data = RT_NULL,
};
static int _proc_find(struct proc_dentry **parent, const char *name)
{
struct proc_dentry *dentry = RT_NULL, *tmp;
dfs_vfs_for_each_subnode(dentry, tmp, (*parent), node)
{
if (dentry == RT_NULL)
{
break;
}
if (rt_strcmp(dentry->name, name) == 0)
{
*parent = dentry;
return 0;
}
}
return -1;
}
static int proc_find(struct proc_dentry **parent, const char **name, rt_bool_t force_lookup)
{
int ret = 0;
char *tmp = RT_NULL;
if (!(*parent))
{
*parent = &_proc_root;
}
tmp = rt_strdup(*name);
if (tmp)
{
char *begin = tmp, *end = RT_NULL;
if (*begin == '/')
{
begin++;
if (*begin == '\0')
{
rt_free(tmp);
*parent = proc_acquire(*parent);
return ret;
}
}
while (1)
{
end = rt_strstr(begin, "/");
if (end)
{
*end = '\0';
ret = _proc_find(parent, begin);
if (ret < 0 || !S_ISDIR((*parent)->mode))
{
*parent = RT_NULL;
ret = -1;
break;
}
begin = end + 1;
}
else if (force_lookup)
{
ret = _proc_find(parent, begin);
if (ret < 0)
{
if ((*parent)->ops && (*parent)->ops->lookup)
{
*parent = (*parent)->ops->lookup(*parent, begin);
if (*parent == RT_NULL)
{
ret = -1;
}
}
else
{
*parent = RT_NULL;
}
}
else
{
*parent = proc_acquire(*parent);
}
break;
}
else
{
*parent = proc_acquire(*parent);
break;
}
}
*name = *name + (begin - tmp);
rt_free(tmp);
}
return ret;
}
static void *single_start(struct dfs_seq_file *seq, off_t *index)
{
return NULL + (*index == 0);
}
static void *single_next(struct dfs_seq_file *seq, void *data, off_t *index)
{
++*index;
return NULL;
}
static void single_stop(struct dfs_seq_file *seq, void *data)
{
}
static int proc_open(struct dfs_file *file)
{
struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data;
if (entry->single_show)
{
struct dfs_seq_ops *seq_ops = (struct dfs_seq_ops *)rt_calloc(1, sizeof(struct dfs_seq_ops));
if (seq_ops)
{
int ret = 0;
seq_ops->start = single_start;
seq_ops->next = single_next;
seq_ops->stop = single_stop;
seq_ops->show = entry->single_show;
ret = dfs_seq_open(file, seq_ops);
if (ret != 0)
{
rt_free(seq_ops);
}
return ret;
}
}
return dfs_seq_open(file, entry->seq_ops);
}
static int proc_close(struct dfs_file *file)
{
struct dfs_seq_file *seq = file->data;
struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data;
if (seq && entry->single_show && seq->ops)
{
rt_free((void *)seq->ops);
seq->ops = RT_NULL;
}
return dfs_seq_release(file);
}
static const struct dfs_file_ops proc_file_ops = {
.open = proc_open,
.read = dfs_seq_read,
.lseek = dfs_seq_lseek,
.close = proc_close,
};
static struct proc_dentry *proc_create(struct proc_dentry **parent, const char *name, mode_t mode)
{
int ret = 0;
struct proc_dentry *dentry = RT_NULL;
ret = proc_find(parent, &name, 0);
if (ret >= 0)
{
dentry = *parent;
ret = proc_find(&dentry, &name, 1);
if (ret < 0)
{
dentry = rt_calloc(1, sizeof(struct proc_dentry));
if (dentry)
{
dentry->mode = mode;
dentry->ref_count = 1;
dentry->name = rt_strdup(name);
dfs_vfs_init_node(&dentry->node);
}
}
else
{
proc_release(dentry);
dentry = RT_NULL;
}
}
return dentry;
}
/**
* @brief The dentry reference count is incremented by one
*
* @param dentry
*
* @return dentry
*/
struct proc_dentry *proc_acquire(struct proc_dentry *dentry)
{
if (dentry)
{
dentry->ref_count += 1;
}
return dentry;
}
/**
* @brief The dentry reference count is minus one, or release
*
* @param dentry
*
* @return none
*/
void proc_release(struct proc_dentry *dentry)
{
if (dentry)
{
if (dentry->ref_count == 1)
{
if (dentry->name)
{
rt_free(dentry->name);
}
if (S_ISLNK(dentry->mode) && dentry->data)
{
rt_free(dentry->data);
}
rt_free(dentry);
}
else
{
dentry->ref_count -= 1;
}
}
}
static struct proc_dentry *proc_register(struct proc_dentry *parent, struct proc_dentry *child)
{
child->parent = parent;
dfs_vfs_append_node(&parent->node, &child->node);
child->ref_count += 1;
child->pid = parent->pid;
return child;
}
/**
* @brief Make a dir
*
* @param name fullpath based on _proc_root or parent
* @param mode permission configuration
* @param parent can be empty
* @param fops
* @param data
*
* @return dentry
*/
struct proc_dentry *proc_mkdir_data(const char *name, mode_t mode, struct proc_dentry *parent,
const struct dfs_file_ops *fops, void *data)
{
struct proc_dentry *dentry, *_parent = parent;
if (mode == 0)
mode = (S_IRUSR | S_IRGRP | S_IROTH) | (S_IXUSR | S_IXGRP | S_IXOTH);
dentry = proc_create(&_parent, name, S_IFDIR | mode);
if (dentry)
{
dentry->fops = fops;
dentry->data = data;
dentry = proc_register(_parent, dentry);
}
proc_release(_parent);
return dentry;
}
/**
* @brief Make a dir
*
* @param name fullpath based on _proc_root or parent
* @param mode permission configuration
* @param parent can be empty
*
* @return dentry
*/
struct proc_dentry *proc_mkdir_mode(const char *name, mode_t mode, struct proc_dentry *parent)
{
return proc_mkdir_data(name, mode, parent, NULL, NULL);
}
/**
* @brief Make a dir
*
* @param name fullpath based on _proc_root or parent
* @param parent can be empty
*
* @return dentry
*/
struct proc_dentry *proc_mkdir(const char *name, struct proc_dentry *parent)
{
return proc_mkdir_data(name, 0, parent, NULL, NULL);
}
static struct proc_dentry *proc_create_reg(const char *name, mode_t mode, struct proc_dentry **parent)
{
struct proc_dentry *dentry = RT_NULL;
if ((mode & S_IFMT) == 0)
mode |= S_IFREG;
if ((mode & (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)) == 0)
mode |= S_IRUSR | S_IRGRP | S_IROTH;
if (!S_ISREG(mode))
{
*parent = RT_NULL;
return dentry;
}
return proc_create(parent, name, mode);
}
/**
* @brief Make a file
*
* @param name fullpath based on _proc_root or parent
* @param mode permission configuration
* @param parent can be empty
* @param fops
* @param data
*
* @return dentry
*/
struct proc_dentry *proc_create_data(const char *name, mode_t mode, struct proc_dentry *parent,
const struct dfs_file_ops *fops, void *data)
{
struct proc_dentry *dentry, *_parent = parent;
dentry = proc_create_reg(name, mode, &_parent);
if (dentry)
{
dentry->fops = fops ? fops : &proc_file_ops;
dentry->data = data;
dentry = proc_register(_parent, dentry);
}
proc_release(_parent);
return dentry;
}
/**
* @brief Make a file
*
* @param name fullpath based on _proc_root or parent
* @param mode permission configuration
* @param parent can be empty
* @param show
* @param data
*
* @return dentry
*/
struct proc_dentry *proc_create_single_data(const char *name, mode_t mode, struct proc_dentry *parent,
int (*show)(struct dfs_seq_file *, void *), void *data)
{
struct proc_dentry *dentry, *_parent = parent;
dentry = proc_create_reg(name, mode, &_parent);
if (dentry)
{
dentry->fops = &proc_file_ops;
dentry->single_show = show;
dentry->data = data;
dentry = proc_register(_parent, dentry);
}
proc_release(_parent);
return dentry;
}
/**
* @brief Make a symlink
*
* @param name fullpath based on _proc_root or parent
* @param parent can be empty
* @param dest link file fullpath
*
* @return dentry
*/
struct proc_dentry *proc_symlink(const char *name, struct proc_dentry *parent, const char *dest)
{
struct proc_dentry *dentry, *_parent = parent;
dentry = proc_create(&_parent, name, (S_IFLNK | (S_IRUSR | S_IRGRP | S_IROTH)
| (S_IWUSR | S_IWGRP | S_IWOTH) | (S_IXUSR | S_IXGRP | S_IXOTH)));
if (dentry)
{
dentry->data = (void *)rt_strdup(dest);
if (dentry->data)
{
dentry = proc_register(_parent, dentry);
}
else
{
proc_release(dentry);
dentry = NULL;
}
}
proc_release(_parent);
return dentry;
}
static void remove_proc_subtree(struct proc_dentry *dentry)
{
struct proc_dentry *iter = RT_NULL, *iter_tmp, *tmp = RT_NULL;
dfs_vfs_for_each_subnode(iter, iter_tmp, dentry, node)
{
if (iter == RT_NULL)
{
break;
}
if (tmp)
{
proc_release(tmp);
tmp = RT_NULL;
}
tmp = iter;
if (S_ISDIR(dentry->mode))
{
remove_proc_subtree(iter);
}
}
if (tmp)
{
proc_release(tmp);
tmp = RT_NULL;
}
}
/**
* @brief remove a dentry
*
* @param dentry
*
* @return none
*/
void proc_remove(struct proc_dentry *dentry)
{
if (dentry && dentry != &_proc_root)
{
if (S_ISDIR(dentry->mode))
{
remove_proc_subtree(dentry);
}
dfs_vfs_remove_node(&dentry->node);
proc_release(dentry);
}
}
/**
* @brief find dentry exist
*
* @param name fullpath based on _proc_root
*
* @return dentry
*/
struct proc_dentry *dfs_proc_find(const char *name)
{
struct proc_dentry *dentry = RT_NULL;
proc_find(&dentry, &name, 1);
return dentry;
}
/**
* @brief remove a dentry on parent
*
* @param name fullpath based on parent
* @param parent
*
* @return none
*/
void proc_remove_dentry(const char *name, struct proc_dentry *parent)
{
struct proc_dentry *dentry = parent;
if (proc_find(&dentry, &name, 1) >= 0)
{
proc_remove(dentry);
proc_release(dentry);
}
}
#define _COLOR_RED "\033[31m"
#define _COLOR_GREEN "\033[32m"
#define _COLOR_BLUE "\033[34m"
#define _COLOR_CYAN "\033[36m"
#define _COLOR_WHITE "\033[37m"
#define _COLOR_NORMAL "\033[0m"
static void dump_proc_subtree(struct proc_dentry *dentry, int tab)
{
struct proc_dentry *iter = RT_NULL, *tmp;
dfs_vfs_for_each_subnode(iter, tmp, dentry, node)
{
if (iter == RT_NULL)
{
break;
}
for(int i = 0; i < tab; i ++)
{
rt_kprintf("%-4s", i + 1 >= tab ? "|-" : " ");
}
if (S_ISDIR(iter->mode))
{
rt_kprintf(_COLOR_BLUE "%-20s" _COLOR_NORMAL " %d\n", iter->name, iter->ref_count);
dump_proc_subtree(iter, tab + 1);
}
else if (S_ISLNK(iter->mode))
{
rt_kprintf(_COLOR_CYAN "%-20s" _COLOR_NORMAL " %d\n", iter->name, iter->ref_count);
}
else
{
rt_kprintf("%-20s %d\n", iter->name, iter->ref_count);
}
}
}
static void proc_dump(struct proc_dentry *dentry)
{
if (dentry)
{
if (S_ISDIR(dentry->mode))
{
rt_kprintf(_COLOR_BLUE "%-20s" _COLOR_NORMAL " %d\n", dentry->name, dentry->ref_count);
dump_proc_subtree(dentry, 1);
}
else if (S_ISLNK(dentry->mode))
{
rt_kprintf(_COLOR_CYAN "%-20s" _COLOR_NORMAL " %d\n", dentry->name, dentry->ref_count);
}
else
{
rt_kprintf("%-20s %d\n", dentry->name, dentry->ref_count);
}
}
}
static int msh_proc_dump(int argc, char** argv)
{
const char *name = argc > 1 ? argv[1] : "/";
struct proc_dentry *dentry = RT_NULL;
int ret = proc_find(&dentry, &name, 1);
if (ret >= 0)
{
proc_dump(dentry);
}
proc_release(dentry);
return 0;
}
MSH_CMD_EXPORT_ALIAS(msh_proc_dump, proc_dump, proc dump);
static int msh_proc_remove(int argc, char** argv)
{
if (argc > 1)
{
const char *name = argv[1];
struct proc_dentry *dentry = RT_NULL;
int ret = proc_find(&dentry, &name, 1);
if (ret >= 0)
{
if (dentry != &_proc_root)
{
proc_remove(dentry);
}
else
{
struct proc_dentry *iter = RT_NULL, *iter_tmp, *tmp = RT_NULL;
dfs_vfs_for_each_subnode(iter, iter_tmp, dentry, node)
{
if (iter == RT_NULL)
{
break;
}
if (tmp)
{
proc_remove(tmp);
}
tmp = iter;
}
if (tmp)
{
proc_remove(tmp);
}
}
}
proc_release(dentry);
}
else
{
rt_kprintf("proc_remove path\n");
}
return 0;
}
MSH_CMD_EXPORT_ALIAS(msh_proc_remove, proc_remove, proc remove);
static int msh_proc_symlink(int argc, char** argv)
{
if (argc > 2)
{
struct proc_dentry *entry = proc_symlink(argv[1], 0, argv[2]);
if (entry)
{
proc_release(entry);
}
}
else
{
rt_kprintf("proc_symlink path dest\n");
}
return 0;
}
MSH_CMD_EXPORT_ALIAS(msh_proc_symlink, proc_symlink, proc symlink);
static int msh_proc_echo(int argc, char** argv)
{
if (argc > 1)
{
for(int i = 1; i <= argc - 1; i ++)
{
struct proc_dentry *entry = proc_create_data(argv[i], 0, 0, 0, 0);
if (entry)
{
proc_release(entry);
}
}
}
else
{
rt_kprintf("proc_echo path\n");
}
return 0;
}
MSH_CMD_EXPORT_ALIAS(msh_proc_echo, proc_echo, proc echo);
static int msh_proc_mkdir(int argc, char** argv)
{
if (argc > 1)
{
for(int i = 1; i <= argc - 1; i ++)
{
struct proc_dentry *entry = proc_mkdir(argv[i], 0);
if (entry)
{
proc_release(entry);
}
}
}
else
{
rt_kprintf("proc_mkdir path\n");
}
return 0;
}
MSH_CMD_EXPORT_ALIAS(msh_proc_mkdir, proc_mkdir, proc mkdir);

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#ifndef __PROC_H__
#define __PROC_H__
#include <dfs_file.h>
#include <dfs_seq_file.h>
#include <dfs_vfs.h>
#ifdef __cplusplus
extern "C"
{
#endif
struct proc_dentry;
struct proc_ops
{
struct proc_dentry *(*lookup)(struct proc_dentry *parent, const char *name);
int (*readlink)(struct proc_dentry *dentry, char *buf, int len);
};
struct proc_dentry
{
rt_uint32_t mode;
rt_atomic_t ref_count;
struct proc_dentry *parent;
struct dfs_vfs_node node;
const struct dfs_file_ops *fops;
const struct proc_ops *ops;
const struct dfs_seq_ops *seq_ops;
int (*single_show)(struct dfs_seq_file *seq, void *data);
int pid;
char *name;
void *data;
};
struct proc_dentry *dfs_proc_find(const char *name);
struct proc_dentry *proc_mkdir_data(const char *name, mode_t mode, struct proc_dentry *parent,
const struct dfs_file_ops *fops, void *data);
struct proc_dentry *proc_mkdir_mode(const char *name, mode_t mode, struct proc_dentry *parent);
struct proc_dentry *proc_mkdir(const char *name, struct proc_dentry *parent);
struct proc_dentry *proc_create_data(const char *name, mode_t mode, struct proc_dentry *parent,
const struct dfs_file_ops *fops, void *data);
struct proc_dentry *proc_create_single_data(const char *name, mode_t mode, struct proc_dentry *parent,
int (*show)(struct dfs_seq_file *, void *), void *data);
struct proc_dentry *proc_symlink(const char *name, struct proc_dentry *parent, const char *dest);
struct proc_dentry *proc_acquire(struct proc_dentry *dentry);
void proc_release(struct proc_dentry *dentry);
void proc_remove(struct proc_dentry *dentry);
void proc_remove_dentry(const char *name, struct proc_dentry *parent);
int proc_pid(int pid);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs_dentry.h>
static char *__proc_cmdline = NULL;
int proc_cmdline_save(const char *cmdline)
{
if (__proc_cmdline)
{
free(__proc_cmdline);
__proc_cmdline = NULL;
}
__proc_cmdline = strdup(cmdline);
return 0;
}
static int single_show(struct dfs_seq_file *seq, void *data)
{
if (__proc_cmdline)
{
dfs_seq_puts(seq, __proc_cmdline);
}
return 0;
}
int proc_cmdline_init(void)
{
struct proc_dentry *dentry = proc_create_single_data("cmdline", 0, NULL, single_show, NULL);
proc_release(dentry);
return 0;
}
INIT_ENV_EXPORT(proc_cmdline_init);

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs_dentry.h>
static void *seq_start(struct dfs_seq_file *seq, off_t *index)
{
off_t i = *index; // seq->index
return NULL + (i == 0);
}
static void seq_stop(struct dfs_seq_file *seq, void *data)
{
}
static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index)
{
/* data: The return value of the start or next*/
off_t i = *index + 1; // seq->index
*index = i;
return NULL;
}
static int seq_show(struct dfs_seq_file *seq, void *data)
{
/* data: The return value of the start or next*/
dfs_seq_puts(seq, "rt_weak const struct dfs_seq_ops *cpuinfo_get_seq_ops(void)\n--need your own function--\n");
return 0;
}
static const struct dfs_seq_ops seq_ops = {
.start = seq_start,
.stop = seq_stop,
.next = seq_next,
.show = seq_show,
};
rt_weak const struct dfs_seq_ops *cpuinfo_get_seq_ops(void)
{
return &seq_ops;
}
static int proc_open(struct dfs_file *file)
{
return dfs_seq_open(file, cpuinfo_get_seq_ops());
}
static int proc_close(struct dfs_file *file)
{
return dfs_seq_release(file);
}
static const struct dfs_file_ops file_ops = {
.open = proc_open,
.read = dfs_seq_read,
.lseek = dfs_seq_lseek,
.close = proc_close,
};
int proc_cpuinfo_init(void)
{
struct proc_dentry *dentry = proc_create_data("cpuinfo", 0, NULL, &file_ops, NULL);
proc_release(dentry);
return 0;
}
INIT_ENV_EXPORT(proc_cpuinfo_init);

View File

@ -0,0 +1,307 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs_dentry.h>
#include <rthw.h>
#include <rtthread.h>
#include <string.h>
#define LIST_FIND_OBJ_NR 8
struct device_show
{
char *buf;
int size;
int len;
int index;
};
typedef struct
{
rt_list_t *list;
rt_list_t **array;
rt_uint8_t type;
int nr; /* input: max nr, can't be 0 */
int nr_out; /* out: got nr */
} list_get_next_t;
static void list_find_init(list_get_next_t *p, rt_uint8_t type, rt_list_t **array, int nr)
{
struct rt_object_information *info;
rt_list_t *list;
info = rt_object_get_information((enum rt_object_class_type)type);
list = &info->object_list;
p->list = list;
p->type = type;
p->array = array;
p->nr = nr;
p->nr_out = 0;
}
static rt_list_t *list_get_next(rt_list_t *current, list_get_next_t *arg)
{
int first_flag = 0;
rt_base_t level;
rt_list_t *node, *list;
rt_list_t **array;
struct rt_object_information *info;
int nr;
arg->nr_out = 0;
if (!arg->nr || !arg->type)
{
return (rt_list_t *)RT_NULL;
}
list = arg->list;
info = rt_list_entry(list, struct rt_object_information, object_list);
if (!current) /* find first */
{
node = list;
first_flag = 1;
}
else
{
node = current;
}
level = rt_spin_lock_irqsave(&info->spinlock);
if (!first_flag)
{
struct rt_object *obj;
/* The node in the list? */
obj = rt_list_entry(node, struct rt_object, list);
if ((obj->type & ~RT_Object_Class_Static) != arg->type)
{
rt_spin_unlock_irqrestore(&info->spinlock, level);
return (rt_list_t *)RT_NULL;
}
}
nr = 0;
array = arg->array;
while (1)
{
node = node->next;
if (node == list)
{
node = (rt_list_t *)RT_NULL;
break;
}
nr++;
*array++ = node;
if (nr == arg->nr)
{
break;
}
}
rt_spin_unlock_irqrestore(&info->spinlock, level);
arg->nr_out = nr;
return node;
}
static char *const device_type_str[RT_Device_Class_Unknown] =
{
"Character Device",
"Block Device",
"Network Interface",
"MTD Device",
"CAN Device",
"RTC",
"Sound Device",
"Graphic Device",
"I2C Bus",
"USB Slave Device",
"USB Host Bus",
"USB OTG Bus",
"SPI Bus",
"SPI Device",
"SDIO Bus",
"PM Pseudo Device",
"Pipe",
"Portal Device",
"Timer Device",
"Miscellaneous Device",
"Sensor Device",
"Touch Device",
"Phy Device",
"Security Device",
"WLAN Device",
"Pin Device",
"ADC Device",
"DAC Device",
"WDT Device",
"PWM Device",
"Bus Device",
};
static void save_info(struct device_show *dev, char *dev_name)
{
char tmp[256] = {0};
int len;
dev->index ++;
rt_snprintf(tmp, 256, "%d %s\n", dev->index, dev_name);
tmp[255] = 0;
len = rt_strlen(tmp);
if (dev->size > dev->len + len)
{
strcat(dev->buf, tmp);
dev->len += len;
}
else
{
if (dev->buf == RT_NULL)
{
dev->buf = rt_calloc(1, 4096);
}
else
{
dev->buf = rt_realloc(dev->buf, dev->size + 4096);
}
if (dev->buf)
{
dev->size += 4096;
strcat(dev->buf, tmp);
dev->len += len;
}
}
}
static void list_device(struct device_show *dev)
{
rt_base_t level;
list_get_next_t find_arg;
struct rt_object_information *info;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t *)RT_NULL;
list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
info = rt_list_entry(find_arg.list, struct rt_object_information, object_list);
do
{
next = list_get_next(next, &find_arg);
{
int i;
for (i = 0; i < find_arg.nr_out; i++)
{
struct rt_object *obj;
struct rt_device *device;
obj = rt_list_entry(obj_list[i], struct rt_object, list);
level = rt_spin_lock_irqsave(&info->spinlock);
if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
{
rt_spin_unlock_irqrestore(&info->spinlock, level);
continue;
}
rt_spin_unlock_irqrestore(&info->spinlock, level);
device = (struct rt_device *)obj;
if (device->type < RT_Device_Class_Unknown)
{
save_info(dev + device->type, device->parent.name);
}
}
}
}
while (next != (rt_list_t *)RT_NULL);
}
static int show_info(struct dfs_seq_file *seq)
{
struct device_show _show[RT_Device_Class_Unknown] = {0};
list_device(_show);
for (int i = 0; i < RT_Device_Class_Unknown; i++)
{
if (_show[i].buf)
{
dfs_seq_printf(seq, "%s:\n", device_type_str[i]);
dfs_seq_write(seq, _show[i].buf, _show[i].len);
dfs_seq_putc(seq, '\n');
rt_free(_show[i].buf);
}
}
return 0;
}
static void *seq_start(struct dfs_seq_file *seq, off_t *index)
{
off_t i = *index; // seq->index
return NULL + (i == 0);
}
static void seq_stop(struct dfs_seq_file *seq, void *data)
{
}
static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index)
{
/* data: The return value of the start or next*/
off_t i = *index + 1; // seq->index
*index = i;
return NULL;
}
static int seq_show(struct dfs_seq_file *seq, void *data)
{
/* data: The return value of the start or next*/
show_info(seq);
return 0;
}
static const struct dfs_seq_ops seq_ops = {
.start = seq_start,
.stop = seq_stop,
.next = seq_next,
.show = seq_show,
};
int proc_devices_init(void)
{
struct proc_dentry *dentry = proc_create_data("devices", 0, NULL, NULL, NULL);
if (dentry)
{
dentry->seq_ops = &seq_ops;
}
proc_release(dentry);
return 0;
}
INIT_ENV_EXPORT(proc_devices_init);

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs_dentry.h>
#include <dfs_fs.h>
static void *seq_start(struct dfs_seq_file *seq, off_t *index)
{
off_t i = *index; // seq->index
struct dfs_filesystem_type *fs = dfs_filesystems();
if (fs)
{
while (i--)
{
fs = fs->next;
if (!fs)
{
break;
}
}
}
return fs;
}
static void seq_stop(struct dfs_seq_file *seq, void *data)
{
}
static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index)
{
/* data: The return value of the start or next*/
off_t i = *index + 1; // seq->index
struct dfs_filesystem_type *fs = (struct dfs_filesystem_type *)data;
*index = i;
return fs->next;
}
static int seq_show(struct dfs_seq_file *seq, void *data)
{
/* data: The return value of the start or next*/
struct dfs_filesystem_type *fs = (struct dfs_filesystem_type *)data;
dfs_seq_printf(seq, "%-9s%s\n", (fs->fs_ops->flags == FS_NEED_DEVICE) ? "" : "nodev", fs->fs_ops->name);
return 0;
}
static const struct dfs_seq_ops seq_ops = {
.start = seq_start,
.stop = seq_stop,
.next = seq_next,
.show = seq_show,
};
int proc_filesystems_init(void)
{
struct proc_dentry *dentry = proc_create_data("filesystems", 0, NULL, NULL, NULL);
if (dentry)
{
dentry->seq_ops = &seq_ops;
}
proc_release(dentry);
return 0;
}
INIT_ENV_EXPORT(proc_filesystems_init);

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs_dentry.h>
#include <mm_page.h>
extern void rt_memory_info(rt_size_t *total,
rt_size_t *used,
rt_size_t *max_used);
static int single_show(struct dfs_seq_file *seq, void *data)
{
dfs_seq_printf(seq, "0.13 0.16 0.17 1/1035 380436\n");
return 0;
}
int proc_loadavg_init(void)
{
struct proc_dentry *dentry = proc_create_single_data("loadavg", 0, NULL, single_show, NULL);
proc_release(dentry);
return 0;
}
INIT_ENV_EXPORT(proc_loadavg_init);

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs_dentry.h>
#include <mm_page.h>
extern void rt_memory_info(rt_size_t *total,
rt_size_t *used,
rt_size_t *max_used);
static int single_show(struct dfs_seq_file *seq, void *data)
{
rt_size_t total, used, max_used, freed;
rt_size_t total_sum = 0;
rt_size_t total_freed = 0;
rt_memory_info(&total, &used, &max_used);
total_sum = total_sum + total;
total_freed = total_freed + total - used;
dfs_seq_printf(seq, "%-16s%8d KB\n", "MemMaxUsed:", max_used / 1024);
dfs_seq_printf(seq, "%-16s%8d KB\n", "MemAvailable:", (total - used) / 1024);
dfs_seq_printf(seq, "%-16s%8d KB\n", "Cached:", 0);
dfs_seq_printf(seq, "%-16s%8d KB\n", "SReclaimable:", 0);
rt_page_get_info(&total, &freed);
total_sum = total_sum + total * RT_MM_PAGE_SIZE;
total_freed = total_freed + freed * RT_MM_PAGE_SIZE;
dfs_seq_printf(seq, "%-16s%8d KB\n", "MemTotal:", total_sum / 1024);
dfs_seq_printf(seq, "%-16s%8d KB\n", "MemFree:", total_freed / 1024);
dfs_seq_printf(seq, "%-16s%8d KB\n", "LowPageTotal:", total * RT_MM_PAGE_SIZE / 1024);
dfs_seq_printf(seq, "%-16s%8d KB\n", "lowPageFree:", freed * RT_MM_PAGE_SIZE/ 1024);
rt_page_high_get_info(&total, &freed);
dfs_seq_printf(seq, "%-16s%8d KB\n", "HighPageTotal:", total * RT_MM_PAGE_SIZE / 1024);
dfs_seq_printf(seq, "%-16s%8d KB\n", "HighPageFree:", freed * RT_MM_PAGE_SIZE / 1024);
return 0;
}
int proc_meminfo_init(void)
{
struct proc_dentry *dentry = proc_create_single_data("meminfo", 0, NULL, single_show, NULL);
proc_release(dentry);
return 0;
}
INIT_ENV_EXPORT(proc_meminfo_init);

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs_dentry.h>
#include <dfs_mnt.h>
const char *mnt_flag(int flag)
{
/*if (flag & MNT_READONLY)
{
return "ro";
}*/
return "rw";
}
static struct dfs_mnt* mnt_show(struct dfs_mnt *mnt, void *parameter)
{
struct dfs_seq_file *seq = (struct dfs_seq_file *)parameter;
if (mnt)
{
if (mnt->dev_id)
{
dfs_seq_printf(seq, "%s %s %s %s 0 0\n", mnt->dev_id->parent.name, mnt->fullpath,
mnt->fs_ops->name, mnt_flag(mnt->flags));
}
else
{
dfs_seq_printf(seq, "%s %s %s %s 0 0\n", mnt->fs_ops->name, mnt->fullpath,
mnt->fs_ops->name, mnt_flag(mnt->flags));
}
}
return RT_NULL;
}
static void *seq_start(struct dfs_seq_file *seq, off_t *index)
{
off_t i = *index; // seq->index
return NULL + (i == 0);
}
static void seq_stop(struct dfs_seq_file *seq, void *data)
{
}
static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index)
{
/* data: The return value of the start or next*/
off_t i = *index + 1; // seq->index
*index = i;
return NULL;
}
static int seq_show(struct dfs_seq_file *seq, void *data)
{
/* data: The return value of the start or next*/
dfs_mnt_foreach(mnt_show, seq);
return 0;
}
static const struct dfs_seq_ops seq_ops = {
.start = seq_start,
.stop = seq_stop,
.next = seq_next,
.show = seq_show,
};
int proc_mounts_init(void)
{
struct proc_dentry *dentry = proc_create_data("mounts", 0, NULL, NULL, NULL);
if (dentry)
{
dentry->seq_ops = &seq_ops;
}
proc_release(dentry);
return 0;
}
INIT_ENV_EXPORT(proc_mounts_init);

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs_dentry.h>
#ifdef RT_USING_LWIP
#include "lwip/opt.h"
#endif
#if LWIP_ROUTE
extern int inet_route_foreach(void (*func)(const char *name, uint32_t ip_addr, uint32_t netmask, void *parameter), void *parameter);
#endif
static void *seq_start(struct dfs_seq_file *seq, off_t *index)
{
off_t i = *index; // seq->index
return NULL + (i == 0);
}
static void seq_stop(struct dfs_seq_file *seq, void *data)
{
}
static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index)
{
/* data: The return value of the start or next*/
off_t i = *index + 1; // seq->index
*index = i;
return NULL;
}
static void route_show(const char *name, uint32_t ip_addr, uint32_t netmask, void *parameter)
{
struct dfs_seq_file *seq = (struct dfs_seq_file *)parameter;
/* "Iface\tDestination\tGateway "
"\tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU"
"\tWindow\tIRTT"); */
/* "%63s%lx%lx%X%d%d%d%lx%d%d%d\n" */
dfs_seq_printf(seq, "%s ", name);
dfs_seq_printf(seq, "%lx ", ip_addr);
dfs_seq_printf(seq, "%lx ", 0);
dfs_seq_printf(seq, "%X ", 1);
dfs_seq_printf(seq, "%d ", 0);
dfs_seq_printf(seq, "%d ", 0);
dfs_seq_printf(seq, "%d ", 0);
dfs_seq_printf(seq, "%lx ", netmask);
dfs_seq_printf(seq, "%d ", 0);
dfs_seq_printf(seq, "%d ", 0);
dfs_seq_printf(seq, "%d\n", 0);
}
static int seq_show(struct dfs_seq_file *seq, void *data)
{
/* data: The return value of the start or next*/
dfs_seq_printf(seq, "\n");
#if LWIP_ROUTE
inet_route_foreach(route_show, seq);
#endif
return 0;
}
static const struct dfs_seq_ops seq_ops = {
.start = seq_start,
.stop = seq_stop,
.next = seq_next,
.show = seq_show,
};
int proc_net_init(void)
{
struct proc_dentry *dentry;
dentry = proc_mkdir("net", NULL);
if (!dentry)
return -1;
proc_release(dentry);
dentry = proc_create_data("net/route", 0, NULL, NULL, NULL);
if (dentry)
{
dentry->seq_ops = &seq_ops;
}
proc_release(dentry);
return 0;
}
INIT_ENV_EXPORT(proc_net_init);

View File

@ -0,0 +1,215 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs_dentry.h>
#include <rthw.h>
#include <rtthread.h>
#include <string.h>
#define LIST_FIND_OBJ_NR 8
typedef struct
{
rt_list_t *list;
rt_list_t **array;
rt_uint8_t type;
int nr; /* input: max nr, can't be 0 */
int nr_out; /* out: got nr */
} list_get_next_t;
static void list_find_init(list_get_next_t *p, rt_uint8_t type, rt_list_t **array, int nr)
{
struct rt_object_information *info;
rt_list_t *list;
info = rt_object_get_information((enum rt_object_class_type)type);
list = &info->object_list;
p->list = list;
p->type = type;
p->array = array;
p->nr = nr;
p->nr_out = 0;
}
static rt_list_t *list_get_next(rt_list_t *current, list_get_next_t *arg)
{
int first_flag = 0;
rt_base_t level;
rt_list_t *node, *list;
rt_list_t **array;
struct rt_object_information *info;
int nr;
arg->nr_out = 0;
if (!arg->nr || !arg->type)
{
return (rt_list_t *)RT_NULL;
}
list = arg->list;
info = rt_list_entry(list, struct rt_object_information, object_list);
if (!current) /* find first */
{
node = list;
first_flag = 1;
}
else
{
node = current;
}
level = rt_spin_lock_irqsave(&info->spinlock);
if (!first_flag)
{
struct rt_object *obj;
/* The node in the list? */
obj = rt_list_entry(node, struct rt_object, list);
if ((obj->type & ~RT_Object_Class_Static) != arg->type)
{
rt_spin_unlock_irqrestore(&info->spinlock, level);
return (rt_list_t *)RT_NULL;
}
}
nr = 0;
array = arg->array;
while (1)
{
node = node->next;
if (node == list)
{
node = (rt_list_t *)RT_NULL;
break;
}
nr++;
*array++ = node;
if (nr == arg->nr)
{
break;
}
}
rt_spin_unlock_irqrestore(&info->spinlock, level);
arg->nr_out = nr;
return node;
}
static int show_info(struct dfs_seq_file *seq)
{
rt_base_t level;
list_get_next_t find_arg;
struct rt_object_information *info;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t *)RT_NULL;
list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
info = rt_list_entry(find_arg.list, struct rt_object_information, object_list);
do
{
next = list_get_next(next, &find_arg);
{
int i;
for (i = 0; i < find_arg.nr_out; i++)
{
struct rt_object *obj;
struct rt_device *device;
obj = rt_list_entry(obj_list[i], struct rt_object, list);
level = rt_spin_lock_irqsave(&info->spinlock);
if ((obj->type & ~RT_Object_Class_Static) != find_arg.type)
{
rt_spin_unlock_irqrestore(&info->spinlock, level);
continue;
}
rt_spin_unlock_irqrestore(&info->spinlock, level);
device = (struct rt_device *)obj;
if (device->type == RT_Device_Class_Block)
{
struct rt_device_blk_geometry geometry = { 0 };
rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
dfs_seq_printf(seq, "%4d %7d %14llu %s\n", 0, 0,
geometry.sector_count, device->parent.name);
}
}
}
} while (next != (rt_list_t *)RT_NULL);
return 0;
}
static void *seq_start(struct dfs_seq_file *seq, off_t *index)
{
off_t i = *index; // seq->index
return NULL + (i == 0);
}
static void seq_stop(struct dfs_seq_file *seq, void *data)
{
}
static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index)
{
/* data: The return value of the start or next*/
off_t i = *index + 1; // seq->index
*index = i;
return NULL;
}
static int seq_show(struct dfs_seq_file *seq, void *data)
{
dfs_seq_puts(seq, "major minor #blocks name\n\n");
/* data: The return value of the start or next*/
show_info(seq);
return 0;
}
static const struct dfs_seq_ops seq_ops = {
.start = seq_start,
.stop = seq_stop,
.next = seq_next,
.show = seq_show,
};
int proc_partitions_init(void)
{
struct proc_dentry *dentry = proc_create_data("partitions", 0, NULL, NULL, NULL);
if (dentry)
{
dentry->seq_ops = &seq_ops;
}
proc_release(dentry);
return 0;
}
INIT_ENV_EXPORT(proc_partitions_init);

View File

@ -0,0 +1,449 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#define __RT_IPC_SOURCE__
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include "lwp_internal.h"
#include <dfs_dentry.h>
#include "lwp_internal.h"
#if defined(RT_USING_SMART)
#include "lwp.h"
#include "lwp_pid.h"
#include <lwp_user_mm.h>
struct pid_dentry
{
const char *name;
mode_t mode;
const struct dfs_file_ops *fops;
const struct proc_ops *ops;
const struct dfs_seq_ops *seq_ops;
int (*single_show)(struct dfs_seq_file *seq, void *data);
void *data;
};
static char stat_transform(int __stat)
{
switch (__stat)
{
case RT_THREAD_RUNNING:
return 'R';
default:
return 'T';
}
}
static int stat_single_show(struct dfs_seq_file *seq, void *data)
{
struct proc_dentry *dentry = (struct proc_dentry *)seq->file->vnode->data;
rt_list_t *list;
int mask = 0;
rt_thread_t thread;
rt_uint64_t user_time_lwp = 0;
rt_uint64_t system_time_lwp = 0;
int lwp_oncpu = RT_CPUS_NR;
int lwp_oncpu_ok = 0;
struct rt_lwp *lwp = RT_NULL;
char** argv = RT_NULL;
char *filename = RT_NULL;
char *dot = RT_NULL;
lwp_pid_lock_take();
lwp = lwp_from_pid_locked(dentry->pid);
argv = lwp_get_command_line_args(lwp);
if (lwp)
{
dfs_seq_printf(seq,"%d ",dentry->pid);
if (argv)
{
filename = strrchr(argv[0], '/');
dot = strchr(argv[0], '.');
if (filename != NULL)
{
filename++;
}
else
{
filename = argv[0];
}
if (dot != NULL)
{
*dot = '\0';
}
if (filename != NULL)
{
dfs_seq_printf(seq,"(%s) ", filename);
}
else
{
dfs_seq_printf(seq,"(%s) ", argv[0]);
}
lwp_free_command_line_args(argv);
}
else
{
dfs_seq_printf(seq,"(%s) ", "");
}
if (lwp->terminated)
{
dfs_seq_printf(seq,"%c ",'Z');
}
else
{
list = lwp->t_grp.next;
while (list != &lwp->t_grp)
{
thread = rt_list_entry(list, struct rt_thread, sibling);
user_time_lwp = user_time_lwp + thread->user_time;
system_time_lwp = system_time_lwp + thread->system_time;
#if RT_CPUS_NR > 1
#define ONCPU(thread) RT_SCHED_CTX(thread).oncpu
#else
#define ONCPU(thread) 0
#endif
if (lwp_oncpu_ok == 0)
{
lwp_oncpu = ONCPU(thread);
lwp_oncpu_ok = 1;
}
if (stat_transform(RT_SCHED_CTX(thread).stat) == 'R')
{
lwp_oncpu = ONCPU(thread);
mask = 1;
}
list = list->next;
}
if (mask == 1)
{
dfs_seq_printf(seq,"%c ",'R');
}
else
{
dfs_seq_printf(seq,"%c ",'S');
}
}
lwp_pid_lock_release();
if (lwp->parent != NULL)
dfs_seq_printf(seq,"%d ",lwp->parent->pid);
else
dfs_seq_printf(seq,"0 ");
dfs_seq_printf(seq, "1 1 0 -1 4194560 48245 133976064 732 425574 ");
dfs_seq_printf(seq,"%llu ",user_time_lwp);//utime
dfs_seq_printf(seq,"%llu ",system_time_lwp);//stime
dfs_seq_printf(seq, "1204291 518742 20 0 1 0 50 ");
dfs_seq_printf(seq, "%d ",rt_aspace_count_vsz(lwp->aspace));//VSZ
dfs_seq_printf(seq, "1422 18446744073709551615 ");
dfs_seq_printf(seq, "1 1 0 0 0 0 671173123 4096 1260 0 0 0 17 ");
dfs_seq_printf(seq, "%d ", lwp_oncpu);//CPU
dfs_seq_printf(seq, "0 0 0 0 0 0 0 0 0 0 0 0 0");
dfs_seq_printf(seq,"\n");
}
else
{
lwp_pid_lock_release();
}
return 0;
}
static int cmdline_single_show(struct dfs_seq_file *seq, void *data)
{
struct proc_dentry *dentry = (struct proc_dentry *)seq->file->vnode->data;
struct rt_lwp *lwp;
char** argv;
lwp_pid_lock_take();
lwp = lwp_from_pid_locked(dentry->pid);
argv = lwp_get_command_line_args(lwp);
lwp_pid_lock_release();
if (argv)
{
for (int i = 0; argv[i] != NULL; i++)
{
dfs_seq_printf(seq, "%s ", argv[i]);
}
dfs_seq_puts(seq, "\n");
lwp_free_command_line_args(argv);
}
else
{
dfs_seq_puts(seq, "error\n");
}
return 0;
}
struct proc_dentry *proc_pid_fd_lookup(struct proc_dentry *parent, const char *name)
{
struct proc_dentry *dentry = RT_NULL;
char num[DIRENT_NAME_MAX];
struct rt_lwp *lwp;
struct dfs_fdtable *table;
lwp_pid_lock_take();
lwp = lwp_from_pid_locked(parent->pid);
table = lwp ? &lwp->fdt : RT_NULL;
lwp_pid_lock_release();
if (!table)
{
return RT_NULL;
}
dfs_file_lock();
for (int i = 0; i < table->maxfd; i++)
{
struct dfs_file *file = table->fds[i];
if (file)
{
rt_snprintf(num, DIRENT_NAME_MAX, "%d", i);
if (rt_strcmp(num, name) == 0)
{
dentry = rt_calloc(1, sizeof(struct proc_dentry));
if (dentry)
{
dentry->mode = (S_IFLNK | (S_IRUSR | S_IRGRP | S_IROTH) | (S_IWUSR | S_IWGRP | S_IWOTH) | (S_IXUSR | S_IXGRP | S_IXOTH));
dentry->ref_count = 1;
dentry->name = rt_strdup(name);
dentry->data = (void *)dfs_dentry_full_path(file->dentry);
if (dentry->data == RT_NULL)
{
//todo add vnode->data
if (file->vnode->type == FT_SOCKET)
dentry->data = (void *)rt_strdup("socket");
else if (file->vnode->type == FT_USER)
dentry->data = (void *)rt_strdup("user");
else if (file->vnode->type == FT_DEVICE)
dentry->data = (void *)rt_strdup("device");
else
dentry->data = (void *)rt_strdup("unknown");
}
dentry->pid = parent->pid;
break;
}
}
}
}
dfs_file_unlock();
return dentry;
}
int proc_pid_fd_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
{
int ret = 0, index = 0;
struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data;
struct rt_lwp *lwp;
struct dfs_fdtable *table;
lwp_pid_lock_take();
lwp = lwp_from_pid_locked(entry->pid);
LWP_LOCK(lwp);
table = lwp ? &lwp->fdt : RT_NULL;
if (!table->fds)
{
LWP_UNLOCK(lwp);
lwp_pid_lock_release();
return 0;
}
count = (count / sizeof(struct dirent));
if (count == 0)
{
LWP_UNLOCK(lwp);
lwp_pid_lock_release();
return -EINVAL;
}
dfs_file_lock();
for (int i = 0; i < table->maxfd; i++)
{
struct dfs_file *df = table->fds[i];
if (df)
{
if (index >= file->fpos)
{
struct dirent *d = dirp + index - file->fpos;
d->d_type = DT_SYMLINK;
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
rt_snprintf(d->d_name, DIRENT_NAME_MAX, "%d", i);
d->d_namlen = rt_strlen(d->d_name);
ret++;
}
index++;
if (index - file->fpos >= count)
{
break;
}
}
}
dfs_file_unlock();
LWP_UNLOCK(lwp);
lwp_pid_lock_release();
if (ret > 0)
{
file->fpos = index;
ret = ret * sizeof(struct dirent);
}
return ret;
}
static const struct proc_ops proc_pid_fd_ops = {
.lookup = proc_pid_fd_lookup,
};
static const struct dfs_file_ops proc_pid_fd_fops = {
.getdents = proc_pid_fd_getdents,
};
int proc_pid_exe_readlink(struct proc_dentry *dentry, char *buf, int len)
{
struct rt_lwp *lwp;
lwp = lwp_self();
len = rt_snprintf(buf, len, "%s", lwp ? lwp->exe_file : "null");
return len;
}
static const struct proc_ops proc_pid_exe_ops = {
.readlink = proc_pid_exe_readlink,
};
int proc_pid_cwd_readlink(struct proc_dentry *dentry, char *buf, int len)
{
struct rt_lwp *lwp;
lwp = lwp_self();
len = rt_snprintf(buf, len, "%s", lwp ? lwp->working_directory : "null");
return len;
}
static const struct proc_ops proc_pid_cwd_ops = {
.readlink = proc_pid_cwd_readlink,
};
static struct pid_dentry pid_dentry_base[] = {
{"cmdline", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, 0, 0, 0, cmdline_single_show, 0},
{"cwd", S_IFLNK | S_IRUSR | S_IXUSR, 0, &proc_pid_cwd_ops, 0, 0},
{"exe", S_IFLNK | S_IRUSR | S_IXUSR, 0, &proc_pid_exe_ops, 0, 0},
{"fd", S_IFDIR | S_IRUSR | S_IXUSR, &proc_pid_fd_fops, &proc_pid_fd_ops, 0, 0, 0},
{"mounts", S_IFLNK | S_IRUSR | S_IXUSR, 0, 0, 0, 0, "/proc/mounts"},
{"stat", S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, 0, 0, 0, stat_single_show, 0},
};
int proc_pid(int pid)
{
char pid_str[64] = {0};
struct proc_dentry *dentry;
rt_snprintf(pid_str, 64, "%d", pid);
pid_str[63] = 0;
dentry = proc_mkdir(pid_str, 0);
if (dentry)
{
struct proc_dentry *ent;
dentry->pid = pid;
for (int j = 0; j < sizeof(pid_dentry_base) / sizeof(struct pid_dentry); j++)
{
if (S_ISDIR(pid_dentry_base[j].mode))
{
ent = proc_mkdir_data(pid_dentry_base[j].name, pid_dentry_base[j].mode, dentry,
pid_dentry_base[j].fops, pid_dentry_base[j].data);
}
else if (S_ISLNK(pid_dentry_base[j].mode))
{
if (pid_dentry_base[j].data == RT_NULL)
{
pid_dentry_base[j].data = "NULL";
}
ent = proc_symlink(pid_dentry_base[j].name, dentry, pid_dentry_base[j].data);
}
else
{
ent = proc_create_data(pid_dentry_base[j].name, pid_dentry_base[j].mode, dentry,
pid_dentry_base[j].fops, pid_dentry_base[j].data);
}
if (ent)
{
if (pid_dentry_base[j].ops)
{
ent->ops = pid_dentry_base[j].ops;
}
if (pid_dentry_base[j].seq_ops)
{
ent->seq_ops = pid_dentry_base[j].seq_ops;
}
if (pid_dentry_base[j].single_show)
{
ent->single_show = pid_dentry_base[j].single_show;
}
proc_release(ent);
}
}
proc_release(dentry);
}
return 0;
}
int msh_proc_pid(int argc, char **argv)
{
if (argc > 1)
{
for (int i = 1; i <= argc - 1; i++)
{
proc_pid(atoi(argv[i]));
}
}
return 0;
}
MSH_CMD_EXPORT_ALIAS(msh_proc_pid, proc_pid, proc pid);
#endif

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs_dentry.h>
#if defined(RT_USING_SMART)
#include <lwp.h>
int proc_self_readlink(struct proc_dentry *dentry, char *buf, int len)
{
struct rt_lwp *lwp = RT_NULL;
lwp = lwp_self();
if (lwp)
{
rt_snprintf(buf, len, "%d", lwp_to_pid(lwp));
buf[len - 1] = 0;
return rt_strlen(buf);
}
else
{
rt_snprintf(buf, len, "null");
buf[len - 1] = 0;
return rt_strlen(buf);
}
return -1;
}
static const struct proc_ops proc_pid_fd_ops = {
.readlink = proc_self_readlink,
};
int proc_self_init(void)
{
struct proc_dentry *ent;
ent = proc_symlink("self", NULL, "NULL");
if (ent)
{
ent->ops = &proc_pid_fd_ops;
}
proc_release(ent);
return 0;
}
INIT_ENV_EXPORT(proc_self_init);
#endif

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs_dentry.h>
static void *seq_start(struct dfs_seq_file *seq, off_t *index)
{
off_t i = *index; // seq->index
return NULL + (i == 0);
}
static void seq_stop(struct dfs_seq_file *seq, void *data)
{
}
static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index)
{
/* data: The return value of the start or next*/
off_t i = *index + 1; // seq->index
*index = i;
return NULL;
}
static int seq_show(struct dfs_seq_file *seq, void *data)
{
int i;
rt_cpu_t pcpu;
rt_uint64_t user_total = 0;
rt_uint64_t system_total = 0;
rt_uint64_t idle_total = 0;
for (i = 0; i < RT_CPUS_NR; i++)
{
pcpu = rt_cpu_index(i);
user_total = user_total + pcpu->cpu_stat.user;
system_total = system_total + pcpu->cpu_stat.system;
idle_total = idle_total + pcpu->cpu_stat.idle;
}
dfs_seq_printf(seq, "cpu %llu 0 %llu %llu 0 0 0 0 0 0\n", user_total, system_total, idle_total);
for (i = 0; i < RT_CPUS_NR; i++)
{
pcpu = rt_cpu_index(i);
dfs_seq_printf(seq, "cpu%d ",i);
dfs_seq_printf(seq, "%llu ",pcpu->cpu_stat.user);//user
dfs_seq_printf(seq, "0 ");//nice
dfs_seq_printf(seq, "%llu ",pcpu->cpu_stat.system);//system
dfs_seq_printf(seq, "%llu ",pcpu->cpu_stat.idle);//idle
dfs_seq_printf(seq, "0 ");//iowait
dfs_seq_printf(seq, "0 ");//irq
dfs_seq_printf(seq, "0 ");//softirq
dfs_seq_printf(seq, "0 0 0\n");//steal,guest,guest_nice
}
return 0;
}
static const struct dfs_seq_ops seq_ops = {
.start = seq_start,
.stop = seq_stop,
.next = seq_next,
.show = seq_show,
};
rt_weak const struct dfs_seq_ops *stat_get_seq_ops(void)
{
return &seq_ops;
}
static int proc_open(struct dfs_file *file)
{
return dfs_seq_open(file, stat_get_seq_ops());
}
static int proc_close(struct dfs_file *file)
{
return dfs_seq_release(file);
}
static const struct dfs_file_ops file_ops = {
.open = proc_open,
.read = dfs_seq_read,
.lseek = dfs_seq_lseek,
.close = proc_close,
};
int proc_stat_init(void)
{
struct proc_dentry *dentry = proc_create_data("stat", 0, NULL, &file_ops, NULL);
proc_release(dentry);
return 0;
}
INIT_ENV_EXPORT(proc_stat_init);

View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs_dentry.h>
static void *seq_start(struct dfs_seq_file *seq, off_t *index)
{
off_t i = *index; // seq->index
return NULL + (i == 0);
}
static void seq_stop(struct dfs_seq_file *seq, void *data)
{
}
static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index)
{
/* data: The return value of the start or next*/
off_t i = *index + 1; // seq->index
*index = i;
return NULL;
}
static int seq_show(struct dfs_seq_file *seq, void *data)
{
/* data: The return value of the start or next*/
dfs_seq_puts(seq, "todo\n");
return 0;
}
static const struct dfs_seq_ops seq_ops = {
.start = seq_start,
.stop = seq_stop,
.next = seq_next,
.show = seq_show,
};
void proc_tty_register_driver(void *driver)
{
//todo
}
void proc_tty_unregister_driver(void *driver)
{
//todo
}
int proc_tty_init(void)
{
struct proc_dentry *dentry;
dentry = proc_mkdir("tty", NULL);
if (!dentry)
return -1;
proc_release(dentry);
dentry = proc_mkdir("tty/ldisc", NULL);
proc_release(dentry);
dentry = proc_mkdir_mode("tty/driver", S_IRUSR|S_IXUSR, NULL);
proc_release(dentry);
dentry = proc_create_data("tty/ldiscs", 0, NULL, NULL, NULL);
if (dentry)
{
dentry->seq_ops = &seq_ops;
}
proc_release(dentry);
dentry = proc_create_data("tty/drivers", 0, NULL, NULL, NULL);
if (dentry)
{
dentry->seq_ops = &seq_ops;
}
proc_release(dentry);
return 0;
}
INIT_ENV_EXPORT(proc_tty_init);

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs_dentry.h>
static int single_show(struct dfs_seq_file *seq, void *data)
{
dfs_seq_printf(seq, "%lu.%02lu %lu.%02lu\n",
(unsigned long)rt_tick_get_millisecond() / 1000, (unsigned long)(rt_tick_get_millisecond() % 1000) / 100,
(unsigned long)rt_tick_get_millisecond() / 1000, (unsigned long)(rt_tick_get_millisecond() % 1000) / 100);
return 0;
}
int proc_uptime_init(void)
{
struct proc_dentry *dentry = proc_create_single_data("uptime", 0, NULL, single_show, NULL);
proc_release(dentry);
return 0;
}
INIT_ENV_EXPORT(proc_uptime_init);

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include "proc.h"
#include "procfs.h"
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs_dentry.h>
static int single_show(struct dfs_seq_file *seq, void *data)
{
dfs_seq_puts(seq, "\n \\ | /\n");
#ifdef RT_USING_SMART
dfs_seq_puts(seq, "- RT - Thread Smart Operating System\n");
#else
dfs_seq_puts(seq, "- RT - Thread Operating System\n");
#endif
dfs_seq_printf(seq, " / | \\ %d.%d.%d build %s %s\n",
(rt_int32_t)RT_VERSION_MAJOR, (rt_int32_t)RT_VERSION_MINOR, (rt_int32_t)RT_VERSION_PATCH,
__DATE__, __TIME__);
dfs_seq_puts(seq, " 2006 - 2022 Copyright by RT-Thread team\n");
return 0;
}
int proc_version_init(void)
{
struct proc_dentry *dentry = proc_create_single_data("version", 0, NULL, single_show, NULL);
proc_release(dentry);
return 0;
}
INIT_ENV_EXPORT(proc_version_init);

View File

@ -0,0 +1,447 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rthw.h>
#include <rtdbg.h>
#include <fcntl.h>
#include <errno.h>
#include <dfs.h>
#include <dfs_fs.h>
#include <dfs_file.h>
#include <dfs_posix.h>
#include <dfs_mnt.h>
#include <dfs_dentry.h>
#include "proc.h"
#include "procfs.h"
#define PROC_DEBUG(...) //rt_kprintf
static int dfs_procfs_open(struct dfs_file *file)
{
rt_err_t ret = RT_EOK;
struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data;
RT_ASSERT(file->ref_count > 0);
// this file is opened and in an fdtable
if (file->ref_count > 1)
{
file->fpos = 0;
return ret;
}
if (entry->fops && entry->fops->open)
{
ret = entry->fops->open(file);
}
PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret);
return ret;
}
static int dfs_procfs_close(struct dfs_file *file)
{
rt_err_t ret = RT_EOK;
struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data;
RT_ASSERT(file->vnode->ref_count > 0);
if (file->vnode->ref_count > 1)
{
return ret;
}
if (entry && entry->fops && entry->fops->close)
{
ret = entry->fops->close(file);
}
PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret);
return ret;
}
static ssize_t dfs_procfs_read(struct dfs_file *file, void *buf, size_t count, off_t *pos)
{
ssize_t ret = -RT_ERROR;
struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data;
if (entry && entry->fops && entry->fops->read)
{
ret = entry->fops->read(file, buf, count, pos);
}
PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret);
return ret;
}
static ssize_t dfs_procfs_write(struct dfs_file *file, const void *buf, size_t count, off_t *pos)
{
ssize_t ret = -RT_ERROR;
struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data;
if (entry && entry->fops && entry->fops->write)
{
ret = entry->fops->write(file, buf, count, pos);
}
PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret);
return ret;
}
static int dfs_procfs_ioctl(struct dfs_file *file, int cmd, void *args)
{
int ret = -RT_ERROR;
struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data;
if (entry && entry->fops && entry->fops->ioctl)
{
ret = entry->fops->ioctl(file, cmd, args);
}
PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret);
return ret;
}
static int dfs_procfs_getdents(struct dfs_file *file, struct dirent *dirp, uint32_t count)
{
int ret = 0;
rt_uint32_t index = 0;
struct dirent *d;
struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data;
if (entry)
{
struct proc_dentry *iter = RT_NULL, *tmp;
/* make integer count */
count = (count / sizeof(struct dirent));
if (count == 0)
{
return -EINVAL;
}
dfs_vfs_for_each_subnode(iter, tmp, entry, node)
{
if (iter == RT_NULL)
{
break;
}
if (index >= file->fpos)
{
d = dirp + index - file->fpos;
if (S_ISDIR(entry->mode))
{
d->d_type = DT_DIR;
}
else if (S_ISLNK(entry->mode))
{
d->d_type = DT_SYMLINK;
}
else
{
d->d_type = DT_REG;
}
d->d_namlen = rt_strlen(iter->name);
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
rt_strncpy(d->d_name, iter->name, rt_strlen(iter->name) + 1);
ret ++;
}
index++;
if (index - file->fpos >= count)
{
break;
}
}
if (ret > 0)
{
file->fpos = index;
}
if (entry->fops && entry->fops->getdents && ret < count)
{
int r;
file->fpos -= index;
r = entry->fops->getdents(file, dirp + ret, (count - ret) * sizeof(struct dirent));
ret = ret * sizeof(struct dirent);
if (r > 0)
{
ret += r;
}
file->fpos += index;
}
else
{
ret = ret * sizeof(struct dirent);
}
}
PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret);
return ret;
}
static int dfs_procfs_poll(struct dfs_file *file, struct rt_pollreq *req)
{
int ret = -RT_ERROR;
struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data;
if (entry && entry->fops && entry->fops->poll)
{
ret = entry->fops->poll(file, req);
}
PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret);
return ret;
}
static int dfs_procfs_flush(struct dfs_file *file)
{
int ret = -RT_ERROR;
struct proc_dentry *entry = (struct proc_dentry *)file->vnode->data;
if (entry && entry->fops && entry->fops->flush)
{
ret = entry->fops->flush(file);
}
PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, file->dentry->pathname, ret);
return ret;
}
static int dfs_procfs_mount(struct dfs_mnt *mnt, unsigned long rwflag, const void *data)
{
RT_ASSERT(mnt != RT_NULL);
return RT_EOK;
}
static int dfs_procfs_umount(struct dfs_mnt *mnt)
{
RT_ASSERT(mnt != RT_NULL);
return RT_EOK;
}
static int dfs_procfs_readlink(struct dfs_dentry *dentry, char *buf, int len)
{
int ret = 0;
struct proc_dentry *entry = dfs_proc_find(dentry->pathname);
if (entry)
{
if (S_ISLNK(entry->mode) && entry->data)
{
if (entry->ops && entry->ops->readlink)
{
ret = entry->ops->readlink(entry, buf, len);
}
else
{
rt_strncpy(buf, (const char *)entry->data, len);
buf[len - 1] = '\0';
ret = rt_strlen(buf);
}
}
proc_release(entry);
}
PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, dentry->pathname, ret);
return ret;
}
static int dfs_procfs_unlink(struct dfs_dentry *dentry)
{
PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, dentry->pathname, -1);
return -RT_ERROR;
}
static int dfs_procfs_stat(struct dfs_dentry *dentry, struct stat *st)
{
int ret = RT_EOK;
struct dfs_vnode *vnode;
if (dentry && dentry->vnode)
{
vnode = dentry->vnode;
st->st_dev = (dev_t)(dentry->mnt->dev_id);
st->st_ino = (ino_t)dfs_dentry_full_path_crc32(dentry);
st->st_gid = vnode->gid;
st->st_uid = vnode->uid;
st->st_mode = vnode->mode;
st->st_nlink = vnode->nlink;
st->st_size = vnode->size;
st->st_mtim.tv_nsec = vnode->mtime.tv_nsec;
st->st_mtim.tv_sec = vnode->mtime.tv_sec;
st->st_ctim.tv_nsec = vnode->ctime.tv_nsec;
st->st_ctim.tv_sec = vnode->ctime.tv_sec;
st->st_atim.tv_nsec = vnode->atime.tv_nsec;
st->st_atim.tv_sec = vnode->atime.tv_sec;
}
PROC_DEBUG(" %s %d >> %s ret: %d\n", __func__, __LINE__, dentry->pathname, ret);
return ret;
}
static int dfs_procfs_statfs(struct dfs_mnt *mnt, struct statfs *buf)
{
if (mnt && buf)
{
buf->f_bsize = 512;
buf->f_blocks = 2048 * 64; // 64M
buf->f_bfree = buf->f_blocks;
buf->f_bavail = buf->f_bfree;
}
PROC_DEBUG(" %s %d\n", __func__, __LINE__);
return RT_EOK;
}
static struct dfs_vnode *dfs_procfs_lookup(struct dfs_dentry *dentry)
{
struct dfs_vnode *vnode = RT_NULL;
struct proc_dentry *entry = dfs_proc_find(dentry->pathname);
if (entry)
{
vnode = dfs_vnode_create();
if (vnode)
{
vnode->nlink = 1;
vnode->size = 0;
if (S_ISDIR(entry->mode))
{
vnode->mode = entry->mode;
vnode->type = FT_DIRECTORY;
}
else if (S_ISLNK(entry->mode))
{
vnode->mode = entry->mode;
vnode->type = FT_SYMLINK;
}
else
{
vnode->mode = entry->mode;
vnode->type = FT_REGULAR;
}
vnode->data = entry;
vnode->mnt = dentry->mnt;
}
proc_release(entry);
}
PROC_DEBUG(" %s %d >> %s\n", __func__, __LINE__, dentry->pathname);
return vnode;
}
static struct dfs_vnode *dfs_procfs_create_vnode(struct dfs_dentry *dentry, int type, mode_t mode)
{
return RT_NULL;
}
static int dfs_procfs_free_vnode(struct dfs_vnode *vnode)
{
return 0;
}
static const struct dfs_file_ops _procfs_fops =
{
.open = dfs_procfs_open,
.close = dfs_procfs_close,
.lseek = generic_dfs_lseek,
.read = dfs_procfs_read,
.write = dfs_procfs_write,
.ioctl = dfs_procfs_ioctl,
.getdents = dfs_procfs_getdents,
.poll = dfs_procfs_poll,
.flush = dfs_procfs_flush,
};
static const struct dfs_filesystem_ops _procfs_ops =
{
.name = "procfs",
.default_fops = &_procfs_fops,
.mount = dfs_procfs_mount,
.umount = dfs_procfs_umount,
.readlink = dfs_procfs_readlink,
.unlink = dfs_procfs_unlink,
.stat = dfs_procfs_stat,
.statfs = dfs_procfs_statfs,
.lookup = dfs_procfs_lookup,
.create_vnode = dfs_procfs_create_vnode,
.free_vnode = dfs_procfs_free_vnode,
};
static struct dfs_filesystem_type _procfs =
{
.fs_ops = &_procfs_ops,
};
int dfs_procfs_init(void)
{
/* register procfs file system */
dfs_register(&_procfs);
return 0;
}
INIT_COMPONENT_EXPORT(dfs_procfs_init);
int proc_read_data(struct dfs_file *file, void *buf, size_t count, off_t *pos)
{
if (file->fpos >= file->vnode->size)
{
return 0;
}
if (file->data)
{
count = file->vnode->size - file->fpos >= count ? count : file->vnode->size - file->fpos;
rt_strncpy(buf, file->data + file->fpos, count);
file->fpos += count;
*pos = file->fpos;
}
else
{
return 0;
}
return count;
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#ifndef __PROC_FS_H__
#define __PROC_FS_H__
#include <dfs_file.h>
int dfs_procfs_init(void);
int proc_read_data(struct dfs_file *file, void *buf, size_t count, off_t *pos);
#endif

View File

@ -262,7 +262,7 @@ ptsno_t ptyfs_register_pts(rt_device_t ptmx, rt_device_t pts)
pts_file = rt_calloc(1, sizeof(struct ptyfs_file));
if (pts_file)
{
snprintf(pts_file->basename, DIRENT_NAME_MAX, "%lu", rc);
snprintf(pts_file->basename, DIRENT_NAME_MAX, "%lu", (unsigned long)rc);
ptyfile_init(pts_file, sb, 0, PTYFS_TYPE_FILE_SLAVE,
PTS_DEFAULT_FILE_MODE, pts);
ptyfile_add_to_root(sb, pts_file);
@ -296,7 +296,7 @@ rt_err_t ptyfs_unregister_pts(rt_device_t ptmx, ptsno_t ptsno)
else
{
/* get path and findout device */
snprintf(path_buf, sizeof(path_buf), "%lu", ptsno);
snprintf(path_buf, sizeof(path_buf), "%lu", (unsigned long)ptsno);
pts_file = ptyfile_lookup(sb, path_buf);
if (pts_file)
{

View File

@ -365,6 +365,7 @@ static const struct dfs_file_ops _rom_fops =
{
.open = dfs_romfs_open,
.close = dfs_romfs_close,
.ioctl = dfs_romfs_ioctl,
.lseek = generic_dfs_lseek,
.read = dfs_romfs_read,
.getdents = dfs_romfs_getdents,

View File

@ -99,15 +99,13 @@ static int _get_subdir(const char *path, char *name)
static int _free_subdir(struct tmpfs_file *dfile)
{
struct tmpfs_file *file;
rt_list_t *list, *temp_list;
struct tmpfs_file *file = RT_NULL, *tmp;
struct tmpfs_sb *superblock;
RT_ASSERT(dfile->type == TMPFS_TYPE_DIR);
rt_list_for_each_safe(list, temp_list, &dfile->subdirs)
dfs_vfs_for_each_subnode(file, tmp, dfile, node)
{
file = rt_list_entry(list, struct tmpfs_file, sibling);
if (file->type == TMPFS_TYPE_DIR)
{
_free_subdir(file);
@ -122,7 +120,7 @@ static int _free_subdir(struct tmpfs_file *dfile)
RT_ASSERT(superblock != NULL);
rt_spin_lock(&superblock->lock);
rt_list_remove(&(file->sibling));
dfs_vfs_remove_node(&file->node);
rt_spin_unlock(&superblock->lock);
rt_free(file);
@ -141,13 +139,11 @@ static int dfs_tmpfs_mount(struct dfs_mnt *mnt,
{
superblock->df_size = sizeof(struct tmpfs_sb);
superblock->magic = TMPFS_MAGIC;
rt_list_init(&superblock->sibling);
superblock->root.name[0] = '/';
superblock->root.sb = superblock;
superblock->root.type = TMPFS_TYPE_DIR;
rt_list_init(&superblock->root.sibling);
rt_list_init(&superblock->root.subdirs);
dfs_vfs_init_node(&superblock->root.node);
rt_spin_lock_init(&superblock->lock);
@ -236,8 +232,7 @@ struct tmpfs_file *dfs_tmpfs_lookup(struct tmpfs_sb *superblock,
{
const char *subpath, *curpath, *filename = RT_NULL;
char subdir_name[TMPFS_NAME_MAX];
struct tmpfs_file *file, *curfile;
rt_list_t *list;
struct tmpfs_file *file, *curfile, *tmp;
subpath = path;
while (*subpath == '/' && *subpath)
@ -265,9 +260,8 @@ find_subpath:
rt_spin_lock(&superblock->lock);
rt_list_for_each(list, &curfile->subdirs)
dfs_vfs_for_each_subnode(file, tmp, curfile, node)
{
file = rt_list_entry(list, struct tmpfs_file, sibling);
if (filename) /* find file */
{
if (rt_strcmp(file->name, filename) == 0)
@ -503,8 +497,7 @@ static int dfs_tmpfs_getdents(struct dfs_file *file,
{
rt_size_t index, end;
struct dirent *d;
struct tmpfs_file *d_file, *n_file;
rt_list_t *list;
struct tmpfs_file *d_file, *n_file, *tmp;
struct tmpfs_sb *superblock;
d_file = (struct tmpfs_file *)file->vnode->data;
@ -527,9 +520,8 @@ static int dfs_tmpfs_getdents(struct dfs_file *file,
index = 0;
count = 0;
rt_list_for_each(list, &d_file->subdirs)
dfs_vfs_for_each_subnode(n_file, tmp, d_file, node)
{
n_file = rt_list_entry(list, struct tmpfs_file, sibling);
if (index >= (rt_size_t)file->fpos)
{
d = dirp + count;
@ -573,7 +565,7 @@ static int dfs_tmpfs_unlink(struct dfs_dentry *dentry)
return -ENOENT;
rt_spin_lock(&superblock->lock);
rt_list_remove(&(d_file->sibling));
dfs_vfs_remove_node(&d_file->node);
rt_spin_unlock(&superblock->lock);
if (rt_atomic_load(&(dentry->ref_count)) == 1)
@ -631,13 +623,13 @@ static int dfs_tmpfs_rename(struct dfs_dentry *old_dentry, struct dfs_dentry *ne
RT_ASSERT(p_file != NULL);
rt_spin_lock(&superblock->lock);
rt_list_remove(&(d_file->sibling));
dfs_vfs_remove_node(&d_file->node);
rt_spin_unlock(&superblock->lock);
strncpy(d_file->name, file_name, TMPFS_NAME_MAX);
rt_spin_lock(&superblock->lock);
rt_list_insert_after(&(p_file->subdirs), &(d_file->sibling));
dfs_vfs_append_node(&p_file->node, &d_file->node);
rt_spin_unlock(&superblock->lock);
rt_free(parent_path);
@ -745,8 +737,7 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t
strncpy(d_file->name, file_name, TMPFS_NAME_MAX);
rt_list_init(&(d_file->subdirs));
rt_list_init(&(d_file->sibling));
dfs_vfs_init_node(&d_file->node);
d_file->data = NULL;
d_file->size = 0;
d_file->sb = superblock;
@ -767,7 +758,7 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t
#endif
}
rt_spin_lock(&superblock->lock);
rt_list_insert_after(&(p_file->subdirs), &(d_file->sibling));
dfs_vfs_append_node(&p_file->node, &d_file->node);
rt_spin_unlock(&superblock->lock);
vnode->mnt = dentry->mnt;

View File

@ -12,6 +12,7 @@
#define __DFS_TMPFS_H__
#include <rtthread.h>
#include <dfs_vfs.h>
#define TMPFS_NAME_MAX 32
#define TMPFS_MAGIC 0x0B0B0B0B
@ -25,8 +26,7 @@ struct tmpfs_file
{
rt_uint32_t type; /* file type */
char name[TMPFS_NAME_MAX]; /* file name */
rt_list_t subdirs; /* file subdir list */
rt_list_t sibling; /* file sibling list */
struct dfs_vfs_node node; /* file node in the tmpfs */
struct tmpfs_sb *sb; /* superblock ptr */
rt_uint8_t *data; /* file date ptr */
rt_size_t size; /* file size */

View File

@ -20,6 +20,38 @@ extern "C"
{
#endif
#define MS_RDONLY 1
#define MS_NOSUID 2
#define MS_NODEV 4
#define MS_NOEXEC 8
#define MS_SYNCHRONOUS 16
#define MS_REMOUNT 32
#define MS_MANDLOCK 64
#define MS_DIRSYNC 128
#define MS_NOATIME 1024
#define MS_NODIRATIME 2048
#define MS_BIND 4096
#define MS_MOVE 8192
#define MS_REC 16384
#define MS_SILENT 32768
#define MS_POSIXACL (1<<16)
#define MS_UNBINDABLE (1<<17)
#define MS_PRIVATE (1<<18)
#define MS_SLAVE (1<<19)
#define MS_SHARED (1<<20)
#define MS_RELATIME (1<<21)
#define MS_KERNMOUNT (1<<22)
#define MS_I_VERSION (1<<23)
#define MS_STRICTATIME (1<<24)
#define MS_LAZYTIME (1<<25)
#define MS_NOREMOTELOCK (1<<27)
#define MS_NOSEC (1<<28)
#define MS_BORN (1<<29)
#define MS_ACTIVE (1<<30)
#define MS_NOUSER (1U<<31)
#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION|MS_LAZYTIME)
/* file system partition table */
struct dfs_partition
{
@ -87,6 +119,7 @@ int dfs_unregister(struct dfs_filesystem_type *fs);
int dfs_register(struct dfs_filesystem_type *fs);
const char *dfs_filesystem_get_mounted_path(struct rt_device *device);
int dfs_remount(const char *path, rt_ubase_t flags, void *data);
int dfs_mount(const char *device_name,
const char *path,
const char *filesystemtype,

View File

@ -39,6 +39,8 @@ struct dfs_mnt
#define MNT_IS_UMOUNT 0x8 /* the mnt is unmount */
#define MNT_IS_LOCKED 0x10 /* the mnt is locked */
#define MNT_FORCE 0x20 /* the mnt force unmount */
#define MNT_LAZY_UMNT 0x40 /* the mnt has pending umount */
#define MNT_RDONLY 0x80 /* the mnt is read only */
rt_atomic_t ref_count; /* reference count */
@ -60,9 +62,16 @@ const char *dfs_mnt_get_mounted_path(struct rt_device *device);
struct dfs_mnt* dfs_mnt_ref(struct dfs_mnt* mnt);
int dfs_mnt_unref(struct dfs_mnt* mnt);
int dfs_mnt_umount(struct dfs_mnt *mnt, int flags);
int dfs_mnt_setflags(struct dfs_mnt *mnt, int flags);
rt_bool_t dfs_mnt_has_child_mnt(struct dfs_mnt *mnt, const char* fullpath);
int dfs_mnt_foreach(struct dfs_mnt* (*func)(struct dfs_mnt *mnt, void *parameter), void *parameter);
int dfs_mnt_umount_iter(rt_bool_t (*filter)(struct dfs_mnt *mnt, void *parameter), void *parameter);
typedef void (*dfs_mnt_umnt_cb_t)(struct dfs_mnt *mnt);
RT_OBJECT_HOOKLIST_DECLARE(dfs_mnt_umnt_cb_t, dfs_mnt_umnt);
#ifdef __cplusplus
}

View File

@ -118,6 +118,7 @@ int dfs_aspace_mmap_write(struct dfs_file *file, struct rt_varea *varea, void *d
void dfs_pcache_release(size_t count);
void dfs_pcache_unmount(struct dfs_mnt *mnt);
void dfs_pcache_clean(struct dfs_mnt *mnt);
#ifdef __cplusplus
}

View File

@ -56,7 +56,7 @@ static inline void dfs_seq_setwidth(struct dfs_seq_file *seq, size_t size)
int dfs_seq_open(struct dfs_file *file, const struct dfs_seq_ops *ops);
ssize_t dfs_seq_read(struct dfs_file *file, void *buf, size_t size, off_t *pos);
ssize_t dfs_seq_lseek(struct dfs_file *file, off_t offset, int whence);
off_t dfs_seq_lseek(struct dfs_file *file, off_t offset, int whence);
int dfs_seq_release(struct dfs_file *file);
int dfs_seq_write(struct dfs_seq_file *seq, const void *data, size_t len);

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#ifndef __DFS_VFS_H__
#define __DFS_VFS_H__
#include "dfs_file.h"
#include "dfs_fs.h"
#ifdef __cplusplus
extern "C"
{
#endif
struct dfs_vfs_node
{
rt_list_t subnode; /* file subnode list */
rt_list_t sibling; /* file sibling list */
};
rt_inline void dfs_vfs_init_node(struct dfs_vfs_node *node)
{
rt_list_init(&node->subnode);
rt_list_init(&node->sibling);
}
rt_inline void dfs_vfs_append_node(struct dfs_vfs_node *dir, struct dfs_vfs_node *node)
{
rt_list_insert_after(&(dir->subnode), &(node->sibling));
}
rt_inline void dfs_vfs_remove_node(struct dfs_vfs_node *node)
{
rt_list_remove(&(node->sibling));
}
#define dfs_vfs_for_each_subnode(node, tmp, dir, member) \
rt_list_for_each_entry_safe(node, tmp, &dir->member.subnode, member.sibling)
#ifdef __cplusplus
}
#endif
#endif /*__DFS_VFS_H__*/

View File

@ -537,6 +537,7 @@ int dfs_dup(int oldfd, int startfd)
fdt = dfs_fdtable_get();
if ((oldfd < 0) || (oldfd >= fdt->maxfd))
{
rt_set_errno(-EBADF);
goto exit;
}
if (!fdt->fds[oldfd])
@ -668,12 +669,17 @@ sysret_t sys_dup(int oldfd)
int sys_dup(int oldfd)
#endif
{
int err = 0;
int newfd = dfs_dup(oldfd, (dfs_fdtable_get() == &_fdtab) ? DFS_STDIO_OFFSET : 0);
if(newfd < 0)
{
err = rt_get_errno();
}
#ifdef RT_USING_SMART
return (sysret_t)newfd;
return err < 0 ? err : newfd;
#else
return newfd;
return err < 0 ? err : newfd;
#endif
}

View File

@ -1379,6 +1379,7 @@ int dfs_file_link(const char *oldname, const char *newname)
if (dfs_file_isdir(oldname) == 0)
{
rt_set_errno(-EPERM);
return ret;
}
@ -1567,6 +1568,10 @@ int dfs_file_symlink(const char *target, const char *linkpath)
rt_free(parent);
}
}
else
{
rt_set_errno(-EPERM);
}
if (fullpath != linkpath)
rt_free(fullpath);

View File

@ -95,6 +95,52 @@ int dfs_unregister(struct dfs_filesystem_type *fs)
return ret;
}
#define REMNT_UNSUPP_FLAGS (~(MS_REMOUNT | MS_RMT_MASK))
int dfs_remount(const char *path, rt_ubase_t flags, void *data)
{
int rc = 0;
char *fullpath = RT_NULL;
struct dfs_mnt *mnt = RT_NULL;
if (flags & REMNT_UNSUPP_FLAGS)
{
return -EINVAL;
}
fullpath = dfs_normalize_path(RT_NULL, path);
if (!fullpath)
{
rc = -ENOENT;
}
else
{
DLOG(msg, "dfs", "mnt", DLOG_MSG, "mnt = dfs_mnt_lookup(%s)", fullpath);
mnt = dfs_mnt_lookup(fullpath);
if (mnt)
{
dfs_lock();
dfs_mnt_setflags(mnt, flags);
dfs_unlock();
}
else
{
struct stat buf = {0};
if (dfs_file_stat(fullpath, &buf) == 0 && S_ISBLK(buf.st_mode))
{
/* path was not already mounted on target */
rc = -EINVAL;
}
else
{
/* path is not a directory */
rc = -ENOTDIR;
}
}
}
return rc;
}
/*
* parent(mount path)
* mnt_parent <- - - - - - - +
@ -127,7 +173,7 @@ int dfs_mount(const char *device_name,
}
else
{
rt_set_errno(ENOENT);
rt_set_errno(ENODEV);
ret = -1;
}
@ -300,7 +346,7 @@ int dfs_mount(const char *device_name,
int dfs_umount(const char *specialfile, int flags)
{
int ret = -RT_ERROR;
int ret = -1;
char *fullpath = RT_NULL;
struct dfs_mnt *mnt = RT_NULL;
@ -314,7 +360,7 @@ int dfs_umount(const char *specialfile, int flags)
if (strcmp(mnt->fullpath, fullpath) == 0)
{
/* is the mount point */
rt_atomic_t ref_count = rt_atomic_load(&(mnt->ref_count));
rt_base_t ref_count = rt_atomic_load(&(mnt->ref_count));
if (!(mnt->flags & MNT_IS_LOCKED) && rt_list_isempty(&mnt->child) && (ref_count == 1 || (flags & MNT_FORCE)))
{
@ -327,17 +373,19 @@ int dfs_umount(const char *specialfile, int flags)
}
else
{
LOG_E("the file system is busy!");
LOG_I("the file system is busy!");
ret = -EBUSY;
}
}
else
{
LOG_E("the path:%s is not a mountpoint!", fullpath);
LOG_I("the path:%s is not a mountpoint!", fullpath);
ret = -EINVAL;
}
}
else
{
LOG_E("no filesystem found.");
LOG_I("no filesystem found.");
}
rt_free(fullpath);
}

View File

@ -10,17 +10,21 @@
#include <rtthread.h>
#include "dfs.h"
#include "dfs_mnt.h"
#include "dfs_dentry.h"
#include "dfs_private.h"
#include <dfs.h>
#include <dfs_dentry.h>
#include <dfs_mnt.h>
#include <dfs_pcache.h>
#define DBG_TAG "DFS.mnt"
#define DBG_LVL DBG_WARNING
#include <rtdbg.h>
static struct dfs_mnt *_root_mnt = RT_NULL;
RT_OBJECT_HOOKLIST_DEFINE(dfs_mnt_umnt);
/*
* mnt tree structure
*
@ -75,6 +79,7 @@ int dfs_mnt_insert(struct dfs_mnt* mnt, struct dfs_mnt* child)
child = _root_mnt;
rt_atomic_sub(&(_root_mnt->parent->ref_count), 1);
rt_atomic_sub(&(_root_mnt->ref_count), 1);
_root_mnt->flags &= ~MNT_IS_LOCKED;
_root_mnt = dfs_mnt_ref(mnt);
mnt->parent = dfs_mnt_ref(mnt);
@ -242,21 +247,24 @@ struct dfs_mnt* dfs_mnt_ref(struct dfs_mnt* mnt)
return mnt;
}
int dfs_mnt_unref(struct dfs_mnt* mnt)
int dfs_mnt_unref(struct dfs_mnt *mnt)
{
rt_err_t ret = RT_EOK;
rt_base_t ref_count;
if (mnt)
{
rt_atomic_sub(&(mnt->ref_count), 1);
ref_count = rt_atomic_sub(&(mnt->ref_count), 1) - 1;
if (rt_atomic_load(&(mnt->ref_count)) == 0)
if (ref_count == 0)
{
dfs_lock();
if (mnt->flags & MNT_IS_UMOUNT)
{
mnt->fs_ops->umount(mnt);
RT_OBJECT_HOOKLIST_CALL(dfs_mnt_umnt, (mnt));
}
/* free full path */
@ -278,6 +286,21 @@ int dfs_mnt_unref(struct dfs_mnt* mnt)
return ret;
}
int dfs_mnt_setflags(struct dfs_mnt *mnt, int flags)
{
int error = 0;
if (flags & MS_RDONLY)
{
mnt->flags |= MNT_RDONLY;
#ifdef RT_USING_PAGECACHE
dfs_pcache_clean(mnt);
#endif
}
return error;
}
int dfs_mnt_destroy(struct dfs_mnt* mnt)
{
rt_err_t ret = RT_EOK;

View File

@ -13,17 +13,19 @@
#define DBG_LVL DBG_WARNING
#include <rtdbg.h>
#include "dfs_pcache.h"
#include "dfs_dentry.h"
#include "dfs_mnt.h"
#include "mm_page.h"
#include <mmu.h>
#include <tlb.h>
#include <dfs_pcache.h>
#include <dfs_dentry.h>
#include <dfs_mnt.h>
#include <rthw.h>
#ifdef RT_USING_PAGECACHE
#include <mm_page.h>
#include <mm_private.h>
#include <mmu.h>
#include <tlb.h>
#ifndef RT_PAGECACHE_COUNT
#define RT_PAGECACHE_COUNT 4096
#endif
@ -160,7 +162,7 @@ void dfs_pcache_release(size_t count)
dfs_pcache_unlock();
}
void dfs_pcache_unmount(struct dfs_mnt *mnt)
static void _pcache_clean(struct dfs_mnt *mnt, int (*cb)(struct dfs_aspace *aspace))
{
rt_list_t *node = RT_NULL;
struct dfs_aspace *aspace = RT_NULL;
@ -175,7 +177,7 @@ void dfs_pcache_unmount(struct dfs_mnt *mnt)
if (aspace && aspace->mnt == mnt)
{
dfs_aspace_clean(aspace);
dfs_aspace_release(aspace);
cb(aspace);
}
}
@ -187,13 +189,28 @@ void dfs_pcache_unmount(struct dfs_mnt *mnt)
if (aspace && aspace->mnt == mnt)
{
dfs_aspace_clean(aspace);
dfs_aspace_release(aspace);
cb(aspace);
}
}
dfs_pcache_unlock();
}
void dfs_pcache_unmount(struct dfs_mnt *mnt)
{
_pcache_clean(mnt, dfs_aspace_release);
}
static int _dummy_cb(struct dfs_aspace *mnt)
{
return 0;
}
void dfs_pcache_clean(struct dfs_mnt *mnt)
{
_pcache_clean(mnt, _dummy_cb);
}
static int dfs_pcache_limit_check(void)
{
int index = 4;
@ -1138,14 +1155,21 @@ int dfs_aspace_write(struct dfs_file *file, const void *buf, size_t count, off_t
if (file && file->vnode && file->vnode->aspace)
{
if (!(file->vnode->aspace->ops->write))
return ret;
struct dfs_vnode *vnode = file->vnode;
struct dfs_aspace *aspace = vnode->aspace;
struct dfs_page *page;
char *ptr = (char *)buf;
if (!(aspace->ops->write))
{
return ret;
}
else if (aspace->mnt && (aspace->mnt->flags & MNT_RDONLY))
{
return -EROFS;
}
ret = 0;
while (count)
@ -1380,7 +1404,8 @@ int dfs_aspace_unmap(struct dfs_file *file, struct rt_varea *varea)
rt_varea_unmap_page(map_varea, vaddr);
if (varea->attr == MMU_MAP_U_RWCB && page->fpos < page->aspace->vnode->size)
if (!rt_varea_is_private_locked(varea) &&
page->fpos < page->aspace->vnode->size)
{
dfs_page_dirty(page);
}
@ -1425,7 +1450,7 @@ int dfs_aspace_page_unmap(struct dfs_file *file, struct rt_varea *varea, void *v
if (map && varea->aspace == map->aspace && vaddr == map->vaddr)
{
if (varea->attr == MMU_MAP_U_RWCB)
if (!rt_varea_is_private_locked(varea))
{
dfs_page_dirty(page);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@ -31,7 +31,17 @@
* return a file descriptor according specified flags.
*
* @param file the path name of file.
* @param flags the file open flags.
* @param flags the file open flags. Common values include:
* - Access modes (mutually exclusive):
* - `O_RDONLY`: Open for read-only access.
* - `O_WRONLY`: Open for write-only access.
* - `O_RDWR`: Open for both reading and writing.
* - File status flags (can be combined with bitwise OR `|`):
* - `O_CREAT`: Create the file if it does not exist. Requires a `mode` argument.
* - `O_TRUNC`: Truncate the file to zero length if it already exists.
* - `O_APPEND`: Append writes to the end of the file.
* - `O_EXCL`: Ensure that `O_CREAT` creates the file exclusively.
* - Other platform-specific flags
*
* @return the non-negative integer on successful open, others for failed.
*/
@ -81,6 +91,22 @@ RTM_EXPORT(open);
#ifndef AT_FDCWD
#define AT_FDCWD (-100)
#endif
/**
* @brief Opens a file relative to a directory file descriptor.
*
* @param dirfd The file descriptor of the directory to base the relative path on.
* @param path The path to the file to be opened, relative to the directory specified by `dirfd`.
* Can be an absolute path (in which case `dirfd` is ignored).
* @param flag File access and status flags (e.g., `O_RDONLY`, `O_WRONLY`, `O_CREAT`).
*
* @return On success, returns a new file descriptor for the opened file.
* On failure, returns `-1` and sets `errno` to indicate the error.
*
* @note When using relative paths, ensure `dirfd` is a valid directory descriptor.
* When `pathname` is absolute, the `dirfd` argument is ignored.
*
*/
int openat(int dirfd, const char *path, int flag, ...)
{
struct dfs_file *d;
@ -171,7 +197,7 @@ int utimensat(int __fd, const char *__path, const struct timespec __times[2], in
}
}
//update time
/*update time*/
attr.ia_valid = ATTR_ATIME_SET | ATTR_MTIME_SET;
time(&current_time);
if (UTIME_NOW == __times[0].tv_nsec)
@ -374,14 +400,22 @@ ssize_t write(int fd, const void *buf, size_t len)
RTM_EXPORT(write);
/**
* this function is a POSIX compliant version, which will seek the offset for
* this function is a POSIX compliant version, which will Reposition the file offset for
* an open file descriptor.
*
* @param fd the file descriptor.
* @param offset the offset to be seeked.
* @param whence the directory of seek.
* The `lseek` function sets the file offset for the file descriptor `fd`
* to a new value, determined by the `offset` and `whence` parameters.
* It can be used to seek to specific positions in a file for reading or writing.
*
* @return the current read/write position in the file, or -1 on failed.
* @param fd the file descriptor.
* @param offset The offset, in bytes, to set the file position.
* The meaning of `offset` depends on the value of `whence`.
* @param whence the directive of seek. It can be one of:
* - `SEEK_SET`: Set the offset to `offset` bytes from the beginning of the file.
* - `SEEK_CUR`: Set the offset to its current location plus `offset` bytes.
* - `SEEK_END`: Set the offset to the size of the file plus `offset` bytes.
*
* @return the resulting read/write position in the file, or -1 on failed.
*/
off_t lseek(int fd, off_t offset, int whence)
{
@ -399,7 +433,7 @@ off_t lseek(int fd, off_t offset, int whence)
result = dfs_file_lseek(file, offset, whence);
if (result < 0)
{
rt_set_errno(result);
rt_set_errno(-EPERM);
return -1;
}
@ -581,9 +615,15 @@ RTM_EXPORT(fsync);
* control functions on devices.
*
* @param fildes the file description
* @param cmd the specified command
* @param cmd the specified command, Common values include:
* - `F_DUPFD`: Duplicate a file descriptor.
* - `F_GETFD`: Get the file descriptor flags.
* - `F_SETFD`: Set the file descriptor flags.
* - `F_GETFL`: Get the file status flags.
* - `F_SETFL`: Set the file status flags.
* @param ... represents the additional information that is needed by this
* specific device to perform the requested function.
* specific device to perform the requested function. For example:
* - When `cmd` is `F_SETFL`, an additional integer argument specifies the new status flags.
*
* @return 0 on successful completion. Otherwise, -1 shall be returned and errno
* set to indicate the error.
@ -765,7 +805,7 @@ RTM_EXPORT(fstatfs);
* this function is a POSIX compliant version, which will make a directory
*
* @param path the directory path to be made.
* @param mode
* @param mode The permission mode for the new directory (unused here, can be set to 0).
*
* @return 0 on successful, others on failed.
*/
@ -827,7 +867,7 @@ int rmdir(const char *pathname)
if (!pathname)
{
rt_set_errno(-RT_ERROR);
rt_set_errno(-EPERM);
return -1;
}
@ -852,7 +892,7 @@ int rmdir(const char *pathname)
if (dirent)
{
rt_set_errno(-RT_ERROR);
rt_set_errno(-EPERM);
return -1;
}
}
@ -861,7 +901,7 @@ int rmdir(const char *pathname)
{
if (S_ISLNK(stat.st_mode))
{
rt_set_errno(-RT_ERROR);
rt_set_errno(-EPERM);
return -1;
}
}

View File

@ -256,7 +256,7 @@ Enomem:
goto Done;
}
ssize_t dfs_seq_lseek(struct dfs_file *file, off_t offset, int whence)
off_t dfs_seq_lseek(struct dfs_file *file, off_t offset, int whence)
{
struct dfs_seq_file *seq = file->data;
off_t retval = -EINVAL;

View File

@ -21,8 +21,21 @@ rsource "touch/Kconfig"
rsource "graphic/Kconfig"
rsource "hwcrypto/Kconfig"
rsource "wlan/Kconfig"
rsource "led/Kconfig"
rsource "mailbox/Kconfig"
rsource "phye/Kconfig"
rsource "ata/Kconfig"
rsource "nvme/Kconfig"
rsource "block/Kconfig"
rsource "scsi/Kconfig"
rsource "regulator/Kconfig"
rsource "reset/Kconfig"
rsource "thermal/Kconfig"
rsource "virtio/Kconfig"
rsource "dma/Kconfig"
rsource "mfd/Kconfig"
rsource "ofw/Kconfig"
rsource "pci/Kconfig"
rsource "pic/Kconfig"
rsource "pin/Kconfig"
rsource "pinctrl/Kconfig"

Some files were not shown because too many files have changed in this diff Show More