串口1,485功能。
数据接收解析及数据库处理
This commit is contained in:
1 parent
e36baf375d
commit
0735772f8a
19 files changed
+2011
-173
No files matched your search
@@ -50,8 +50,8 @@ CONFIG_RT_USING_MUTEX=y
|
|||||||
CONFIG_RT_USING_EVENT=y
|
CONFIG_RT_USING_EVENT=y
|
||||||
CONFIG_RT_USING_MAILBOX=y
|
CONFIG_RT_USING_MAILBOX=y
|
||||||
CONFIG_RT_USING_MESSAGEQUEUE=y
|
CONFIG_RT_USING_MESSAGEQUEUE=y
|
||||||
# CONFIG_RT_USING_MESSAGEQUEUE_PRIORITY is not set
|
CONFIG_RT_USING_MESSAGEQUEUE_PRIORITY=y
|
||||||
# CONFIG_RT_USING_SIGNALS is not set
|
CONFIG_RT_USING_SIGNALS=y
|
||||||
# end of Inter-Thread communication
|
# end of Inter-Thread communication
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1054,7 +1054,25 @@ CONFIG_PKG_LITTLEFS_VER="v2.11.2"
|
|||||||
# CONFIG_PKG_USING_DM9051 is not set
|
# CONFIG_PKG_USING_DM9051 is not set
|
||||||
# CONFIG_PKG_USING_SSD1306 is not set
|
# CONFIG_PKG_USING_SSD1306 is not set
|
||||||
# CONFIG_PKG_USING_QKEY is not set
|
# CONFIG_PKG_USING_QKEY is not set
|
||||||
# CONFIG_PKG_USING_RS485 is not set
|
CONFIG_PKG_USING_RS485=y
|
||||||
|
CONFIG_PKG_RS485_PATH="/packages/peripherals/rs485"
|
||||||
|
CONFIG_RS485_USING_DEV=y
|
||||||
|
# CONFIG_RS485_USING_DMA_RX is not set
|
||||||
|
# CONFIG_RS485_USING_INT_TX is not set
|
||||||
|
# CONFIG_RS485_USING_DMA_TX is not set
|
||||||
|
CONFIG_RS485_SW_DLY_US=0
|
||||||
|
# CONFIG_RS485_USING_TEST is not set
|
||||||
|
# CONFIG_RS485_USING_SAMPLE_MASTER is not set
|
||||||
|
# CONFIG_RS485_USING_SAMPLE_SLAVE is not set
|
||||||
|
# CONFIG_PKG_USING_RS485_LATEST_VERSION is not set
|
||||||
|
CONFIG_PKG_USING_RS485_V106=y
|
||||||
|
# CONFIG_PKG_USING_RS485_V105 is not set
|
||||||
|
# CONFIG_PKG_USING_RS485_V104 is not set
|
||||||
|
# CONFIG_PKG_USING_RS485_V103 is not set
|
||||||
|
# CONFIG_PKG_USING_RS485_V102 is not set
|
||||||
|
# CONFIG_PKG_USING_RS485_V101 is not set
|
||||||
|
# CONFIG_PKG_USING_RS485_V100 is not set
|
||||||
|
CONFIG_PKG_RS485_VER="v1.06"
|
||||||
# CONFIG_PKG_USING_RS232 is not set
|
# CONFIG_PKG_USING_RS232 is not set
|
||||||
# CONFIG_PKG_USING_NES is not set
|
# CONFIG_PKG_USING_NES is not set
|
||||||
# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
|
# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
|
||||||
|
|||||||
@@ -144,6 +144,7 @@
|
|||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/LVGL-v8.3.11/src}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/LVGL-v8.3.11/src}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/cJSON-v1.7.17}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/cJSON-v1.7.17}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/littlefs-v2.11.2}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/littlefs-v2.11.2}"" />
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/rs485-v1.06/inc}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/sqlite-v3.19.3}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/sqlite-v3.19.3}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/devfs}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/devfs}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/elmfat}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/elmfat}"" />
|
||||||
@@ -323,6 +324,7 @@
|
|||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/LVGL-v8.3.11/src}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/LVGL-v8.3.11/src}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/cJSON-v1.7.17}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/cJSON-v1.7.17}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/littlefs-v2.11.2}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/littlefs-v2.11.2}"" />
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/rs485-v1.06/inc}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/sqlite-v3.19.3}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/sqlite-v3.19.3}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/devfs}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/devfs}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/elmfat}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/elmfat}"" />
|
||||||
@@ -465,6 +467,7 @@
|
|||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/LVGL-v8.3.11/src}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/LVGL-v8.3.11/src}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/cJSON-v1.7.17}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/cJSON-v1.7.17}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/littlefs-v2.11.2}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/littlefs-v2.11.2}"" />
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/rs485-v1.06/inc}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/sqlite-v3.19.3}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/sqlite-v3.19.3}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/devfs}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/devfs}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/elmfat}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/elmfat}"" />
|
||||||
@@ -611,6 +614,7 @@
|
|||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/LVGL-v8.3.11/src}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/LVGL-v8.3.11/src}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/cJSON-v1.7.17}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/cJSON-v1.7.17}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/littlefs-v2.11.2}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/littlefs-v2.11.2}"" />
|
||||||
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/rs485-v1.06/inc}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/sqlite-v3.19.3}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//packages/sqlite-v3.19.3}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/devfs}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/devfs}"" />
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/elmfat}"" />
|
<listOptionValue builtIn="false" value=""${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/elmfat}"" />
|
||||||
@@ -643,7 +647,7 @@
|
|||||||
</toolChain>
|
</toolChain>
|
||||||
</folderInfo>
|
</folderInfo>
|
||||||
<sourceEntries>
|
<sourceEntries>
|
||||||
<entry excluding="//cubemx/Drivers|//cubemx/EWARM|//cubemx/Src/stm32h7xx_it.c|//cubemx/Src/system_stm32h7xx.c|//packages/LVGL-v8.3.11/demos|//packages/LVGL-v8.3.11/env_support/rt-thread/squareline|//packages/LVGL-v8.3.11/examples|//packages/LVGL-v8.3.11/tests|//packages/littlefs-v2.11.2/runners|//packages/sqlite-v3.19.3/dbhelper.c|//packages/sqlite-v3.19.3/rtthread_io_methods.c|//packages/sqlite-v3.19.3/rtthread_mutex.c|//packages/sqlite-v3.19.3/rtthread_vfs.c|//packages/sqlite-v3.19.3/shell.c|//packages/sqlite-v3.19.3/student_dao.c|//rt-thread/components/dfs/dfs_v1/filesystems/cromfs|//rt-thread/components/dfs/dfs_v1/filesystems/mqueue|//rt-thread/components/dfs/dfs_v1/filesystems/nfs|//rt-thread/components/dfs/dfs_v1/filesystems/ramfs|//rt-thread/components/dfs/dfs_v1/filesystems/romfs|//rt-thread/components/dfs/dfs_v1/filesystems/skeleton|//rt-thread/components/dfs/dfs_v2|//rt-thread/components/drivers/audio|//rt-thread/components/drivers/can|//rt-thread/components/drivers/clk|//rt-thread/components/drivers/core/dm.c|//rt-thread/components/drivers/core/driver.c|//rt-thread/components/drivers/core/platform.c|//rt-thread/components/drivers/core/platform_ofw.c|//rt-thread/components/drivers/cputime|//rt-thread/components/drivers/fdt|//rt-thread/components/drivers/hwcrypto|//rt-thread/components/drivers/hwtimer|//rt-thread/components/drivers/i2c|//rt-thread/components/drivers/ktime|//rt-thread/components/drivers/misc|//rt-thread/components/drivers/mtd/mtd_nand.c|//rt-thread/components/drivers/ofw|//rt-thread/components/drivers/phy|//rt-thread/components/drivers/pic|//rt-thread/components/drivers/pin/pin_dm.c|//rt-thread/components/drivers/pin/pin_ofw.c|//rt-thread/components/drivers/pinctrl|//rt-thread/components/drivers/pm|//rt-thread/components/drivers/rtc/alarm.c|//rt-thread/components/drivers/rtc/soft_rtc.c|//rt-thread/components/drivers/sensor|//rt-thread/components/drivers/serial/serial_dm.c|//rt-thread/components/drivers/serial/serial_tty.c|//rt-thread/components/drivers/serial/serial_v2.c|//rt-thread/components/drivers/spi/enc28j60.c|//rt-thread/components/drivers/spi/spi-bit-ops.c|//rt-thread/components/drivers/spi/spi_wifi_rw009.c|//rt-thread/components/drivers/touch|//rt-thread/components/drivers/usb|//rt-thread/components/drivers/virtio|//rt-thread/components/drivers/wlan|//rt-thread/components/fal/samples/porting/fal_flash_stm32f2_port.c|//rt-thread/components/legacy|//rt-thread/components/libc/compilers/armlibc|//rt-thread/components/libc/compilers/dlib|//rt-thread/components/libc/compilers/musl|//rt-thread/components/libc/compilers/picolibc|//rt-thread/components/libc/cplusplus|//rt-thread/components/libc/posix|//rt-thread/components/lwp|//rt-thread/components/mm|//rt-thread/components/mprotect|//rt-thread/components/net|//rt-thread/components/utilities|//rt-thread/components/vbus|//rt-thread/libcpu/aarch64|//rt-thread/libcpu/arc|//rt-thread/libcpu/arm/AT91SAM7S|//rt-thread/libcpu/arm/AT91SAM7X|//rt-thread/libcpu/arm/am335x|//rt-thread/libcpu/arm/arm926|//rt-thread/libcpu/arm/armv6|//rt-thread/libcpu/arm/common/atomic_arm.c|//rt-thread/libcpu/arm/common/divsi3.S|//rt-thread/libcpu/arm/cortex-a|//rt-thread/libcpu/arm/cortex-m0|//rt-thread/libcpu/arm/cortex-m23|//rt-thread/libcpu/arm/cortex-m3|//rt-thread/libcpu/arm/cortex-m33|//rt-thread/libcpu/arm/cortex-m4|//rt-thread/libcpu/arm/cortex-m7/context_iar.S|//rt-thread/libcpu/arm/cortex-m7/context_rvds.S|//rt-thread/libcpu/arm/cortex-m7/mpu.c|//rt-thread/libcpu/arm/cortex-m85|//rt-thread/libcpu/arm/cortex-r4|//rt-thread/libcpu/arm/cortex-r52|//rt-thread/libcpu/arm/dm36x|//rt-thread/libcpu/arm/lpc214x|//rt-thread/libcpu/arm/lpc24xx|//rt-thread/libcpu/arm/realview-a8-vmm|//rt-thread/libcpu/arm/s3c24x0|//rt-thread/libcpu/arm/s3c44b0|//rt-thread/libcpu/arm/sep4020|//rt-thread/libcpu/arm/zynqmp-r5|//rt-thread/libcpu/avr32|//rt-thread/libcpu/blackfin|//rt-thread/libcpu/c-sky|//rt-thread/libcpu/ia32|//rt-thread/libcpu/m16c|//rt-thread/libcpu/mips|//rt-thread/libcpu/nios|//rt-thread/libcpu/ppc|//rt-thread/libcpu/risc-v|//rt-thread/libcpu/rx|//rt-thread/libcpu/sim|//rt-thread/libcpu/sparc-v8|//rt-thread/libcpu/ti-dsp|//rt-thread/libcpu/unicore32|//rt-thread/libcpu/v850|//rt-thread/libcpu/xilinx|//rt-thread/src/cpu.c|//rt-thread/src/mem.c|//rt-thread/src/scheduler_mp.c|//rt-thread/src/signal.c|//rt-thread/src/slab.c|//rt-thread/tools" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="" />
|
<entry excluding="//cubemx/Drivers|//cubemx/EWARM|//cubemx/Src/stm32h7xx_it.c|//cubemx/Src/system_stm32h7xx.c|//packages/LVGL-v8.3.11/demos|//packages/LVGL-v8.3.11/env_support/rt-thread/squareline|//packages/LVGL-v8.3.11/examples|//packages/LVGL-v8.3.11/tests|//packages/littlefs-v2.11.2/runners|//packages/sqlite-v3.19.3/dbhelper.c|//packages/sqlite-v3.19.3/rtthread_io_methods.c|//packages/sqlite-v3.19.3/rtthread_mutex.c|//packages/sqlite-v3.19.3/rtthread_vfs.c|//packages/sqlite-v3.19.3/shell.c|//packages/sqlite-v3.19.3/student_dao.c|//rt-thread/components/dfs/dfs_v1/filesystems/cromfs|//rt-thread/components/dfs/dfs_v1/filesystems/mqueue|//rt-thread/components/dfs/dfs_v1/filesystems/nfs|//rt-thread/components/dfs/dfs_v1/filesystems/ramfs|//rt-thread/components/dfs/dfs_v1/filesystems/romfs|//rt-thread/components/dfs/dfs_v1/filesystems/skeleton|//rt-thread/components/dfs/dfs_v2|//rt-thread/components/drivers/audio|//rt-thread/components/drivers/can|//rt-thread/components/drivers/clk|//rt-thread/components/drivers/core/dm.c|//rt-thread/components/drivers/core/driver.c|//rt-thread/components/drivers/core/platform.c|//rt-thread/components/drivers/core/platform_ofw.c|//rt-thread/components/drivers/cputime|//rt-thread/components/drivers/fdt|//rt-thread/components/drivers/hwcrypto|//rt-thread/components/drivers/hwtimer|//rt-thread/components/drivers/i2c|//rt-thread/components/drivers/ktime|//rt-thread/components/drivers/misc|//rt-thread/components/drivers/mtd/mtd_nand.c|//rt-thread/components/drivers/ofw|//rt-thread/components/drivers/phy|//rt-thread/components/drivers/pic|//rt-thread/components/drivers/pin/pin_dm.c|//rt-thread/components/drivers/pin/pin_ofw.c|//rt-thread/components/drivers/pinctrl|//rt-thread/components/drivers/pm|//rt-thread/components/drivers/rtc/alarm.c|//rt-thread/components/drivers/rtc/soft_rtc.c|//rt-thread/components/drivers/sensor|//rt-thread/components/drivers/serial/serial_dm.c|//rt-thread/components/drivers/serial/serial_tty.c|//rt-thread/components/drivers/serial/serial_v2.c|//rt-thread/components/drivers/spi/enc28j60.c|//rt-thread/components/drivers/spi/spi-bit-ops.c|//rt-thread/components/drivers/spi/spi_wifi_rw009.c|//rt-thread/components/drivers/touch|//rt-thread/components/drivers/usb|//rt-thread/components/drivers/virtio|//rt-thread/components/drivers/wlan|//rt-thread/components/fal/samples/porting/fal_flash_stm32f2_port.c|//rt-thread/components/legacy|//rt-thread/components/libc/compilers/armlibc|//rt-thread/components/libc/compilers/dlib|//rt-thread/components/libc/compilers/musl|//rt-thread/components/libc/compilers/picolibc|//rt-thread/components/libc/cplusplus|//rt-thread/components/libc/posix|//rt-thread/components/lwp|//rt-thread/components/mm|//rt-thread/components/mprotect|//rt-thread/components/net|//rt-thread/components/utilities|//rt-thread/components/vbus|//rt-thread/libcpu/aarch64|//rt-thread/libcpu/arc|//rt-thread/libcpu/arm/AT91SAM7S|//rt-thread/libcpu/arm/AT91SAM7X|//rt-thread/libcpu/arm/am335x|//rt-thread/libcpu/arm/arm926|//rt-thread/libcpu/arm/armv6|//rt-thread/libcpu/arm/common/atomic_arm.c|//rt-thread/libcpu/arm/common/divsi3.S|//rt-thread/libcpu/arm/cortex-a|//rt-thread/libcpu/arm/cortex-m0|//rt-thread/libcpu/arm/cortex-m23|//rt-thread/libcpu/arm/cortex-m3|//rt-thread/libcpu/arm/cortex-m33|//rt-thread/libcpu/arm/cortex-m4|//rt-thread/libcpu/arm/cortex-m7/context_iar.S|//rt-thread/libcpu/arm/cortex-m7/context_rvds.S|//rt-thread/libcpu/arm/cortex-m7/mpu.c|//rt-thread/libcpu/arm/cortex-m85|//rt-thread/libcpu/arm/cortex-r4|//rt-thread/libcpu/arm/cortex-r52|//rt-thread/libcpu/arm/dm36x|//rt-thread/libcpu/arm/lpc214x|//rt-thread/libcpu/arm/lpc24xx|//rt-thread/libcpu/arm/realview-a8-vmm|//rt-thread/libcpu/arm/s3c24x0|//rt-thread/libcpu/arm/s3c44b0|//rt-thread/libcpu/arm/sep4020|//rt-thread/libcpu/arm/zynqmp-r5|//rt-thread/libcpu/avr32|//rt-thread/libcpu/blackfin|//rt-thread/libcpu/c-sky|//rt-thread/libcpu/ia32|//rt-thread/libcpu/m16c|//rt-thread/libcpu/mips|//rt-thread/libcpu/nios|//rt-thread/libcpu/ppc|//rt-thread/libcpu/risc-v|//rt-thread/libcpu/rx|//rt-thread/libcpu/sim|//rt-thread/libcpu/sparc-v8|//rt-thread/libcpu/ti-dsp|//rt-thread/libcpu/unicore32|//rt-thread/libcpu/v850|//rt-thread/libcpu/xilinx|//rt-thread/src/cpu.c|//rt-thread/src/mem.c|//rt-thread/src/scheduler_mp.c|//rt-thread/src/slab.c|//rt-thread/tools" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="" />
|
||||||
</sourceEntries>
|
</sourceEntries>
|
||||||
</configuration>
|
</configuration>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||||
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-1181000638286128853" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM Cross GCC Built-in Compiler Settings " parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-1121190519793770309" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM Cross GCC Built-in Compiler Settings " parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||||
</provider>
|
</provider>
|
||||||
|
|||||||
+26
-92
@@ -11,117 +11,58 @@
|
|||||||
*/
|
*/
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
#include <rtdevice.h>
|
#include <rtdevice.h>
|
||||||
#include <drivers/serial.h> // ← 显式包含,确保 RT_SERIAL_EVENT_RX_IDLE 可见
|
|
||||||
#include "data_comm.h"
|
#include "data_comm.h"
|
||||||
|
#include <rs485.h>
|
||||||
|
|
||||||
#define DBG_TAG "SCCM_link"
|
#define DBG_TAG "SCCM_link"
|
||||||
#define DBG_LVL DBG_LOG
|
#define DBG_LVL DBG_LOG
|
||||||
#include <rtdbg.h>
|
#include <rtdbg.h>
|
||||||
|
|
||||||
#define SAMPLE_UART_NAME "uart1"
|
|
||||||
#define RX_LINE_BUF_SIZE 1024
|
|
||||||
|
|
||||||
static rt_device_t serial;
|
|
||||||
static struct rt_semaphore rx_sem;
|
static struct rt_semaphore rx_sem;
|
||||||
|
|
||||||
// 接收回调
|
#define RX_LINE_BUF_SIZE 1024
|
||||||
static rt_err_t uart_rx_ind(rt_device_t dev, rt_size_t size)
|
#define RS485_SAMPLE_SLAVE_SERIAL "uart1"
|
||||||
{
|
#define RS485_SAMPLE_SLAVE_BAUDRATE 115200
|
||||||
// 注意:在 RT-Thread 5.x,当使用 INT_RX 时,size 是接收到的字节数
|
#define RS485_SAMPLE_MASTER_PARITY 0 //0 -- none parity
|
||||||
// 但若启用了 RX_IDLE 模式,底层驱动会在 IDLE 时回调,并传入事件
|
#define RS485_SAMPLE_SLAVE_PIN -1 //-1 -- nonuse rs485 mode control
|
||||||
// 安全做法:检查是否为事件(高位标志)
|
#define RS485_SAMPLE_SLAVE_LVL 1
|
||||||
// if (size & RT_SERIAL_EVENT_RX_IDLE)
|
#define RS485_TOM_MS 50
|
||||||
{
|
|
||||||
LOG_D("RX IDLE event received");
|
|
||||||
rt_sem_release(&rx_sem);
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果是普通数据(size > 0),也可处理,但本例依赖 IDLE 触发
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int read_line_from_uart(char *buf, int maxlen)
|
|
||||||
{
|
|
||||||
char ch;
|
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
while (len < maxlen - 1)
|
|
||||||
{
|
|
||||||
// 注意:在 INT_RX 模式下,rt_device_read 会从驱动内部 buffer 读取
|
|
||||||
rt_size_t result = rt_device_read(serial, 0, &ch, 1);
|
|
||||||
if (result <= 0)
|
|
||||||
{
|
|
||||||
break; // 无更多数据
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[len++] = ch;
|
|
||||||
if (ch == '\n')
|
|
||||||
{
|
|
||||||
buf[len] = '\0';
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[len] = '\0';
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uart_thread_entry(void *parameter)
|
void uart_thread_entry(void *parameter)
|
||||||
{
|
{
|
||||||
char input[RX_LINE_BUF_SIZE];
|
|
||||||
int len;
|
|
||||||
|
|
||||||
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
|
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
|
||||||
|
|
||||||
serial = rt_device_find(SAMPLE_UART_NAME);
|
static rt_uint8_t input[RX_LINE_BUF_SIZE];
|
||||||
if (!serial)
|
rs485_inst_t *hinst = rs485_create(RS485_SAMPLE_SLAVE_SERIAL, RS485_SAMPLE_SLAVE_BAUDRATE,
|
||||||
|
RS485_SAMPLE_MASTER_PARITY, RS485_SAMPLE_SLAVE_PIN, RS485_SAMPLE_SLAVE_LVL);
|
||||||
|
|
||||||
|
if (hinst == RT_NULL)
|
||||||
{
|
{
|
||||||
LOG_E("Cannot find %s", SAMPLE_UART_NAME);
|
LOG_E("create LINK instance fail.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 1: 设置串口基本参数(波特率等)
|
rs485_set_recv_tmo(hinst, RS485_TOM_MS);
|
||||||
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
|
if (rs485_connect(hinst) != RT_EOK)
|
||||||
config.baud_rate = BAUD_RATE_115200; // 根据需要调整
|
|
||||||
config.data_bits = DATA_BITS_8;
|
|
||||||
config.stop_bits = STOP_BITS_1;
|
|
||||||
config.parity = PARITY_NONE;
|
|
||||||
config.bufsz = RX_LINE_BUF_SIZE; // 驱动内部接收 buffer 大小
|
|
||||||
rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);
|
|
||||||
|
|
||||||
// Step 2: 【关键】启用 RX IDLE 模式
|
|
||||||
// rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, (void*)RT_SERIAL_RX_IDLE);
|
|
||||||
|
|
||||||
// Step 3: 打开串口(使用中断接收)
|
|
||||||
rt_err_t result = rt_device_open(serial, RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX);
|
|
||||||
if (result != RT_EOK)
|
|
||||||
{
|
{
|
||||||
LOG_E("Failed to open %s, error=%d", SAMPLE_UART_NAME, result);
|
rs485_destory(hinst);
|
||||||
|
LOG_E("LINK connect fail.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4: 设置回调
|
LOG_I("SCCM thread running on %s", RS485_SAMPLE_SLAVE_SERIAL);
|
||||||
rt_device_set_rx_indicate(serial, uart_rx_ind);
|
|
||||||
|
|
||||||
LOG_I("SCCM thread (IDLE mode) running on %s", SAMPLE_UART_NAME);
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
// 等待数据就绪
|
int len = rs485_recv(hinst, input, sizeof(input));
|
||||||
if (rt_sem_take(&rx_sem, RT_WAITING_FOREVER) == RT_EOK)
|
|
||||||
{
|
if (len > 0)
|
||||||
// 处理接收到的数据(提取完整行)
|
|
||||||
while ((len = get_line(input, sizeof(input))) > 0)
|
|
||||||
{
|
{
|
||||||
// 动态分配请求结构体(见之前完整代码)
|
// 动态分配请求结构体(见之前完整代码)
|
||||||
struct proc_request *req = rt_malloc(sizeof(struct proc_request));
|
struct proc_request *req = rt_malloc(sizeof(struct proc_request));
|
||||||
if (!req) continue;
|
if (!req) continue;
|
||||||
|
rt_strncpy(req->input, (const char *)input, sizeof(req->input));
|
||||||
rt_strncpy(req->input, input, sizeof(req->input));
|
|
||||||
req->input_len = len;
|
req->input_len = len;
|
||||||
//req->input[len]='\0';
|
|
||||||
|
|
||||||
req->sem = rt_malloc(sizeof(struct rt_semaphore));
|
req->sem = rt_malloc(sizeof(struct rt_semaphore));
|
||||||
if (!req->sem) {
|
if (!req->sem) {
|
||||||
rt_free(req);
|
rt_free(req);
|
||||||
@@ -133,12 +74,11 @@ void uart_thread_entry(void *parameter)
|
|||||||
if (rt_mq_send(proc_mq, &req, sizeof(req)) == RT_EOK)
|
if (rt_mq_send(proc_mq, &req, sizeof(req)) == RT_EOK)
|
||||||
{
|
{
|
||||||
// 等待处理完成
|
// 等待处理完成
|
||||||
if (rt_sem_take(req->sem, RT_WAITING_FOREVER) == RT_EOK)
|
if (rt_sem_take(req->sem, rt_tick_from_millisecond(100)) >= RT_EOK)
|
||||||
{
|
{
|
||||||
rt_device_write(serial, 0, req->output, req->output_len);
|
rs485_send(hinst, req->output, req->output_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清理
|
// 清理
|
||||||
rt_sem_detach(req->sem); // 或 rt_sem_delete
|
rt_sem_detach(req->sem); // 或 rt_sem_delete
|
||||||
rt_free(req->sem);
|
rt_free(req->sem);
|
||||||
@@ -146,16 +86,10 @@ void uart_thread_entry(void *parameter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int start_uart_thread(void)
|
int start_uart_thread(void)
|
||||||
{
|
{
|
||||||
rt_thread_t tid = rt_thread_create("data_uart",
|
rt_thread_t tid = rt_thread_create("uart1",uart_thread_entry,RT_NULL,2048,20,10);
|
||||||
uart_thread_entry,
|
|
||||||
RT_NULL,
|
|
||||||
2048,
|
|
||||||
25,
|
|
||||||
10);
|
|
||||||
if (tid != RT_NULL)
|
if (tid != RT_NULL)
|
||||||
{
|
{
|
||||||
rt_thread_startup(tid);
|
rt_thread_startup(tid);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
*/
|
*/
|
||||||
/* DATA_comm.c */
|
/* DATA_comm.c */
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
#include "cjson.h"
|
#include "cjson.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -24,11 +25,10 @@
|
|||||||
#include <rtdbg.h>
|
#include <rtdbg.h>
|
||||||
|
|
||||||
rt_mq_t proc_mq;
|
rt_mq_t proc_mq;
|
||||||
|
//static struct proc_request *req;
|
||||||
|
|
||||||
char cjson_falg=0;//是否解析cjson
|
char cjson_falg=0;//是否解析cjson
|
||||||
char *json_buffer=NULL;
|
char *json_buffer=NULL;//
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 截取两个指定子串之间的内容
|
* 截取两个指定子串之间的内容
|
||||||
@@ -432,17 +432,18 @@ void proc_thread_entry(void *parameter)
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
// 接收请求指针
|
// 接收请求指针
|
||||||
if (rt_mq_recv(proc_mq, &req, sizeof(req), RT_WAITING_FOREVER) == RT_EOK)
|
if (rt_mq_recv(proc_mq, &req, sizeof(req), RT_WAITING_FOREVER) >= RT_EOK)
|
||||||
{
|
{
|
||||||
if (!req) continue;
|
if (!req) continue;
|
||||||
memcpy(DATA_api,req->input,5);
|
memcpy(DATA_api,req->input,5);
|
||||||
extract_between(req->input, "[", "]", DATA_machins, sizeof(DATA_machins));
|
extract_between(req->input, "[", "]", DATA_machins, sizeof(DATA_machins));
|
||||||
|
|
||||||
if(strcmp(DATA_machins,machine_ID)==0)
|
if(strcmp(DATA_machins,machine_ID)==0)
|
||||||
{
|
{
|
||||||
char *p=strstr(req->input,"]");
|
char *p=strstr(req->input,"]");
|
||||||
if(!p){cjson_falg=0;}
|
if(!p)
|
||||||
else {
|
{
|
||||||
|
cjson_falg=0;
|
||||||
|
}else {
|
||||||
p += strlen("]");
|
p += strlen("]");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,8 +482,7 @@ int data_comm_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dat_comm_stack = rt_memheap_alloc(&sram_DTCMRAM, 1024*6);
|
dat_comm_stack = rt_memheap_alloc(&sram_DTCMRAM, 1024*6);
|
||||||
dat_err = rt_thread_init(&dat_comm_thread, "dat_comm", proc_thread_entry, RT_NULL,
|
dat_err = rt_thread_init(&dat_comm_thread, "dat_comm", proc_thread_entry, RT_NULL,dat_comm_stack, 1024*6, 15, 10);
|
||||||
dat_comm_stack, 1024*6, 15, 10);
|
|
||||||
|
|
||||||
if(dat_err != RT_EOK)
|
if(dat_err != RT_EOK)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-12
@@ -12,7 +12,6 @@
|
|||||||
#include <dfs_posix.h>
|
#include <dfs_posix.h>
|
||||||
#include <light/RUN_LED.h>
|
#include <light/RUN_LED.h>
|
||||||
#include "DB_SQLite.h"
|
#include "DB_SQLite.h"
|
||||||
#include "DATA_comm.h"
|
|
||||||
#include "DATA_uart.h"
|
#include "DATA_uart.h"
|
||||||
|
|
||||||
#define DBG_TAG "main"
|
#define DBG_TAG "main"
|
||||||
@@ -23,19 +22,9 @@ extern rt_sem_t mount_sem; // 引用上面SD挂载线程定义的信号量
|
|||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
/*volatile uint32_t *sdram_test = (uint32_t*)0xC0000000;
|
|
||||||
*sdram_test = 0xAABBCCDD;
|
|
||||||
rt_thread_mdelay(1); // 等待稳定
|
|
||||||
if (*sdram_test != 0xAABBCCDD)
|
|
||||||
{
|
|
||||||
rt_kprintf("SDRAM init failed!\n");
|
|
||||||
while (1); // 卡死,不要继续
|
|
||||||
}
|
|
||||||
rt_kprintf("SDRAM test OK\n");*/
|
|
||||||
|
|
||||||
rt_sem_take(mount_sem, rt_tick_from_millisecond(5000)); // 等待挂载完成,最多等待 5 秒
|
rt_sem_take(mount_sem, rt_tick_from_millisecond(5000)); // 等待挂载完成,最多等待 5 秒
|
||||||
thread_DB_SQLite();
|
thread_DB_SQLite();
|
||||||
//start_uart_thread();
|
start_uart_thread();
|
||||||
thread_RUN_LED();//运行指示灯线程
|
thread_RUN_LED();//运行指示灯线程
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
@@ -282,10 +282,10 @@ static void db_sqlite(void *parameter) {
|
|||||||
// 默认启用数据库
|
// 默认启用数据库
|
||||||
db_enabled = RT_TRUE;
|
db_enabled = RT_TRUE;
|
||||||
|
|
||||||
while (1) {
|
while (1)
|
||||||
rt_thread_mdelay(500);
|
{
|
||||||
// 接收命令
|
// 接收命令
|
||||||
if (rt_mq_recv(db_mq, &cmd, sizeof(struct db_command), RT_WAITING_FOREVER) != RT_EOK)
|
if (rt_mq_recv(db_mq, &cmd, sizeof(struct db_command), RT_WAITING_FOREVER) <= RT_EOK)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//检查排队超时
|
//检查排队超时
|
||||||
@@ -310,12 +310,14 @@ static void db_sqlite(void *parameter) {
|
|||||||
if (cmd.type == DB_CMD_EXIT) break;
|
if (cmd.type == DB_CMD_EXIT) break;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//打开数据库(如果未打开)
|
//打开数据库(如果未打开)
|
||||||
rt_mutex_take(state_mutex, RT_WAITING_FOREVER);
|
rt_mutex_take(state_mutex, RT_WAITING_FOREVER);
|
||||||
|
if (!g_db && current_enabled)
|
||||||
{
|
{
|
||||||
if (!g_db && current_enabled) {
|
|
||||||
int rc = sqlite3_open(DB_NAME, &g_db);
|
int rc = sqlite3_open(DB_NAME, &g_db);
|
||||||
if (rc != SQLITE_OK) {
|
if (rc != SQLITE_OK)
|
||||||
|
{
|
||||||
rt_kprintf("Failed to open DB at %s: %s\n", DB_NAME, sqlite3_errmsg(g_db));
|
rt_kprintf("Failed to open DB at %s: %s\n", DB_NAME, sqlite3_errmsg(g_db));
|
||||||
sqlite3_close(g_db);
|
sqlite3_close(g_db);
|
||||||
g_db = RT_NULL;
|
g_db = RT_NULL;
|
||||||
@@ -326,14 +328,14 @@ static void db_sqlite(void *parameter) {
|
|||||||
rt_kprintf("Opened database: %s\n", DB_NAME);
|
rt_kprintf("Opened database: %s\n", DB_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
rt_mutex_release(state_mutex);
|
rt_mutex_release(state_mutex);
|
||||||
|
|
||||||
//执行命令
|
//执行命令
|
||||||
handle_db_command(&cmd);
|
handle_db_command(&cmd);
|
||||||
|
|
||||||
//返回结果
|
//返回结果
|
||||||
if (cmd.reply_sem) {
|
if (cmd.reply_sem != RT_NULL) {
|
||||||
rt_sem_release(cmd.reply_sem);
|
rt_sem_release(cmd.reply_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,65 +374,42 @@ static void db_sqlite(void *parameter) {
|
|||||||
*/
|
*/
|
||||||
rt_err_t db_send_command(enum db_cmd_type type, const char* sql, rt_int32_t timeout_ms)
|
rt_err_t db_send_command(enum db_cmd_type type, const char* sql, rt_int32_t timeout_ms)
|
||||||
{
|
{
|
||||||
struct db_command cmd;
|
if (!sql || !db_mq) {
|
||||||
rt_sem_t sem = RT_NULL;
|
return -RT_EINVAL;
|
||||||
rt_err_t result = RT_EOK;
|
}
|
||||||
|
|
||||||
// 1. 创建临时信号量用于同步
|
struct db_command cmd;
|
||||||
sem = rt_sem_create("db_rep", 0, RT_IPC_FLAG_FIFO);
|
rt_sem_t sem = rt_sem_create("db_rep", 0, RT_IPC_FLAG_FIFO);
|
||||||
if (sem == RT_NULL)
|
if (sem == RT_NULL) {
|
||||||
{
|
|
||||||
rt_kprintf("Failed to create reply semaphore!\n");
|
|
||||||
return -RT_ENOMEM;
|
return -RT_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 构造命令
|
// 初始化命令结构体
|
||||||
rt_memset(&cmd, 0, sizeof(cmd));
|
rt_memset(&cmd, 0, sizeof(cmd));
|
||||||
cmd.type = type;
|
cmd.type = type;
|
||||||
rt_strncpy(cmd.sql, sql, MAX_SQL_LEN - 1);
|
rt_strncpy(cmd.sql, sql, MAX_SQL_LEN - 1);
|
||||||
cmd.reply_sem = sem;
|
cmd.reply_sem = sem;
|
||||||
cmd.send_tick = rt_tick_get();
|
cmd.send_tick = rt_tick_get();
|
||||||
|
|
||||||
// 3. 发送命令到消息队列
|
// 发送命令到数据库线程队列
|
||||||
if (rt_mq_send(db_mq, &cmd, sizeof(cmd)) != RT_EOK)
|
if (rt_mq_send(db_mq, &cmd, sizeof(cmd)) != RT_EOK) {
|
||||||
{
|
|
||||||
rt_kprintf("Failed to send command to db_mq!\n");
|
|
||||||
rt_sem_delete(sem);
|
rt_sem_delete(sem);
|
||||||
return -RT_ERROR;
|
return -RT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 等待数据库线程处理完成(超时保护)
|
// 计算等待 tick(兼容 RT_WAITING_FOREVER)
|
||||||
if (timeout_ms > 0)
|
rt_int32_t wait_ticks;
|
||||||
{
|
if (timeout_ms == RT_WAITING_FOREVER) {
|
||||||
rt_int32_t tick = rt_tick_from_millisecond(timeout_ms);
|
wait_ticks = RT_WAITING_FOREVER;
|
||||||
result = rt_sem_take(sem, tick);
|
} else if (timeout_ms <= 0) {
|
||||||
}
|
wait_ticks = 0; // 立即超时
|
||||||
else
|
} else {
|
||||||
{
|
wait_ticks = rt_tick_from_millisecond(timeout_ms);
|
||||||
result = rt_sem_take(sem, RT_WAITING_FOREVER); // 永久等待(慎用)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 检查结果
|
// 等待数据库线程处理完成
|
||||||
if (result == RT_EOK)
|
rt_err_t result = rt_sem_take(sem, wait_ticks);
|
||||||
{
|
//rt_sem_delete(sem);
|
||||||
rt_kprintf("SQL executed: code=%d\n", cmd.result_code);
|
|
||||||
if (type == DB_CMD_SELECT || strlen(cmd.result) > 0)
|
|
||||||
{
|
|
||||||
rt_kprintf("Result: %s\n", cmd.result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (result == -RT_ETIMEOUT)
|
|
||||||
{
|
|
||||||
rt_kprintf("Database response timeout!\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rt_kprintf("Wait failed: %d\n", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. 删除信号量
|
|
||||||
rt_sem_delete(sem);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,14 +417,12 @@ rt_err_t db_send_command(enum db_cmd_type type, const char* sql, rt_int32_t time
|
|||||||
void thread_DB_SQLite(void)
|
void thread_DB_SQLite(void)
|
||||||
{
|
{
|
||||||
rt_thread_t tid;
|
rt_thread_t tid;
|
||||||
tid = rt_thread_create("db_sql", db_sqlite, RT_NULL, 1024 *32, 20, 10);
|
tid = rt_thread_create("db_sql", db_sqlite, RT_NULL, 1024 *48, 20, 10);
|
||||||
|
|
||||||
if (tid != RT_NULL)
|
if (tid != RT_NULL)
|
||||||
{
|
{
|
||||||
rt_thread_startup(tid);
|
rt_thread_startup(tid);
|
||||||
}
|
}else{
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_D("Failed to create SQLite thread!\n");
|
LOG_D("Failed to create SQLite thread!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,9 +6,10 @@
|
|||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2025-10-20 Administrator the first version
|
* 2025-10-20 Administrator the first version
|
||||||
|
* 2025-11-29 Qwen Add auto_delete_sem to fix semaphore UAF
|
||||||
*/
|
*/
|
||||||
#ifndef APPLICATIONS_DB_DB_SQLITE_H_
|
#ifndef APPLICATIONS_DB_DB_SQLITE_H_
|
||||||
#define APPLICATIONS_DB_SQLITE_SYS_H_
|
#define APPLICATIONS_DB_DB_SQLITE_H_ // ← 注意:修正宏名,与文件路径一致(原为 _SYS_H_)
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
||||||
@@ -69,6 +70,7 @@ struct db_command
|
|||||||
char result[MAX_RESULT_LEN]; /**< 结果或错误信息 */
|
char result[MAX_RESULT_LEN]; /**< 结果或错误信息 */
|
||||||
rt_sem_t reply_sem; /**< 回应信号量(由调用方创建,用于同步) */
|
rt_sem_t reply_sem; /**< 回应信号量(由调用方创建,用于同步) */
|
||||||
rt_tick_t send_tick; /**< 发送时刻的系统 tick,用于超时检测 */
|
rt_tick_t send_tick; /**< 发送时刻的系统 tick,用于超时检测 */
|
||||||
|
rt_bool_t auto_delete_sem; /**< 是否由数据库线程自动删除 reply_sem */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ========================
|
/* ========================
|
||||||
|
|||||||
Binary file not shown.
@@ -18,5 +18,10 @@
|
|||||||
"path": "/packages/system/littlefs",
|
"path": "/packages/system/littlefs",
|
||||||
"ver": "v2.11.2",
|
"ver": "v2.11.2",
|
||||||
"name": "LITTLEFS"
|
"name": "LITTLEFS"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/packages/peripherals/rs485",
|
||||||
|
"ver": "v1.06",
|
||||||
|
"name": "RS485"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
Vendored
+504
@@ -0,0 +1,504 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 2.1, February 1999
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
(This is the first released version of the Lesser GPL. It also counts
|
||||||
|
as the successor of the GNU Library Public License, version 2, hence
|
||||||
|
the version number 2.1.)
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Lesser General Public License, applies to some
|
||||||
|
specially designated software packages--typically libraries--of the
|
||||||
|
Free Software Foundation and other authors who decide to use it. You
|
||||||
|
can use it too, but we suggest you first think carefully about whether
|
||||||
|
this license or the ordinary General Public License is the better
|
||||||
|
strategy to use in any particular case, based on the explanations below.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom of use,
|
||||||
|
not price. Our General Public Licenses are designed to make sure that
|
||||||
|
you have the freedom to distribute copies of free software (and charge
|
||||||
|
for this service if you wish); that you receive source code or can get
|
||||||
|
it if you want it; that you can change the software and use pieces of
|
||||||
|
it in new free programs; and that you are informed that you can do
|
||||||
|
these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
distributors to deny you these rights or to ask you to surrender these
|
||||||
|
rights. These restrictions translate to certain responsibilities for
|
||||||
|
you if you distribute copies of the library or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link other code with the library, you must provide
|
||||||
|
complete object files to the recipients, so that they can relink them
|
||||||
|
with the library after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
We protect your rights with a two-step method: (1) we copyright the
|
||||||
|
library, and (2) we offer you this license, which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
To protect each distributor, we want to make it very clear that
|
||||||
|
there is no warranty for the free library. Also, if the library is
|
||||||
|
modified by someone else and passed on, the recipients should know
|
||||||
|
that what they have is not the original version, so that the original
|
||||||
|
author's reputation will not be affected by problems that might be
|
||||||
|
introduced by others.
|
||||||
|
|
||||||
|
Finally, software patents pose a constant threat to the existence of
|
||||||
|
any free program. We wish to make sure that a company cannot
|
||||||
|
effectively restrict the users of a free program by obtaining a
|
||||||
|
restrictive license from a patent holder. Therefore, we insist that
|
||||||
|
any patent license obtained for a version of the library must be
|
||||||
|
consistent with the full freedom of use specified in this license.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the
|
||||||
|
ordinary GNU General Public License. This license, the GNU Lesser
|
||||||
|
General Public License, applies to certain designated libraries, and
|
||||||
|
is quite different from the ordinary General Public License. We use
|
||||||
|
this license for certain libraries in order to permit linking those
|
||||||
|
libraries into non-free programs.
|
||||||
|
|
||||||
|
When a program is linked with a library, whether statically or using
|
||||||
|
a shared library, the combination of the two is legally speaking a
|
||||||
|
combined work, a derivative of the original library. The ordinary
|
||||||
|
General Public License therefore permits such linking only if the
|
||||||
|
entire combination fits its criteria of freedom. The Lesser General
|
||||||
|
Public License permits more lax criteria for linking other code with
|
||||||
|
the library.
|
||||||
|
|
||||||
|
We call this license the "Lesser" General Public License because it
|
||||||
|
does Less to protect the user's freedom than the ordinary General
|
||||||
|
Public License. It also provides other free software developers Less
|
||||||
|
of an advantage over competing non-free programs. These disadvantages
|
||||||
|
are the reason we use the ordinary General Public License for many
|
||||||
|
libraries. However, the Lesser license provides advantages in certain
|
||||||
|
special circumstances.
|
||||||
|
|
||||||
|
For example, on rare occasions, there may be a special need to
|
||||||
|
encourage the widest possible use of a certain library, so that it becomes
|
||||||
|
a de-facto standard. To achieve this, non-free programs must be
|
||||||
|
allowed to use the library. A more frequent case is that a free
|
||||||
|
library does the same job as widely used non-free libraries. In this
|
||||||
|
case, there is little to gain by limiting the free library to free
|
||||||
|
software only, so we use the Lesser General Public License.
|
||||||
|
|
||||||
|
In other cases, permission to use a particular library in non-free
|
||||||
|
programs enables a greater number of people to use a large body of
|
||||||
|
free software. For example, permission to use the GNU C Library in
|
||||||
|
non-free programs enables many more people to use the whole GNU
|
||||||
|
operating system, as well as its variant, the GNU/Linux operating
|
||||||
|
system.
|
||||||
|
|
||||||
|
Although the Lesser General Public License is Less protective of the
|
||||||
|
users' freedom, it does ensure that the user of a program that is
|
||||||
|
linked with the Library has the freedom and the wherewithal to run
|
||||||
|
that program using a modified version of the Library.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, whereas the latter must
|
||||||
|
be combined with the library in order to run.
|
||||||
|
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library or other
|
||||||
|
program which contains a notice placed by the copyright holder or
|
||||||
|
other authorized party saying it may be distributed under the terms of
|
||||||
|
this Lesser General Public License (also called "this License").
|
||||||
|
Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, complete source code means
|
||||||
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete source code as you receive it, in any medium, provided that
|
||||||
|
you conspicuously and appropriately publish on each copy an
|
||||||
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
|
warranty; and distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also combine or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (1) uses at run time a
|
||||||
|
copy of the library already present on the user's computer system,
|
||||||
|
rather than copying library functions into the executable, and (2)
|
||||||
|
will operate properly with a modified version of the library, if
|
||||||
|
the user installs one, as long as the modified version is
|
||||||
|
interface-compatible with the version that the work was made with.
|
||||||
|
|
||||||
|
c) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
d) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
e) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the materials to be distributed need not include anything that is
|
||||||
|
normally distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties with
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Lesser General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
{description}
|
||||||
|
Copyright (C) {year} {fullname}
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
|
USA
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
|
library `Frob' (a library for tweaking knobs) written by James Random
|
||||||
|
Hacker.
|
||||||
|
|
||||||
|
{signature of Ty Coon}, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
from building import *
|
||||||
|
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
path = [cwd+'/inc']
|
||||||
|
src = Glob('src/*.c')
|
||||||
|
|
||||||
|
group = DefineGroup('rs485', src, depend = ['PKG_USING_RS485'], CPPPATH = path)
|
||||||
|
|
||||||
|
Return('group')
|
||||||
Vendored
+135
@@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* rs485.h
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2020-06-08 qiyongzhong first version
|
||||||
|
* 2020-12-17 qiyongzhong add sample
|
||||||
|
* 2020-12-18 qiyongzhong add rs485_send_then_recv
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DRV_RS485_H__
|
||||||
|
#define __DRV_RS485_H__
|
||||||
|
|
||||||
|
#include <rtconfig.h>
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
//#define RS485_USING_TEST //使用测试功能
|
||||||
|
//#define RS485_USING_SAMPLE_SLAVE //使用从机示例
|
||||||
|
//#define RS485_USING_SAMPLE_MASTER //使用主机示例
|
||||||
|
//#define RS485_USING_DMA_RX //使用DMA接收
|
||||||
|
//#define RS485_USING_INT_TX //使用中断发送
|
||||||
|
//#define RS485_USING_DMA_TX //使用DMA发送
|
||||||
|
|
||||||
|
#ifndef RS485_SW_DLY_US
|
||||||
|
#define RS485_SW_DLY_US 0 //发送引脚控制切换延时
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RS485_TX_COMP_TMO_MAX (3 * RT_TICK_PER_SECOND)//最大DMA传输完成超时
|
||||||
|
#define RS485_BYTE_TMO_MIN 2 //最小字节超时
|
||||||
|
#define RS485_BYTE_TMO_MAX 200 //最大字节超时
|
||||||
|
|
||||||
|
typedef struct rs485_inst rs485_inst_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief create rs485 instance dynamically
|
||||||
|
* @param serial - serial device name
|
||||||
|
* @param baudrate - serial baud rate
|
||||||
|
* @param parity - serial parity mode
|
||||||
|
* @param pin - mode contrle pin
|
||||||
|
* @param level - send mode level
|
||||||
|
* @retval instance handle
|
||||||
|
*/
|
||||||
|
rs485_inst_t * rs485_create(const char *serial, int baudrate, int parity, int pin, int level);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief destory rs485 instance created dynamically
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @retval 0 - success, other - error
|
||||||
|
*/
|
||||||
|
int rs485_destory(rs485_inst_t * hinst);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief config rs485 params
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @param baudrate - baudrate of communication
|
||||||
|
* @param databits - data bits, 5~8
|
||||||
|
* @param parity - parity bit, 0~2, 0 - none, 1 - odd, 2 - even
|
||||||
|
* @param stopbits - stop bits, 0~1, 0 - 1 stop bit, 1 - 2 stop bits
|
||||||
|
* @retval 0 - success, other - error
|
||||||
|
*/
|
||||||
|
int rs485_config(rs485_inst_t * hinst, int baudrate, int databits, int parity, int stopbits);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief set wait datas timeout for receiving
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @param tmo_ms - receive wait timeout, 0--no wait, <0--wait forever, >0--wait timeout, default = 0
|
||||||
|
* @retval 0 - success, other - error
|
||||||
|
*/
|
||||||
|
int rs485_set_recv_tmo(rs485_inst_t * hinst, int tmo_ms);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief set byte interval timeout for receiving
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @param tmo_ms - byte interval timeout, default is calculated from baudrate
|
||||||
|
* @retval 0 - success, other - error
|
||||||
|
*/
|
||||||
|
int rs485_set_byte_tmo(rs485_inst_t * hinst, int tmo_ms);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief open rs485 connect
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @retval 0 - success, other - error
|
||||||
|
*/
|
||||||
|
int rs485_connect(rs485_inst_t * hinst);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief close rs485 connect
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @retval 0 - success, other - error
|
||||||
|
*/
|
||||||
|
int rs485_disconn(rs485_inst_t * hinst);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief receive datas from rs485
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @param buf - buffer addr
|
||||||
|
* @param size - maximum length of received datas
|
||||||
|
* @retval >=0 - length of received datas, <0 - error
|
||||||
|
*/
|
||||||
|
int rs485_recv(rs485_inst_t * hinst, void *buf, int size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief send datas to rs485
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @param buf - buffer addr
|
||||||
|
* @param size - length of send datas
|
||||||
|
* @retval >=0 - length of sent datas, <0 - error
|
||||||
|
*/
|
||||||
|
int rs485_send(rs485_inst_t * hinst, void *buf, int size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief break rs485 receive wait
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @retval 0 - success, other - error
|
||||||
|
*/
|
||||||
|
int rs485_break_recv(rs485_inst_t * hinst);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief send data to rs485 and then receive response data from rs485
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @param send_buf - send buffer addr
|
||||||
|
* @param send_len - length of send datas
|
||||||
|
* @param recv_buf - recv buffer addr
|
||||||
|
* @param recv_size - maximum length of received datas
|
||||||
|
* @retval >=0 - length of received datas, <0 - error
|
||||||
|
*/
|
||||||
|
int rs485_send_then_recv(rs485_inst_t * hinst, void *send_buf, int send_len, void *recv_buf, int recv_size);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
Vendored
+136
@@ -0,0 +1,136 @@
|
|||||||
|
# RS485驱动包
|
||||||
|
|
||||||
|
## 1.简介
|
||||||
|
|
||||||
|
**rs485** rs485接口通信驱动包。
|
||||||
|
|
||||||
|
### 1.1目录结构
|
||||||
|
|
||||||
|
`rs485` 软件包目录结构如下所示:
|
||||||
|
|
||||||
|
```
|
||||||
|
rs485
|
||||||
|
├───inc // 头文件目录
|
||||||
|
│ └───rs485.h // API 接口头文件
|
||||||
|
├───src // 源码目录
|
||||||
|
│ | rs485.c // 主模块
|
||||||
|
│ | rs485_test.c // 测试模块
|
||||||
|
│ | rs485_sample_slave.c // 从模式示例
|
||||||
|
│ └───rs485_sample_master.c // 主模式示例
|
||||||
|
│ license // 软件包许可证
|
||||||
|
│ readme.md // 软件包使用说明
|
||||||
|
└───SConscript // RT-Thread 默认的构建脚本
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2许可证
|
||||||
|
|
||||||
|
rs485 package 遵循 LGPLv2.1 许可,详见 `LICENSE` 文件。
|
||||||
|
|
||||||
|
### 1.3依赖
|
||||||
|
|
||||||
|
- RT_Thread 4.0
|
||||||
|
- serial
|
||||||
|
- pin
|
||||||
|
|
||||||
|
## 2.使用
|
||||||
|
|
||||||
|
### 2.1接口函数说明
|
||||||
|
|
||||||
|
#### rs485_inst_t * rs485_create(char *serial, int baudrate, int parity, int pin, int level);
|
||||||
|
- 功能 :动态创建rs485实例
|
||||||
|
- 参数 :serial--串口设备名称
|
||||||
|
- 参数 :baudrate--串口波特率
|
||||||
|
- 参数 :parity--串口检验位
|
||||||
|
- 参数 :pin--rs485收发模式控制引脚
|
||||||
|
- 参数 :level--发送模式控制电平
|
||||||
|
- 返回 :成功返回实例指针,失败返回NULL
|
||||||
|
|
||||||
|
#### int rs485_destory(rs485_inst_t * hinst);
|
||||||
|
- 功能 :销毁rs485实例
|
||||||
|
- 参数 :hinst--rs485实例指针
|
||||||
|
- 返回 :0--成功,其它--失败
|
||||||
|
|
||||||
|
#### int rs485_config(rs485_inst_t * hinst, int baudrate, int databits, int parity, int stopbits);
|
||||||
|
- 功能 :配置rs485通信参数
|
||||||
|
- 参数 :hinst--rs485实例指针
|
||||||
|
- 参数 :baudrate--通信波特率
|
||||||
|
- 参数 :databits--数据位数, 5~8
|
||||||
|
- 参数 :parity--检验位, 0~2, 0--无校验, 1--奇校验, 2--偶校验
|
||||||
|
- 参数 :stopbits--停止位, 0~1, 0--1个停止位, 1--2个停止位
|
||||||
|
- 返回 :0--成功,其它--错误
|
||||||
|
|
||||||
|
#### int rs485_set_recv_tmo(rs485_inst_t * hinst, int tmo_ms);
|
||||||
|
- 功能 :设置rs485接收超时时间
|
||||||
|
- 参数 :hinst--rs485实例指针
|
||||||
|
- 参数 :tmo_ms--超时时间,单位ms
|
||||||
|
- 返回 :0--成功,其它--错误
|
||||||
|
|
||||||
|
#### int rs485_set_byte_tmo(rs485_inst_t * hinst, int tmo_ms);
|
||||||
|
- 功能 :设置rs485接收字节间隔超时时间
|
||||||
|
- 参数 :hinst--rs485实例指针
|
||||||
|
- 参数 :tmo_ms--超时时间,单位ms
|
||||||
|
- 返回 :0--成功,其它--错误
|
||||||
|
|
||||||
|
#### int rs485_connect(rs485_inst_t * hinst);
|
||||||
|
- 功能 :打开rs485连接
|
||||||
|
- 参数 :hinst--rs485实例指针
|
||||||
|
- 返回 :0--成功,其它--错误
|
||||||
|
|
||||||
|
#### int rs485_disconn(rs485_inst_t * hinst);
|
||||||
|
- 功能 :关闭rs485连接
|
||||||
|
- 参数 :hinst--rs485实例指针
|
||||||
|
- 返回 :0--成功,其它--错误
|
||||||
|
|
||||||
|
#### int rs485_recv(rs485_inst_t * hinst, void *buf, int size);
|
||||||
|
- 功能 :从rs485接收数据
|
||||||
|
- 参数 :hinst--rs485实例指针
|
||||||
|
- 参数 :buf--接收数据缓冲区指针
|
||||||
|
- 参数 :size--缓冲区尺寸
|
||||||
|
- 返回 :>=0--接收到的数据长度,<0--错误
|
||||||
|
|
||||||
|
#### int rs485_send(rs485_inst_t * hinst, void *buf, int size);
|
||||||
|
- 功能 :向rs485发送数据
|
||||||
|
- 参数 :hinst--rs485实例指针
|
||||||
|
- 参数 :buf--发送数据缓冲区指针
|
||||||
|
- 参数 :size--发送数据长度
|
||||||
|
- 返回 :>=0--发送的数据长度,<0--错误
|
||||||
|
|
||||||
|
#### int rs485_break_recv(rs485_inst_t * hinst);
|
||||||
|
- 功能 :中断rs485接收等待
|
||||||
|
- 参数 :hinst--rs485实例指针
|
||||||
|
- 返回 :0--成功,其它--错误
|
||||||
|
|
||||||
|
#### int rs485_send_then_recv(rs485_inst_t * hinst, void *send_buf, int send_len, void *recv_buf, int recv_size);
|
||||||
|
- 功能 :先向rs485发送命令数据,然后从rs485接收响应数据,在多线程使用同一rs485时,可不受打扰地完成发送命令接收响应功能
|
||||||
|
- 参数 :hinst--rs485实例指针
|
||||||
|
- 参数 :send_buf--发送数据缓冲区指针
|
||||||
|
- 参数 :send_len--发送数据长度
|
||||||
|
- 参数 :recv_buf--接收数据缓冲区指针
|
||||||
|
- 参数 :recv_size--接收缓冲区尺寸
|
||||||
|
- 返回 :>=0--接收到的数据长度,<0--错误
|
||||||
|
|
||||||
|
### 2.2获取组件
|
||||||
|
|
||||||
|
- **方式1:**
|
||||||
|
通过 *Env配置工具* 或 *RT-Thread studio* 开启软件包,根据需要配置各项参数;配置路径为 *RT-Thread online packages -> peripherals packages -> rs485*
|
||||||
|
|
||||||
|
|
||||||
|
### 2.3配置参数说明
|
||||||
|
|
||||||
|
| 参数宏 | 说明 |
|
||||||
|
| ---- | ---- |
|
||||||
|
| RS485_USING_TEST | 使用测试功能
|
||||||
|
| RS485_TEST_SERIAL | 串口设备名称
|
||||||
|
| RS485_TEST_BAUDRATE | 串口波特率
|
||||||
|
| RS485_TEST_PARITY | 串口校验位
|
||||||
|
| RS485_TEST_PIN | 收发模式控制引脚
|
||||||
|
| RS485_TEST_LEVEL | 发送模式控制电平
|
||||||
|
| RS485_TEST_BUF_SIZE | 缓冲区尺寸
|
||||||
|
| RS485_TEST_RECV_TMO | 接收超时时间
|
||||||
|
|
||||||
|
## 3. 联系方式
|
||||||
|
|
||||||
|
* 维护:qiyongzhong
|
||||||
|
* 主页:https://github.com/qiyongzhong0/rt-thread-rs485
|
||||||
|
* 主页:https://gitee.com/qiyongzhong0/rt-thread-rs485
|
||||||
|
* 邮箱:917768104@qq.com
|
||||||
Vendored
+625
@@ -0,0 +1,625 @@
|
|||||||
|
/*
|
||||||
|
* drv_rs485.c
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2020-06-08 qiyongzhong first version
|
||||||
|
* 2020-12-14 qiyongzhong fix bug and release v1.0
|
||||||
|
* 2020-12-17 qiyongzhong fix log tag
|
||||||
|
* 2020-12-18 qiyongzhong add rs485_send_then_recv
|
||||||
|
* 2023-09-19 qiyongzhong add switch delay
|
||||||
|
* 2024-12-05 qiyongzhong add dma-rx, int-tx, dma-tx
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
#include <rthw.h>
|
||||||
|
#include <rs485.h>
|
||||||
|
|
||||||
|
#define DBG_TAG "rs485"
|
||||||
|
#define DBG_LVL DBG_INFO
|
||||||
|
#include <rtdbg.h>
|
||||||
|
|
||||||
|
#define RS485_EVT_RX_IND (1<<0)
|
||||||
|
#define RS485_EVT_RX_BREAK (1<<1)
|
||||||
|
|
||||||
|
struct rs485_inst
|
||||||
|
{
|
||||||
|
rt_device_t serial; //serial device handle
|
||||||
|
rt_mutex_t lock; //mutex handle
|
||||||
|
rt_event_t evt; //event handle
|
||||||
|
rt_uint8_t status; //connect status
|
||||||
|
rt_uint8_t level; //control pin send mode level, 0--low, 1--high
|
||||||
|
rt_int16_t pin; //control pin number used, -1--no using
|
||||||
|
rt_int32_t timeout; //receive block timeout, ms
|
||||||
|
rt_int32_t byte_tmo; //receive byte interval timeout, ms
|
||||||
|
#ifdef RS485_USING_DMA_TX
|
||||||
|
rt_int32_t tx_dly_ms;
|
||||||
|
struct rt_completion tx_comp;//send completion
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef RS485_USING_DMA_TX
|
||||||
|
static rt_err_t rs485_send_comp_hook(rt_device_t dev, void *buffer)
|
||||||
|
{
|
||||||
|
rs485_inst_t *hinst = (rs485_inst_t *)(dev->user_data);
|
||||||
|
rt_completion_done(&(hinst->tx_comp));
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static rt_err_t rs485_recv_ind_hook(rt_device_t dev, rt_size_t size)
|
||||||
|
{
|
||||||
|
rs485_inst_t *hinst = (rs485_inst_t *)(dev->user_data);
|
||||||
|
if (hinst->evt)
|
||||||
|
{
|
||||||
|
rt_event_send(hinst->evt, RS485_EVT_RX_IND);
|
||||||
|
}
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rs485_cal_byte_tmo(int baudrate)
|
||||||
|
{
|
||||||
|
int tmo = (40 * 1000) / baudrate;
|
||||||
|
if (tmo < RS485_BYTE_TMO_MIN)
|
||||||
|
{
|
||||||
|
tmo = RS485_BYTE_TMO_MIN;
|
||||||
|
}
|
||||||
|
else if (tmo > RS485_BYTE_TMO_MAX)
|
||||||
|
{
|
||||||
|
tmo = RS485_BYTE_TMO_MAX;
|
||||||
|
}
|
||||||
|
return (tmo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rs485_mode_set(rs485_inst_t *hinst, int mode) // mode : 0--receive mode, 1--send mode
|
||||||
|
{
|
||||||
|
if (hinst->pin < 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode)
|
||||||
|
{
|
||||||
|
rt_pin_write(hinst->pin, hinst->level);
|
||||||
|
#if (RS485_SW_DLY_US > 0)
|
||||||
|
rt_hw_us_delay(RS485_SW_DLY_US);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef RS485_USING_DMA_TX
|
||||||
|
rt_completion_wait(&(hinst->tx_comp), RS485_TX_COMP_TMO_MAX);
|
||||||
|
rt_thread_mdelay(hinst->tx_dly_ms);//等待末尾数据传输完成
|
||||||
|
#elif (RS485_SW_DLY_US > 0)
|
||||||
|
rt_hw_us_delay(RS485_SW_DLY_US);
|
||||||
|
#endif
|
||||||
|
rt_pin_write(hinst->pin, !hinst->level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rs485_dev_open(rs485_inst_t *hinst)
|
||||||
|
{
|
||||||
|
#ifdef RS485_USING_DMA_RX
|
||||||
|
|
||||||
|
#ifdef RS485_USING_DMA_TX
|
||||||
|
if (rt_device_open(hinst->serial, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX) == RT_EOK)
|
||||||
|
{
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RS485_USING_INT_TX
|
||||||
|
if (rt_device_open(hinst->serial, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_INT_TX) == RT_EOK)
|
||||||
|
{
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (rt_device_open(hinst->serial, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX) == RT_EOK)
|
||||||
|
{
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RS485_USING_DMA_TX
|
||||||
|
if (rt_device_open(hinst->serial, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_TX) == RT_EOK)
|
||||||
|
{
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RS485_USING_INT_TX
|
||||||
|
if (rt_device_open(hinst->serial, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX) == RT_EOK)
|
||||||
|
{
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (rt_device_open(hinst->serial, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX) == RT_EOK)
|
||||||
|
{
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief create rs485 instance dynamically
|
||||||
|
* @param serial - serial device name
|
||||||
|
* @param baudrate - serial baud rate
|
||||||
|
* @param parity - serial parity mode
|
||||||
|
* @param pin - mode contrle pin
|
||||||
|
* @param level - send mode level
|
||||||
|
* @retval instance handle
|
||||||
|
*/
|
||||||
|
rs485_inst_t * rs485_create(const char *name, int baudrate, int parity, int pin, int level)
|
||||||
|
{
|
||||||
|
rs485_inst_t *hinst;
|
||||||
|
rt_device_t dev;
|
||||||
|
|
||||||
|
dev = rt_device_find(name);
|
||||||
|
if (dev == RT_NULL)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 instance initiliaze error, the serial device(%s) no found.", name);
|
||||||
|
return(RT_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev->type != RT_Device_Class_Char)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 instance initiliaze error, the serial device(%s) type is not char.", name);
|
||||||
|
return(RT_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
hinst = rt_malloc(sizeof(struct rs485_inst));
|
||||||
|
if (hinst == RT_NULL)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 create fail. no memory for rs485 create instance.");
|
||||||
|
return(RT_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
hinst->lock = rt_mutex_create(name, RT_IPC_FLAG_FIFO);
|
||||||
|
if (hinst->lock == RT_NULL)
|
||||||
|
{
|
||||||
|
rt_free(hinst);
|
||||||
|
LOG_E("rs485 create fail. no memory for rs485 create mutex.");
|
||||||
|
return(RT_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
hinst->evt = rt_event_create(name, RT_IPC_FLAG_FIFO);
|
||||||
|
if (hinst->evt == RT_NULL)
|
||||||
|
{
|
||||||
|
rt_mutex_delete(hinst->lock);
|
||||||
|
rt_free(hinst);
|
||||||
|
LOG_E("rs485 create fail. no memory for rs485 create event.");
|
||||||
|
return(RT_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RS485_USING_DMA_TX
|
||||||
|
hinst->tx_dly_ms = ((2 * 11 *1000) / baudrate) + 1;
|
||||||
|
rt_completion_init(&(hinst->tx_comp));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hinst->serial = dev;
|
||||||
|
hinst->status = 0;
|
||||||
|
hinst->pin = pin;
|
||||||
|
hinst->level = (level != 0);
|
||||||
|
hinst->timeout = 0;
|
||||||
|
hinst->byte_tmo = rs485_cal_byte_tmo(baudrate);
|
||||||
|
|
||||||
|
rs485_config(hinst, baudrate, 8, parity, 0);
|
||||||
|
|
||||||
|
LOG_D("rs485 create success.");
|
||||||
|
|
||||||
|
return(hinst);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief destory rs485 instance created dynamically
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @retval 0 - success, other - error
|
||||||
|
*/
|
||||||
|
int rs485_destory(rs485_inst_t * hinst)
|
||||||
|
{
|
||||||
|
if (hinst == RT_NULL)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 destory fail. hinst is NULL.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
rs485_disconn(hinst);
|
||||||
|
|
||||||
|
if (hinst->lock)
|
||||||
|
{
|
||||||
|
rt_mutex_delete(hinst->lock);
|
||||||
|
hinst->lock = RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hinst->evt)
|
||||||
|
{
|
||||||
|
rt_event_delete(hinst->evt);
|
||||||
|
hinst->evt = RT_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_free(hinst);
|
||||||
|
|
||||||
|
LOG_D("rs485 destory success.");
|
||||||
|
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief config rs485 params
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @param baudrate - baudrate of communication
|
||||||
|
* @param databits - data bits, 5~8
|
||||||
|
* @param parity - parity bit, 0~2, 0 - none, 1 - odd, 2 - even
|
||||||
|
* @param stopbits - stop bits, 0~1, 0 - 1 stop bit, 1 - 2 stop bits
|
||||||
|
* @retval 0 - success, other - error
|
||||||
|
*/
|
||||||
|
int rs485_config(rs485_inst_t * hinst, int baudrate, int databits, int parity, int stopbits)
|
||||||
|
{
|
||||||
|
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
|
||||||
|
|
||||||
|
if (hinst == RT_NULL)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 config fail. hinst is NULL.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RS485_USING_DMA_TX
|
||||||
|
hinst->tx_dly_ms = ((2 * 11 *1000) / baudrate) + 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hinst->byte_tmo = rs485_cal_byte_tmo(baudrate);
|
||||||
|
|
||||||
|
config.baud_rate = baudrate;
|
||||||
|
config.data_bits = databits;
|
||||||
|
config.parity = parity;
|
||||||
|
config.stop_bits = stopbits;
|
||||||
|
rt_device_control(hinst->serial, RT_DEVICE_CTRL_CONFIG, &config);
|
||||||
|
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief set wait datas timeout for receiving
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @param tmo_ms - receive wait timeout, 0--no wait, <0--wait forever, >0--wait timeout, default = 0
|
||||||
|
* @retval 0 - success, other - error
|
||||||
|
*/
|
||||||
|
int rs485_set_recv_tmo(rs485_inst_t * hinst, int tmo_ms)
|
||||||
|
{
|
||||||
|
if (hinst == RT_NULL)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 set recv timeout fail. hinst is NULL.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
hinst->timeout = tmo_ms;
|
||||||
|
|
||||||
|
LOG_D("rs485 set recv timeout success. the value is %d.", tmo_ms);
|
||||||
|
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief set byte interval timeout for receiving
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @param tmo_ms - byte interval timeout, default is calculated from baudrate
|
||||||
|
* @retval 0 - success, other - error
|
||||||
|
*/
|
||||||
|
int rs485_set_byte_tmo(rs485_inst_t * hinst, int tmo_ms)
|
||||||
|
{
|
||||||
|
if (hinst == RT_NULL)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 set byte timeout fail. hinst is NULL.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tmo_ms < RS485_BYTE_TMO_MIN)
|
||||||
|
{
|
||||||
|
tmo_ms = RS485_BYTE_TMO_MIN;
|
||||||
|
}
|
||||||
|
else if (tmo_ms > RS485_BYTE_TMO_MAX)
|
||||||
|
{
|
||||||
|
tmo_ms = RS485_BYTE_TMO_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
hinst->byte_tmo = tmo_ms;
|
||||||
|
|
||||||
|
LOG_D("rs485 set byte timeout success. the value is %d.", tmo_ms);
|
||||||
|
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief open rs485 connect
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @retval 0 - success, other - error
|
||||||
|
*/
|
||||||
|
int rs485_connect(rs485_inst_t * hinst)
|
||||||
|
{
|
||||||
|
if (hinst == RT_NULL)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 connect fail. hinst is NULL.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hinst->status == 1)//is connected
|
||||||
|
{
|
||||||
|
LOG_D("rs485 is connected.");
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( rs485_dev_open(hinst) != RT_EOK)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 instance connect error. serial open fail.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hinst->pin >= 0)
|
||||||
|
{
|
||||||
|
rt_pin_mode(hinst->pin, PIN_MODE_OUTPUT);
|
||||||
|
rt_pin_write(hinst->pin, ! hinst->level);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
hinst->serial->user_data = hinst;
|
||||||
|
hinst->serial->rx_indicate = rs485_recv_ind_hook;
|
||||||
|
#ifdef RS485_USING_DMA_TX
|
||||||
|
hinst->serial->tx_complete = rs485_send_comp_hook;
|
||||||
|
#endif
|
||||||
|
hinst->status = 1;
|
||||||
|
|
||||||
|
LOG_D("rs485 connect success.");
|
||||||
|
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief close rs485 connect
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @retval 0 - success, other - error
|
||||||
|
*/
|
||||||
|
int rs485_disconn(rs485_inst_t * hinst)
|
||||||
|
{
|
||||||
|
if (hinst == RT_NULL)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 disconnect fail. hinst is NULL.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hinst->status == 0)//is not connected
|
||||||
|
{
|
||||||
|
LOG_D("rs485 is not connected.");
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_mutex_take(hinst->lock, RT_WAITING_FOREVER);
|
||||||
|
|
||||||
|
if (hinst->serial)
|
||||||
|
{
|
||||||
|
hinst->serial->rx_indicate = RT_NULL;
|
||||||
|
#ifdef RS485_USING_DMA_TX
|
||||||
|
hinst->serial->tx_complete = RT_NULL;
|
||||||
|
#endif
|
||||||
|
rt_device_close(hinst->serial);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hinst->pin >= 0)
|
||||||
|
{
|
||||||
|
rt_pin_mode(hinst->pin, PIN_MODE_INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
hinst->status = 0;
|
||||||
|
|
||||||
|
rt_mutex_release(hinst->lock);
|
||||||
|
|
||||||
|
LOG_D("rs485 disconnect success.");
|
||||||
|
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief receive datas from rs485
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @param buf - buffer addr
|
||||||
|
* @param size - maximum length of received datas
|
||||||
|
* @retval >=0 - length of received datas, <0 - error
|
||||||
|
*/
|
||||||
|
int rs485_recv(rs485_inst_t * hinst, void *buf, int size)
|
||||||
|
{
|
||||||
|
int recv_len = 0;
|
||||||
|
rt_uint32_t recved = 0;
|
||||||
|
|
||||||
|
if (hinst == RT_NULL || buf == RT_NULL || size == 0)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 receive fail. param error.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hinst->status == 0)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 receive fail. it is not connected.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rt_mutex_take(hinst->lock, RT_WAITING_FOREVER) != RT_EOK)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 receive fail. it is destoried.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(size)
|
||||||
|
{
|
||||||
|
int len = rt_device_read(hinst->serial, 0, (char *)buf + recv_len, size);
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
recv_len += len;
|
||||||
|
size -= len;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rt_event_control(hinst->evt, RT_IPC_CMD_RESET, RT_NULL);
|
||||||
|
if (recv_len)
|
||||||
|
{
|
||||||
|
if (rt_event_recv(hinst->evt, RS485_EVT_RX_IND,
|
||||||
|
(RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR), hinst->byte_tmo, &recved) != RT_EOK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rt_event_recv(hinst->evt, (RS485_EVT_RX_IND | RS485_EVT_RX_BREAK),
|
||||||
|
(RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR), hinst->timeout, &recved) != RT_EOK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((recved & RS485_EVT_RX_BREAK) != 0)
|
||||||
|
{
|
||||||
|
rt_mutex_release(hinst->lock);
|
||||||
|
rt_thread_delay(2);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_mutex_release(hinst->lock);
|
||||||
|
|
||||||
|
return(recv_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief send datas to rs485
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @param buf - buffer addr
|
||||||
|
* @param size - length of send datas
|
||||||
|
* @retval >=0 - length of sent datas, <0 - error
|
||||||
|
*/
|
||||||
|
int rs485_send(rs485_inst_t * hinst, void *buf, int size)
|
||||||
|
{
|
||||||
|
int send_len = 0;
|
||||||
|
|
||||||
|
if (hinst == RT_NULL || buf == RT_NULL || size == 0)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 send fail. param is error.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hinst->status == 0)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 send fail. it is not connected.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rt_mutex_take(hinst->lock, RT_WAITING_FOREVER) != RT_EOK)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 send fail. it is destoried.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
rs485_mode_set(hinst, 1);//set to send mode
|
||||||
|
|
||||||
|
send_len = rt_device_write(hinst->serial, 0, buf, size);
|
||||||
|
|
||||||
|
rs485_mode_set(hinst, 0);//set to receive mode
|
||||||
|
|
||||||
|
rt_mutex_release(hinst->lock);
|
||||||
|
|
||||||
|
return(send_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief break rs485 receive wait
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @retval 0 - success, other - error
|
||||||
|
*/
|
||||||
|
int rs485_break_recv(rs485_inst_t * hinst)
|
||||||
|
{
|
||||||
|
if ((hinst == RT_NULL) || (hinst->evt == RT_NULL))
|
||||||
|
{
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_event_send(hinst->evt, RS485_EVT_RX_BREAK);
|
||||||
|
|
||||||
|
return (RT_EOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief send data to rs485 and then receive response data from rs485
|
||||||
|
* @param hinst - instance handle
|
||||||
|
* @param send_buf - send buffer addr
|
||||||
|
* @param send_len - length of send datas
|
||||||
|
* @param recv_buf - recv buffer addr
|
||||||
|
* @param recv_size - maximum length of received datas
|
||||||
|
* @retval >=0 - length of received datas, <0 - error
|
||||||
|
*/
|
||||||
|
int rs485_send_then_recv(rs485_inst_t * hinst, void *send_buf, int send_len, void *recv_buf, int recv_size)
|
||||||
|
{
|
||||||
|
int recv_len = 0;
|
||||||
|
rt_uint32_t recved = 0;
|
||||||
|
|
||||||
|
if (hinst == RT_NULL || send_buf == RT_NULL || send_len == 0 || recv_buf == RT_NULL || recv_size == 0)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 send then recv fail. param is error.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hinst->status == 0)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 send_then_recv fail. it is not connected.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rt_mutex_take(hinst->lock, RT_WAITING_FOREVER) != RT_EOK)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 send_then_recv fail. it is destoried.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
rs485_mode_set(hinst, 1);//set to send mode
|
||||||
|
send_len = rt_device_write(hinst->serial, 0, send_buf, send_len);
|
||||||
|
rs485_mode_set(hinst, 0);//set to receive mode
|
||||||
|
if (send_len < 0)
|
||||||
|
{
|
||||||
|
rt_mutex_release(hinst->lock);
|
||||||
|
LOG_E("rs485 send_then_recv fail. send datas error.");
|
||||||
|
return(-RT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(recv_size)
|
||||||
|
{
|
||||||
|
int len = rt_device_read(hinst->serial, 0, (char *)recv_buf + recv_len, recv_size);
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
recv_len += len;
|
||||||
|
recv_size -= len;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rt_event_control(hinst->evt, RT_IPC_CMD_RESET, RT_NULL);
|
||||||
|
if (recv_len)
|
||||||
|
{
|
||||||
|
if (rt_event_recv(hinst->evt, RS485_EVT_RX_IND,
|
||||||
|
(RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR), hinst->byte_tmo, &recved) != RT_EOK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rt_event_recv(hinst->evt, RS485_EVT_RX_IND,
|
||||||
|
(RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR), hinst->timeout, &recved) != RT_EOK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_mutex_release(hinst->lock);
|
||||||
|
|
||||||
|
return(recv_len);
|
||||||
|
}
|
||||||
|
|
||||||
+97
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* rs485_sample_master.c
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2020-12-17 qiyongzhong first version
|
||||||
|
* 2020-12-18 qiyongzhong fix to rs485_send_then_recv
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
#include <rs485.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define DBG_TAG "rs485.sample.master"
|
||||||
|
#define DBG_LVL DBG_LOG
|
||||||
|
#include <rtdbg.h>
|
||||||
|
|
||||||
|
#ifdef RS485_USING_SAMPLE_MASTER
|
||||||
|
|
||||||
|
#ifndef RS485_SAMPLE_MASTER_SERIAL
|
||||||
|
#define RS485_SAMPLE_MASTER_SERIAL "uart2" //serial device name
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RS485_SAMPLE_MASTER_BAUDRATE
|
||||||
|
#define RS485_SAMPLE_MASTER_BAUDRATE 9600
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RS485_SAMPLE_MASTER_PARITY
|
||||||
|
#define RS485_SAMPLE_MASTER_PARITY 0 //0 -- none parity
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RS485_SAMPLE_MASTER_PIN
|
||||||
|
#define RS485_SAMPLE_MASTER_PIN -1 //-1 -- nonuse rs485 mode control
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RS485_SAMPLE_MASTER_LVL
|
||||||
|
#define RS485_SAMPLE_MASTER_LVL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void rs485_sample_master(void *args)
|
||||||
|
{
|
||||||
|
const char read_cmd[] = "read datas test\r\n";
|
||||||
|
static rt_uint8_t buf[256];
|
||||||
|
rs485_inst_t *hinst = rs485_create(RS485_SAMPLE_MASTER_SERIAL, RS485_SAMPLE_MASTER_BAUDRATE,
|
||||||
|
RS485_SAMPLE_MASTER_PARITY, RS485_SAMPLE_MASTER_PIN, RS485_SAMPLE_MASTER_LVL);
|
||||||
|
|
||||||
|
if (hinst == RT_NULL)
|
||||||
|
{
|
||||||
|
LOG_E("create rs485 instance fail.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs485_set_recv_tmo(hinst, 1000);
|
||||||
|
if (rs485_connect(hinst) != RT_EOK)
|
||||||
|
{
|
||||||
|
rs485_destory(hinst);
|
||||||
|
LOG_E("rs485 connect fail.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
int len = strlen(read_cmd);
|
||||||
|
len = rs485_send_then_recv(hinst, (void *)read_cmd, len, buf, sizeof(buf));
|
||||||
|
if (len < 0)
|
||||||
|
{
|
||||||
|
LOG_E("rs485 send datas error.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
{
|
||||||
|
LOG_D("rs485 recv timeout.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[len] = 0;
|
||||||
|
LOG_D("rs485 recv %d datas : %s", len, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
rs485_destory(hinst);
|
||||||
|
LOG_D("rs485 test end.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rs485_sample_master_init(void)
|
||||||
|
{
|
||||||
|
rt_thread_t tid = rt_thread_create("rs485master", rs485_sample_master, RT_NULL, 1024, 8, 20);
|
||||||
|
RT_ASSERT(tid != RT_NULL);
|
||||||
|
rt_thread_startup(tid);
|
||||||
|
LOG_I("rs485 sample master thread startup...");
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
INIT_APP_EXPORT(rs485_sample_master_init);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* rs485_sample_slave.c
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2020-12-17 qiyongzhong first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
#include <rs485.h>
|
||||||
|
|
||||||
|
#define DBG_TAG "rs485.sample.slave"
|
||||||
|
#define DBG_LVL DBG_LOG
|
||||||
|
#include <rtdbg.h>
|
||||||
|
|
||||||
|
#ifdef RS485_USING_SAMPLE_SLAVE
|
||||||
|
|
||||||
|
#ifndef RS485_SAMPLE_SLAVE_SERIAL
|
||||||
|
#define RS485_SAMPLE_SLAVE_SERIAL "uart2"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RS485_SAMPLE_SLAVE_BAUDRATE
|
||||||
|
#define RS485_SAMPLE_SLAVE_BAUDRATE 9600
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RS485_SAMPLE_MASTER_PARITY
|
||||||
|
#define RS485_SAMPLE_MASTER_PARITY 0 //0 -- none parity
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RS485_SAMPLE_SLAVE_PIN
|
||||||
|
#define RS485_SAMPLE_SLAVE_PIN -1 //-1 -- nonuse rs485 mode control
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RS485_SAMPLE_SLAVE_LVL
|
||||||
|
#define RS485_SAMPLE_SLAVE_LVL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void rs485_sample_slave_loopback_test(void *args)
|
||||||
|
{
|
||||||
|
static rt_uint8_t buf[256];
|
||||||
|
rs485_inst_t *hinst = rs485_create(RS485_SAMPLE_SLAVE_SERIAL, RS485_SAMPLE_SLAVE_BAUDRATE,
|
||||||
|
RS485_SAMPLE_MASTER_PARITY, RS485_SAMPLE_SLAVE_PIN, RS485_SAMPLE_SLAVE_LVL);
|
||||||
|
|
||||||
|
if (hinst == RT_NULL)
|
||||||
|
{
|
||||||
|
LOG_E("create rs485 instance fail.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rs485_set_recv_tmo(hinst, RT_WAITING_FOREVER);
|
||||||
|
if (rs485_connect(hinst) != RT_EOK)
|
||||||
|
{
|
||||||
|
rs485_destory(hinst);
|
||||||
|
LOG_E("rs485 connect fail.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
int len = rs485_recv(hinst, buf, sizeof(buf));
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
rs485_send(hinst, buf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rs485_sample_slave_init(void)
|
||||||
|
{
|
||||||
|
rt_thread_t tid = rt_thread_create("rs485slave", rs485_sample_slave_loopback_test, RT_NULL, 1024, 8, 20);
|
||||||
|
RT_ASSERT(tid != RT_NULL);
|
||||||
|
rt_thread_startup(tid);
|
||||||
|
LOG_I("rs485 sample slave thread startup...");
|
||||||
|
return(RT_EOK);
|
||||||
|
}
|
||||||
|
INIT_APP_EXPORT(rs485_sample_slave_init);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
+317
@@ -0,0 +1,317 @@
|
|||||||
|
/*
|
||||||
|
* rs485_test.c
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2020-06-08 qiyongzhong first version
|
||||||
|
* 2020-12-17 qiyongzhong add config function
|
||||||
|
* 2020-12-18 qiyongzhong add send_then_recv
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rtthread.h>
|
||||||
|
#include <rs485.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef RS485_USING_TEST
|
||||||
|
|
||||||
|
#ifndef RS485_TEST_SERIAL
|
||||||
|
#define RS485_TEST_SERIAL "uart1" //default test serial
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RS485_TEST_BAUDRATE
|
||||||
|
#define RS485_TEST_BAUDRATE 9600 //defalut test baudrate
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RS485_TEST_PARITY
|
||||||
|
#define RS485_TEST_PARITY 0 //defalut test parity
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RS485_TEST_PIN
|
||||||
|
#define RS485_TEST_PIN GET_PIN(A, 0) //default test ctrl pin
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RS485_TEST_LEVEL
|
||||||
|
#define RS485_TEST_LEVEL 1 //default test send mode level
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RS485_TEST_BUF_SIZE
|
||||||
|
#define RS485_TEST_BUF_SIZE 1024 //default test buffer size
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RS485_TEST_RECV_TMO
|
||||||
|
#define RS485_TEST_RECV_TMO 30000 //default test recicve timeout
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static rs485_inst_t * test_hinst = RT_NULL;
|
||||||
|
static char test_buf[RS485_TEST_BUF_SIZE];
|
||||||
|
|
||||||
|
static const char *cmd_info[] =
|
||||||
|
{
|
||||||
|
"Usage: \n",
|
||||||
|
"rs485 create [serial] [baudrate] [parity] [pin] [level] - create rs485 instance.\n",
|
||||||
|
"rs485 destory - destory rs485 instance.\n",
|
||||||
|
"rs485 set_recv_tmo [tmo_ms] - set recieve timeout.\n",
|
||||||
|
"rs485 set_byte_tmo [tmo_ms] - set byte timeout.\n",
|
||||||
|
"rs485 connect - open rs485 connect.\n",
|
||||||
|
"rs485 disconn - close rs485 connect.\n",
|
||||||
|
"rs485 recv [size] - receive from rs485.\n",
|
||||||
|
"rs485 send [size] - send to rs485.\n",
|
||||||
|
"rs485 cfg [baudrate] [databits] [parity] [stopbits] - config rs485.\n",
|
||||||
|
"rs485 send_then_recv [send_size] [recv_size] - send to rs485 and then receive from rs485.\n",
|
||||||
|
"\n"
|
||||||
|
};
|
||||||
|
|
||||||
|
static void show_cmd_info(void)
|
||||||
|
{
|
||||||
|
for(int i=0; i<sizeof(cmd_info)/sizeof(char*); i++)
|
||||||
|
{
|
||||||
|
rt_kprintf(cmd_info[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rs485_test(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
show_cmd_info();
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "create") == 0)
|
||||||
|
{
|
||||||
|
char *serial = RS485_TEST_SERIAL;
|
||||||
|
int baudrate = RS485_TEST_BAUDRATE;
|
||||||
|
int parity = RS485_TEST_PARITY;
|
||||||
|
int pin = RS485_TEST_PIN;
|
||||||
|
int level = RS485_TEST_LEVEL;
|
||||||
|
|
||||||
|
if (test_hinst != NULL)
|
||||||
|
{
|
||||||
|
rt_kprintf("the test instance is not NULL, please deinit/destory first.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (argc >= 3)
|
||||||
|
{
|
||||||
|
serial = argv[2];
|
||||||
|
}
|
||||||
|
if ( argc >= 4)
|
||||||
|
{
|
||||||
|
baudrate = atoi(argv[3]);
|
||||||
|
}
|
||||||
|
if (argc >= 5)
|
||||||
|
{
|
||||||
|
parity = atoi(argv[4]);
|
||||||
|
}
|
||||||
|
if (argc >= 6)
|
||||||
|
{
|
||||||
|
pin = atoi(argv[5]);
|
||||||
|
}
|
||||||
|
if (argc >= 7)
|
||||||
|
{
|
||||||
|
level = atoi(argv[6]);
|
||||||
|
}
|
||||||
|
test_hinst = rs485_create(serial, baudrate, parity, pin, level);
|
||||||
|
if (test_hinst != NULL)
|
||||||
|
{
|
||||||
|
rt_kprintf("rs485 instance create success.\n");
|
||||||
|
rt_kprintf("rs485 serial : %s \n", serial);
|
||||||
|
rt_kprintf("rs485 baudrate : %d \n", baudrate);
|
||||||
|
rt_kprintf("rs485 parity : %d \n", parity);
|
||||||
|
rt_kprintf("rs485 control pin : %d \n", pin);
|
||||||
|
rt_kprintf("rs485 send mode level : %d \n", level);
|
||||||
|
|
||||||
|
rs485_set_recv_tmo(test_hinst, RS485_TEST_RECV_TMO);
|
||||||
|
rt_kprintf("rs485 receive timeout : %d \n", RS485_TEST_RECV_TMO);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "destory") == 0)
|
||||||
|
{
|
||||||
|
rs485_destory(test_hinst);
|
||||||
|
test_hinst = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "set_recv_tmo") == 0)
|
||||||
|
{
|
||||||
|
int tmo_ms = RS485_TEST_RECV_TMO;
|
||||||
|
if (argc >= 3)
|
||||||
|
{
|
||||||
|
tmo_ms = atoi(argv[2]);
|
||||||
|
}
|
||||||
|
rs485_set_recv_tmo(test_hinst, tmo_ms);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "set_byte_tmo") == 0)
|
||||||
|
{
|
||||||
|
int tmo_ms = 0;
|
||||||
|
if (argc >= 3)
|
||||||
|
{
|
||||||
|
tmo_ms = atoi(argv[2]);
|
||||||
|
}
|
||||||
|
rs485_set_byte_tmo(test_hinst, tmo_ms);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "connect") == 0)
|
||||||
|
{
|
||||||
|
if (test_hinst == NULL)
|
||||||
|
{
|
||||||
|
rt_kprintf("the test instance is NULL, please create first.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (rs485_connect(test_hinst) == RT_EOK)
|
||||||
|
{
|
||||||
|
rt_kprintf("rs485 instance connect success.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rt_kprintf("rs485 instance connect fail.\n");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "disconn") == 0)
|
||||||
|
{
|
||||||
|
rs485_disconn(test_hinst);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "recv") == 0)
|
||||||
|
{
|
||||||
|
int size = RS485_TEST_BUF_SIZE;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
if (test_hinst == NULL)
|
||||||
|
{
|
||||||
|
rt_kprintf("the test instance is NULL, please create first.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (argc >= 3)
|
||||||
|
{
|
||||||
|
size = atoi(argv[2]);
|
||||||
|
if (size > RS485_TEST_BUF_SIZE)
|
||||||
|
{
|
||||||
|
size = RS485_TEST_BUF_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rt_kprintf("rs485 start receiving, max length : %d .\n", size);
|
||||||
|
len = rs485_recv(test_hinst, test_buf, size);
|
||||||
|
if (len == 0)
|
||||||
|
{
|
||||||
|
rt_kprintf("rs485 receive timeout.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rt_kprintf("rs485 received %d datas (hex) : ", len);
|
||||||
|
for (int i=0; i<len; i++)
|
||||||
|
{
|
||||||
|
rt_kprintf("%02X ", test_buf[i]);
|
||||||
|
}
|
||||||
|
rt_kprintf("\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "send") == 0)
|
||||||
|
{
|
||||||
|
int size = RS485_TEST_BUF_SIZE;
|
||||||
|
|
||||||
|
if (test_hinst == NULL)
|
||||||
|
{
|
||||||
|
rt_kprintf("the test instance is NULL, please create first.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (argc >= 3)
|
||||||
|
{
|
||||||
|
size = atoi(argv[2]);
|
||||||
|
if (size > RS485_TEST_BUF_SIZE)
|
||||||
|
{
|
||||||
|
size = RS485_TEST_BUF_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i=0; i<size; i++)
|
||||||
|
{
|
||||||
|
test_buf[i] = i;
|
||||||
|
}
|
||||||
|
size = rs485_send(test_hinst, test_buf, size);
|
||||||
|
rt_kprintf("rs485 transmit completed. length : %d .\n", size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "cfg") == 0)
|
||||||
|
{
|
||||||
|
int baudrate = RS485_TEST_BAUDRATE;
|
||||||
|
int databits = 8;
|
||||||
|
int parity = RS485_TEST_PARITY;
|
||||||
|
int stopbits = 1;
|
||||||
|
|
||||||
|
if (test_hinst == NULL)
|
||||||
|
{
|
||||||
|
rt_kprintf("the test instance is NULL, please create first.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (argc >= 3)
|
||||||
|
{
|
||||||
|
baudrate = atoi(argv[2]);
|
||||||
|
}
|
||||||
|
if ( argc >= 4)
|
||||||
|
{
|
||||||
|
databits = atoi(argv[3]);
|
||||||
|
}
|
||||||
|
if (argc >= 5)
|
||||||
|
{
|
||||||
|
parity = atoi(argv[4]);
|
||||||
|
}
|
||||||
|
if (argc >= 6)
|
||||||
|
{
|
||||||
|
stopbits = atoi(argv[5]);
|
||||||
|
}
|
||||||
|
rs485_config(test_hinst, baudrate, databits, parity, stopbits);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "send_then_recv") == 0)
|
||||||
|
{
|
||||||
|
int send_size = RS485_TEST_BUF_SIZE;
|
||||||
|
int recv_size = RS485_TEST_BUF_SIZE;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
if (test_hinst == NULL)
|
||||||
|
{
|
||||||
|
rt_kprintf("the test instance is NULL, please create first.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (argc >= 3)
|
||||||
|
{
|
||||||
|
send_size = atoi(argv[2]);
|
||||||
|
}
|
||||||
|
if (argc >= 4)
|
||||||
|
{
|
||||||
|
recv_size = atoi(argv[3]);
|
||||||
|
}
|
||||||
|
for (int i=0; i<send_size; i++)
|
||||||
|
{
|
||||||
|
test_buf[i] = i;
|
||||||
|
}
|
||||||
|
rt_kprintf("rs485 send %d datas, then receive max length : %d .\n", send_size, recv_size);
|
||||||
|
len = rs485_send_then_recv(test_hinst, test_buf, send_size, test_buf, recv_size);
|
||||||
|
if (len == 0)
|
||||||
|
{
|
||||||
|
rt_kprintf("rs485 receive timeout.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rt_kprintf("rs485 received %d datas (hex) : ", len);
|
||||||
|
for (int i=0; i<len; i++)
|
||||||
|
{
|
||||||
|
rt_kprintf("%02X ", test_buf[i]);
|
||||||
|
}
|
||||||
|
rt_kprintf("\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_kprintf("error ! unsupported command .\n");
|
||||||
|
}
|
||||||
|
MSH_CMD_EXPORT_ALIAS(rs485_test, rs485, test rs485 module functions);
|
||||||
|
#endif
|
||||||
@@ -36,6 +36,8 @@
|
|||||||
#define RT_USING_EVENT
|
#define RT_USING_EVENT
|
||||||
#define RT_USING_MAILBOX
|
#define RT_USING_MAILBOX
|
||||||
#define RT_USING_MESSAGEQUEUE
|
#define RT_USING_MESSAGEQUEUE
|
||||||
|
#define RT_USING_MESSAGEQUEUE_PRIORITY
|
||||||
|
#define RT_USING_SIGNALS
|
||||||
/* end of Inter-Thread communication */
|
/* end of Inter-Thread communication */
|
||||||
|
|
||||||
/* Memory Management */
|
/* Memory Management */
|
||||||
@@ -346,6 +348,10 @@
|
|||||||
/* touch drivers */
|
/* touch drivers */
|
||||||
|
|
||||||
/* end of touch drivers */
|
/* end of touch drivers */
|
||||||
|
#define PKG_USING_RS485
|
||||||
|
#define RS485_USING_DEV
|
||||||
|
#define RS485_SW_DLY_US 0
|
||||||
|
#define PKG_USING_RS485_V106
|
||||||
/* end of peripheral libraries and drivers */
|
/* end of peripheral libraries and drivers */
|
||||||
|
|
||||||
/* AI packages */
|
/* AI packages */
|
||||||
|
|||||||
Reference in new issue
Block a user