summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorarmink <[email protected]>2019-12-17 20:11:46 +0800
committerarmink <[email protected]>2019-12-17 20:11:46 +0800
commit4875ee8a3ab95c4fbf1e09941d3f44d99a9a632b (patch)
tree15c596c04a842bac747bbcf05a703b8da76f8eac /components
parentfa46d6ac861f26b472d62abdf1278c445431ce4c (diff)
Sync from master (75a3f3dd3a930eab1dc58fa0258a9d1605a0ac11)
Diffstat (limited to 'components')
-rw-r--r--components/Kconfig16
-rw-r--r--components/cplusplus/Queue.h2
-rw-r--r--components/cplusplus/Thread.cpp21
-rw-r--r--components/cplusplus/Thread.h7
-rw-r--r--components/dfs/filesystems/elmfat/dfs_elm.c39
-rw-r--r--components/dfs/filesystems/elmfat/ff.c2
-rw-r--r--components/dfs/filesystems/nfs/SConscript2
-rw-r--r--components/dfs/filesystems/nfs/dfs_nfs.c13
-rw-r--r--components/dfs/filesystems/nfs/mount_xdr.c2
-rw-r--r--components/dfs/filesystems/nfs/nfs_auth.c172
-rw-r--r--components/dfs/filesystems/nfs/nfs_xdr.c2
-rw-r--r--components/dfs/filesystems/uffs/dfs_uffs.c4
-rw-r--r--components/dfs/include/dfs_file.h4
-rw-r--r--components/dfs/include/dfs_fs.h1
-rw-r--r--components/dfs/include/dfs_posix.h1
-rw-r--r--components/dfs/src/dfs.c8
-rw-r--r--components/dfs/src/dfs_file.c33
-rw-r--r--components/dfs/src/dfs_fs.c39
-rw-r--r--components/dfs/src/dfs_posix.c50
-rw-r--r--components/dfs/src/poll.c5
-rw-r--r--components/dfs/src/select.c3
-rwxr-xr-xcomponents/drivers/Kconfig412
-rw-r--r--components/drivers/audio/audio.c641
-rw-r--r--components/drivers/audio/audio_pipe.c44
-rw-r--r--components/drivers/can/can.c158
-rw-r--r--components/drivers/hwcrypto/SConscript34
-rw-r--r--components/drivers/hwcrypto/hw_bignum.c315
-rw-r--r--components/drivers/hwcrypto/hw_bignum.h186
-rw-r--r--components/drivers/hwcrypto/hw_crc.c117
-rw-r--r--components/drivers/hwcrypto/hw_crc.h148
-rw-r--r--components/drivers/hwcrypto/hw_gcm.c218
-rw-r--r--components/drivers/hwcrypto/hw_gcm.h182
-rw-r--r--components/drivers/hwcrypto/hw_hash.c111
-rw-r--r--components/drivers/hwcrypto/hw_hash.h110
-rw-r--r--components/drivers/hwcrypto/hw_rng.c110
-rw-r--r--components/drivers/hwcrypto/hw_rng.h79
-rw-r--r--components/drivers/hwcrypto/hw_symmetric.c276
-rw-r--r--components/drivers/hwcrypto/hw_symmetric.h189
-rw-r--r--components/drivers/hwcrypto/hwcrypto.c255
-rw-r--r--components/drivers/hwcrypto/hwcrypto.h193
-rw-r--r--components/drivers/i2c/fm24clxx.c160
-rw-r--r--components/drivers/i2c/fm24clxx.h26
-rw-r--r--components/drivers/i2c/i2c-bit-ops.c76
-rw-r--r--components/drivers/i2c/i2c_core.c25
-rw-r--r--components/drivers/i2c/i2c_dev.c16
-rw-r--r--components/drivers/include/drivers/audio.h144
-rw-r--r--components/drivers/include/drivers/can.h6
-rw-r--r--components/drivers/include/drivers/crypto.h23
-rw-r--r--components/drivers/include/drivers/i2c.h11
-rw-r--r--components/drivers/include/drivers/mtd.h105
-rw-r--r--components/drivers/include/drivers/mtd_nand.h88
-rw-r--r--components/drivers/include/drivers/mtdnand.h101
-rw-r--r--components/drivers/include/drivers/mtdnor.h35
-rw-r--r--components/drivers/include/drivers/pm.h24
-rw-r--r--components/drivers/include/drivers/pulse_encoder.h58
-rw-r--r--components/drivers/include/drivers/rt_inputcapture.h60
-rw-r--r--components/drivers/include/ipc/workqueue.h6
-rw-r--r--components/drivers/include/rtdevice.h12
-rw-r--r--components/drivers/misc/SConscript6
-rw-r--r--components/drivers/misc/pulse_encoder.c136
-rw-r--r--components/drivers/misc/rt_drv_pwm.c2
-rw-r--r--components/drivers/misc/rt_inputcapture.c195
-rw-r--r--components/drivers/mtd/SConscript15
-rw-r--r--components/drivers/mtd/mtd.c236
-rw-r--r--components/drivers/mtd/mtd_nand.c370
-rw-r--r--components/drivers/mtd/mtdnand.c645
-rw-r--r--components/drivers/mtd/mtdnor.c74
-rw-r--r--components/drivers/pm/pm.c48
-rw-r--r--components/drivers/sdio/block_dev.c7
-rw-r--r--components/drivers/sdio/mmc.c13
-rw-r--r--components/drivers/sdio/sdio.c10
-rw-r--r--components/drivers/sensors/sensor.c148
-rw-r--r--components/drivers/sensors/sensor.h1
-rw-r--r--components/drivers/sensors/sensor_cmd.c100
-rw-r--r--components/drivers/serial/serial.c35
-rw-r--r--components/drivers/spi/SConscript15
-rw-r--r--components/drivers/spi/device_driver_list.txt10
-rw-r--r--components/drivers/spi/sfud/inc/sfud_cfg.h2
-rw-r--r--components/drivers/spi/sfud/inc/sfud_flash_def.h1
-rw-r--r--components/drivers/spi/spi_flash_at45dbxx.c433
-rw-r--r--components/drivers/spi/spi_flash_at45dbxx.h27
-rw-r--r--components/drivers/spi/spi_flash_gd.c347
-rw-r--r--components/drivers/spi/spi_flash_gd.h18
-rw-r--r--components/drivers/spi/spi_flash_sfud.c7
-rw-r--r--components/drivers/spi/spi_flash_sst25vfxx.c358
-rw-r--r--components/drivers/spi/spi_flash_sst25vfxx.h28
-rw-r--r--components/drivers/spi/spi_flash_w25qxx.c393
-rw-r--r--components/drivers/spi/spi_flash_w25qxx.h20
-rw-r--r--components/drivers/spi/spi_flash_w25qxx_mtd.c336
-rw-r--r--components/drivers/spi/spi_flash_w25qxx_mtd.h20
-rw-r--r--components/drivers/src/pipe.c2
-rw-r--r--components/drivers/src/ringblk_buf.c46
-rw-r--r--components/drivers/src/ringbuffer.c4
-rw-r--r--components/drivers/src/workqueue.c48
-rw-r--r--components/drivers/touch/SConscript11
-rw-r--r--components/drivers/touch/touch.c258
-rw-r--r--components/drivers/touch/touch.h107
-rw-r--r--components/drivers/usb/usbdevice/SConscript6
-rw-r--r--components/drivers/usb/usbdevice/class/audio.h676
-rw-r--r--components/drivers/usb/usbdevice/class/audio_mic.c577
-rw-r--r--components/drivers/usb/usbdevice/class/audio_speaker.c578
-rw-r--r--components/drivers/usb/usbdevice/class/ecm.c50
-rw-r--r--components/drivers/usb/usbdevice/class/hid.c2
-rw-r--r--components/drivers/usb/usbdevice/class/rndis.c236
-rw-r--r--components/drivers/usb/usbdevice/class/rndis.h9
-rw-r--r--components/drivers/usb/usbdevice/core/core.c57
-rw-r--r--components/drivers/wlan/SConscript24
-rw-r--r--components/drivers/wlan/wlan_cfg.c4
-rw-r--r--components/drivers/wlan/wlan_cmd.c37
-rw-r--r--components/drivers/wlan/wlan_dev.c43
-rw-r--r--components/drivers/wlan/wlan_dev.h7
-rw-r--r--components/drivers/wlan/wlan_lwip.c124
-rw-r--r--components/drivers/wlan/wlan_mgnt.c365
-rw-r--r--components/drivers/wlan/wlan_mgnt.h8
-rw-r--r--components/drivers/wlan/wlan_prot.c20
-rw-r--r--components/drivers/wlan/wlan_prot.h2
-rw-r--r--components/drivers/wlan/wlan_workqueue.c4
-rw-r--r--components/finsh/SConscript14
-rw-r--r--components/finsh/cmd.c17
-rw-r--r--components/finsh/finsh_vm.c22
-rw-r--r--components/finsh/msh.c31
-rw-r--r--components/finsh/msh_cmd.c331
-rw-r--r--components/finsh/msh_file.c271
-rw-r--r--components/finsh/shell.c45
-rw-r--r--components/finsh/shell.h6
-rw-r--r--components/finsh/symbol.c11
-rw-r--r--components/libc/Kconfig6
-rw-r--r--components/libc/compilers/armlibc/libc.h10
-rw-r--r--components/libc/compilers/armlibc/sys/time.h54
-rw-r--r--components/libc/compilers/armlibc/sys/types.h6
-rw-r--r--components/libc/compilers/armlibc/time.c82
-rw-r--r--components/libc/compilers/common/SConscript11
-rw-r--r--components/libc/compilers/common/gmtime_r.c88
-rw-r--r--components/libc/compilers/common/sys/time.h (renamed from components/libc/compilers/dlib/sys/time.h)1
-rw-r--r--components/libc/compilers/common/time.c291
-rw-r--r--components/libc/compilers/dlib/libc.h10
-rw-r--r--components/libc/compilers/dlib/sys/errno.h16
-rw-r--r--components/libc/compilers/dlib/sys/signal.h16
-rw-r--r--components/libc/compilers/dlib/sys/types.h6
-rw-r--r--components/libc/compilers/dlib/sys/unistd.h8
-rw-r--r--components/libc/compilers/dlib/time.c86
-rw-r--r--components/libc/compilers/minilibc/math.h3
-rw-r--r--components/libc/compilers/minilibc/sys/types.h10
-rw-r--r--components/libc/compilers/newlib/libc.h12
-rw-r--r--components/libc/compilers/newlib/syscalls.c15
-rw-r--r--components/libc/pthreads/pthread.c33
-rw-r--r--components/net/Kconfig53
-rw-r--r--components/net/at/Kconfig19
-rw-r--r--components/net/at/at_socket/at_socket.c73
-rw-r--r--components/net/at/include/at.h4
-rw-r--r--components/net/at/src/at_cli.c10
-rw-r--r--components/net/at/src/at_server.c99
-rw-r--r--components/net/freemodbus/Changelog.txt329
-rw-r--r--components/net/freemodbus/Kconfig27
-rw-r--r--components/net/freemodbus/SConscript77
-rw-r--r--components/net/freemodbus/bsd.txt25
-rw-r--r--components/net/freemodbus/gpl.txt340
-rw-r--r--components/net/freemodbus/lgpl.txt504
-rw-r--r--components/net/freemodbus/modbus/ascii/mbascii.c485
-rw-r--r--components/net/freemodbus/modbus/ascii/mbascii.h56
-rw-r--r--components/net/freemodbus/modbus/functions/mbfunccoils.c269
-rw-r--r--components/net/freemodbus/modbus/functions/mbfunccoils_m.c390
-rw-r--r--components/net/freemodbus/modbus/functions/mbfuncdiag.c29
-rw-r--r--components/net/freemodbus/modbus/functions/mbfuncdisc.c125
-rw-r--r--components/net/freemodbus/modbus/functions/mbfuncdisc_m.c162
-rw-r--r--components/net/freemodbus/modbus/functions/mbfuncholding.c308
-rw-r--r--components/net/freemodbus/modbus/functions/mbfuncholding_m.c455
-rw-r--r--components/net/freemodbus/modbus/functions/mbfuncinput.c122
-rw-r--r--components/net/freemodbus/modbus/functions/mbfuncinput_m.c148
-rw-r--r--components/net/freemodbus/modbus/functions/mbfuncother.c88
-rw-r--r--components/net/freemodbus/modbus/functions/mbutils.c141
-rw-r--r--components/net/freemodbus/modbus/include/mb.h417
-rw-r--r--components/net/freemodbus/modbus/include/mb_m.h402
-rw-r--r--components/net/freemodbus/modbus/include/mbconfig.h124
-rw-r--r--components/net/freemodbus/modbus/include/mbframe.h87
-rw-r--r--components/net/freemodbus/modbus/include/mbfunc.h80
-rw-r--r--components/net/freemodbus/modbus/include/mbport.h205
-rw-r--r--components/net/freemodbus/modbus/include/mbproto.h83
-rw-r--r--components/net/freemodbus/modbus/include/mbutils.h108
-rw-r--r--components/net/freemodbus/modbus/mb.c412
-rw-r--r--components/net/freemodbus/modbus/mb_m.c406
-rw-r--r--components/net/freemodbus/modbus/rtu/mbcrc.c98
-rw-r--r--components/net/freemodbus/modbus/rtu/mbcrc.h36
-rw-r--r--components/net/freemodbus/modbus/rtu/mbrtu.c354
-rw-r--r--components/net/freemodbus/modbus/rtu/mbrtu.h64
-rw-r--r--components/net/freemodbus/modbus/rtu/mbrtu_m.c443
-rw-r--r--components/net/freemodbus/modbus/tcp/mbtcp.c158
-rw-r--r--components/net/freemodbus/modbus/tcp/mbtcp.h53
-rw-r--r--components/net/freemodbus/port/port.c38
-rw-r--r--components/net/freemodbus/port/port.h61
-rw-r--r--components/net/freemodbus/port/portevent.c68
-rw-r--r--components/net/freemodbus/port/portevent_m.c239
-rw-r--r--components/net/freemodbus/port/portserial.c225
-rw-r--r--components/net/freemodbus/port/portserial_m.c229
-rw-r--r--components/net/freemodbus/port/porttimer.c63
-rw-r--r--components/net/freemodbus/port/porttimer_m.c107
-rw-r--r--components/net/freemodbus/port/user_mb_app.c286
-rw-r--r--components/net/freemodbus/port/user_mb_app.h46
-rw-r--r--components/net/freemodbus/port/user_mb_app_m.c294
-rw-r--r--components/net/lwip-1.4.1/src/arch/sys_arch.c8
-rw-r--r--components/net/lwip-1.4.1/src/core/dns.c7
-rw-r--r--components/net/lwip-1.4.1/src/netif/ethernetif.c39
-rw-r--r--components/net/lwip-2.0.2/src/arch/sys_arch.c4
-rw-r--r--components/net/lwip-2.0.2/src/core/dns.c7
-rw-r--r--components/net/lwip-2.0.2/src/core/netif.c15
-rw-r--r--components/net/lwip-2.0.2/src/include/netif/ethernetif.h1
-rw-r--r--components/net/lwip-2.0.2/src/netif/ethernetif.c79
-rw-r--r--components/net/lwip-2.1.0/src/arch/sys_arch.c4
-rw-r--r--components/net/lwip-2.1.0/src/core/dns.c7
-rw-r--r--components/net/lwip-2.1.0/src/core/netif.c15
-rw-r--r--components/net/lwip-2.1.0/src/include/netif/ethernetif.h1
-rw-r--r--components/net/lwip-2.1.0/src/netif/ethernetif.c76
-rw-r--r--components/net/lwip-2.1.0/src/netif/lowpan6.c2
-rw-r--r--components/net/lwip_dhcpd/SConscript2
-rw-r--r--components/net/lwip_dhcpd/dhcp_server.c10
-rw-r--r--components/net/lwip_dhcpd/dhcp_server.h1
-rw-r--r--components/net/lwip_dhcpd/dhcp_server_raw.c86
-rw-r--r--components/net/netdev/include/netdev.h15
-rw-r--r--components/net/netdev/include/netdev_ipaddr.h253
-rw-r--r--components/net/netdev/src/netdev.c284
-rw-r--r--components/net/netdev/src/netdev_ipaddr.c357
-rw-r--r--components/net/sal_socket/impl/af_inet_lwip.c12
-rw-r--r--components/net/sal_socket/include/sal_socket.h20
-rw-r--r--components/net/sal_socket/socket/net_sockets.c4
-rw-r--r--components/net/sal_socket/src/sal_socket.c200
-rw-r--r--components/utilities/Kconfig8
-rw-r--r--components/utilities/ulog/backend/console_be.c2
-rw-r--r--components/utilities/ulog/ulog.c2
-rw-r--r--components/utilities/utest/utest.c10
-rw-r--r--components/utilities/utest/utest.h8
-rw-r--r--components/utilities/utest/utest_assert.h8
-rw-r--r--components/utilities/ymodem/ry_sy.c237
-rw-r--r--components/utilities/ymodem/ymodem.c401
-rw-r--r--components/utilities/ymodem/ymodem.h46
234 files changed, 10689 insertions, 15119 deletions
diff --git a/components/Kconfig b/components/Kconfig
index 7c6ca0150c..c3d2b53209 100644
--- a/components/Kconfig
+++ b/components/Kconfig
@@ -1,14 +1,13 @@
menu "RT-Thread Components"
config RT_USING_COMPONENTS_INIT
- bool "Use components automatically initialization"
- default y
-
-if RT_USING_COMPONENTS_INIT
- config RT_USING_USER_MAIN
- bool "The main() function as user entry function"
- default y
-
+ bool
+ default n
+
+config RT_USING_USER_MAIN
+ bool
+ default n
+
if RT_USING_USER_MAIN
config RT_MAIN_THREAD_STACK_SIZE
int "Set main thread stack size"
@@ -19,7 +18,6 @@ if RT_USING_COMPONENTS_INIT
default 10 if RT_THREAD_PRIORITY_32
default 85 if RT_THREAD_PRIORITY_256
endif
-endif
source "$RTT_DIR/components/cplusplus/Kconfig"
diff --git a/components/cplusplus/Queue.h b/components/cplusplus/Queue.h
index 351e3ec66b..23a4638798 100644
--- a/components/cplusplus/Queue.h
+++ b/components/cplusplus/Queue.h
@@ -68,7 +68,7 @@ public:
private:
struct rt_messagequeue mID;
- char mPool[(sizeof(struct rt_messagequeue) + sizeof(T)) * queue_sz];
+ char mPool[(sizeof(void *) + RT_ALIGN(sizeof(T), RT_ALIGN_SIZE)) * queue_sz];
};
}
diff --git a/components/cplusplus/Thread.cpp b/components/cplusplus/Thread.cpp
index 0f6315d178..b21fbdce1f 100644
--- a/components/cplusplus/Thread.cpp
+++ b/components/cplusplus/Thread.cpp
@@ -14,7 +14,7 @@ Thread::Thread(rt_uint32_t stack_size,
rt_uint8_t priority,
rt_uint32_t tick,
const char *name)
-: _entry(RT_NULL), _param(RT_NULL), started(false)
+ : _entry(RT_NULL), _param(RT_NULL), started(false)
{
rt_event_init(&_event, name, 0);
@@ -32,7 +32,7 @@ Thread::Thread(void (*entry)(void *p),
rt_uint8_t priority,
rt_uint32_t tick,
const char *name)
-: _entry(RT_NULL), _param(p), started(false)
+ : _entry(entry), _param(p), started(false)
{
rt_event_init(&_event, name, 0);
@@ -46,6 +46,7 @@ Thread::Thread(void (*entry)(void *p),
Thread::~Thread()
{
+ rt_event_detach(&_event);
rt_thread_delete(_thread);
}
@@ -79,23 +80,23 @@ void Thread::func(Thread *pThis)
}
else
{
- pThis->run();
+ pThis->run(pThis->_param);
}
rt_event_send(&pThis->_event, 1);
}
-void Thread::run()
+void Thread::run(void *parameter)
{
/* please overload this method */
}
-void Thread::wait(int32_t millisec)
+rt_err_t Thread::wait(int32_t millisec)
{
- join(millisec);
+ return join(millisec);
}
-void Thread::join(int32_t millisec)
+rt_err_t Thread::join(int32_t millisec)
{
if (started)
{
@@ -106,6 +107,10 @@ void Thread::join(int32_t millisec)
else
tick = rt_tick_from_millisecond(millisec);
- rt_event_recv(&_event, 1, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, tick, RT_NULL);
+ return rt_event_recv(&_event, 1, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, tick, RT_NULL);
+ }
+ else
+ {
+ return -RT_ENOSYS;
}
}
diff --git a/components/cplusplus/Thread.h b/components/cplusplus/Thread.h
index 71ee50e1f9..b578659489 100644
--- a/components/cplusplus/Thread.h
+++ b/components/cplusplus/Thread.h
@@ -45,16 +45,15 @@ public:
static void sleep(int32_t millisec);
- void wait(int32_t millisec);
- void join(int32_t millisec = -1);
+ rt_err_t wait(int32_t millisec);
+ rt_err_t join(int32_t millisec = -1);
protected:
- virtual void run();
+ virtual void run(void *parameter);
private:
static void func(Thread *pThis);
-private:
rt_thread_t _thread;
thread_func_t _entry;
diff --git a/components/dfs/filesystems/elmfat/dfs_elm.c b/components/dfs/filesystems/elmfat/dfs_elm.c
index a45c15aa03..b4c4c627aa 100644
--- a/components/dfs/filesystems/elmfat/dfs_elm.c
+++ b/components/dfs/filesystems/elmfat/dfs_elm.c
@@ -202,7 +202,7 @@ int dfs_elm_mkfs(rt_device_t dev_id)
int index;
char logic_nbr[2] = {'0', ':'};
- work = rt_malloc(_MAX_SS);
+ work = (BYTE *)rt_malloc(_MAX_SS);
if (RT_NULL == work)
{
return -ENOMEM;
@@ -233,7 +233,7 @@ int dfs_elm_mkfs(rt_device_t dev_id)
}
else
{
- fat = rt_malloc(sizeof(FATFS));
+ fat = (FATFS *)rt_malloc(sizeof(FATFS));
if (fat == RT_NULL)
{
rt_free(work); /* release memory */
@@ -340,7 +340,7 @@ int dfs_elm_open(struct dfs_fd *file)
vol = elm_get_vol((FATFS *)fs->data);
if (vol < 0)
return -ENOENT;
- drivers_fn = rt_malloc(256);
+ drivers_fn = (char *)rt_malloc(256);
if (drivers_fn == RT_NULL)
return -ENOMEM;
@@ -478,6 +478,33 @@ int dfs_elm_close(struct dfs_fd *file)
int dfs_elm_ioctl(struct dfs_fd *file, int cmd, void *args)
{
+ switch (cmd)
+ {
+ case RT_FIOFTRUNCATE:
+ {
+ FIL *fd;
+ FSIZE_t fptr, length;
+ FRESULT result = FR_OK;
+ fd = (FIL *)(file->data);
+ RT_ASSERT(fd != RT_NULL);
+
+ /* save file read/write point */
+ fptr = fd->fptr;
+ length = *(off_t*)args;
+ if (length <= fd->obj.objsize)
+ {
+ fd->fptr = length;
+ result = f_truncate(fd);
+ }
+ else
+ {
+ result = f_lseek(fd, length);
+ }
+ /* restore file read/write point */
+ fd->fptr = fptr;
+ return elm_result_to_dfs(result);
+ }
+ }
return -ENOSYS;
}
@@ -648,7 +675,7 @@ int dfs_elm_unlink(struct dfs_filesystem *fs, const char *path)
vol = elm_get_vol((FATFS *)fs->data);
if (vol < 0)
return -ENOENT;
- drivers_fn = rt_malloc(256);
+ drivers_fn = (char *)rt_malloc(256);
if (drivers_fn == RT_NULL)
return -ENOMEM;
@@ -680,7 +707,7 @@ int dfs_elm_rename(struct dfs_filesystem *fs, const char *oldpath, const char *n
if (vol < 0)
return -ENOENT;
- drivers_oldfn = rt_malloc(256);
+ drivers_oldfn = (char *)rt_malloc(256);
if (drivers_oldfn == RT_NULL)
return -ENOMEM;
drivers_newfn = newpath;
@@ -714,7 +741,7 @@ int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
vol = elm_get_vol((FATFS *)fs->data);
if (vol < 0)
return -ENOENT;
- drivers_fn = rt_malloc(256);
+ drivers_fn = (char *)rt_malloc(256);
if (drivers_fn == RT_NULL)
return -ENOMEM;
diff --git a/components/dfs/filesystems/elmfat/ff.c b/components/dfs/filesystems/elmfat/ff.c
index 4a2f0258b6..19df7450e2 100644
--- a/components/dfs/filesystems/elmfat/ff.c
+++ b/components/dfs/filesystems/elmfat/ff.c
@@ -569,7 +569,7 @@ static WCHAR LfnBuf[_MAX_LFN+1]; /* LFN enabled with static working buffer */
#define FREE_NAMBUF() ff_memfree(lfn)
#else
#define DEF_NAMBUF WCHAR *lfn;
-#define INIT_NAMBUF(fs) { lfn = ff_memalloc((_MAX_LFN+1)*2); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; }
+#define INIT_NAMBUF(fs) { lfn = (WCHAR *)ff_memalloc((_MAX_LFN+1)*2); if (!lfn) LEAVE_FF(fs, FR_NOT_ENOUGH_CORE); (fs)->lfnbuf = lfn; }
#define FREE_NAMBUF() ff_memfree(lfn)
#endif
diff --git a/components/dfs/filesystems/nfs/SConscript b/components/dfs/filesystems/nfs/SConscript
index 8f1e6defcd..f830dfc754 100644
--- a/components/dfs/filesystems/nfs/SConscript
+++ b/components/dfs/filesystems/nfs/SConscript
@@ -6,6 +6,8 @@ cwd = GetCurrentDir()
src = Glob('*.c') + Glob('rpc/*.c')
CPPPATH = [cwd]
+SrcRemove(src, ['rpc/auth_none.c'])
+
group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_NFS'], CPPPATH = CPPPATH)
Return('group')
diff --git a/components/dfs/filesystems/nfs/dfs_nfs.c b/components/dfs/filesystems/nfs/dfs_nfs.c
index f365314564..e60f6f98c0 100644
--- a/components/dfs/filesystems/nfs/dfs_nfs.c
+++ b/components/dfs/filesystems/nfs/dfs_nfs.c
@@ -225,7 +225,7 @@ static nfs_fh3 *get_dir_handle(nfs_filesystem *nfs, const char *name)
copy_handle(handle, &nfs->current_handle);
}
- while ((file = strtok_r(NULL, "/", &path)) != NULL && path[0] != 0)
+ while ((file = strtok_r(NULL, "/", &path)) != NULL && path && path[0] != 0)
{
LOOKUP3args args;
LOOKUP3res res;
@@ -747,7 +747,7 @@ int nfs_open(struct dfs_fd *file)
RT_ASSERT(file->data != NULL);
struct dfs_filesystem *dfs_nfs = ((struct dfs_filesystem *)(file->data));
nfs = (struct nfs_filesystem *)(dfs_nfs->data);
-
+ RT_ASSERT(nfs != NULL);
if (file->flags & O_DIRECTORY)
{
@@ -1106,6 +1106,15 @@ int nfs_getdents(struct dfs_fd *file, struct dirent *dirp, uint32_t count)
if (name == NULL)
break;
+ if (rt_strcmp(name, ".") == 0)
+ {
+ continue;
+ }
+ else if (rt_strcmp(name, "..") == 0)
+ {
+ continue;
+ }
+
d->d_type = DT_REG;
d->d_namlen = rt_strlen(name);
diff --git a/components/dfs/filesystems/nfs/mount_xdr.c b/components/dfs/filesystems/nfs/mount_xdr.c
index 8e191d3017..04faa3bb7a 100644
--- a/components/dfs/filesystems/nfs/mount_xdr.c
+++ b/components/dfs/filesystems/nfs/mount_xdr.c
@@ -101,6 +101,8 @@ xdr_mountres3(register XDR *xdrs, mountres3 *objp)
if (!xdr_mountres3_ok(xdrs, &objp->mountres3_u.mountinfo))
return (FALSE);
break;
+ default :
+ return (FALSE);
}
return (TRUE);
}
diff --git a/components/dfs/filesystems/nfs/nfs_auth.c b/components/dfs/filesystems/nfs/nfs_auth.c
new file mode 100644
index 0000000000..c65a1126a6
--- /dev/null
+++ b/components/dfs/filesystems/nfs/nfs_auth.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+
+#define MAX_MARSHEL_SIZE 64
+
+struct nfs_credentia
+{
+ rt_uint32_t stamp;
+ char *name;
+ rt_uint32_t uid;
+ rt_uint32_t gid;
+ rt_uint32_t *auxi;
+ rt_uint32_t auxi_count;
+};
+
+static void authnone_verf(AUTH *);
+static bool_t authnone_validate(AUTH *, struct opaque_auth *);
+static bool_t authnone_refresh(AUTH *);
+static void authnone_destroy(AUTH *);
+static bool_t authnone_marshal(AUTH *client, XDR *xdrs);
+
+static struct nfs_credentia _credentia = {
+ .stamp = 0,
+ .name = "rt-thread",
+ .uid = 0,
+ .gid = 0,
+ .auxi = NULL,
+ .auxi_count = 0,
+};
+
+struct opaque_auth _null_auth;
+
+static struct auth_ops ops =
+{
+ authnone_verf,
+ authnone_marshal,
+ authnone_validate,
+ authnone_refresh,
+ authnone_destroy
+};
+
+static struct authnone_private
+{
+ AUTH no_client;
+ char marshalled_client[MAX_MARSHEL_SIZE];
+ unsigned int mcnt;
+} *authnone_private;
+
+AUTH *authnone_create(void)
+{
+ register struct authnone_private *ap = authnone_private;
+ XDR xdr_stream;
+ register XDR *xdrs;
+ extern bool_t xdr_opaque_auth(XDR * xdrs, struct opaque_auth * ap);
+ struct opaque_auth auth;
+ rt_uint32_t *auth_buf, *auth_base;
+ int buf_len = 0, str_len = 0;
+
+ if (_credentia.name)
+ {
+ str_len = strlen(_credentia.name);
+ }
+ if (str_len == 0)
+ {
+ _credentia.name = "unknown";
+ str_len = strlen(_credentia.name);
+ }
+ buf_len = ((str_len) + (sizeof(rt_uint32_t)) - 1) & ~((sizeof(rt_uint32_t)) - 1);
+ buf_len += sizeof(struct nfs_credentia);
+ if (_credentia.auxi && _credentia.auxi_count)
+ {
+ buf_len += sizeof(rt_uint32_t) * _credentia.auxi_count;
+ }
+ auth_buf = auth_base = rt_malloc(buf_len);
+ if (auth_buf == NULL)
+ {
+ return NULL;
+ }
+ memset(auth_buf, 0, buf_len);
+ *auth_buf++ = htonl(rt_tick_get());
+ *auth_buf++ = htonl(str_len);
+ memcpy(auth_buf, _credentia.name, str_len);
+ auth_buf += (str_len + sizeof(rt_uint32_t) - 1) >> 2;
+ *auth_buf++ = htonl(_credentia.uid);
+ *auth_buf++ = htonl(_credentia.gid);
+ if (_credentia.auxi && _credentia.auxi_count)
+ {
+ rt_uint32_t tmp_cnt = 0;
+ *auth_buf++ = htonl(_credentia.auxi_count);
+ while (tmp_cnt < _credentia.auxi_count)
+ {
+ *auth_buf++ = htonl(_credentia.auxi[tmp_cnt]);
+ }
+ }
+ else
+ {
+ *auth_buf++ = htonl(0);
+ }
+
+ if (ap == 0)
+ {
+ ap = (struct authnone_private *) rt_malloc(sizeof(*ap));
+ if (ap == 0)
+ {
+ rt_free(auth_base);
+ return NULL;
+ }
+ memset(ap, 0, sizeof(*ap));
+ authnone_private = ap;
+ }
+
+ if (!ap->mcnt)
+ {
+ memset(&auth, 0, sizeof(auth));
+ auth.oa_flavor = 1;
+ auth.oa_base = (char *)auth_base;
+ auth.oa_length = (auth_buf - auth_base) * sizeof(rt_uint32_t);
+ ap->no_client.ah_cred = auth;
+ ap->no_client.ah_verf = _null_auth;
+ ap->no_client.ah_ops = &ops;
+ xdrs = &xdr_stream;
+ xdrmem_create(xdrs, ap->marshalled_client,
+ (unsigned int) MAX_MARSHEL_SIZE, XDR_ENCODE);
+ (void) xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
+ (void) xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
+ ap->mcnt = XDR_GETPOS(xdrs);
+ XDR_DESTROY(xdrs);
+ }
+ rt_free(auth_base);
+ return (&ap->no_client);
+}
+
+/*ARGSUSED*/
+static bool_t authnone_marshal(AUTH *client, XDR *xdrs)
+{
+ register struct authnone_private *ap = authnone_private;
+
+ if (ap == 0)
+ return (0);
+ return ((*xdrs->x_ops->x_putbytes)(xdrs,
+ ap->marshalled_client, ap->mcnt));
+}
+
+static void authnone_verf(AUTH *x)
+{
+}
+
+static bool_t authnone_validate(AUTH *x, struct opaque_auth *x1)
+{
+
+ return (TRUE);
+}
+
+static bool_t authnone_refresh(AUTH *x)
+{
+
+ return (FALSE);
+}
+
+static void authnone_destroy(AUTH *x)
+{
+}
diff --git a/components/dfs/filesystems/nfs/nfs_xdr.c b/components/dfs/filesystems/nfs/nfs_xdr.c
index 4cd69ba743..33563976c3 100644
--- a/components/dfs/filesystems/nfs/nfs_xdr.c
+++ b/components/dfs/filesystems/nfs/nfs_xdr.c
@@ -496,6 +496,8 @@ xdr_GETATTR3res(register XDR *xdrs, GETATTR3res *objp)
if (!xdr_GETATTR3resok(xdrs, &objp->GETATTR3res_u.resok))
return (FALSE);
break;
+ default :
+ return (FALSE);
}
return (TRUE);
}
diff --git a/components/dfs/filesystems/uffs/dfs_uffs.c b/components/dfs/filesystems/uffs/dfs_uffs.c
index c89102f3e3..fb8caf9dd7 100644
--- a/components/dfs/filesystems/uffs/dfs_uffs.c
+++ b/components/dfs/filesystems/uffs/dfs_uffs.c
@@ -226,7 +226,7 @@ static int dfs_uffs_mkfs(rt_device_t dev_id)
}
/*2. then unmount the partition */
- uffs_Mount(nand_part[index].mount_path);
+ uffs_UnMount(nand_part[index].mount_path);
mtd = nand_part[index].dev;
/*3. erase all blocks on the partition */
@@ -234,11 +234,13 @@ static int dfs_uffs_mkfs(rt_device_t dev_id)
for (; block <= mtd->block_end; block++)
{
rt_mtd_nand_erase_block(mtd, block);
+#if defined(RT_UFFS_USE_CHECK_MARK_FUNCITON)
if (rt_mtd_nand_check_block(mtd, block) != RT_EOK)
{
rt_kprintf("found bad block %d\n", block);
rt_mtd_nand_mark_badblock(mtd, block);
}
+#endif
}
/*4. remount it */
diff --git a/components/dfs/include/dfs_file.h b/components/dfs/include/dfs_file.h
index aaff3f6e9c..2dfacd653e 100644
--- a/components/dfs/include/dfs_file.h
+++ b/components/dfs/include/dfs_file.h
@@ -66,6 +66,10 @@ int dfs_file_lseek(struct dfs_fd *fd, off_t offset);
int dfs_file_stat(const char *path, struct stat *buf);
int dfs_file_rename(const char *oldpath, const char *newpath);
+int dfs_file_ftruncate(struct dfs_fd *fd, off_t length);
+
+/* 0x5254 is just a magic number to make these relatively unique ("RT") */
+#define RT_FIOFTRUNCATE 0x52540000U
#ifdef __cplusplus
}
diff --git a/components/dfs/include/dfs_fs.h b/components/dfs/include/dfs_fs.h
index d3a00fc542..58a9e5cf55 100644
--- a/components/dfs/include/dfs_fs.h
+++ b/components/dfs/include/dfs_fs.h
@@ -90,6 +90,7 @@ int dfs_unmount(const char *specialfile);
int dfs_mkfs(const char *fs_name, const char *device_name);
int dfs_statfs(const char *path, struct statfs *buffer);
+int dfs_mount_device(rt_device_t dev);
#ifdef __cplusplus
}
diff --git a/components/dfs/include/dfs_posix.h b/components/dfs/include/dfs_posix.h
index 9fd76debe2..87d5f0771e 100644
--- a/components/dfs/include/dfs_posix.h
+++ b/components/dfs/include/dfs_posix.h
@@ -58,6 +58,7 @@ int fstat(int fildes, struct stat *buf);
int fsync(int fildes);
int fcntl(int fildes, int cmd, ...);
int ioctl(int fildes, int cmd, ...);
+int ftruncate(int fd, off_t length);
/* directory api*/
int rmdir(const char *path);
diff --git a/components/dfs/src/dfs.c b/components/dfs/src/dfs.c
index 5bddb96930..b20de13988 100644
--- a/components/dfs/src/dfs.c
+++ b/components/dfs/src/dfs.c
@@ -141,7 +141,7 @@ static int fd_alloc(struct dfs_fdtable *fdt, int startfd)
cnt = fdt->maxfd + 4;
cnt = cnt > DFS_FD_MAX ? DFS_FD_MAX : cnt;
- fds = rt_realloc(fdt->fds, cnt * sizeof(struct dfs_fd *));
+ fds = (struct dfs_fd **)rt_realloc(fdt->fds, cnt * sizeof(struct dfs_fd *));
if (fds == NULL) goto __exit; /* return fdt->maxfd */
/* clean the new allocated fds */
@@ -157,7 +157,7 @@ static int fd_alloc(struct dfs_fdtable *fdt, int startfd)
/* allocate 'struct dfs_fd' */
if (idx < (int)fdt->maxfd && fdt->fds[idx] == RT_NULL)
{
- fdt->fds[idx] = rt_calloc(1, sizeof(struct dfs_fd));
+ fdt->fds[idx] = (struct dfs_fd *)rt_calloc(1, sizeof(struct dfs_fd));
if (fdt->fds[idx] == RT_NULL)
idx = fdt->maxfd;
}
@@ -393,7 +393,7 @@ char *dfs_normalize_path(const char *directory, const char *filename)
if (filename[0] != '/') /* it's a absolute path, use it directly */
{
- fullpath = rt_malloc(strlen(directory) + strlen(filename) + 2);
+ fullpath = (char *)rt_malloc(strlen(directory) + strlen(filename) + 2);
if (fullpath == NULL)
return NULL;
@@ -537,7 +537,7 @@ int list_fd(void)
if (fd && fd->fops)
{
- rt_kprintf("%2d ", index);
+ rt_kprintf("%2d ", index + DFS_FD_OFFSET);
if (fd->type == FT_DIRECTORY) rt_kprintf("%-7.7s ", "dir");
else if (fd->type == FT_REGULAR) rt_kprintf("%-7.7s ", "file");
else if (fd->type == FT_SOCKET) rt_kprintf("%-7.7s ", "socket");
diff --git a/components/dfs/src/dfs_file.c b/components/dfs/src/dfs_file.c
index 65fd0c45e8..1063a278ab 100644
--- a/components/dfs/src/dfs_file.c
+++ b/components/dfs/src/dfs_file.c
@@ -482,6 +482,35 @@ __exit:
return result;
}
+/**
+ * this function is will cause the regular file referenced by fd
+ * to be truncated to a size of precisely length bytes.
+ *
+ * @param fd the file descriptor.
+ * @param length the length to be truncated.
+ *
+ * @return the status of truncated.
+ */
+int dfs_file_ftruncate(struct dfs_fd *fd, off_t length)
+{
+ int result;
+
+ /* fd is null or not a regular file system fd, or length is invalid */
+ if (fd == NULL || fd->type != FT_REGULAR || length < 0)
+ return -EINVAL;
+
+ if (fd->fops->ioctl == NULL)
+ return -ENOSYS;
+
+ result = fd->fops->ioctl(fd, RT_FIOFTRUNCATE, (void*)&length);
+
+ /* update current size */
+ if (result == 0)
+ fd->size = length;
+
+ return result;
+}
+
#ifdef RT_USING_FINSH
#include <finsh.h>
@@ -600,7 +629,7 @@ static void copyfile(const char *src, const char *dst)
rt_uint8_t *block_ptr;
rt_int32_t read_bytes;
- block_ptr = rt_malloc(BUF_SZ);
+ block_ptr = (rt_uint8_t *)rt_malloc(BUF_SZ);
if (block_ptr == NULL)
{
rt_kprintf("out of memory\n");
@@ -715,7 +744,7 @@ static void copydir(const char *src, const char *dst)
static const char *_get_path_lastname(const char *path)
{
char *ptr;
- if ((ptr = strrchr(path, '/')) == NULL)
+ if ((ptr = (char *)strrchr(path, '/')) == NULL)
return path;
/* skip the '/' then return */
diff --git a/components/dfs/src/dfs_fs.c b/components/dfs/src/dfs_fs.c
index 04d862e85d..164beed719 100644
--- a/components/dfs/src/dfs_fs.c
+++ b/components/dfs/src/dfs_fs.c
@@ -508,7 +508,7 @@ int dfs_mount_table(void)
mount_table[index].rwflag,
mount_table[index].data) != 0)
{
- rt_kprintf("mount fs[%s] on %s failed.\n", mount_table[index].filesystemtype,
+ LOG_E("mount fs[%s] on %s failed.\n", mount_table[index].filesystemtype,
mount_table[index].path);
return -RT_ERROR;
}
@@ -518,6 +518,43 @@ int dfs_mount_table(void)
return 0;
}
INIT_ENV_EXPORT(dfs_mount_table);
+
+int dfs_mount_device(rt_device_t dev)
+{
+ int index = 0;
+
+ if(dev == RT_NULL) {
+ rt_kprintf("the device is NULL to be mounted.\n");
+ return -RT_ERROR;
+ }
+
+ while (1)
+ {
+ if (mount_table[index].path == NULL) break;
+
+ if(strcmp(mount_table[index].device_name, dev->parent.name) == 0) {
+ if (dfs_mount(mount_table[index].device_name,
+ mount_table[index].path,
+ mount_table[index].filesystemtype,
+ mount_table[index].rwflag,
+ mount_table[index].data) != 0)
+ {
+ LOG_E("mount fs[%s] device[%s] to %s failed.\n", mount_table[index].filesystemtype, dev->parent.name,
+ mount_table[index].path);
+ return -RT_ERROR;
+ } else {
+ LOG_D("mount fs[%s] device[%s] to %s ok.\n", mount_table[index].filesystemtype, dev->parent.name,
+ mount_table[index].path);
+ return RT_EOK;
+ }
+ }
+
+ index ++;
+ }
+
+ rt_kprintf("can't find device:%s to be mounted.\n", dev->parent.name);
+ return -RT_ERROR;
+}
#endif
#ifdef RT_USING_FINSH
diff --git a/components/dfs/src/dfs_posix.c b/components/dfs/src/dfs_posix.c
index 6d643e2d4a..fc603df437 100644
--- a/components/dfs/src/dfs_posix.c
+++ b/components/dfs/src/dfs_posix.c
@@ -265,11 +265,11 @@ RTM_EXPORT(lseek);
*
* note: the old and new file name must be belong to a same file system.
*/
-int rename(const char *old, const char *new)
+int rename(const char *old_file, const char *new_file)
{
int result;
- result = dfs_file_rename(old, new);
+ result = dfs_file_rename(old_file, new_file);
if (result < 0)
{
rt_set_errno(result);
@@ -472,6 +472,52 @@ int ioctl(int fildes, int cmd, ...)
RTM_EXPORT(ioctl);
/**
+ *
+ * this function is a POSIX compliant version, which cause the regular file
+ * referenced by fd to be truncated to a size of precisely length bytes.
+ * @param fd the file descriptor.
+ * @param length the length to be truncated.
+ *
+ * @return Upon successful completion, ftruncate() shall return 0;
+ * otherwise, -1 shall be returned and errno set to indicate the error.
+ */
+int ftruncate(int fd, off_t length)
+{
+ int result;
+ struct dfs_fd *d;
+
+ d = fd_get(fd);
+ if (d == NULL)
+ {
+ rt_set_errno(-EBADF);
+
+ return -1;
+ }
+
+ if (length < 0)
+ {
+ fd_put(d);
+ rt_set_errno(-EINVAL);
+
+ return -1;
+ }
+ result = dfs_file_ftruncate(d, length);
+ if (result < 0)
+ {
+ fd_put(d);
+ rt_set_errno(result);
+
+ return -1;
+ }
+
+ /* release the ref-count of fd */
+ fd_put(d);
+
+ return 0;
+}
+RTM_EXPORT(ftruncate);
+
+/**
* this function is a POSIX compliant version, which will return the
* information about a mounted file system.
*
diff --git a/components/dfs/src/poll.c b/components/dfs/src/poll.c
index aee157eed5..3f304549f7 100644
--- a/components/dfs/src/poll.c
+++ b/components/dfs/src/poll.c
@@ -19,6 +19,8 @@
#include <dfs_posix.h>
#include <dfs_poll.h>
+#ifdef RT_USING_POSIX
+
struct rt_poll_node;
struct rt_poll_table
@@ -54,7 +56,7 @@ static void _poll_add(rt_wqueue_t *wq, rt_pollreq_t *req)
struct rt_poll_table *pt;
struct rt_poll_node *node;
- node = rt_malloc(sizeof(struct rt_poll_node));
+ node = (struct rt_poll_node *)rt_malloc(sizeof(struct rt_poll_node));
if (node == RT_NULL)
return;
@@ -214,3 +216,4 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout)
return num;
}
+#endif
diff --git a/components/dfs/src/select.c b/components/dfs/src/select.c
index b20f7cf656..181855bc74 100644
--- a/components/dfs/src/select.c
+++ b/components/dfs/src/select.c
@@ -14,6 +14,8 @@
#include <dfs_poll.h>
#include <dfs_select.h>
+#ifdef RT_USING_POSIX
+
static void fdszero(fd_set *set, int nfds)
{
fd_mask *m;
@@ -178,3 +180,4 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struc
return ret;
}
+#endif
diff --git a/components/drivers/Kconfig b/components/drivers/Kconfig
index 792dc1b028..c567233c84 100755
--- a/components/drivers/Kconfig
+++ b/components/drivers/Kconfig
@@ -48,7 +48,7 @@ config RT_USING_CAN
if RT_USING_CAN
config RT_CAN_USING_HDR
bool "Enable CAN hardware filter"
- default y
+ default n
endif
config RT_USING_HWTIMER
@@ -88,11 +88,21 @@ config RT_USING_I2C
default n
if RT_USING_I2C
+ config RT_I2C_DEBUG
+ bool "Use I2C debug mesage"
+ default n
+
config RT_USING_I2C_BITOPS
bool "Use GPIO to simulate I2C"
default y
endif
+if RT_USING_I2C_BITOPS
+ config RT_I2C_BITOPS_DEBUG
+ bool "Use simulate I2C debug mesage"
+ default n
+endif
+
config RT_USING_PIN
bool "Using generic GPIO device drivers"
default y
@@ -119,27 +129,12 @@ config RT_USING_MTD_NAND
default n
endif
-config RT_USING_MTD
- bool "Using Memory Technology Device (MTD)"
- default n
-
- if RT_USING_MTD
- config MTD_USING_NOR
- bool "Using MTD Nor Flash device"
- default n
-
- config MTD_USING_NAND
- bool "Using MTD Nand Flash device"
- default n
- endif
-
config RT_USING_PM
bool "Using Power Management device drivers"
default n
config RT_USING_RTC
bool "Using RTC device drivers"
- select RT_USING_LIBC
default n
if RT_USING_RTC
@@ -212,6 +207,9 @@ config RT_USING_SPI
config RT_USING_SFUD
bool "Using Serial Flash Universal Driver"
default n
+ help
+ An using JEDEC's SFDP standard serial (SPI) flash universal driver library
+
if RT_USING_SFUD
config RT_SFUD_USING_SFDP
bool "Using auto probe flash JEDEC SFDP parameter"
@@ -226,19 +224,18 @@ config RT_USING_SPI
select RT_USING_QSPI
default n
+ config RT_SFUD_SPI_MAX_HZ
+ int "Default spi maximum speed(HZ)"
+ range 0 50000000
+ default 50000000
+ help
+ Read the JEDEC SFDP command must run at 50 MHz or less,and you also can use rt_spi_configure(); to config spi speed.
+
config RT_DEBUG_SFUD
bool "Show more SFUD debug information"
default n
endif
- config RT_USING_W25QXX
- bool "Using W25QXX SPI NorFlash"
- default n
-
- config RT_USING_GD
- bool "Using GD SPI NorFlash"
- default n
-
config RT_USING_ENC28J60
bool "Using ENC28J60 SPI Ethernet network interface"
select RT_USING_LWIP
@@ -257,6 +254,20 @@ config RT_USING_WDT
config RT_USING_AUDIO
bool "Using Audio device drivers"
default n
+
+ if RT_USING_AUDIO
+ config RT_AUDIO_REPLAY_MP_BLOCK_SIZE
+ int "Replay memmory pool block size"
+ default 4096
+
+ config RT_AUDIO_REPLAY_MP_BLOCK_COUNT
+ int "Replay memmory pool block count"
+ default 2
+
+ config RT_AUDIO_RECORD_PIPE_SIZE
+ int "Record pipe size"
+ default 2048
+ endif
config RT_USING_SENSOR
bool "Using Sensor device drivers"
@@ -269,67 +280,309 @@ if RT_USING_SENSOR
default y
endif
-menu "Using WiFi"
- config RT_USING_WIFI
- bool "Using Wi-Fi framework"
+config RT_USING_TOUCH
+ bool "Using Touch device drivers"
+ default n
+
+menuconfig RT_USING_HWCRYPTO
+ bool "Using Hardware Crypto drivers"
default n
+ if RT_USING_HWCRYPTO
+ config RT_HWCRYPTO_DEFAULT_NAME
+ string "Hardware crypto device name"
+ default "hwcryto"
+
+ config RT_HWCRYPTO_IV_MAX_SIZE
+ int "IV max size"
+ default "16"
+
+ config RT_HWCRYPTO_KEYBIT_MAX_SIZE
+ int "Key max bit length"
+ default 256
+
+ config RT_HWCRYPTO_USING_GCM
+ bool "Using Hardware GCM"
+ default n
+
+ config RT_HWCRYPTO_USING_AES
+ bool "Using Hardware AES"
+ default n
+
+ if RT_HWCRYPTO_USING_AES
+ config RT_HWCRYPTO_USING_AES_ECB
+ bool "Using Hardware AES ECB mode"
+ default y
+
+ config RT_HWCRYPTO_USING_AES_CBC
+ bool "Using Hardware AES CBC mode"
+ default n
+
+ config RT_HWCRYPTO_USING_AES_CFB
+ bool "Using Hardware AES CFB mode"
+ default n
+
+ config RT_HWCRYPTO_USING_AES_CTR
+ bool "Using Hardware AES CTR mode"
+ default n
+
+ config RT_HWCRYPTO_USING_AES_OFB
+ bool "Using Hardware AES OFB mode"
+ default n
+ endif
+
+ config RT_HWCRYPTO_USING_DES
+ bool "Using Hardware DES"
+ default n
+
+ if RT_HWCRYPTO_USING_DES
+ config RT_HWCRYPTO_USING_DES_ECB
+ bool "Using Hardware DES ECB mode"
+ default y
+
+ config RT_HWCRYPTO_USING_DES_CBC
+ bool "Using Hardware DES CBC mode"
+ default n
+ endif
+
+ config RT_HWCRYPTO_USING_3DES
+ bool "Using Hardware 3DES"
+ default n
+
+ if RT_HWCRYPTO_USING_3DES
+ config RT_HWCRYPTO_USING_3DES_ECB
+ bool "Using Hardware 3DES ECB mode"
+ default y
+
+ config RT_HWCRYPTO_USING_3DES_CBC
+ bool "Using Hardware 3DES CBC mode"
+ default n
+ endif
+
+ config RT_HWCRYPTO_USING_RC4
+ bool "Using Hardware RC4"
+ default n
+
+ config RT_HWCRYPTO_USING_MD5
+ bool "Using Hardware MD5"
+ default n
+
+ config RT_HWCRYPTO_USING_SHA1
+ bool "Using Hardware SHA1"
+ default n
+
+ config RT_HWCRYPTO_USING_SHA2
+ bool "Using Hardware SHA2"
+ default n
+
+ if RT_HWCRYPTO_USING_SHA2
+ config RT_HWCRYPTO_USING_SHA2_224
+ bool "Using Hardware SHA2_224 mode"
+ default n
+
+ config RT_HWCRYPTO_USING_SHA2_256
+ bool "Using Hardware SHA2_256 mode"
+ default y
+
+ config RT_HWCRYPTO_USING_SHA2_384
+ bool "Using Hardware SHA2_384 mode"
+ default n
+
+ config RT_HWCRYPTO_USING_SHA2_512
+ bool "Using Hardware SHA2_512 mode"
+ default n
+ endif
+
+ config RT_HWCRYPTO_USING_RNG
+ bool "Using Hardware RNG"
+ default n
+
+ config RT_HWCRYPTO_USING_CRC
+ bool "Using Hardware CRC"
+ default n
+
+ if RT_HWCRYPTO_USING_CRC
+ config RT_HWCRYPTO_USING_CRC_07
+ bool "Using Hardware CRC-8 0x07 polynomial"
+ default n
+
+ config RT_HWCRYPTO_USING_CRC_8005
+ bool "Using Hardware CRC-16 0x8005 polynomial"
+ default n
+
+ config RT_HWCRYPTO_USING_CRC_1021
+ bool "Using Hardware CRC-16 0x1021 polynomial"
+ default n
+
+ config RT_HWCRYPTO_USING_CRC_3D65
+ bool "Using Hardware CRC-16 0x3D65 polynomial"
+ default n
+
+ config RT_HWCRYPTO_USING_CRC_04C11DB7
+ bool "Using Hardware CRC-32 0x04C11DB7 polynomial"
+ default n
+ endif
+
+ config RT_HWCRYPTO_USING_BIGNUM
+ bool "Using Hardware bignum"
+ default n
+
+ if RT_HWCRYPTO_USING_BIGNUM
+ config RT_HWCRYPTO_USING_BIGNUM_EXPTMOD
+ bool "Using Hardware bignum expt_mod operation"
+ default y
+
+ config RT_HWCRYPTO_USING_BIGNUM_MULMOD
+ bool "Using Hardware bignum mul_mod operation"
+ default y
+
+ config RT_HWCRYPTO_USING_BIGNUM_MUL
+ bool "Using Hardware bignum mul operation"
+ default n
+
+ config RT_HWCRYPTO_USING_BIGNUM_ADD
+ bool "Using Hardware bignum add operation"
+ default n
+
+ config RT_HWCRYPTO_USING_BIGNUM_SUB
+ bool "Using Hardware bignum sub operation"
+ default n
+ endif
+ endif
+
+config RT_USING_PULSE_ENCODER
+ bool "Using PULSE ENCODER device drivers"
+ default n
+
+config RT_USING_INPUT_CAPTURE
+ bool "Using INPUT CAPTURE device drivers"
+ default n
+
+if RT_USING_INPUT_CAPTURE
+ config RT_INPUT_CAPTURE_RB_SIZE
+ int "Set input capture ringbuffer size"
+ default 100
+endif
+
+menuconfig RT_USING_WIFI
+ bool "Using Wi-Fi framework"
+ default n
+
if RT_USING_WIFI
config RT_WLAN_DEVICE_STA_NAME
- string "The WiFi device name for station"
+ string "The device name for station"
default "wlan0"
config RT_WLAN_DEVICE_AP_NAME
- string "The WiFi device name for ap"
+ string "The device name for ap"
default "wlan1"
- config RT_WLAN_DEFAULT_PROT
- string "Default transport protocol"
- default "lwip"
-
- config RT_WLAN_SCAN_WAIT_MS
- int "Set scan timeout time(ms)"
- default 10000
-
- config RT_WLAN_CONNECT_WAIT_MS
- int "Set connect timeout time(ms)"
- default 10000
-
config RT_WLAN_SSID_MAX_LENGTH
- int "SSID name maximum length"
+ int "SSID maximum length"
default 32
config RT_WLAN_PASSWORD_MAX_LENGTH
- int "Maximum password length"
+ int "Password maximum length"
default 32
- config RT_WLAN_SCAN_SORT
- bool "Automatic sorting of scan results"
+ config RT_WLAN_DEV_EVENT_NUM
+ int "Driver events maxcount"
+ default 2
+
+ config RT_WLAN_MANAGE_ENABLE
+ bool "Connection management Enable"
default y
- config RT_WLAN_CFG_INFO_MAX
- int "Maximum number of WiFi information automatically saved"
- default 3
+ if RT_WLAN_MANAGE_ENABLE
+ config RT_WLAN_SCAN_WAIT_MS
+ int "Set scan timeout time(ms)"
+ default 10000
- config RT_WLAN_WORKQUEUE_THREAD_NAME
- string "WiFi work queue thread name"
- default "wlan_job"
+ config RT_WLAN_CONNECT_WAIT_MS
+ int "Set connect timeout time(ms)"
+ default 10000
- config RT_WLAN_WORKQUEUE_THREAD_SIZE
- int "wifi work queue thread size"
- default 2048
+ config RT_WLAN_SCAN_SORT
+ bool "Automatic sorting of scan results"
+ default y
- config RT_WLAN_WORKQUEUE_THREAD_PRIO
- int "WiFi work queue thread priority"
- default 22
+ config RT_WLAN_MSH_CMD_ENABLE
+ bool "MSH command Enable"
+ default y
- config RT_WLAN_DEV_EVENT_NUM
- int "Maximum number of driver events"
- default 2
+ config RT_WLAN_AUTO_CONNECT_ENABLE
+ bool "Auto connect Enable"
+ select RT_WLAN_CFG_ENABLE
+ select RT_WLAN_WORK_THREAD_ENABLE
+ default y
- config RT_WLAN_PROT_LWIP_PBUF_FORCE
- bool "Forced use of PBUF transmission"
- default n
+ if RT_WLAN_AUTO_CONNECT_ENABLE
+ config AUTO_CONNECTION_PERIOD_MS
+ int "Auto connect period(ms)"
+ default 2000
+ endif
+ endif
+
+ config RT_WLAN_CFG_ENABLE
+ bool "WiFi information automatically saved Enable"
+ default y
+
+ if RT_WLAN_CFG_ENABLE
+ config RT_WLAN_CFG_INFO_MAX
+ int "Maximum number of WiFi information automatically saved"
+ default 3
+ endif
+
+ config RT_WLAN_PROT_ENABLE
+ bool "Transport protocol manage Enable"
+ default y
+
+ if RT_WLAN_PROT_ENABLE
+ config RT_WLAN_PROT_NAME_LEN
+ int "Transport protocol name length"
+ default 8
+
+ config RT_WLAN_PROT_MAX
+ int "Transport protocol maxcount"
+ default 2
+
+ config RT_WLAN_DEFAULT_PROT
+ string "Default transport protocol"
+ default "lwip"
+
+ config RT_WLAN_PROT_LWIP_ENABLE
+ bool "LWIP transport protocol Enable"
+ select RT_USING_LWIP
+ default y
+
+ if RT_WLAN_PROT_LWIP_ENABLE
+ config RT_WLAN_PROT_LWIP_NAME
+ string "LWIP transport protocol name"
+ default "lwip"
+
+ config RT_WLAN_PROT_LWIP_PBUF_FORCE
+ bool "Forced use of PBUF transmission"
+ default n
+ endif
+ endif
+
+ config RT_WLAN_WORK_THREAD_ENABLE
+ bool "WLAN work queue thread Enable"
+ default y
+
+ if RT_WLAN_WORK_THREAD_ENABLE
+ config RT_WLAN_WORKQUEUE_THREAD_NAME
+ string "WLAN work queue thread name"
+ default "wlan"
+
+ config RT_WLAN_WORKQUEUE_THREAD_SIZE
+ int "WLAN work queue thread size"
+ default 2048
+
+ config RT_WLAN_WORKQUEUE_THREAD_PRIO
+ int "WLAN work queue thread priority"
+ default 15
+ endif
menuconfig RT_WLAN_DEBUG
bool "Enable WLAN Debugging Options"
@@ -361,7 +614,6 @@ menu "Using WiFi"
default n
endif
endif
-endmenu
menu "Using USB"
config RT_USING_USB_HOST
@@ -424,6 +676,9 @@ menu "Using USB"
config _RT_USB_DEVICE_WINUSB
bool "Enable to use device as winusb device"
select RT_USB_DEVICE_WINUSB
+ config _RT_USB_DEVICE_AUDIO
+ bool "Enable to use device as audio device"
+ select RT_USB_DEVICE_AUDIO
endchoice
if RT_USB_DEVICE_COMPOSITE
config RT_USB_DEVICE_CDC
@@ -449,6 +704,9 @@ menu "Using USB"
config RT_USB_DEVICE_WINUSB
bool "Enable to use device as winusb device"
default n
+ config RT_USB_DEVICE_AUDIO
+ bool "Enable to use device as audio device"
+ default n
endif
if RT_USB_DEVICE_CDC
config RT_VCOM_TASK_STK_SIZE
@@ -477,6 +735,14 @@ menu "Using USB"
string "msc class disk name"
default "flash0"
endif
+
+ if RT_USB_DEVICE_RNDIS
+ config RNDIS_DELAY_LINK_UP
+ bool "Delay linkup media connection"
+ select RT_USING_TIMER_SOFT
+ default n
+ endif
+
if RT_USB_DEVICE_HID
config RT_USB_DEVICE_HID_KEYBOARD
bool "Use to HID device as Keyboard"
@@ -508,6 +774,24 @@ menu "Using USB"
bool "Use to HID device as media keyboard"
default y
endif
+ if RT_USB_DEVICE_AUDIO
+ config RT_USB_DEVICE_AUDIO_MIC
+ bool "Use usb mic device as audio device"
+ default n
+ if RT_USB_DEVICE_AUDIO_MIC
+ config RT_USBD_MIC_DEVICE_NAME
+ string "audio mic device name"
+ default "mic0"
+ endif
+ config RT_USB_DEVICE_AUDIO_SPEAKER
+ bool "Use usb speaker device as audio device"
+ default n
+ if RT_USB_DEVICE_AUDIO_SPEAKER
+ config RT_USBD_SPEAKER_DEVICE_NAME
+ string "audio speaker device name"
+ default "sound0"
+ endif
+ endif
endif
endmenu
endmenu
diff --git a/components/drivers/audio/audio.c b/components/drivers/audio/audio.c
index 6a5ebc8741..28ddf0fe56 100644
--- a/components/drivers/audio/audio.c
+++ b/components/drivers/audio/audio.c
@@ -5,83 +5,208 @@
*
* Change Logs:
* Date Author Notes
- * 2017-05-09 Urey first version
+ * 2017-05-09 Urey first version
+ * 2019-07-09 Zero-Free improve device ops interface and data flows
*/
#include <stdio.h>
+#include <string.h>
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
-#include <drivers/audio.h>
+#define DBG_TAG "audio"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
-#include "audio_pipe.h"
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-#define AUDIO_DEBUG 0
-#if AUDIO_DEBUG
-#define AUDIO_DBG(...) printf("[AUDIO]:"),printf(__VA_ARGS__)
-#else
-#define AUDIO_DBG(...)
-#endif
-
-static struct rt_audio_pipe audio_pipe;
+enum
+{
+ REPLAY_EVT_NONE = 0x00,
+ REPLAY_EVT_START = 0x01,
+ REPLAY_EVT_STOP = 0x02,
+};
static rt_err_t _audio_send_replay_frame(struct rt_audio_device *audio)
{
rt_err_t result = RT_EOK;
- rt_base_t level;
- struct rt_audio_frame frame;
+ rt_uint8_t *data;
+ rt_size_t dst_size, src_size;
+ rt_uint16_t position, remain_bytes, index = 0;
+ struct rt_audio_buf_info *buf_info;
RT_ASSERT(audio != RT_NULL);
- //check repaly queue is empty
- if (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) != RT_EOK)
+ buf_info = &audio->replay->buf_info;
+ /* save current pos */
+ position = audio->replay->pos;
+ dst_size = buf_info->block_size;
+
+ /* check repaly queue is empty */
+ if (rt_data_queue_peak(&audio->replay->queue, (const void **)&data, &src_size) != RT_EOK)
{
- AUDIO_DBG("TX queue is empty\n");
- result = -RT_EEMPTY;
+ /* ack stop event */
+ if (audio->replay->event & REPLAY_EVT_STOP)
+ rt_completion_done(&audio->replay->cmp);
- level = rt_hw_interrupt_disable();
- audio->replay->activated = RT_FALSE;
- rt_hw_interrupt_enable(level);
+ /* send zero frames */
+ memset(&buf_info->buffer[audio->replay->pos], 0, dst_size);
- goto _exit;
+ audio->replay->pos += dst_size;
+ audio->replay->pos %= buf_info->total_size;
}
-
- if (audio->ops->transmit != RT_NULL)
+ else
{
- AUDIO_DBG("audio transmit...\n");
- if (audio->ops->transmit(audio, frame.data_ptr, RT_NULL, frame.data_size) != frame.data_size)
+ memset(&buf_info->buffer[audio->replay->pos], 0, dst_size);
+
+ /* copy data from memory pool to hardware device fifo */
+ while (index < dst_size)
{
- result = -RT_EBUSY;
+ result = rt_data_queue_peak(&audio->replay->queue, (const void **)&data, &src_size);
+ if (result != RT_EOK)
+ {
+ LOG_D("under run %d, remain %d", audio->replay->pos, remain_bytes);
+ audio->replay->pos -= remain_bytes;
+ audio->replay->pos += dst_size;
+ audio->replay->pos %= buf_info->total_size;
+ audio->replay->read_index = 0;
+ result = -RT_EEMPTY;
+ break;
+ }
+
+ remain_bytes = MIN((dst_size - index), (src_size - audio->replay->read_index));
+ memcpy(&buf_info->buffer[audio->replay->pos],
+ &data[audio->replay->read_index], remain_bytes);
+
+ index += remain_bytes;
+ audio->replay->read_index += remain_bytes;
+ audio->replay->pos += remain_bytes;
+ audio->replay->pos %= buf_info->total_size;
+
+ if (audio->replay->read_index == src_size)
+ {
+ /* free memory */
+ audio->replay->read_index = 0;
+ rt_data_queue_pop(&audio->replay->queue, (const void **)&data, &src_size, RT_WAITING_NO);
+ rt_mp_free(data);
- goto _exit;
+ /* notify transmitted complete. */
+ if (audio->parent.tx_complete != RT_NULL)
+ audio->parent.tx_complete(&audio->parent, (void *)data);
+ }
}
}
- //pop the head frame...
- rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER);
+ if (audio->ops->transmit != RT_NULL)
+ {
+ if (audio->ops->transmit(audio, &buf_info->buffer[position], RT_NULL, dst_size) != dst_size)
+ result = -RT_ERROR;
+ }
- _exit: return result;
+ return result;
}
static rt_err_t _audio_flush_replay_frame(struct rt_audio_device *audio)
{
- struct rt_audio_frame frame;
+ rt_err_t result = RT_EOK;
- if (audio->replay == RT_NULL)
- return -RT_EIO;
- while (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) == RT_EOK)
+ if (audio->replay->write_index)
{
- //pop the head frame...
- rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER);
+ result = rt_data_queue_push(&audio->replay->queue,
+ (const void **)audio->replay->write_data,
+ audio->replay->write_index,
+ RT_WAITING_FOREVER);
- /* notify transmitted complete. */
- if (audio->parent.tx_complete != RT_NULL)
- audio->parent.tx_complete(&audio->parent, (void *) frame.data_ptr);
+ audio->replay->write_index = 0;
}
- return RT_EOK;
+ return result;
+}
+
+static rt_err_t _aduio_replay_start(struct rt_audio_device *audio)
+{
+ rt_err_t result = RT_EOK;
+
+ if (audio->replay->activated != RT_TRUE)
+ {
+ /* start playback hardware device */
+ if (audio->ops->start)
+ result = audio->ops->start(audio, AUDIO_STREAM_REPLAY);
+
+ audio->replay->activated = RT_TRUE;
+ LOG_D("start audio replay device");
+ }
+
+ return result;
+}
+
+static rt_err_t _aduio_replay_stop(struct rt_audio_device *audio)
+{
+ rt_err_t result = RT_EOK;
+
+ if (audio->replay->activated == RT_TRUE)
+ {
+ /* flush replay remian frames */
+ _audio_flush_replay_frame(audio);
+
+ /* notify irq(or thread) to stop the data transmission */
+ audio->replay->event |= REPLAY_EVT_STOP;
+
+ /* waiting for the remaining data transfer to complete */
+ rt_completion_init(&audio->replay->cmp);
+ rt_completion_wait(&audio->replay->cmp, RT_WAITING_FOREVER);
+ audio->replay->event &= ~REPLAY_EVT_STOP;
+
+ /* stop playback hardware device */
+ if (audio->ops->stop)
+ result = audio->ops->stop(audio, AUDIO_STREAM_REPLAY);
+
+ audio->replay->activated = RT_FALSE;
+ LOG_D("stop audio replay device");
+ }
+
+ return result;
+}
+
+static rt_err_t _audio_record_start(struct rt_audio_device *audio)
+{
+ rt_err_t result = RT_EOK;
+
+ if (audio->record->activated != RT_TRUE)
+ {
+ /* open audio record pipe */
+ rt_device_open(RT_DEVICE(&audio->record->pipe), RT_DEVICE_OFLAG_RDONLY);
+
+ /* start record hardware device */
+ if (audio->ops->start)
+ result = audio->ops->start(audio, AUDIO_STREAM_RECORD);
+
+ audio->record->activated = RT_TRUE;
+ LOG_D("start audio record device");
+ }
+
+ return result;
+}
+
+static rt_err_t _audio_record_stop(struct rt_audio_device *audio)
+{
+ rt_err_t result = RT_EOK;
+
+ if (audio->record->activated == RT_TRUE)
+ {
+ /* stop record hardware device */
+ if (audio->ops->stop)
+ result = audio->ops->stop(audio, AUDIO_STREAM_RECORD);
+
+ /* close audio record pipe */
+ rt_device_close(RT_DEVICE(&audio->record->pipe));
+
+ audio->record->activated = RT_FALSE;
+ LOG_D("stop audio record device");
+ }
+
+ return result;
}
static rt_err_t _audio_dev_init(struct rt_device *dev)
@@ -96,9 +221,68 @@ static rt_err_t _audio_dev_init(struct rt_device *dev)
audio->replay = RT_NULL;
audio->record = RT_NULL;
- /* apply configuration */
+ /* initialize replay */
+ if (dev->flag & RT_DEVICE_FLAG_WRONLY)
+ {
+ struct rt_audio_replay *replay = (struct rt_audio_replay *) rt_malloc(sizeof(struct rt_audio_replay));
+
+ if (replay == RT_NULL)
+ return -RT_ENOMEM;
+ memset(replay, 0, sizeof(struct rt_audio_replay));
+
+ /* init memory pool for replay */
+ replay->mp = rt_mp_create("adu_mp", RT_AUDIO_REPLAY_MP_BLOCK_COUNT, RT_AUDIO_REPLAY_MP_BLOCK_SIZE);
+ if (replay->mp == RT_NULL)
+ {
+ rt_free(replay);
+ LOG_E("create memory pool for repaly failed");
+ return -RT_ENOMEM;
+ }
+
+ /* init queue for audio replay */
+ rt_data_queue_init(&replay->queue, CFG_AUDIO_REPLAY_QUEUE_COUNT, 0, RT_NULL);
+
+ /* init mutex lock for audio replay */
+ rt_mutex_init(&replay->lock, "replay", RT_IPC_FLAG_PRIO);
+
+ replay->activated = RT_FALSE;
+ audio->replay = replay;
+ }
+
+ /* initialize record */
+ if (dev->flag & RT_DEVICE_FLAG_RDONLY)
+ {
+ struct rt_audio_record *record = (struct rt_audio_record *) rt_malloc(sizeof(struct rt_audio_record));
+ rt_uint8_t *buffer;
+
+ if (record == RT_NULL)
+ return -RT_ENOMEM;
+ memset(record, 0, sizeof(struct rt_audio_record));
+
+ /* init pipe for record*/
+ buffer = rt_malloc(RT_AUDIO_RECORD_PIPE_SIZE);
+ if (buffer == RT_NULL)
+ {
+ rt_free(record);
+ LOG_E("malloc memory for for record pipe failed");
+ return -RT_ENOMEM;
+ }
+ rt_audio_pipe_init(&record->pipe, "record",
+ (rt_int32_t)(RT_PIPE_FLAG_FORCE_WR | RT_PIPE_FLAG_BLOCK_RD),
+ buffer,
+ RT_AUDIO_RECORD_PIPE_SIZE);
+
+ record->activated = RT_FALSE;
+ audio->record = record;
+ }
+
+ /* initialize hardware configuration */
if (audio->ops->init)
- result = audio->ops->init(audio);
+ audio->ops->init(audio);
+
+ /* get replay buffer information */
+ if (audio->ops->buffer_info)
+ audio->ops->buffer_info(audio, &audio->replay->buf_info);
return result;
}
@@ -122,65 +306,27 @@ static rt_err_t _audio_dev_open(struct rt_device *dev, rt_uint16_t oflag)
/* initialize the Rx/Tx structure according to open flag */
if (oflag & RT_DEVICE_OFLAG_WRONLY)
{
- AUDIO_DBG("open audio device ,oflag = %x\n",oflag);
- if (audio->replay == RT_NULL)
+ if (audio->replay->activated != RT_TRUE)
{
- struct rt_audio_replay *replay = (struct rt_audio_replay *) rt_malloc(sizeof(struct rt_audio_replay));
-
- if (replay == RT_NULL)
- {
- AUDIO_DBG("request memory for replay error\n");
- return -RT_ENOMEM;
- }
-
- //init queue for audio replay
- rt_data_queue_init(&replay->queue, CFG_AUDIO_REPLAY_QUEUE_COUNT, CFG_AUDIO_REPLAY_QUEUE_COUNT / 2, RT_NULL);
-
- replay->activated = RT_FALSE;
- audio->replay = replay;
+ LOG_D("open audio replay device, oflag = %x\n", oflag);
+ audio->replay->write_index = 0;
+ audio->replay->read_index = 0;
+ audio->replay->pos = 0;
+ audio->replay->event = REPLAY_EVT_NONE;
}
-
dev->open_flag |= RT_DEVICE_OFLAG_WRONLY;
}
if (oflag & RT_DEVICE_OFLAG_RDONLY)
{
- if (audio->record == RT_NULL)
+ /* open record pipe */
+ if (audio->record->activated != RT_TRUE)
{
- struct rt_audio_record *record = (struct rt_audio_record *) rt_malloc(sizeof(struct rt_audio_record));
-
- if (record == RT_NULL)
- {
- AUDIO_DBG("request memory for record error\n");
- return -RT_ENOMEM;
- }
-
- //init pipe for record
- {
- rt_uint8_t *buf = rt_malloc(CFG_AUDIO_RECORD_PIPE_SIZE);
-
- if (buf == RT_NULL)
- {
- rt_free(record);
- AUDIO_DBG("request pipe memory error\n");
+ LOG_D("open audio record device ,oflag = %x\n", oflag);
- return -RT_ENOMEM;
- }
-
- rt_audio_pipe_init(&audio_pipe, "recpipe", (rt_int32_t)(RT_PIPE_FLAG_FORCE_WR | RT_PIPE_FLAG_BLOCK_RD), buf,
- CFG_AUDIO_RECORD_PIPE_SIZE);
- }
-
- record->activated = RT_FALSE;
- audio->record = record;
- }
-
- //open record pipe
- if (audio->record != RT_NULL)
- {
- rt_device_open(RT_DEVICE(&audio_pipe), RT_DEVICE_OFLAG_RDONLY);
+ _audio_record_start(audio);
+ audio->record->activated = RT_TRUE;
}
-
dev->open_flag |= RT_DEVICE_OFLAG_RDONLY;
}
@@ -193,39 +339,17 @@ static rt_err_t _audio_dev_close(struct rt_device *dev)
RT_ASSERT(dev != RT_NULL);
audio = (struct rt_audio_device *) dev;
- //shutdown the lower device
- if (audio->ops->shutdown != RT_NULL)
- audio->ops->shutdown(audio);
-
if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
{
- struct rt_audio_frame frame;
- //stop replay stream
- audio->ops->stop(audio, AUDIO_STREAM_REPLAY);
-
- //flush all frame
- while (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) == RT_EOK)
- {
- //pop the head frame...
- rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER);
-
- /* notify transmitted complete. */
- if (audio->parent.tx_complete != RT_NULL)
- audio->parent.tx_complete(&audio->parent, (void *) frame.data_ptr);
- }
-
+ /* stop replay stream */
+ _aduio_replay_stop(audio);
dev->open_flag &= ~RT_DEVICE_OFLAG_WRONLY;
}
if (dev->open_flag & RT_DEVICE_OFLAG_RDONLY)
{
- //stop record stream
- audio->ops->stop(audio, AUDIO_STREAM_RECORD);
-
- //close record pipe
- if (audio->record != RT_NULL)
- rt_device_close(RT_DEVICE(&audio_pipe));
-
+ /* stop record stream */
+ _audio_record_stop(audio);
dev->open_flag &= ~RT_DEVICE_OFLAG_RDONLY;
}
@@ -237,17 +361,19 @@ static rt_size_t _audio_dev_read(struct rt_device *dev, rt_off_t pos, void *buff
struct rt_audio_device *audio;
RT_ASSERT(dev != RT_NULL);
audio = (struct rt_audio_device *) dev;
+
if (!(dev->open_flag & RT_DEVICE_OFLAG_RDONLY) || (audio->record == RT_NULL))
return 0;
- return rt_device_read(RT_DEVICE(&audio_pipe), pos, buffer, size);
+ return rt_device_read(RT_DEVICE(&audio->record->pipe), pos, buffer, size);
}
static rt_size_t _audio_dev_write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
- rt_err_t result = RT_EOK;
- rt_base_t level;
+
struct rt_audio_device *audio;
+ rt_uint8_t *ptr;
+ rt_uint16_t block_size, remain_bytes, index = 0;
RT_ASSERT(dev != RT_NULL);
audio = (struct rt_audio_device *) dev;
@@ -255,34 +381,46 @@ static rt_size_t _audio_dev_write(struct rt_device *dev, rt_off_t pos, const voi
if (!(dev->open_flag & RT_DEVICE_OFLAG_WRONLY) || (audio->replay == RT_NULL))
return 0;
- AUDIO_DBG("audio write : pos = %d,buffer = %x,size = %d\n",pos,(rt_uint32_t)buffer,size);
- //push a new frame to tx queue
+ /* push a new frame to replay data queue */
+ ptr = (rt_uint8_t *)buffer;
+ block_size = RT_AUDIO_REPLAY_MP_BLOCK_SIZE;
+
+ rt_mutex_take(&audio->replay->lock, RT_WAITING_FOREVER);
+ while (index < size)
{
- result = rt_data_queue_push(&audio->replay->queue, buffer, size,
- RT_WAITING_FOREVER);
- if (result != RT_EOK)
+ /* request buffer from replay memory pool */
+ if (audio->replay->write_index % block_size == 0)
{
- AUDIO_DBG("TX frame queue push error\n");
- rt_set_errno(-RT_EFULL);
- return 0;
+ audio->replay->write_data = rt_mp_alloc(audio->replay->mp, RT_WAITING_FOREVER);
+ memset(audio->replay->write_data, 0, block_size);
+ }
+
+ /* copy data to replay memory pool */
+ remain_bytes = MIN((block_size - audio->replay->write_index), (size - index));
+ memcpy(&audio->replay->write_data[audio->replay->write_index], &ptr[index], remain_bytes);
+
+ index += remain_bytes;
+ audio->replay->write_index += remain_bytes;
+ audio->replay->write_index %= block_size;
+
+ if (audio->replay->write_index == 0)
+ {
+ rt_data_queue_push(&audio->replay->queue,
+ audio->replay->write_data,
+ block_size,
+ RT_WAITING_FOREVER);
}
}
+ rt_mutex_release(&audio->replay->lock);
- //check tx state...
- level = rt_hw_interrupt_disable();
+ /* check replay state */
if (audio->replay->activated != RT_TRUE)
{
+ _aduio_replay_start(audio);
audio->replay->activated = RT_TRUE;
- rt_hw_interrupt_enable(level);
-
- _audio_send_replay_frame(audio);
- }
- else
- {
- rt_hw_interrupt_enable(level);
}
- return size;
+ return index;
}
static rt_err_t _audio_dev_control(struct rt_device *dev, int cmd, void *args)
@@ -292,112 +430,70 @@ static rt_err_t _audio_dev_control(struct rt_device *dev, int cmd, void *args)
RT_ASSERT(dev != RT_NULL);
audio = (struct rt_audio_device *) dev;
- //dev stat...
+ /* dev stat...*/
switch (cmd)
{
- case AUDIO_CTL_GETCAPS:
- {
- struct rt_audio_caps *caps = (struct rt_audio_caps *) args;
+ case AUDIO_CTL_GETCAPS:
+ {
+ struct rt_audio_caps *caps = (struct rt_audio_caps *) args;
- AUDIO_DBG("AUDIO_CTL_GETCAPS: main_type = %d,sub_type = %d\n",caps->main_type,caps->sub_type);
- if (audio->ops->getcaps != RT_NULL)
- {
- result = audio->ops->getcaps(audio, caps);
- }
- }
- break;
- case AUDIO_CTL_CONFIGURE:
+ LOG_D("AUDIO_CTL_GETCAPS: main_type = %d,sub_type = %d", caps->main_type, caps->sub_type);
+ if (audio->ops->getcaps != RT_NULL)
{
- struct rt_audio_caps *caps = (struct rt_audio_caps *) args;
-
- AUDIO_DBG("AUDIO_CTL_CONFIGURE: main_type = %d,sub_type = %d\n",caps->main_type,caps->sub_type);
- if (audio->ops->configure != RT_NULL)
- {
- result = audio->ops->configure(audio, caps);
- }
+ result = audio->ops->getcaps(audio, caps);
}
break;
- case AUDIO_CTL_SHUTDOWN:
- {
- AUDIO_DBG("AUDIO_CTL_SHUTDOWN\n");
-
- if (audio->ops->shutdown != RT_NULL)
- result = audio->ops->shutdown(audio);
+ }
- //flush replay frame...
- _audio_flush_replay_frame(audio);
- }
- break;
+ case AUDIO_CTL_CONFIGURE:
+ {
+ struct rt_audio_caps *caps = (struct rt_audio_caps *) args;
- case AUDIO_CTL_START:
+ LOG_D("AUDIO_CTL_CONFIGURE: main_type = %d,sub_type = %d", caps->main_type, caps->sub_type);
+ if (audio->ops->configure != RT_NULL)
{
- int stream = *(int *) args;
-
- AUDIO_DBG("AUDIO_CTL_START: stream = %d\n",stream);
- if (audio->ops->start != RT_NULL)
- result = audio->ops->start(audio, stream);
+ result = audio->ops->configure(audio, caps);
}
+
break;
- case AUDIO_CTL_STOP:
- {
- int stream = *(int *) args;
+ }
- AUDIO_DBG("AUDIO_CTL_STOP: stream = %d\n",stream);
- if (audio->ops->start != RT_NULL)
- result = audio->ops->stop(audio, stream);
+ case AUDIO_CTL_START:
+ {
+ int stream = *(int *) args;
- if (stream == AUDIO_STREAM_REPLAY)
- {
- _audio_flush_replay_frame(audio);
- }
- }
- break;
- case AUDIO_CTL_PAUSE:
+ LOG_D("AUDIO_CTL_START: stream = %d", stream);
+ if (stream == AUDIO_STREAM_REPLAY)
{
- int stream = *(int *) args;
-
- AUDIO_DBG("AUDIO_CTL_PAUSE: stream = %d\n",stream);
- if (audio->ops->start != RT_NULL)
- result = audio->ops->suspend(audio, stream);
+ result = _aduio_replay_start(audio);
}
- break;
- case AUDIO_CTL_RESUME:
+ else
{
- int stream = *(int *) args;
-
- AUDIO_DBG("AUDIO_CTL_RESUME: stream = %d\n",stream);
- if (audio->ops->start != RT_NULL)
- result = audio->ops->resume(audio, stream);
-
- //resume tx frame...
- if (stream == AUDIO_STREAM_REPLAY)
- _audio_send_replay_frame(audio);
+ result = _audio_record_start(audio);
}
+
break;
- case AUDIO_CTL_ALLOCBUFFER:
- {
- struct rt_audio_buf_desc *desc = (struct rt_audio_buf_desc *) args;
+ }
- if (desc)
- {
- desc->data_size = AUDIO_DEVICE_DECODE_MP_BLOCK_SZ * 2;
- desc->data_ptr = rt_mp_alloc(&audio->mp, RT_WAITING_FOREVER);
+ case AUDIO_CTL_STOP:
+ {
+ int stream = *(int *) args;
- result = RT_EOK;
- }
- else result = -RT_EIO;
+ LOG_D("AUDIO_CTL_STOP: stream = %d", stream);
+ if (stream == AUDIO_STREAM_REPLAY)
+ {
+ result = _aduio_replay_stop(audio);
}
- break;
- case AUDIO_CTL_FREEBUFFER:
+ else
{
- rt_uint8_t *data_ptr = (rt_uint8_t *) args;
- if (data_ptr)
- rt_mp_free(data_ptr);
+ result = _audio_record_stop(audio);
}
+
break;
- default:
- result = audio->ops->control(audio, cmd, args);
+ }
+
+ default:
break;
}
@@ -418,7 +514,9 @@ const static struct rt_device_ops audio_ops =
rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data)
{
+ rt_err_t result = RT_EOK;
struct rt_device *device;
+
RT_ASSERT(audio != RT_NULL);
device = &(audio->parent);
@@ -438,15 +536,14 @@ rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_u
#endif
device->user_data = data;
- //init memory pool for replay
- {
- rt_uint8_t *mempool = rt_malloc(AUDIO_DEVICE_DECODE_MP_SZ);
- rt_mp_init(&audio->mp, "adu_mp", mempool, AUDIO_DEVICE_DECODE_MP_SZ,
- AUDIO_DEVICE_DECODE_MP_BLOCK_SZ * 2);
- }
-
/* register a character device */
- return rt_device_register(device, name, flag | RT_DEVICE_FLAG_REMOVABLE);
+ result = rt_device_register(device, name, flag | RT_DEVICE_FLAG_REMOVABLE);
+
+ /* initialize audio device */
+ if (result == RT_EOK)
+ result = rt_device_init(device);
+
+ return result;
}
int rt_audio_samplerate_to_speed(rt_uint32_t bitValue)
@@ -454,43 +551,43 @@ int rt_audio_samplerate_to_speed(rt_uint32_t bitValue)
int speed = 0;
switch (bitValue)
{
- case AUDIO_SAMP_RATE_8K:
- speed = 8000;
+ case AUDIO_SAMP_RATE_8K:
+ speed = 8000;
break;
- case AUDIO_SAMP_RATE_11K:
- speed = 11052;
+ case AUDIO_SAMP_RATE_11K:
+ speed = 11052;
break;
- case AUDIO_SAMP_RATE_16K:
- speed = 16000;
+ case AUDIO_SAMP_RATE_16K:
+ speed = 16000;
break;
- case AUDIO_SAMP_RATE_22K:
- speed = 22050;
+ case AUDIO_SAMP_RATE_22K:
+ speed = 22050;
break;
- case AUDIO_SAMP_RATE_32K:
- speed = 32000;
+ case AUDIO_SAMP_RATE_32K:
+ speed = 32000;
break;
- case AUDIO_SAMP_RATE_44K:
- speed = 44100;
+ case AUDIO_SAMP_RATE_44K:
+ speed = 44100;
break;
- case AUDIO_SAMP_RATE_48K:
- speed = 48000;
+ case AUDIO_SAMP_RATE_48K:
+ speed = 48000;
break;
- case AUDIO_SAMP_RATE_96K:
- speed = 96000;
+ case AUDIO_SAMP_RATE_96K:
+ speed = 96000;
break;
- case AUDIO_SAMP_RATE_128K:
- speed = 128000;
+ case AUDIO_SAMP_RATE_128K:
+ speed = 128000;
break;
- case AUDIO_SAMP_RATE_160K:
- speed = 160000;
+ case AUDIO_SAMP_RATE_160K:
+ speed = 160000;
break;
- case AUDIO_SAMP_RATE_172K:
- speed = 176400;
+ case AUDIO_SAMP_RATE_172K:
+ speed = 176400;
break;
- case AUDIO_SAMP_RATE_192K:
- speed = 192000;
+ case AUDIO_SAMP_RATE_192K:
+ speed = 192000;
break;
- default:
+ default:
break;
}
@@ -498,46 +595,18 @@ int rt_audio_samplerate_to_speed(rt_uint32_t bitValue)
return speed;
}
-rt_uint32_t rt_audio_format_to_bits(rt_uint32_t format)
+void rt_audio_tx_complete(struct rt_audio_device *audio)
{
- switch (format)
- {
- case AUDIO_FMT_PCM_U8:
- case AUDIO_FMT_PCM_S8:
- return 8;
- case AUDIO_FMT_PCM_S16_LE:
- case AUDIO_FMT_PCM_S16_BE:
- case AUDIO_FMT_PCM_U16_LE:
- case AUDIO_FMT_PCM_U16_BE:
- return 16;
- default:
- return 32;
- };
-}
-
-void rt_audio_tx_complete(struct rt_audio_device *audio, rt_uint8_t *pbuf)
-{
- rt_err_t result;
- AUDIO_DBG("audio tx complete ptr=%x...\n",(rt_uint32_t)pbuf);
-
- //try to send all frame
- do
- {
- result = _audio_send_replay_frame(audio);
- } while (result == RT_EOK);
-
- /* notify transmitted complete. */
- if (audio->parent.tx_complete != RT_NULL)
- audio->parent.tx_complete(&audio->parent, (void *) pbuf);
+ /* try to send next frame */
+ _audio_send_replay_frame(audio);
}
void rt_audio_rx_done(struct rt_audio_device *audio, rt_uint8_t *pbuf, rt_size_t len)
{
- //save data to record pipe
- rt_device_write(RT_DEVICE(RT_DEVICE(&audio_pipe)), 0, pbuf, len);
+ /* save data to record pipe */
+ rt_device_write(RT_DEVICE(&audio->record->pipe), 0, pbuf, len);
/* invoke callback */
if (audio->parent.rx_indicate != RT_NULL)
audio->parent.rx_indicate(&audio->parent, len);
}
-
diff --git a/components/drivers/audio/audio_pipe.c b/components/drivers/audio/audio_pipe.c
index 4df9fd8a49..d7c37009b6 100644
--- a/components/drivers/audio/audio_pipe.c
+++ b/components/drivers/audio/audio_pipe.c
@@ -24,8 +24,8 @@ static void _rt_pipe_resume_writer(struct rt_audio_pipe *pipe)
/* get suspended thread */
thread = rt_list_entry(pipe->suspended_write_list.next,
- struct rt_thread,
- tlist);
+ struct rt_thread,
+ tlist);
/* resume the write thread */
rt_thread_resume(thread);
@@ -50,7 +50,7 @@ static rt_size_t rt_pipe_read(rt_device_t dev,
if (!(pipe->flag & RT_PIPE_FLAG_BLOCK_RD))
{
level = rt_hw_interrupt_disable();
- read_nbytes = rt_ringbuffer_get(&(pipe->ringbuffer), buffer, size);
+ read_nbytes = rt_ringbuffer_get(&(pipe->ringbuffer), (rt_uint8_t *)buffer, size);
/* if the ringbuffer is empty, there won't be any writer waiting */
if (read_nbytes)
@@ -66,9 +66,10 @@ static rt_size_t rt_pipe_read(rt_device_t dev,
/* current context checking */
RT_DEBUG_NOT_IN_INTERRUPT;
- do {
+ do
+ {
level = rt_hw_interrupt_disable();
- read_nbytes = rt_ringbuffer_get(&(pipe->ringbuffer), buffer, size);
+ read_nbytes = rt_ringbuffer_get(&(pipe->ringbuffer), (rt_uint8_t *)buffer, size);
if (read_nbytes == 0)
{
rt_thread_suspend(thread);
@@ -85,7 +86,8 @@ static rt_size_t rt_pipe_read(rt_device_t dev,
rt_hw_interrupt_enable(level);
break;
}
- } while (read_nbytes == 0);
+ }
+ while (read_nbytes == 0);
return read_nbytes;
}
@@ -104,8 +106,8 @@ static void _rt_pipe_resume_reader(struct rt_audio_pipe *pipe)
/* get suspended thread */
thread = rt_list_entry(pipe->suspended_read_list.next,
- struct rt_thread,
- tlist);
+ struct rt_thread,
+ tlist);
/* resume the read thread */
rt_thread_resume(thread);
@@ -128,16 +130,16 @@ static rt_size_t rt_pipe_write(rt_device_t dev,
RT_ASSERT(pipe != RT_NULL);
if ((pipe->flag & RT_PIPE_FLAG_FORCE_WR) ||
- !(pipe->flag & RT_PIPE_FLAG_BLOCK_WR))
+ !(pipe->flag & RT_PIPE_FLAG_BLOCK_WR))
{
level = rt_hw_interrupt_disable();
if (pipe->flag & RT_PIPE_FLAG_FORCE_WR)
write_nbytes = rt_ringbuffer_put_force(&(pipe->ringbuffer),
- buffer, size);
+ (const rt_uint8_t *)buffer, size);
else
write_nbytes = rt_ringbuffer_put(&(pipe->ringbuffer),
- buffer, size);
+ (const rt_uint8_t *)buffer, size);
_rt_pipe_resume_reader(pipe);
@@ -151,9 +153,10 @@ static rt_size_t rt_pipe_write(rt_device_t dev,
/* current context checking */
RT_DEBUG_NOT_IN_INTERRUPT;
- do {
+ do
+ {
level = rt_hw_interrupt_disable();
- write_nbytes = rt_ringbuffer_put(&(pipe->ringbuffer), buffer, size);
+ write_nbytes = rt_ringbuffer_put(&(pipe->ringbuffer), (const rt_uint8_t *)buffer, size);
if (write_nbytes == 0)
{
/* pipe full, waiting on suspended write list */
@@ -171,7 +174,8 @@ static rt_size_t rt_pipe_write(rt_device_t dev,
rt_hw_interrupt_enable(level);
break;
}
- } while (write_nbytes == 0);
+ }
+ while (write_nbytes == 0);
return write_nbytes;
}
@@ -183,7 +187,7 @@ static rt_err_t rt_pipe_control(rt_device_t dev, int cmd, void *args)
pipe = (struct rt_audio_pipe *)dev;
if (cmd == PIPE_CTRL_GET_SPACE && args)
- *(rt_size_t*)args = rt_ringbuffer_space_len(&pipe->ringbuffer);
+ *(rt_size_t *)args = rt_ringbuffer_space_len(&pipe->ringbuffer);
return RT_EOK;
}
@@ -212,10 +216,10 @@ const static struct rt_device_ops audio_pipe_ops =
* @return the operation status, RT_EOK on successful
*/
rt_err_t rt_audio_pipe_init(struct rt_audio_pipe *pipe,
- const char *name,
- rt_int32_t flag,
- rt_uint8_t *buf,
- rt_size_t size)
+ const char *name,
+ rt_int32_t flag,
+ rt_uint8_t *buf,
+ rt_size_t size)
{
RT_ASSERT(pipe);
RT_ASSERT(buf);
@@ -270,7 +274,7 @@ rt_err_t rt_audio_pipe_create(const char *name, rt_int32_t flag, rt_size_t size)
return -RT_ENOMEM;
/* create ring buffer of pipe */
- rb_memptr = rt_malloc(size);
+ rb_memptr = (rt_uint8_t *)rt_malloc(size);
if (rb_memptr == RT_NULL)
{
rt_free(pipe);
diff --git a/components/drivers/can/can.c b/components/drivers/can/can.c
index 0769c79fd7..3d60dbaa55 100644
--- a/components/drivers/can/can.c
+++ b/components/drivers/can/can.c
@@ -27,10 +27,15 @@ static rt_err_t rt_can_init(struct rt_device *dev)
/* initialize rx/tx */
can->can_rx = RT_NULL;
can->can_tx = RT_NULL;
+#ifdef RT_CAN_USING_HDR
+ can->hdr = RT_NULL;
+#endif
/* apply configuration */
if (can->ops->configure)
result = can->ops->configure(can, &can->config);
+ else
+ result = -RT_ENOSYS;
return result;
}
@@ -293,7 +298,7 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
can->can_rx = rx_fifo;
dev->open_flag |= RT_DEVICE_FLAG_INT_RX;
- /* configure low level device */
+ /* open can rx interrupt */
can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX);
}
}
@@ -311,7 +316,7 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
tx_fifo->buffer = (struct rt_can_sndbxinx_list *)(tx_fifo + 1);
rt_memset(tx_fifo->buffer, 0,
- can->config.sndboxnumber * sizeof(struct rt_can_sndbxinx_list));
+ can->config.sndboxnumber * sizeof(struct rt_can_sndbxinx_list));
rt_list_init(&tx_fifo->freelist);
for (i = 0; i < can->config.sndboxnumber; i++)
{
@@ -325,7 +330,7 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
can->can_tx = tx_fifo;
dev->open_flag |= RT_DEVICE_FLAG_INT_TX;
- /* configure low level device */
+ /* open can tx interrupt */
can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_TX);
}
}
@@ -406,7 +411,7 @@ static rt_err_t rt_can_close(struct rt_device *dev)
rt_free(rx_fifo);
dev->open_flag &= ~RT_DEVICE_FLAG_INT_RX;
can->can_rx = RT_NULL;
- /* configure low level device */
+ /* clear can rx interrupt */
can->ops->control(can, RT_DEVICE_CTRL_CLR_INT, (void *)RT_DEVICE_FLAG_INT_RX);
}
@@ -420,7 +425,7 @@ static rt_err_t rt_can_close(struct rt_device *dev)
rt_free(tx_fifo);
dev->open_flag &= ~RT_DEVICE_FLAG_INT_TX;
can->can_tx = RT_NULL;
- /* configure low level device */
+ /* clear can tx interrupt */
can->ops->control(can, RT_DEVICE_CTRL_CLR_INT, (void *)RT_DEVICE_FLAG_INT_TX);
}
@@ -484,6 +489,7 @@ static rt_err_t rt_can_control(struct rt_device *dev,
struct rt_can_device *can;
rt_err_t res;
+ res = RT_EOK;
RT_ASSERT(dev != RT_NULL);
can = (struct rt_can_device *)dev;
@@ -501,8 +507,9 @@ static rt_err_t rt_can_control(struct rt_device *dev,
case RT_DEVICE_CTRL_CONFIG:
/* configure device */
- can->ops->configure(can, (struct can_configure *)args);
+ res = can->ops->configure(can, (struct can_configure *)args);
break;
+
case RT_CAN_CMD_SET_PRIV:
/* configure device */
if ((rt_uint32_t)args != can->config.privmode)
@@ -513,7 +520,6 @@ static rt_err_t rt_can_control(struct rt_device *dev,
res = can->ops->control(can, cmd, args);
if (res != RT_EOK) return res;
-
tx_fifo = (struct rt_can_tx_fifo *) can->can_tx;
if (can->config.privmode)
{
@@ -522,11 +528,11 @@ static rt_err_t rt_can_control(struct rt_device *dev,
level = rt_hw_interrupt_disable();
if(rt_list_isempty(&tx_fifo->buffer[i].list))
{
- rt_sem_release(&(tx_fifo->sem));
+ rt_sem_release(&(tx_fifo->sem));
}
else
{
- rt_list_remove(&tx_fifo->buffer[i].list);
+ rt_list_remove(&tx_fifo->buffer[i].list);
}
rt_hw_interrupt_enable(level);
}
@@ -544,7 +550,6 @@ static rt_err_t rt_can_control(struct rt_device *dev,
rt_hw_interrupt_enable(level);
}
}
- return RT_EOK;
}
break;
@@ -561,74 +566,73 @@ static rt_err_t rt_can_control(struct rt_device *dev,
return res;
}
- {
- struct rt_can_filter_config *pfilter;
- struct rt_can_filter_item *pitem;
- rt_uint32_t count;
- rt_base_t level;
+ struct rt_can_filter_config *pfilter;
+ struct rt_can_filter_item *pitem;
+ rt_uint32_t count;
+ rt_base_t level;
- pfilter = (struct rt_can_filter_config *)args;
- count = pfilter->count;
- pitem = pfilter->items;
- if (pfilter->actived)
+ pfilter = (struct rt_can_filter_config *)args;
+ RT_ASSERT(pfilter);
+ count = pfilter->count;
+ pitem = pfilter->items;
+ if (pfilter->actived)
+ {
+ while (count)
{
- while (count)
+ if (pitem->hdr >= can->config.maxhdr || pitem->hdr < 0)
{
- if (pitem->hdr >= can->config.maxhdr || pitem->hdr < 0)
- {
- count--;
- pitem++;
- continue;
- }
-
- level = rt_hw_interrupt_disable();
- if (!can->hdr[pitem->hdr].connected)
- {
- rt_hw_interrupt_enable(level);
- rt_memcpy(&can->hdr[pitem->hdr].filter, pitem,
- sizeof(struct rt_can_filter_item));
- level = rt_hw_interrupt_disable();
- can->hdr[pitem->hdr].connected = 1;
- can->hdr[pitem->hdr].msgs = 0;
- rt_list_init(&can->hdr[pitem->hdr].list);
- }
- rt_hw_interrupt_enable(level);
-
count--;
pitem++;
+ continue;
}
+
+ level = rt_hw_interrupt_disable();
+ if (!can->hdr[pitem->hdr].connected)
+ {
+ rt_hw_interrupt_enable(level);
+ rt_memcpy(&can->hdr[pitem->hdr].filter, pitem,
+ sizeof(struct rt_can_filter_item));
+ level = rt_hw_interrupt_disable();
+ can->hdr[pitem->hdr].connected = 1;
+ can->hdr[pitem->hdr].msgs = 0;
+ rt_list_init(&can->hdr[pitem->hdr].list);
+ }
+ rt_hw_interrupt_enable(level);
+
+ count--;
+ pitem++;
}
- else
+ }
+ else
+ {
+ while (count)
{
- while (count)
+ if (pitem->hdr >= can->config.maxhdr || pitem->hdr < 0)
{
- if (pitem->hdr >= can->config.maxhdr || pitem->hdr < 0)
- {
- count--;
- pitem++;
- continue;
- }
- level = rt_hw_interrupt_disable();
+ count--;
+ pitem++;
+ continue;
+ }
+ level = rt_hw_interrupt_disable();
- if (can->hdr[pitem->hdr].connected)
+ if (can->hdr[pitem->hdr].connected)
+ {
+ can->hdr[pitem->hdr].connected = 0;
+ can->hdr[pitem->hdr].msgs = 0;
+ if (!rt_list_isempty(&can->hdr[pitem->hdr].list))
{
- can->hdr[pitem->hdr].connected = 0;
- can->hdr[pitem->hdr].msgs = 0;
- if (!rt_list_isempty(&can->hdr[pitem->hdr].list))
- {
- rt_list_remove(can->hdr[pitem->hdr].list.next);
- }
- rt_hw_interrupt_enable(level);
- rt_memset(&can->hdr[pitem->hdr].filter, 0,
- sizeof(struct rt_can_filter_item));
+ rt_list_remove(can->hdr[pitem->hdr].list.next);
}
- else
- {
- rt_hw_interrupt_enable(level);
- }
- count--;
- pitem++;
+ rt_hw_interrupt_enable(level);
+ rt_memset(&can->hdr[pitem->hdr].filter, 0,
+ sizeof(struct rt_can_filter_item));
+ }
+ else
+ {
+ rt_hw_interrupt_enable(level);
}
+ count--;
+ pitem++;
}
}
break;
@@ -642,12 +646,16 @@ static rt_err_t rt_can_control(struct rt_device *dev,
/* control device */
if (can->ops->control != RT_NULL)
{
- can->ops->control(can, cmd, args);
+ res = can->ops->control(can, cmd, args);
+ }
+ else
+ {
+ res = -RT_ENOSYS;
}
break;
}
- return RT_EOK;
+ return res;
}
/*
@@ -655,8 +663,10 @@ static rt_err_t rt_can_control(struct rt_device *dev,
*/
static void cantimeout(void *arg)
{
- rt_can_t can = (rt_can_t)arg;
+ rt_can_t can;
+ can = (rt_can_t)arg;
+ RT_ASSERT(can);
rt_device_control((rt_device_t)can, RT_CAN_CMD_GET_STATUS, (void *)&can->status);
if (can->status_indicate.ind != RT_NULL)
@@ -690,7 +700,7 @@ const static struct rt_device_ops can_device_ops =
/*
* can register
*/
-rt_err_t rt_hw_can_register(struct rt_can_device *can,
+rt_err_t rt_hw_can_register(struct rt_can_device *can,
const char *name,
const struct rt_can_ops *ops,
void *data)
@@ -843,7 +853,10 @@ void rt_hw_can_isr(struct rt_can_device *can, int event)
level = rt_hw_interrupt_disable();
rx_length = can->hdr[hdr].msgs * sizeof(struct rt_can_msg);
rt_hw_interrupt_enable(level);
- can->hdr[hdr].filter.ind(&can->parent, can->hdr[hdr].filter.args, hdr, rx_length);
+ if (rx_length)
+ {
+ can->hdr[hdr].filter.ind(&can->parent, can->hdr[hdr].filter.args, hdr, rx_length);
+ }
}
else
#endif
@@ -857,7 +870,10 @@ void rt_hw_can_isr(struct rt_can_device *can, int event)
rx_length = rt_list_len(&rx_fifo->uselist)* sizeof(struct rt_can_msg);
rt_hw_interrupt_enable(level);
- can->parent.rx_indicate(&can->parent, rx_length);
+ if (rx_length)
+ {
+ can->parent.rx_indicate(&can->parent, rx_length);
+ }
}
}
break;
diff --git a/components/drivers/hwcrypto/SConscript b/components/drivers/hwcrypto/SConscript
new file mode 100644
index 0000000000..90feff50b3
--- /dev/null
+++ b/components/drivers/hwcrypto/SConscript
@@ -0,0 +1,34 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd = GetCurrentDir()
+CPPPATH = [cwd, str(Dir('#'))]
+
+src = ['hwcrypto.c']
+
+if (GetDepend(['RT_HWCRYPTO_USING_AES']) or
+ GetDepend(['RT_HWCRYPTO_USING_DES']) or
+ GetDepend(['RT_HWCRYPTO_USING_3DES']) or
+ GetDepend(['RT_HWCRYPTO_USING_RC4'])):
+ src += ['hw_symmetric.c']
+ if GetDepend(['RT_HWCRYPTO_USING_GCM']):
+ src += ['hw_gcm.c']
+
+if (GetDepend(['RT_HWCRYPTO_USING_MD5']) or
+ GetDepend(['RT_HWCRYPTO_USING_SHA1']) or
+ GetDepend(['RT_HWCRYPTO_USING_SHA2'])):
+ src += ['hw_hash.c']
+
+if GetDepend(['RT_HWCRYPTO_USING_RNG']):
+ src += ['hw_rng.c']
+
+if GetDepend(['RT_HWCRYPTO_USING_CRC']):
+ src += ['hw_crc.c']
+
+if GetDepend(['RT_HWCRYPTO_USING_BIGNUM']):
+ src += ['hw_bignum.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_HWCRYPTO'], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/components/drivers/hwcrypto/hw_bignum.c b/components/drivers/hwcrypto/hw_bignum.c
new file mode 100644
index 0000000000..88813566b1
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_bignum.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_bignum.h>
+
+static struct rt_hwcrypto_ctx *bignum_default;
+
+rt_inline rt_err_t hwcrypto_bignum_dev_is_init(void)
+{
+ struct rt_hwcrypto_device *dev;
+
+ if (bignum_default)
+ {
+ return RT_EOK;
+ }
+ dev = rt_hwcrypto_dev_default();
+ if (dev == RT_NULL)
+ {
+ return -RT_ERROR;
+ }
+ return rt_hwcrypto_bignum_default(dev);
+}
+
+/**
+ * @brief Setting bignum default devices
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_default(struct rt_hwcrypto_device *device)
+{
+ if (bignum_default)
+ {
+ rt_hwcrypto_ctx_destroy(bignum_default);
+ bignum_default = RT_NULL;
+ }
+ if (device == RT_NULL)
+ {
+ return RT_EOK;
+ }
+ bignum_default = rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_BIGNUM, sizeof(struct hwcrypto_bignum));
+ if (bignum_default == RT_NULL)
+ {
+ return -RT_ERROR;
+ }
+ return RT_EOK;
+}
+
+/**
+ * @brief Init bignum obj
+ *
+ * @param n bignum obj
+ */
+void rt_hwcrypto_bignum_init(struct hw_bignum_mpi *n)
+{
+ if(n == RT_NULL)
+ return;
+
+ n->sign = 1;
+ n->total = 0;
+ n->p = RT_NULL;
+}
+
+/**
+ * @brief free a bignum obj
+ *
+ * @param Pointer to bignum obj
+ */
+void rt_hwcrypto_bignum_free(struct hw_bignum_mpi *n)
+{
+ if (n)
+ {
+ rt_free(n->p);
+ n->sign = 0;
+ n->total = 0;
+ n->p = RT_NULL;
+ }
+}
+
+/**
+ * @brief Get length of bignum as an unsigned binary buffer
+ *
+ * @param n bignum obj
+ *
+ * @return binary buffer length
+ */
+int rt_hwcrypto_bignum_get_len(const struct hw_bignum_mpi *n)
+{
+ int tmp_len, total;
+
+ if (n == RT_NULL || n->p == RT_NULL)
+ {
+ return 0;
+ }
+ tmp_len = 0;
+ total = n->total;
+ while ((total > 0) && (n->p[total - 1] == 0))
+ {
+ tmp_len++;
+ total--;
+ }
+ return n->total - tmp_len;
+}
+
+/**
+ * @brief Export n into unsigned binary data, big endian
+ *
+ * @param n bignum obj
+ * @param buf Buffer for the binary number
+ * @param len Length of the buffer
+ *
+ * @return export bin length
+ */
+int rt_hwcrypto_bignum_export_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len)
+{
+ int cp_len, i, j;
+
+ if (n == RT_NULL || buf == RT_NULL)
+ {
+ return 0;
+ }
+ rt_memset(buf, 0, len);
+ cp_len = n->total > len ? len : n->total;
+ for(i = cp_len, j = 0; i > 0; i--, j++)
+ {
+ buf[i - 1] = n->p[j];
+ }
+
+ return cp_len;
+}
+
+/**
+ * @brief Import n from unsigned binary data, big endian
+ *
+ * @param n bignum obj
+ * @param buf Buffer for the binary number
+ * @param len Length of the buffer
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_import_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len)
+{
+ int cp_len, i, j;
+ void *temp_p;
+
+ if (n == RT_NULL || buf == RT_NULL)
+ {
+ return 0;
+ }
+ if (n->total < len)
+ {
+ temp_p = rt_malloc(len);
+ if (temp_p == RT_NULL)
+ {
+ return 0;
+ }
+ rt_memset(temp_p, 0, len);
+ rt_free(n->p);
+ n->p = temp_p;
+ n->total = len;
+ }
+ cp_len = n->total > len ? len : n->total;
+
+ for(i = cp_len, j = 0; i > 0; i--, j++)
+ {
+ n->p[j] = buf[i - 1];
+ }
+
+ return cp_len;
+}
+
+/**
+ * @brief x = a + b
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_add(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b)
+{
+ struct hwcrypto_bignum *bignum_ctx;
+
+ if (hwcrypto_bignum_dev_is_init() != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+ bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+ if (bignum_ctx->ops->add)
+ {
+ return bignum_ctx->ops->add(bignum_ctx, x, a, b);
+ }
+ return -RT_ERROR;
+}
+
+/**
+ * @brief x = a - b
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_sub(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b)
+{
+ struct hwcrypto_bignum *bignum_ctx;
+
+ if (hwcrypto_bignum_dev_is_init() != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+ bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+ if (bignum_ctx->ops->sub)
+ {
+ return bignum_ctx->ops->sub(bignum_ctx, x, a, b);
+ }
+ return -RT_ERROR;
+}
+
+/**
+ * @brief x = a * b
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_mul(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b)
+{
+ struct hwcrypto_bignum *bignum_ctx;
+
+ if (hwcrypto_bignum_dev_is_init() != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+ bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+ if (bignum_ctx->ops->mul)
+ {
+ return bignum_ctx->ops->mul(bignum_ctx, x, a, b);
+ }
+ return -RT_ERROR;
+}
+
+/**
+ * @brief x = a * b (mod c)
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_mulmod(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b,
+ const struct hw_bignum_mpi *c)
+{
+ struct hwcrypto_bignum *bignum_ctx;
+
+ if (hwcrypto_bignum_dev_is_init() != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+ bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+ if (bignum_ctx->ops->mulmod)
+ {
+ return bignum_ctx->ops->mulmod(bignum_ctx, x, a, b, c);
+ }
+ return -RT_ERROR;
+}
+
+/**
+ * @brief x = a ^ b (mod c)
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_exptmod(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b,
+ const struct hw_bignum_mpi *c)
+{
+ struct hwcrypto_bignum *bignum_ctx;
+
+ if (hwcrypto_bignum_dev_is_init() != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+ bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+ if (bignum_ctx->ops->exptmod)
+ {
+ return bignum_ctx->ops->exptmod(bignum_ctx, x, a, b, c);
+ }
+ return -RT_ERROR;
+}
diff --git a/components/drivers/hwcrypto/hw_bignum.h b/components/drivers/hwcrypto/hw_bignum.h
new file mode 100644
index 0000000000..a1f567e68f
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_bignum.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#ifndef __HW_BIGNUM_H__
+#define __HW_BIGNUM_H__
+
+#include <hwcrypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_bignum;
+
+/* bignum obj */
+struct hw_bignum_mpi
+{
+ int sign; /**< integer sign */
+ rt_size_t total; /**< total of limbs */
+ rt_uint8_t *p; /**< pointer to limbs */
+};
+
+struct hwcrypto_bignum_ops
+{
+ rt_err_t (*add)(struct hwcrypto_bignum *bignum_ctx,
+ struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b); /**< x = a + b */
+ rt_err_t (*sub)(struct hwcrypto_bignum *bignum_ctx,
+ struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b); /**< x = a - b */
+ rt_err_t (*mul)(struct hwcrypto_bignum *bignum_ctx,
+ struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b); /**< x = a * b */
+ rt_err_t (*mulmod)(struct hwcrypto_bignum *bignum_ctx,
+ struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b,
+ const struct hw_bignum_mpi *c); /**< x = a * b (mod c) */
+ rt_err_t (*exptmod)(struct hwcrypto_bignum *bignum_ctx,
+ struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b,
+ const struct hw_bignum_mpi *c); /**< x = a ^ b (mod c) */
+};
+
+/**
+ * @brief bignum context. Hardware driver usage
+ */
+struct hwcrypto_bignum
+{
+ struct rt_hwcrypto_ctx parent; /**< Inheritance from hardware crypto context */
+ const struct hwcrypto_bignum_ops *ops; /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief Setting bignum default devices
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_default(struct rt_hwcrypto_device *device);
+
+/**
+ * @brief Init bignum obj
+ */
+void rt_hwcrypto_bignum_init(struct hw_bignum_mpi *n);
+
+/**
+ * @brief free a bignum obj
+ *
+ * @param Pointer to bignum obj
+ */
+void rt_hwcrypto_bignum_free(struct hw_bignum_mpi *n);
+
+/**
+ * @brief Get length of bignum as an unsigned binary buffer
+ *
+ * @param n bignum obj
+ *
+ * @return binary buffer Length
+ */
+int rt_hwcrypto_bignum_get_len(const struct hw_bignum_mpi *n);
+
+/**
+ * @brief Export n into unsigned binary data, big endian
+ *
+ * @param n bignum obj
+ * @param buf Buffer for the binary number
+ * @param len Length of the buffer
+ *
+ * @return export bin length
+ */
+int rt_hwcrypto_bignum_export_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len);
+
+/**
+ * @brief Import n from unsigned binary data, big endian
+ *
+ * @param n bignum obj
+ * @param buf Buffer for the binary number
+ * @param len Length of the buffer
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_import_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len);
+
+/**
+ * @brief x = a + b
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_add(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b);
+
+/**
+ * @brief x = a - b
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_sub(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b);
+
+/**
+ * @brief x = a * b
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_mul(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b);
+
+/**
+ * @brief x = a * b (mod c)
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_mulmod(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b,
+ const struct hw_bignum_mpi *c);
+
+/**
+ * @brief x = a ^ b (mod c)
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_exptmod(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b,
+ const struct hw_bignum_mpi *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/hwcrypto/hw_crc.c b/components/drivers/hwcrypto/hw_crc.c
new file mode 100644
index 0000000000..20579711e2
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_crc.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_crc.h>
+
+/**
+ * @brief Creating CRC Context
+ *
+ * @param device Hardware crypto device
+ * @param mode Setting default mode or custom mode
+ *
+ * @return CRC context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_crc_create(struct rt_hwcrypto_device *device,
+ hwcrypto_crc_mode mode)
+{
+ struct hwcrypto_crc *crc_ctx;
+
+ crc_ctx = (struct hwcrypto_crc *)rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_CRC, sizeof(struct hwcrypto_crc));
+ if (crc_ctx == RT_NULL)
+ {
+ return RT_NULL;
+ }
+
+ switch (mode)
+ {
+ case HWCRYPTO_CRC_CRC8:
+ {
+ struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC8_CFG;
+ crc_ctx->crc_cfg = temp;
+ break;
+ }
+ case HWCRYPTO_CRC_CRC16:
+ {
+ struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC16_CFG;
+ crc_ctx->crc_cfg = temp;
+ break;
+ }
+ case HWCRYPTO_CRC_CRC32:
+ {
+ struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC32_CFG;
+ crc_ctx->crc_cfg = temp;
+ break;
+ }
+ case HWCRYPTO_CRC_CCITT:
+ {
+ struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC_CCITT_CFG;
+ crc_ctx->crc_cfg = temp;
+ break;
+ }
+ case HWCRYPTO_CRC_DNP:
+ {
+ struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC_DNP_CFG;
+ crc_ctx->crc_cfg = temp;
+ break;
+ }
+ default:
+ break;
+ }
+
+ return &crc_ctx->parent;
+}
+
+/**
+ * @brief Destroy CRC Context
+ *
+ * @param ctx CRC context
+ */
+void rt_hwcrypto_crc_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+ rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief Processing a packet of data
+ *
+ * @param ctx CRC context
+ * @param input Data buffer to be Processed
+ * @param length Data Buffer length
+ *
+ * @return RT_EOK on success.
+ */
+rt_uint32_t rt_hwcrypto_crc_update(struct rt_hwcrypto_ctx *ctx,
+ const rt_uint8_t *input,
+ rt_size_t length)
+{
+ struct hwcrypto_crc *crc_ctx = (struct hwcrypto_crc *)ctx;
+ if (ctx && crc_ctx->ops->update)
+ {
+ return crc_ctx->ops->update(crc_ctx, input, length);
+ }
+ return 0;
+}
+
+/**
+ * @brief CRC context configuration
+ *
+ * @param ctx CRC context
+ * @param cfg CRC config
+ */
+void rt_hwcrypto_crc_cfg(struct rt_hwcrypto_ctx *ctx,
+ struct hwcrypto_crc_cfg *cfg)
+{
+ if (cfg)
+ {
+ ((struct hwcrypto_crc *)ctx)->crc_cfg = *cfg;
+ }
+}
diff --git a/components/drivers/hwcrypto/hw_crc.h b/components/drivers/hwcrypto/hw_crc.h
new file mode 100644
index 0000000000..a6df92a2ef
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_crc.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#ifndef __HW_CRC_H__
+#define __HW_CRC_H__
+
+#include <hwcrypto.h>
+
+#define CRC_FLAG_REFIN (0x1 << 0)
+#define CRC_FLAG_REFOUT (0x1 << 1)
+
+#define HWCRYPTO_CRC8_CFG \
+{ \
+ .last_val = 0x00, \
+ .poly = 0x07, \
+ .width = 8, \
+ .xorout = 0x00, \
+ .flags = 0, \
+}
+
+#define HWCRYPTO_CRC16_CFG \
+{ \
+ .last_val = 0x0000, \
+ .poly = 0x8005, \
+ .width = 16, \
+ .xorout = 0x0000, \
+ .flags = 0, \
+}
+
+#define HWCRYPTO_CRC32_CFG \
+{ \
+ .last_val = 0x00000000, \
+ .poly = 0x04C11DB7, \
+ .width = 32, \
+ .xorout = 0x00000000, \
+ .flags = 0, \
+}
+
+#define HWCRYPTO_CRC_CCITT_CFG \
+{ \
+ .last_val = 0x0000, \
+ .poly = 0x1021, \
+ .width = 16, \
+ .xorout = 0x0000, \
+ .flags = CRC_FLAG_REFIN | CRC_FLAG_REFOUT, \
+}
+
+#define HWCRYPTO_CRC_DNP_CFG \
+{ \
+ .last_val = 0x0000, \
+ .poly = 0x3D65, \
+ .width = 16, \
+ .xorout = 0xffff, \
+ .flags = CRC_FLAG_REFIN | CRC_FLAG_REFOUT, \
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_crc;
+
+typedef enum
+{
+ HWCRYPTO_CRC_CUSTOM, /**< Custom CRC mode */
+ HWCRYPTO_CRC_CRC8, /**< poly : 0x07 */
+ HWCRYPTO_CRC_CRC16, /**< poly : 0x8005 */
+ HWCRYPTO_CRC_CRC32, /**< poly : 0x04C11DB7 */
+ HWCRYPTO_CRC_CCITT, /**< poly : 0x1021 */
+ HWCRYPTO_CRC_DNP, /**< poly : 0x3D65 */
+} hwcrypto_crc_mode;
+
+struct hwcrypto_crc_cfg
+{
+ rt_uint32_t last_val; /**< Last CRC value cache */
+ rt_uint32_t poly; /**< CRC polynomial */
+ rt_uint16_t width; /**< CRC value width */
+ rt_uint32_t xorout; /**< Result XOR Value */
+ rt_uint16_t flags; /**< Input or output data reverse. CRC_FLAG_REFIN or CRC_FLAG_REFOUT */
+};
+
+struct hwcrypto_crc_ops
+{
+ rt_uint32_t (*update)(struct hwcrypto_crc *ctx,
+ const rt_uint8_t *in, rt_size_t length); /**< Perform a CRC calculation. return CRC value */
+};
+
+/**
+ * @brief CRC context. Hardware driver usage
+ */
+struct hwcrypto_crc
+{
+ struct rt_hwcrypto_ctx parent; /**< Inherited from the standard device */
+ struct hwcrypto_crc_cfg crc_cfg; /**< CRC configure */
+ const struct hwcrypto_crc_ops *ops; /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief Creating CRC Context
+ *
+ * @param device Hardware crypto device
+ * @param mode Setting default mode or custom mode
+ *
+ * @return CRC context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_crc_create(struct rt_hwcrypto_device *device,
+ hwcrypto_crc_mode mode);
+
+/**
+ * @brief Destroy CRC Context
+ *
+ * @param ctx CRC context
+ */
+void rt_hwcrypto_crc_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Processing a packet of data
+ *
+ * @param ctx CRC context
+ * @param input Data buffer to be Processed
+ * @param length Data Buffer length
+ *
+ * @return CRC value
+ */
+rt_uint32_t rt_hwcrypto_crc_update(struct rt_hwcrypto_ctx *ctx,
+ const rt_uint8_t *input, rt_size_t length);
+
+/**
+ * @brief CRC context configuration
+ *
+ * @param ctx CRC context
+ * @param cfg CRC config
+ */
+void rt_hwcrypto_crc_cfg(struct rt_hwcrypto_ctx *ctx,
+ struct hwcrypto_crc_cfg *cfg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/hwcrypto/hw_gcm.c b/components/drivers/hwcrypto/hw_gcm.c
new file mode 100644
index 0000000000..8d0f49149a
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_gcm.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-14 tyx the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_gcm.h>
+
+/**
+ * @brief Creating GCM Context
+ *
+ * @param device Hardware crypto device
+ * @param type Type of symmetric crypto context
+ *
+ * @return GCM context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_gcm_create(struct rt_hwcrypto_device *device,
+ hwcrypto_type crypt_type)
+{
+ struct rt_hwcrypto_ctx *ctx;
+
+ ctx = rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_GCM, sizeof(struct hwcrypto_gcm));
+ if (ctx)
+ {
+ ((struct hwcrypto_gcm *)ctx)->crypt_type = crypt_type;
+ }
+ return ctx;
+}
+
+/**
+ * @brief Destroy GCM Context
+ *
+ * @param ctx GCM context
+ */
+void rt_hwcrypto_gcm_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+ rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief This function starts a GCM encryption or decryption operation
+ *
+ * @param ctx GCM context
+ * @param add The buffer holding the additional data
+ * @param add_len The length of the additional data
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_start(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *add,
+ rt_size_t add_len)
+{
+ struct hwcrypto_gcm *gcm_ctx = (struct hwcrypto_gcm *)ctx;
+
+ if (gcm_ctx && gcm_ctx->ops->start)
+ {
+ return gcm_ctx->ops->start(gcm_ctx, add, add_len);
+ }
+ return -RT_EINVAL;
+}
+
+/**
+ * @brief This function finishes the GCM operation and generates the authentication tag
+ *
+ * @param ctx GCM context
+ * @param tag The buffer for holding the tag
+ * @param tag_len The length of the tag to generate
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_finish(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *tag,
+ rt_size_t tag_len)
+{
+ struct hwcrypto_gcm *gcm_ctx = (struct hwcrypto_gcm *)ctx;
+
+ if (gcm_ctx && gcm_ctx->ops->finish)
+ {
+ return gcm_ctx->ops->finish(gcm_ctx, tag, tag_len);
+ }
+ return -RT_EINVAL;
+}
+
+/**
+ * @brief This function performs a symmetric encryption or decryption operation
+ *
+ * @param ctx GCM context
+ * @param mode Operation mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT
+ * @param length The length of the input data in Bytes. This must be a multiple of the block size
+ * @param in The buffer holding the input data
+ * @param out The buffer holding the output data
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode,
+ rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out)
+{
+ return rt_hwcrypto_symmetric_crypt(ctx, mode, length, in, out);
+}
+
+/**
+ * @brief Set Symmetric Encryption and Decryption Key
+ *
+ * @param ctx GCM context
+ * @param key The crypto key
+ * @param bitlen The crypto key bit length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_setkey(struct rt_hwcrypto_ctx *ctx,
+ const rt_uint8_t *key, rt_uint32_t bitlen)
+{
+ return rt_hwcrypto_symmetric_setkey(ctx, key, bitlen);
+}
+
+/**
+ * @brief Get Symmetric Encryption and Decryption Key
+ *
+ * @param ctx GCM context
+ * @param key The crypto key buffer
+ * @param bitlen The crypto key bit length
+ *
+ * @return Key length of copy
+ */
+rt_err_t rt_hwcrypto_gcm_getkey(struct rt_hwcrypto_ctx *ctx,
+ rt_uint8_t *key, rt_uint32_t bitlen)
+{
+ return rt_hwcrypto_symmetric_getkey(ctx, key, bitlen);
+}
+
+/**
+ * @brief Set Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv The crypto initialization vector
+ * @param len The crypto initialization vector length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_setiv(struct rt_hwcrypto_ctx *ctx,
+ const rt_uint8_t *iv, rt_size_t len)
+{
+ return rt_hwcrypto_symmetric_setiv(ctx, iv, len);
+}
+
+/**
+ * @brief Get Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv The crypto initialization vector buffer
+ * @param len The crypto initialization vector buffer length
+ *
+ * @return IV length of copy
+ */
+rt_err_t rt_hwcrypto_gcm_getiv(struct rt_hwcrypto_ctx *ctx,
+ rt_uint8_t *iv, rt_size_t len)
+{
+ return rt_hwcrypto_symmetric_getiv(ctx, iv, len);
+}
+
+/**
+ * @brief Set offset in initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv_off The offset in IV
+ */
+void rt_hwcrypto_gcm_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off)
+{
+ rt_hwcrypto_symmetric_set_ivoff(ctx, iv_off);
+}
+
+/**
+ * @brief Get offset in initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv_off It must point to a valid memory
+ */
+void rt_hwcrypto_gcm_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off)
+{
+ rt_hwcrypto_symmetric_get_ivoff(ctx, iv_off);
+}
+
+/**
+ * @brief This function copy GCM context
+ *
+ * @param des The destination GCM context
+ * @param src The GCM context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_cpy(struct rt_hwcrypto_ctx *des,
+ const struct rt_hwcrypto_ctx *src)
+{
+ struct hwcrypto_gcm *gcm_des = (struct hwcrypto_gcm *)des;
+ struct hwcrypto_gcm *gcm_src = (struct hwcrypto_gcm *)src;
+
+ if (des != RT_NULL && src != RT_NULL)
+ {
+ gcm_des->crypt_type = gcm_src->crypt_type;
+ /* symmetric crypto context copy */
+ return rt_hwcrypto_symmetric_cpy(des, src);
+ }
+ return -RT_EINVAL;
+}
+
+/**
+ * @brief Reset GCM context
+ *
+ * @param ctx GCM context
+ */
+void rt_hwcrypto_gcm_reset(struct rt_hwcrypto_ctx *ctx)
+{
+ rt_hwcrypto_symmetric_reset(ctx);
+}
diff --git a/components/drivers/hwcrypto/hw_gcm.h b/components/drivers/hwcrypto/hw_gcm.h
new file mode 100644
index 0000000000..a73b2b0634
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_gcm.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-14 tyx the first version
+ */
+
+#ifndef __HW_GCM_H__
+#define __HW_GCM_H__
+
+#include "hw_symmetric.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_gcm;
+
+struct hwcrypto_gcm_ops
+{
+ rt_err_t (*start)(struct hwcrypto_gcm *gcm_ctx,
+ const unsigned char *add, size_t add_len); /**< Set additional data. start GCM operation */
+ rt_err_t (*finish)(struct hwcrypto_gcm *gcm_ctx,
+ const unsigned char *tag, size_t tag_len); /**< finish GCM operation. get tag */
+};
+
+/**
+ * @brief GCM context. Hardware driver usage
+ */
+struct hwcrypto_gcm
+{
+ struct hwcrypto_symmetric parent; /**< Inheritance from hardware symmetric crypto context */
+ hwcrypto_type crypt_type; /**< symmetric crypto type. eg: AES/DES */
+ const struct hwcrypto_gcm_ops *ops; /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief Creating GCM Context
+ *
+ * @param device Hardware crypto device
+ * @param type Type of symmetric crypto context
+ *
+ * @return GCM context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_gcm_create(struct rt_hwcrypto_device *device,
+ hwcrypto_type crypt_type);
+
+/**
+ * @brief Destroy GCM Context
+ *
+ * @param ctx GCM context
+ */
+void rt_hwcrypto_gcm_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief This function starts a GCM encryption or decryption operation
+ *
+ * @param ctx GCM context
+ * @param add The buffer holding the additional data
+ * @param add_len The length of the additional data
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_start(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *add,
+ rt_size_t add_len);
+
+/**
+ * @brief This function finishes the GCM operation and generates the authentication tag
+ *
+ * @param ctx GCM context
+ * @param tag The buffer for holding the tag
+ * @param tag_len The length of the tag to generate
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_finish(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *tag,
+ rt_size_t tag_len);
+
+/**
+ * @brief This function performs a symmetric encryption or decryption operation
+ *
+ * @param ctx GCM context
+ * @param mode Operation mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT
+ * @param length The length of the input data in Bytes. This must be a multiple of the block size
+ * @param in The buffer holding the input data
+ * @param out The buffer holding the output data
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode,
+ rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out);
+
+/**
+ * @brief Set Symmetric Encryption and Decryption Key
+ *
+ * @param ctx GCM context
+ * @param key The crypto key
+ * @param bitlen The crypto key bit length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_setkey(struct rt_hwcrypto_ctx *ctx,
+ const rt_uint8_t *key, rt_uint32_t bitlen);
+
+/**
+ * @brief Get Symmetric Encryption and Decryption Key
+ *
+ * @param ctx GCM context
+ * @param key The crypto key buffer
+ * @param bitlen The crypto key bit length
+ *
+ * @return Key length of copy
+ */
+rt_err_t rt_hwcrypto_gcm_getkey(struct rt_hwcrypto_ctx *ctx,
+ rt_uint8_t *key, rt_uint32_t bitlen);
+
+/**
+ * @brief Set Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv The crypto initialization vector
+ * @param len The crypto initialization vector length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_setiv(struct rt_hwcrypto_ctx *ctx,
+ const rt_uint8_t *iv, rt_size_t len);
+
+/**
+ * @brief Get Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv The crypto initialization vector buffer
+ * @param len The crypto initialization vector buffer length
+ *
+ * @return IV length of copy
+ */
+rt_err_t rt_hwcrypto_gcm_getiv(struct rt_hwcrypto_ctx *ctx,
+ rt_uint8_t *iv, rt_size_t len);
+
+/**
+ * @brief Set offset in initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv_off The offset in IV
+ */
+void rt_hwcrypto_gcm_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off);
+
+/**
+ * @brief Get offset in initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv_off It must point to a valid memory
+ */
+void rt_hwcrypto_gcm_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off);
+
+/**
+ * @brief This function copy GCM context
+ *
+ * @param des The destination GCM context
+ * @param src The GCM context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_cpy(struct rt_hwcrypto_ctx *des,
+ const struct rt_hwcrypto_ctx *src);
+
+/**
+ * @brief Reset GCM context
+ *
+ * @param ctx GCM context
+ */
+void rt_hwcrypto_gcm_reset(struct rt_hwcrypto_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/hwcrypto/hw_hash.c b/components/drivers/hwcrypto/hw_hash.c
new file mode 100644
index 0000000000..b20069ac0e
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_hash.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-23 tyx the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_hash.h>
+
+/**
+ * @brief Creating hash Context
+ *
+ * @param device Hardware crypto device
+ * @param type Type of hash context
+ *
+ * @return Hash context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_hash_create(struct rt_hwcrypto_device *device, hwcrypto_type type)
+{
+ struct rt_hwcrypto_ctx *ctx;
+
+ ctx = rt_hwcrypto_ctx_create(device, type, sizeof(struct hwcrypto_hash));
+ return ctx;
+}
+
+/**
+ * @brief Destroy hash Context
+ *
+ * @param ctx Hash context
+ */
+void rt_hwcrypto_hash_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+ rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief Get the final hash value
+ *
+ * @param ctx Hash context
+ * @param output Hash value buffer
+ * @param length Hash value buffer length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_finish(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *output, rt_size_t length)
+{
+ if (ctx && ((struct hwcrypto_hash *)ctx)->ops->finish)
+ {
+ return ((struct hwcrypto_hash *)ctx)->ops->finish((struct hwcrypto_hash *)ctx, output, length);
+ }
+ return -RT_ERROR;
+}
+
+/**
+ * @brief Processing a packet of data
+ *
+ * @param ctx Hash context
+ * @param input Data buffer to be Processed
+ * @param length Data Buffer length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_update(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *input, rt_size_t length)
+{
+ if (ctx && ((struct hwcrypto_hash *)ctx)->ops->update)
+ {
+ return ((struct hwcrypto_hash *)ctx)->ops->update((struct hwcrypto_hash *)ctx, input, length);
+ }
+ return -RT_ERROR;
+}
+
+/**
+ * @brief This function copy hash context
+ *
+ * @param des The destination hash context
+ * @param src The hash context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
+{
+ return rt_hwcrypto_ctx_cpy(des, src);
+}
+
+/**
+ * @brief Reset hash context
+ *
+ * @param ctx Hash context
+ */
+void rt_hwcrypto_hash_reset(struct rt_hwcrypto_ctx *ctx)
+{
+ rt_hwcrypto_ctx_reset(ctx);
+}
+
+/**
+ * @brief Setting hash context type
+ *
+ * @param ctx Hash context
+ * @param type Types of settings
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type)
+{
+ return rt_hwcrypto_set_type(ctx, type);
+}
diff --git a/components/drivers/hwcrypto/hw_hash.h b/components/drivers/hwcrypto/hw_hash.h
new file mode 100644
index 0000000000..de0310e84c
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_hash.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-23 tyx the first version
+ */
+
+#ifndef __HW_HASH_H__
+#define __HW_HASH_H__
+
+#include <hwcrypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_hash;
+
+struct hwcrypto_hash_ops
+{
+ rt_err_t (*update)(struct hwcrypto_hash *hash_ctx,
+ const rt_uint8_t *in, rt_size_t length); /**< Processing a packet of data */
+ rt_err_t (*finish)(struct hwcrypto_hash *hash_ctx,
+ rt_uint8_t *out, rt_size_t length); /**< Get the final hash value */
+};
+
+/**
+ * @brief hash context. Hardware driver usage
+ */
+struct hwcrypto_hash
+{
+ struct rt_hwcrypto_ctx parent; /**< Inheritance from hardware crypto context */
+ const struct hwcrypto_hash_ops *ops; /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief Creating hash Context
+ *
+ * @param device Hardware crypto device
+ * @param type Type of hash context
+ *
+ * @return Hash context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_hash_create(struct rt_hwcrypto_device *device,
+ hwcrypto_type type);
+
+/**
+ * @brief Destroy hash Context
+ *
+ * @param ctx Hash context
+ */
+void rt_hwcrypto_hash_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Get the final hash value
+ *
+ * @param ctx Hash context
+ * @param output Hash value buffer
+ * @param length Hash value buffer length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_finish(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *output, rt_size_t length);
+
+/**
+ * @brief Processing a packet of data
+ *
+ * @param ctx Hash context
+ * @param input Data buffer to be Processed
+ * @param length Data Buffer length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_update(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *input, rt_size_t length);
+
+/**
+ * @brief This function copy hash context
+ *
+ * @param des The destination hash context
+ * @param src The hash context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src);
+
+/**
+ * @brief Reset hash context
+ *
+ * @param ctx Hash context
+ */
+void rt_hwcrypto_hash_reset(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Setting hash context type
+ *
+ * @param ctx Hash context
+ * @param type Types of settings
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/hwcrypto/hw_rng.c b/components/drivers/hwcrypto/hw_rng.c
new file mode 100644
index 0000000000..13a17cc6be
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_rng.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_rng.h>
+
+/* Used to save default RNG Context */
+static struct rt_hwcrypto_ctx *ctx_default;
+
+/**
+ * @brief Creating RNG Context
+ *
+ * @param device Hardware crypto device
+ *
+ * @return RNG context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_rng_create(struct rt_hwcrypto_device *device)
+{
+ struct rt_hwcrypto_ctx *ctx;
+
+ ctx = rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_RNG, sizeof(struct hwcrypto_rng));
+ return ctx;
+}
+
+/**
+ * @brief Destroy RNG Context
+ *
+ * @param ctx RNG context
+ */
+void rt_hwcrypto_rng_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+ /* Destroy the defaule RNG Context ? */
+ if (ctx == ctx_default)
+ {
+ ctx_default = RT_NULL;
+ }
+ rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief Setting RNG default devices
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_rng_default(struct rt_hwcrypto_device *device)
+{
+ struct rt_hwcrypto_ctx *tmp_ctx;
+
+ /* if device is null, destroy default RNG Context */
+ if (device == RT_NULL)
+ {
+ if (ctx_default)
+ {
+ rt_hwcrypto_rng_destroy(ctx_default);
+ ctx_default = RT_NULL;
+ }
+ return RT_EOK;
+ }
+ /* Try create RNG Context */
+ tmp_ctx = rt_hwcrypto_rng_create(device);
+ if (tmp_ctx == RT_NULL)
+ {
+ return -RT_ERROR;
+ }
+ /* create RNG Context success, update default RNG Context */
+ rt_hwcrypto_rng_destroy(ctx_default);
+ ctx_default = tmp_ctx;
+
+ return RT_EOK;
+}
+
+/**
+ * @brief Getting Random Numbers from RNG Context
+ *
+ * @param ctx RNG context
+ *
+ * @return Random number
+ */
+rt_uint32_t rt_hwcrypto_rng_update_ctx(struct rt_hwcrypto_ctx *ctx)
+{
+ if (ctx)
+ {
+ return ((struct hwcrypto_rng *)ctx)->ops->update((struct hwcrypto_rng *)ctx);
+ }
+ return 0;
+}
+
+/**
+ * @brief Return a random number
+ *
+ * @return Random number
+ */
+rt_uint32_t rt_hwcrypto_rng_update(void)
+{
+ /* Default device does not exist ? */
+ if (ctx_default == RT_NULL)
+ {
+ /* try create Context from default device */
+ rt_hwcrypto_rng_default(rt_hwcrypto_dev_default());
+ }
+ return rt_hwcrypto_rng_update_ctx(ctx_default);
+}
diff --git a/components/drivers/hwcrypto/hw_rng.h b/components/drivers/hwcrypto/hw_rng.h
new file mode 100644
index 0000000000..fc28afdb1e
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_rng.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#ifndef __HW_RNG_H__
+#define __HW_RNG_H__
+
+#include <hwcrypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_rng;
+
+struct hwcrypto_rng_ops
+{
+ rt_uint32_t (*update)(struct hwcrypto_rng *ctx); /**< Return a random number */
+};
+
+/**
+ * @brief random context. Hardware driver usage
+ */
+struct hwcrypto_rng
+{
+ struct rt_hwcrypto_ctx parent; /**< Inheritance from hardware crypto context */
+ const struct hwcrypto_rng_ops *ops; /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief Creating RNG Context
+ *
+ * @param device Hardware crypto device
+ *
+ * @return RNG context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_rng_create(struct rt_hwcrypto_device *device);
+
+/**
+ * @brief Destroy RNG Context
+ *
+ * @param ctx RNG context
+ */
+void rt_hwcrypto_rng_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Setting RNG default devices
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_rng_default(struct rt_hwcrypto_device *device);
+
+/**
+ * @brief Getting Random Numbers from RNG Context
+ *
+ * @param ctx RNG context
+ *
+ * @return Random number
+ */
+rt_uint32_t rt_hwcrypto_rng_update_ctx(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Return a random number
+ *
+ * @return Random number
+ */
+rt_uint32_t rt_hwcrypto_rng_update(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/hwcrypto/hw_symmetric.c b/components/drivers/hwcrypto/hw_symmetric.c
new file mode 100644
index 0000000000..789c5c1a2c
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_symmetric.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_symmetric.h>
+
+/**
+ * @brief Creating Symmetric Encryption and Decryption Context
+ *
+ * @param device Hardware crypto device
+ * @param type Type of symmetric crypto context
+ *
+ * @return Symmetric crypto context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_symmetric_create(struct rt_hwcrypto_device *device, hwcrypto_type type)
+{
+ struct rt_hwcrypto_ctx *ctx;
+
+ ctx = rt_hwcrypto_ctx_create(device, type, sizeof(struct hwcrypto_symmetric));
+ return ctx;
+}
+
+/**
+ * @brief Destroy Symmetric Encryption and Decryption Context
+ *
+ * @param ctx Symmetric crypto context
+ */
+void rt_hwcrypto_symmetric_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+ rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief This function performs a symmetric encryption or decryption operation
+ *
+ * @param ctx Symmetric crypto context
+ * @param mode Operation mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT
+ * @param length The length of the input data in Bytes. This must be a multiple of the block size
+ * @param in The buffer holding the input data
+ * @param out The buffer holding the output data
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode, rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out)
+{
+ struct hwcrypto_symmetric *symmetric_ctx;
+ struct hwcrypto_symmetric_info symmetric_info;
+ rt_err_t err;
+
+ if (ctx == RT_NULL)
+ {
+ return -RT_EINVAL;
+ }
+ symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+ if (symmetric_ctx->ops->crypt == RT_NULL)
+ {
+ return -RT_ERROR;
+ }
+ if (mode != HWCRYPTO_MODE_ENCRYPT && mode != HWCRYPTO_MODE_DECRYPT)
+ {
+ return -EINVAL;
+ }
+
+ /* Input information packaging */
+ symmetric_info.mode = mode;
+ symmetric_info.in = in;
+ symmetric_info.out = out;
+ symmetric_info.length = length;
+
+ /* Calling Hardware Encryption and Decryption Function */
+ err = symmetric_ctx->ops->crypt(symmetric_ctx, &symmetric_info);
+
+ /* clean up flags */
+ symmetric_ctx->flags &= ~(SYMMTRIC_MODIFY_KEY | SYMMTRIC_MODIFY_IV | SYMMTRIC_MODIFY_IVOFF);
+ return err;
+}
+
+/**
+ * @brief Set Symmetric Encryption and Decryption Key
+ *
+ * @param ctx Symmetric crypto context
+ * @param key The crypto key
+ * @param bitlen The crypto key bit length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_setkey(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *key, rt_uint32_t bitlen)
+{
+ struct hwcrypto_symmetric *symmetric_ctx;
+
+ if (ctx && bitlen <= RT_HWCRYPTO_KEYBIT_MAX_SIZE)
+ {
+ symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+ rt_memcpy(symmetric_ctx->key, key, bitlen >> 3);
+ /* Record key length */
+ symmetric_ctx->key_bitlen = bitlen;
+ /* Key change flag set up */
+ symmetric_ctx->flags |= SYMMTRIC_MODIFY_KEY;
+ return RT_EOK;
+ }
+
+ return -RT_EINVAL;
+}
+
+/**
+ * @brief Get Symmetric Encryption and Decryption Key
+ *
+ * @param ctx Symmetric crypto context
+ * @param key The crypto key buffer
+ * @param bitlen The crypto key bit length
+ *
+ * @return Key length of copy
+ */
+int rt_hwcrypto_symmetric_getkey(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *key, rt_uint32_t bitlen)
+{
+ struct hwcrypto_symmetric *symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+
+ if (ctx && bitlen >= symmetric_ctx->key_bitlen)
+ {
+ rt_memcpy(key, symmetric_ctx->key, symmetric_ctx->key_bitlen >> 3);
+ return symmetric_ctx->key_bitlen;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Set Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv The crypto initialization vector
+ * @param len The crypto initialization vector length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_setiv(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *iv, rt_size_t len)
+{
+ struct hwcrypto_symmetric *symmetric_ctx;
+
+ if (ctx && len <= RT_HWCRYPTO_IV_MAX_SIZE)
+ {
+ symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+ rt_memcpy(symmetric_ctx->iv, iv, len);
+ symmetric_ctx->iv_len = len;
+ /* IV change flag set up */
+ symmetric_ctx->flags |= SYMMTRIC_MODIFY_IV;
+ return RT_EOK;
+ }
+
+ return -RT_EINVAL;
+}
+
+/**
+ * @brief Get Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv The crypto initialization vector buffer
+ * @param len The crypto initialization vector buffer length
+ *
+ * @return IV length of copy
+ */
+int rt_hwcrypto_symmetric_getiv(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *iv, rt_size_t len)
+{
+ struct hwcrypto_symmetric *symmetric_ctx = (struct hwcrypto_symmetric *)ctx;;
+
+ if (ctx && len >= symmetric_ctx->iv_len)
+ {
+ rt_memcpy(iv, symmetric_ctx->iv, symmetric_ctx->iv_len);
+ return symmetric_ctx->iv_len;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Set offset in initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv_off The offset in IV
+ */
+void rt_hwcrypto_symmetric_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off)
+{
+ if (ctx)
+ {
+ ((struct hwcrypto_symmetric *)ctx)->iv_off = iv_off;
+ /* iv_off change flag set up */
+ ((struct hwcrypto_symmetric *)ctx)->flags |= SYMMTRIC_MODIFY_IVOFF;
+ }
+}
+
+/**
+ * @brief Get offset in initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv_off It must point to a valid memory
+ */
+void rt_hwcrypto_symmetric_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off)
+{
+ if (ctx && iv_off)
+ {
+ *iv_off = ((struct hwcrypto_symmetric *)ctx)->iv_off;
+ }
+}
+
+/**
+ * @brief This function copy symmetric crypto context
+ *
+ * @param des The destination symmetric crypto context
+ * @param src The symmetric crypto context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
+{
+ struct hwcrypto_symmetric *symmetric_des = (struct hwcrypto_symmetric *)des;
+ struct hwcrypto_symmetric *symmetric_src = (struct hwcrypto_symmetric *)src;
+
+ if (des != RT_NULL && src != RT_NULL)
+ {
+ /* Copy Symmetric Encryption and Decryption Context Information */
+ symmetric_des->flags = symmetric_src->flags ;
+ symmetric_des->iv_len = symmetric_src->iv_len ;
+ symmetric_des->iv_off = symmetric_src->iv_off ;
+ symmetric_des->key_bitlen = symmetric_src->key_bitlen;
+ rt_memcpy(symmetric_des->iv, symmetric_src->iv, symmetric_src->iv_len);
+ rt_memcpy(symmetric_des->key, symmetric_src->key, symmetric_src->key_bitlen >> 3);
+
+ /* Hardware context copy */
+ return rt_hwcrypto_ctx_cpy(des, src);
+ }
+ return -RT_EINVAL;
+}
+
+/**
+ * @brief Reset symmetric crypto context
+ *
+ * @param ctx Symmetric crypto context
+ */
+void rt_hwcrypto_symmetric_reset(struct rt_hwcrypto_ctx *ctx)
+{
+ struct hwcrypto_symmetric *symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+ if (ctx != RT_NULL)
+ {
+ /* Copy Symmetric Encryption and Decryption Context Information */
+ symmetric_ctx->flags = 0x00;
+ symmetric_ctx->iv_len = 0x00;
+ symmetric_ctx->iv_off = 0x00;
+ symmetric_ctx->key_bitlen = 0x00;
+ rt_memset(symmetric_ctx->iv, 0, RT_HWCRYPTO_IV_MAX_SIZE);
+ rt_memset(symmetric_ctx->key, 0, RT_HWCRYPTO_KEYBIT_MAX_SIZE >> 3);
+
+ /* Hardware context reset */
+ rt_hwcrypto_ctx_reset(ctx);
+ }
+}
+
+/**
+ * @brief Setting symmetric crypto context type
+ *
+ * @param ctx Symmetric crypto context
+ * @param type Types of settings
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type)
+{
+ return rt_hwcrypto_set_type(ctx, type);
+}
diff --git a/components/drivers/hwcrypto/hw_symmetric.h b/components/drivers/hwcrypto/hw_symmetric.h
new file mode 100644
index 0000000000..12f4dbec30
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_symmetric.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#ifndef __HW_SYMMETRIC_H__
+#define __HW_SYMMETRIC_H__
+
+#include <hwcrypto.h>
+
+#ifndef RT_HWCRYPTO_IV_MAX_SIZE
+#define RT_HWCRYPTO_IV_MAX_SIZE (16)
+#endif
+#ifndef RT_HWCRYPTO_KEYBIT_MAX_SIZE
+#define RT_HWCRYPTO_KEYBIT_MAX_SIZE (256)
+#endif
+
+#define SYMMTRIC_MODIFY_KEY (0x1 << 0)
+#define SYMMTRIC_MODIFY_IV (0x1 << 1)
+#define SYMMTRIC_MODIFY_IVOFF (0x1 << 2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_symmetric;
+struct hwcrypto_symmetric_info;
+
+struct hwcrypto_symmetric_ops
+{
+ rt_err_t (*crypt)(struct hwcrypto_symmetric *symmetric_ctx,
+ struct hwcrypto_symmetric_info *symmetric_info); /**< Hardware Symmetric Encryption and Decryption Callback */
+};
+
+/**
+ * @brief Hardware driver usage, including input and output information
+ */
+struct hwcrypto_symmetric_info
+{
+ hwcrypto_mode mode; /**< crypto mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT */
+ const rt_uint8_t *in; /**< Input data */
+ rt_uint8_t *out; /**< Output data will be written */
+ rt_size_t length; /**< The length of the input data in Bytes. It's a multiple of block size. */
+};
+
+/**
+ * @brief Symmetric crypto context. Hardware driver usage
+ */
+struct hwcrypto_symmetric
+{
+ struct rt_hwcrypto_ctx parent; /**< Inheritance from hardware crypto context */
+ rt_uint32_t flags; /**< key or iv or ivoff has been changed. The flag will be set up */
+ rt_int32_t iv_len; /**< initialization vector effective length */
+ rt_int32_t iv_off; /**< The offset in IV */
+ rt_uint8_t iv[RT_HWCRYPTO_IV_MAX_SIZE]; /**< The initialization vector */
+ rt_uint8_t key[RT_HWCRYPTO_KEYBIT_MAX_SIZE >> 3]; /**< The crypto key */
+ rt_int32_t key_bitlen; /**< The crypto key bit length */
+ const struct hwcrypto_symmetric_ops *ops; /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief Creating Symmetric Encryption and Decryption Context
+ *
+ * @param device Hardware crypto device
+ * @param type Type of symmetric crypto context
+ *
+ * @return Symmetric crypto context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_symmetric_create(struct rt_hwcrypto_device *device,
+ hwcrypto_type type);
+
+/**
+ * @brief Destroy Symmetric Encryption and Decryption Context
+ *
+ * @param ctx Symmetric crypto context
+ */
+void rt_hwcrypto_symmetric_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief This function performs a symmetric encryption or decryption operation
+ *
+ * @param ctx Symmetric crypto context
+ * @param mode Operation mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT
+ * @param length The length of the input data in Bytes. This must be a multiple of the block size
+ * @param in The buffer holding the input data
+ * @param out The buffer holding the output data
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode,
+ rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out);
+
+/**
+ * @brief Set Symmetric Encryption and Decryption Key
+ *
+ * @param ctx Symmetric crypto context
+ * @param key The crypto key
+ * @param bitlen The crypto key bit length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_setkey(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *key, rt_uint32_t bitlen);
+
+/**
+ * @brief Get Symmetric Encryption and Decryption Key
+ *
+ * @param ctx Symmetric crypto context
+ * @param key The crypto key buffer
+ * @param bitlen The crypto key bit length
+ *
+ * @return Key length of copy
+ */
+int rt_hwcrypto_symmetric_getkey(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *key, rt_uint32_t bitlen);
+
+/**
+ * @brief Set Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv The crypto initialization vector
+ * @param len The crypto initialization vector length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_setiv(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *iv, rt_size_t len);
+
+/**
+ * @brief Get Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv The crypto initialization vector buffer
+ * @param len The crypto initialization vector buffer length
+ *
+ * @return IV length of copy
+ */
+int rt_hwcrypto_symmetric_getiv(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *iv, rt_size_t len);
+
+/**
+ * @brief Set offset in initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv_off The offset in IV
+ */
+void rt_hwcrypto_symmetric_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off);
+
+/**
+ * @brief Get offset in initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv_off It must point to a valid memory
+ */
+void rt_hwcrypto_symmetric_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off);
+
+/**
+ * @brief This function copy symmetric crypto context
+ *
+ * @param des The destination symmetric crypto context
+ * @param src The symmetric crypto context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src);
+
+/**
+ * @brief Reset symmetric crypto context
+ *
+ * @param ctx Symmetric crypto context
+ */
+void rt_hwcrypto_symmetric_reset(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Setting symmetric crypto context type
+ *
+ * @param ctx Symmetric crypto context
+ * @param type Types of settings
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/hwcrypto/hwcrypto.c b/components/drivers/hwcrypto/hwcrypto.c
new file mode 100644
index 0000000000..bbe1ff63fb
--- /dev/null
+++ b/components/drivers/hwcrypto/hwcrypto.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-23 tyx the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hwcrypto.h>
+
+/**
+ * @brief Setting context type (Direct calls are not recommended)
+ *
+ * @param ctx Crypto context
+ * @param type Types of settings
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type)
+{
+ if (ctx)
+ {
+ /* Is it the same category? */
+ if ((ctx->type & HWCRYPTO_MAIN_TYPE_MASK) == (type & HWCRYPTO_MAIN_TYPE_MASK))
+ {
+ ctx->type = type;
+ return RT_EOK;
+ }
+ /* Context is empty type */
+ else if (ctx->type == HWCRYPTO_TYPE_NULL)
+ {
+ ctx->type = type;
+ return RT_EOK;
+ }
+ else
+ {
+ return -RT_ERROR;
+ }
+ }
+ return -RT_EINVAL;
+}
+
+/**
+ * @brief Reset context type (Direct calls are not recommended)
+ *
+ * @param ctx Crypto context
+ *
+ */
+void rt_hwcrypto_ctx_reset(struct rt_hwcrypto_ctx *ctx)
+{
+ if (ctx && ctx->device->ops->reset)
+ {
+ ctx->device->ops->reset(ctx);
+ }
+}
+
+/**
+ * @brief Init crypto context
+ *
+ * @param ctx The context to initialize
+ * @param device Hardware crypto device
+ * @param type Type of context
+ * @param obj_size Size of context object
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_ctx_init(struct rt_hwcrypto_ctx *ctx, struct rt_hwcrypto_device *device, hwcrypto_type type)
+{
+ rt_err_t err;
+
+ /* Setting context type */
+ rt_hwcrypto_set_type(ctx, type);
+ ctx->device = device;
+ /* Create hardware context */
+ err = ctx->device->ops->create(ctx);
+ if (err != RT_EOK)
+ {
+ return err;
+ }
+ return RT_EOK;
+}
+
+/**
+ * @brief Create crypto context
+ *
+ * @param device Hardware crypto device
+ * @param type Type of context
+ * @param obj_size Size of context object
+ *
+ * @return Crypto context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_ctx_create(struct rt_hwcrypto_device *device, hwcrypto_type type, rt_uint32_t obj_size)
+{
+ struct rt_hwcrypto_ctx *ctx;
+ rt_err_t err;
+
+ /* Parameter checking */
+ if (device == RT_NULL || obj_size < sizeof(struct rt_hwcrypto_ctx))
+ {
+ return RT_NULL;
+ }
+ ctx = rt_malloc(obj_size);
+ if (ctx == RT_NULL)
+ {
+ return ctx;
+ }
+ rt_memset(ctx, 0, obj_size);
+ /* Init context */
+ err = rt_hwcrypto_ctx_init(ctx, device, type);
+ if (err != RT_EOK)
+ {
+ rt_free(ctx);
+ ctx = RT_NULL;
+ }
+ return ctx;
+}
+
+/**
+ * @brief Destroy crypto context
+ *
+ * @param device Crypto context
+ */
+void rt_hwcrypto_ctx_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+ if (ctx == RT_NULL)
+ {
+ return;
+ }
+ /* Destroy hardware context */
+ if (ctx->device->ops->destroy)
+ {
+ ctx->device->ops->destroy(ctx);
+ }
+ /* Free the resources */
+ rt_free(ctx);
+}
+
+/**
+ * @brief Copy crypto context
+ *
+ * @param des The destination context
+ * @param src The context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_ctx_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
+{
+ if (des == RT_NULL || src == RT_NULL)
+ {
+ return -RT_EINVAL;
+ }
+
+ /* The equipment is different or of different types and cannot be copied */
+ if (des->device != src->device ||
+ (des->type & HWCRYPTO_MAIN_TYPE_MASK) != (src->type & HWCRYPTO_MAIN_TYPE_MASK))
+ {
+ return -RT_EINVAL;
+ }
+ des->type = src->type;
+ /* Calling Hardware Context Copy Function */
+ return src->device->ops->copy(des, src);
+}
+
+/**
+ * @brief Get the default hardware crypto device
+ *
+ * @return Hardware crypto device
+ *
+ */
+struct rt_hwcrypto_device *rt_hwcrypto_dev_default(void)
+{
+ static struct rt_hwcrypto_device *hwcrypto_dev;
+
+ /* If there is a default device, return the device */
+ if (hwcrypto_dev)
+ {
+ return hwcrypto_dev;
+ }
+ /* Find by default device name */
+ hwcrypto_dev = (struct rt_hwcrypto_device *)rt_device_find(RT_HWCRYPTO_DEFAULT_NAME);
+ return hwcrypto_dev;
+}
+
+/**
+ * @brief Get the unique ID of the device
+ *
+ * @param device Device object
+ *
+ * @return Device unique ID
+ */
+rt_uint64_t rt_hwcrypto_id(struct rt_hwcrypto_device *device)
+{
+ if (device)
+ {
+ return device->id;
+ }
+ return 0;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops hwcrypto_ops =
+{
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ RT_NULL
+};
+#endif
+
+/**
+ * @brief Register hardware crypto device
+ *
+ * @param device Hardware crypto device
+ * @param name Name of device
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_register(struct rt_hwcrypto_device *device, const char *name)
+{
+ rt_err_t err;
+
+ RT_ASSERT(device != RT_NULL);
+ RT_ASSERT(name != RT_NULL);
+ RT_ASSERT(device->ops != RT_NULL);
+ RT_ASSERT(device->ops->create != RT_NULL);
+ RT_ASSERT(device->ops->destroy != RT_NULL);
+ RT_ASSERT(device->ops->copy != RT_NULL);
+ RT_ASSERT(device->ops->reset != RT_NULL);
+
+ rt_memset(&device->parent, 0, sizeof(struct rt_device));
+#ifdef RT_USING_DEVICE_OPS
+ device->parent.ops = &hwcrypto_ops;
+#else
+ device->parent.init = RT_NULL;
+ device->parent.open = RT_NULL;
+ device->parent.close = RT_NULL;
+ device->parent.read = RT_NULL;
+ device->parent.write = RT_NULL;
+ device->parent.control = RT_NULL;
+#endif
+
+ device->parent.user_data = RT_NULL;
+ device->parent.type = RT_Device_Class_Miscellaneous;
+
+ /* Register device */
+ err = rt_device_register(&device->parent, name, RT_DEVICE_FLAG_RDWR);
+
+ return err;
+}
diff --git a/components/drivers/hwcrypto/hwcrypto.h b/components/drivers/hwcrypto/hwcrypto.h
new file mode 100644
index 0000000000..a428f4437d
--- /dev/null
+++ b/components/drivers/hwcrypto/hwcrypto.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-23 tyx the first version
+ */
+
+#ifndef __HWCRYPTO_H__
+#define __HWCRYPTO_H__
+
+#include <rtthread.h>
+
+#ifndef RT_HWCRYPTO_DEFAULT_NAME
+#define RT_HWCRYPTO_DEFAULT_NAME ("hwcryto")
+#endif
+
+#define HWCRYPTO_MAIN_TYPE_MASK (0xffffUL << 16)
+#define HWCRYPTO_SUB_TYPE_MASK (0xffUL << 8)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ HWCRYPTO_TYPE_NULL = 0x00000000,
+
+ /* Main Type */
+ /* symmetric Type */
+ HWCRYPTO_TYPE_HEAD = __LINE__,
+ HWCRYPTO_TYPE_AES = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< AES */
+ HWCRYPTO_TYPE_DES = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< DES */
+ HWCRYPTO_TYPE_3DES = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< 3DES */
+ HWCRYPTO_TYPE_RC4 = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< RC4 */
+ HWCRYPTO_TYPE_GCM = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< GCM */
+ /* HASH Type */
+ HWCRYPTO_TYPE_MD5 = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< MD5 */
+ HWCRYPTO_TYPE_SHA1 = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< SHA1 */
+ HWCRYPTO_TYPE_SHA2 = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< SHA2 */
+ /* Other Type */
+ HWCRYPTO_TYPE_RNG = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< RNG */
+ HWCRYPTO_TYPE_CRC = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< CRC */
+ HWCRYPTO_TYPE_BIGNUM = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< BIGNUM */
+
+ /* AES Subtype */
+ HWCRYPTO_TYPE_AES_ECB = HWCRYPTO_TYPE_AES | (0x01 << 8),
+ HWCRYPTO_TYPE_AES_CBC = HWCRYPTO_TYPE_AES | (0x02 << 8),
+ HWCRYPTO_TYPE_AES_CFB = HWCRYPTO_TYPE_AES | (0x03 << 8),
+ HWCRYPTO_TYPE_AES_CTR = HWCRYPTO_TYPE_AES | (0x04 << 8),
+ HWCRYPTO_TYPE_AES_OFB = HWCRYPTO_TYPE_AES | (0x05 << 8),
+
+ /* DES Subtype */
+ HWCRYPTO_TYPE_DES_ECB = HWCRYPTO_TYPE_DES | (0x01 << 8),
+ HWCRYPTO_TYPE_DES_CBC = HWCRYPTO_TYPE_DES | (0x02 << 8),
+
+ /* 3DES Subtype */
+ HWCRYPTO_TYPE_3DES_ECB = HWCRYPTO_TYPE_3DES | (0x01 << 8),
+ HWCRYPTO_TYPE_3DES_CBC = HWCRYPTO_TYPE_3DES | (0x02 << 8),
+
+ /* SHA2 Subtype */
+ HWCRYPTO_TYPE_SHA224 = HWCRYPTO_TYPE_SHA2 | (0x01 << 8),
+ HWCRYPTO_TYPE_SHA256 = HWCRYPTO_TYPE_SHA2 | (0x02 << 8),
+ HWCRYPTO_TYPE_SHA384 = HWCRYPTO_TYPE_SHA2 | (0x03 << 8),
+ HWCRYPTO_TYPE_SHA512 = HWCRYPTO_TYPE_SHA2 | (0x04 << 8),
+} hwcrypto_type;
+
+typedef enum
+{
+ HWCRYPTO_MODE_ENCRYPT = 0x1, /**< Encryption operations */
+ HWCRYPTO_MODE_DECRYPT = 0x2, /**< Decryption operations */
+ HWCRYPTO_MODE_UNKNOWN = 0x7fffffff, /**< Unknown */
+} hwcrypto_mode;
+
+struct rt_hwcrypto_ctx;
+
+struct rt_hwcrypto_ops
+{
+ rt_err_t (*create)(struct rt_hwcrypto_ctx *ctx); /**< Creating hardware context */
+ void (*destroy)(struct rt_hwcrypto_ctx *ctx); /**< Delete hardware context */
+ rt_err_t (*copy)(struct rt_hwcrypto_ctx *des,
+ const struct rt_hwcrypto_ctx *src); /**< Cpoy hardware context */
+ void (*reset)(struct rt_hwcrypto_ctx *ctx); /**< Reset hardware context */
+};
+
+struct rt_hwcrypto_device
+{
+ struct rt_device parent; /**< Inherited from the standard device */
+ const struct rt_hwcrypto_ops *ops; /**< Hardware crypto ops */
+ rt_uint64_t id; /**< Unique id */
+ void *user_data; /**< Device user data */
+};
+
+struct rt_hwcrypto_ctx
+{
+ struct rt_hwcrypto_device *device; /**< Binding device */
+ hwcrypto_type type; /**< Encryption and decryption types */
+ void *contex; /**< Hardware context */
+};
+
+/**
+ * @brief Setting context type (Direct calls are not recommended)
+ *
+ * @param ctx Crypto context
+ * @param type Types of settings
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type);
+
+/**
+ * @brief Reset context type (Direct calls are not recommended)
+ *
+ * @param ctx Crypto context
+ */
+void rt_hwcrypto_ctx_reset(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Init crypto context (Direct calls are not recommended)
+ *
+ * @param ctx The context to initialize
+ * @param device Hardware crypto device
+ * @param type Type of context
+ * @param obj_size Size of context object
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_ctx_init(struct rt_hwcrypto_ctx *ctx,
+ struct rt_hwcrypto_device *device, hwcrypto_type type);
+
+/**
+ * @brief Create crypto context (Direct calls are not recommended)
+ *
+ * @param device Hardware crypto device
+ * @param type Type of context
+ * @param obj_size Size of context object
+ *
+ * @return Crypto context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_ctx_create(struct rt_hwcrypto_device *device,
+ hwcrypto_type type, rt_uint32_t obj_size);
+
+/**
+ * @brief Destroy crypto context (Direct calls are not recommended)
+ *
+ * @param device Crypto context
+ */
+void rt_hwcrypto_ctx_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Copy crypto context (Direct calls are not recommended)
+ *
+ * @param des The destination context
+ * @param src The context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_ctx_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src);
+
+/**
+ * @brief Register hardware crypto device
+ *
+ * @param device Hardware crypto device
+ * @param name Name of device
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_register(struct rt_hwcrypto_device *device, const char *name);
+
+/**
+ * @brief Get the default hardware crypto device
+ *
+ * @return Hardware crypto device
+ *
+ */
+struct rt_hwcrypto_device *rt_hwcrypto_dev_default(void);
+
+/**
+ * @brief Get the unique ID of the device
+ *
+ * @param device Device object
+ *
+ * @return Device unique ID
+ */
+rt_uint64_t rt_hwcrypto_id(struct rt_hwcrypto_device *device);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/i2c/fm24clxx.c b/components/drivers/i2c/fm24clxx.c
deleted file mode 100644
index eecf3d455a..0000000000
--- a/components/drivers/i2c/fm24clxx.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2017-07-14 aubr.cool 1st version
- */
-#include <rtthread.h>
-#include <rtdevice.h>
-#include "fm24clxx.h"
-
-struct fm24clxx_device
-{
- struct rt_device parent;
- struct rt_i2c_bus_device *bus;
-};
-
-/* RT-Thread device interface */
-
-static rt_err_t fm24clxx_init(rt_device_t dev)
-{
- return RT_EOK;
-}
-static rt_err_t fm24clxx_open(rt_device_t dev, rt_uint16_t oflag)
-{
- return RT_EOK;
-}
-
-static rt_err_t fm24clxx_close(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t fm24clxx_control(rt_device_t dev, int cmd, void *args)
-{
- return RT_EOK;
-}
-
-static rt_size_t fm24clxx_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
-{
- struct fm24clxx_device *fm24clxx;
- const struct fm24clxx_config *cfg;
- struct rt_i2c_msg msg[2];
- rt_uint8_t mem_addr[2] = {0,};
- rt_size_t ret = 0;
- RT_ASSERT(dev != 0);
-
- fm24clxx = (struct fm24clxx_device *) dev;
-
- RT_ASSERT(fm24clxx->parent.user_data != 0);
- cfg = (const struct fm24clxx_config *) fm24clxx->parent.user_data;
-
- if(pos > cfg->size)
- {
- return 0;
- }
-
- if(pos + size > cfg->size)
- {
- size = cfg->size - pos;
- }
-
- msg[0].addr = cfg->addr;
- msg[0].flags = cfg->flags | RT_I2C_WR;
- mem_addr[0] = (pos >> 8);
- mem_addr[1] = (rt_uint8_t) pos;
- msg[0].buf = (rt_uint8_t *) mem_addr;
- msg[0].len = 2;
-
- msg[1].addr = cfg->addr;
- msg[1].flags = cfg->flags | RT_I2C_RD;
- msg[1].buf = (rt_uint8_t *) buffer;
- msg[1].len = size;
-
- ret = rt_i2c_transfer(fm24clxx->bus, msg, 2);
- return (ret == 2) ? size : 0;
-}
-
-static rt_size_t fm24clxx_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
-{
- struct fm24clxx_device *fm24clxx;
- const struct fm24clxx_config *cfg;
- struct rt_i2c_msg msg[2];
- rt_uint8_t mem_addr[2] = {0,};
- rt_size_t ret = 0;
- RT_ASSERT(dev != 0);
-
- fm24clxx = (struct fm24clxx_device *) dev;
-
- RT_ASSERT(fm24clxx->parent.user_data != 0);
- cfg = (const struct fm24clxx_config *) fm24clxx->parent.user_data;
-
- if(pos > cfg->size)
- {
- return 0;
- }
-
- if(pos + size > cfg->size)
- {
- size = cfg->size - pos;
- }
-
- msg[0].addr = cfg->addr;
- msg[0].flags = cfg->flags | RT_I2C_WR;
- mem_addr[0] = (pos >> 8);
- mem_addr[1] = (rt_uint8_t) pos;
- msg[0].buf = (rt_uint8_t *) mem_addr;
- msg[0].len = 2;
-
- msg[1].addr = cfg->addr;
- msg[1].flags = cfg->flags | RT_I2C_WR | RT_I2C_NO_START;
- msg[1].buf = (rt_uint8_t *) buffer;
- msg[1].len = size;
-
- ret = rt_i2c_transfer(fm24clxx->bus, msg, 2);
- return (ret == 2) ? size : 0;
-}
-
-#ifdef RT_USING_DEVICE_OPS
-const static struct rt_device fm24clxx_ops =
-{
- fm24clxx_init,
- fm24clxx_open,
- fm24clxx_close,
- fm24clxx_read,
- fm24clxx_write,
- fm24clxx_control
-};
-#endif
-
-rt_err_t fm24clxx_register(const char *fm_device_name, const char *i2c_bus, void *user_data)
-{
- static struct fm24clxx_device fm24clxx_drv;
- struct rt_i2c_bus_device *bus;
-
- bus = rt_i2c_bus_device_find(i2c_bus);
- if (bus == RT_NULL)
- {
- return RT_ENOSYS;
- }
-
- fm24clxx_drv.bus = bus;
- fm24clxx_drv.parent.type = RT_Device_Class_Block;
-#ifdef RT_USING_DEVICE_OPS
- fm24clxx_drv.parent.ops = &fm24clxx_ops;
-#else
- fm24clxx_drv.parent.init = fm24clxx_init;
- fm24clxx_drv.parent.open = fm24clxx_open;
- fm24clxx_drv.parent.close = fm24clxx_close;
- fm24clxx_drv.parent.read = fm24clxx_read;
- fm24clxx_drv.parent.write = fm24clxx_write;
- fm24clxx_drv.parent.control = fm24clxx_control;
-#endif
-
- fm24clxx_drv.parent.user_data = user_data;
-
- return rt_device_register(&fm24clxx_drv.parent, fm_device_name, RT_DEVICE_FLAG_RDWR);
-} \ No newline at end of file
diff --git a/components/drivers/i2c/fm24clxx.h b/components/drivers/i2c/fm24clxx.h
deleted file mode 100644
index 74ee065470..0000000000
--- a/components/drivers/i2c/fm24clxx.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2017-07-14 aubr.cool 1st version
- */
-
-#ifndef __FM24CLXX_H__
-#define __FM24CLXX_H__
-
-#include <rtthread.h>
-
-struct fm24clxx_config
-{
- rt_uint32_t size;
- rt_uint16_t addr;
- rt_uint16_t flags;
-};
-
-extern rt_err_t fm24clxx_register(const char *e2m_device_name,
- const char *i2c_bus, void *user_data);
-
-#endif /*__FM24CLXX_H__*/ \ No newline at end of file
diff --git a/components/drivers/i2c/i2c-bit-ops.c b/components/drivers/i2c/i2c-bit-ops.c
index 26479a1d68..99338eef54 100644
--- a/components/drivers/i2c/i2c-bit-ops.c
+++ b/components/drivers/i2c/i2c-bit-ops.c
@@ -10,11 +10,13 @@
#include <rtdevice.h>
-#ifdef RT_I2C_BIT_DEBUG
-#define bit_dbg(fmt, ...) rt_kprintf(fmt, ##__VA_ARGS__)
+#define DBG_TAG "I2C"
+#ifdef RT_I2C_BITOPS_DEBUG
+#define DBG_LVL DBG_LOG
#else
-#define bit_dbg(fmt, ...)
+#define DBG_LVL DBG_INFO
#endif
+#include <rtdbg.h>
#define SET_SDA(ops, val) ops->set_sda(ops->data, val)
#define SET_SCL(ops, val) ops->set_scl(ops->data, val)
@@ -54,11 +56,11 @@ static rt_err_t SCL_H(struct rt_i2c_bit_ops *ops)
return -RT_ETIMEOUT;
rt_thread_delay((ops->timeout + 1) >> 1);
}
-#ifdef RT_I2C_BIT_DEBUG
+#ifdef RT_I2C_BITOPS_DEBUG
if (rt_tick_get() != start)
{
- bit_dbg("wait %ld tick for SCL line to go high\n",
- rt_tick_get() - start);
+ LOG_D("wait %ld tick for SCL line to go high",
+ rt_tick_get() - start);
}
#endif
@@ -70,14 +72,14 @@ done:
static void i2c_start(struct rt_i2c_bit_ops *ops)
{
-#ifdef RT_I2C_BIT_DEBUG
+#ifdef RT_I2C_BITOPS_DEBUG
if (ops->get_scl && !GET_SCL(ops))
{
- bit_dbg("I2C bus error, SCL line low\n");
+ LOG_E("I2C bus error, SCL line low");
}
if (ops->get_sda && !GET_SDA(ops))
{
- bit_dbg("I2C bus error, SDA line low\n");
+ LOG_E("I2C bus error, SDA line low");
}
#endif
SDA_L(ops);
@@ -114,13 +116,13 @@ rt_inline rt_bool_t i2c_waitack(struct rt_i2c_bit_ops *ops)
if (SCL_H(ops) < 0)
{
- bit_dbg("wait ack timeout\n");
+ LOG_W("wait ack timeout");
return -RT_ETIMEOUT;
}
ack = !GET_SDA(ops); /* ACK : SDA pin is pulled low */
- bit_dbg("%s\n", ack ? "ACK" : "NACK");
+ LOG_D("%s", ack ? "ACK" : "NACK");
SCL_L(ops);
@@ -132,7 +134,7 @@ static rt_int32_t i2c_writeb(struct rt_i2c_bus_device *bus, rt_uint8_t data)
rt_int32_t i;
rt_uint8_t bit;
- struct rt_i2c_bit_ops *ops = bus->priv;
+ struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
for (i = 7; i >= 0; i--)
{
@@ -142,8 +144,8 @@ static rt_int32_t i2c_writeb(struct rt_i2c_bus_device *bus, rt_uint8_t data)
i2c_delay(ops);
if (SCL_H(ops) < 0)
{
- bit_dbg("i2c_writeb: 0x%02x, "
- "wait scl pin high timeout at bit %d\n",
+ LOG_D("i2c_writeb: 0x%02x, "
+ "wait scl pin high timeout at bit %d",
data, i);
return -RT_ETIMEOUT;
@@ -159,7 +161,7 @@ static rt_int32_t i2c_readb(struct rt_i2c_bus_device *bus)
{
rt_uint8_t i;
rt_uint8_t data = 0;
- struct rt_i2c_bit_ops *ops = bus->priv;
+ struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
SDA_H(ops);
i2c_delay(ops);
@@ -169,8 +171,8 @@ static rt_int32_t i2c_readb(struct rt_i2c_bus_device *bus)
if (SCL_H(ops) < 0)
{
- bit_dbg("i2c_readb: wait scl pin high "
- "timeout at bit %d\n", 7 - i);
+ LOG_D("i2c_readb: wait scl pin high "
+ "timeout at bit %d", 7 - i);
return -RT_ETIMEOUT;
}
@@ -205,13 +207,13 @@ static rt_size_t i2c_send_bytes(struct rt_i2c_bus_device *bus,
}
else if (ret == 0)
{
- i2c_dbg("send bytes: NACK.\n");
+ LOG_D("send bytes: NACK.");
return 0;
}
else
{
- i2c_dbg("send bytes: error %d\n", ret);
+ LOG_E("send bytes: error %d", ret);
return ret;
}
@@ -222,14 +224,14 @@ static rt_size_t i2c_send_bytes(struct rt_i2c_bus_device *bus,
static rt_err_t i2c_send_ack_or_nack(struct rt_i2c_bus_device *bus, int ack)
{
- struct rt_i2c_bit_ops *ops = bus->priv;
+ struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
if (ack)
SET_SDA(ops, 0);
i2c_delay(ops);
if (SCL_H(ops) < 0)
{
- bit_dbg("ACK or NACK timeout\n");
+ LOG_E("ACK or NACK timeout.");
return -RT_ETIMEOUT;
}
@@ -263,7 +265,7 @@ static rt_size_t i2c_recv_bytes(struct rt_i2c_bus_device *bus,
ptr ++;
count --;
- bit_dbg("recieve bytes: 0x%02x, %s\n",
+ LOG_D("recieve bytes: 0x%02x, %s",
val, (flags & RT_I2C_NO_READ_ACK) ?
"(No ACK/NACK)" : (count ? "ACK" : "NACK"));
@@ -282,7 +284,7 @@ static rt_int32_t i2c_send_address(struct rt_i2c_bus_device *bus,
rt_uint8_t addr,
rt_int32_t retries)
{
- struct rt_i2c_bit_ops *ops = bus->priv;
+ struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
rt_int32_t i;
rt_err_t ret = 0;
@@ -291,10 +293,10 @@ static rt_int32_t i2c_send_address(struct rt_i2c_bus_device *bus,
ret = i2c_writeb(bus, addr);
if (ret == 1 || i == retries)
break;
- bit_dbg("send stop condition\n");
+ LOG_D("send stop condition");
i2c_stop(ops);
i2c_delay2(ops);
- bit_dbg("send start condition\n");
+ LOG_D("send start condition");
i2c_start(ops);
}
@@ -306,7 +308,7 @@ static rt_err_t i2c_bit_send_address(struct rt_i2c_bus_device *bus,
{
rt_uint16_t flags = msg->flags;
rt_uint16_t ignore_nack = msg->flags & RT_I2C_IGNORE_NACK;
- struct rt_i2c_bit_ops *ops = bus->priv;
+ struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
rt_uint8_t addr1, addr2;
rt_int32_t retries;
@@ -319,12 +321,12 @@ static rt_err_t i2c_bit_send_address(struct rt_i2c_bus_device *bus,
addr1 = 0xf0 | ((msg->addr >> 7) & 0x06);
addr2 = msg->addr & 0xff;
- bit_dbg("addr1: %d, addr2: %d\n", addr1, addr2);
+ LOG_D("addr1: %d, addr2: %d", addr1, addr2);
ret = i2c_send_address(bus, addr1, retries);
if ((ret != 1) && !ignore_nack)
{
- bit_dbg("NACK: sending first addr\n");
+ LOG_W("NACK: sending first addr");
return -RT_EIO;
}
@@ -332,19 +334,19 @@ static rt_err_t i2c_bit_send_address(struct rt_i2c_bus_device *bus,
ret = i2c_writeb(bus, addr2);
if ((ret != 1) && !ignore_nack)
{
- bit_dbg("NACK: sending second addr\n");
+ LOG_W("NACK: sending second addr");
return -RT_EIO;
}
if (flags & RT_I2C_RD)
{
- bit_dbg("send repeated start condition\n");
+ LOG_D("send repeated start condition");
i2c_restart(ops);
addr1 |= 0x01;
ret = i2c_send_address(bus, addr1, retries);
if ((ret != 1) && !ignore_nack)
{
- bit_dbg("NACK: sending repeated addr\n");
+ LOG_E("NACK: sending repeated addr");
return -RT_EIO;
}
@@ -369,11 +371,11 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
rt_uint32_t num)
{
struct rt_i2c_msg *msg;
- struct rt_i2c_bit_ops *ops = bus->priv;
+ struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
rt_int32_t i, ret;
rt_uint16_t ignore_nack;
- bit_dbg("send start condition\n");
+ LOG_D("send start condition");
i2c_start(ops);
for (i = 0; i < num; i++)
{
@@ -388,7 +390,7 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
ret = i2c_bit_send_address(bus, msg);
if ((ret != RT_EOK) && !ignore_nack)
{
- bit_dbg("receive NACK from device addr 0x%02x msg %d\n",
+ LOG_D("receive NACK from device addr 0x%02x msg %d",
msgs[i].addr, i);
goto out;
}
@@ -397,7 +399,7 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
{
ret = i2c_recv_bytes(bus, msg);
if (ret >= 1)
- bit_dbg("read %d byte%s\n", ret, ret == 1 ? "" : "s");
+ LOG_D("read %d byte%s", ret, ret == 1 ? "" : "s");
if (ret < msg->len)
{
if (ret >= 0)
@@ -409,7 +411,7 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
{
ret = i2c_send_bytes(bus, msg);
if (ret >= 1)
- bit_dbg("write %d byte%s\n", ret, ret == 1 ? "" : "s");
+ LOG_D("write %d byte%s", ret, ret == 1 ? "" : "s");
if (ret < msg->len)
{
if (ret >= 0)
@@ -421,7 +423,7 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
ret = i;
out:
- bit_dbg("send stop condition\n");
+ LOG_D("send stop condition");
i2c_stop(ops);
return ret;
diff --git a/components/drivers/i2c/i2c_core.c b/components/drivers/i2c/i2c_core.c
index f245abb9ca..f358c2b758 100644
--- a/components/drivers/i2c/i2c_core.c
+++ b/components/drivers/i2c/i2c_core.c
@@ -10,6 +10,14 @@
#include <rtdevice.h>
+#define DBG_TAG "I2C"
+#ifdef RT_I2C_DEBUG
+#define DBG_LVL DBG_LOG
+#else
+#define DBG_LVL DBG_INFO
+#endif
+#include <rtdbg.h>
+
rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus,
const char *bus_name)
{
@@ -21,7 +29,7 @@ rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus,
res = rt_i2c_bus_device_device_init(bus, bus_name);
- i2c_dbg("I2C bus [%s] registered\n", bus_name);
+ LOG_I("I2C bus [%s] registered", bus_name);
return res;
}
@@ -32,7 +40,7 @@ struct rt_i2c_bus_device *rt_i2c_bus_device_find(const char *bus_name)
rt_device_t dev = rt_device_find(bus_name);
if (dev == RT_NULL || dev->type != RT_Device_Class_I2CBUS)
{
- i2c_dbg("I2C bus %s not exist\n", bus_name);
+ LOG_E("I2C bus %s not exist", bus_name);
return RT_NULL;
}
@@ -53,9 +61,9 @@ rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,
#ifdef RT_I2C_DEBUG
for (ret = 0; ret < num; ret++)
{
- i2c_dbg("msgs[%d] %c, addr=0x%02x, len=%d\n", ret,
- (msgs[ret].flags & RT_I2C_RD) ? 'R' : 'W',
- msgs[ret].addr, msgs[ret].len);
+ LOG_D("msgs[%d] %c, addr=0x%02x, len=%d", ret,
+ (msgs[ret].flags & RT_I2C_RD) ? 'R' : 'W',
+ msgs[ret].addr, msgs[ret].len);
}
#endif
@@ -67,7 +75,7 @@ rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,
}
else
{
- i2c_dbg("I2C bus operation not supported\n");
+ LOG_E("I2C bus operation not supported");
return 0;
}
@@ -83,7 +91,7 @@ rt_size_t rt_i2c_master_send(struct rt_i2c_bus_device *bus,
struct rt_i2c_msg msg;
msg.addr = addr;
- msg.flags = flags & RT_I2C_ADDR_10BIT;
+ msg.flags = flags;
msg.len = count;
msg.buf = (rt_uint8_t *)buf;
@@ -103,8 +111,7 @@ rt_size_t rt_i2c_master_recv(struct rt_i2c_bus_device *bus,
RT_ASSERT(bus != RT_NULL);
msg.addr = addr;
- msg.flags = flags & RT_I2C_ADDR_10BIT;
- msg.flags |= RT_I2C_RD;
+ msg.flags = flags | RT_I2C_RD;
msg.len = count;
msg.buf = buf;
diff --git a/components/drivers/i2c/i2c_dev.c b/components/drivers/i2c/i2c_dev.c
index 6c7df8e427..59f728be09 100644
--- a/components/drivers/i2c/i2c_dev.c
+++ b/components/drivers/i2c/i2c_dev.c
@@ -11,6 +11,14 @@
#include <rtdevice.h>
+#define DBG_TAG "I2C"
+#ifdef RT_I2C_DEBUG
+#define DBG_LVL DBG_LOG
+#else
+#define DBG_LVL DBG_INFO
+#endif
+#include <rtdbg.h>
+
static rt_size_t i2c_bus_device_read(rt_device_t dev,
rt_off_t pos,
void *buffer,
@@ -23,12 +31,12 @@ static rt_size_t i2c_bus_device_read(rt_device_t dev,
RT_ASSERT(bus != RT_NULL);
RT_ASSERT(buffer != RT_NULL);
- i2c_dbg("I2C bus dev [%s] reading %u bytes.\n", dev->parent.name, count);
+ LOG_D("I2C bus dev [%s] reading %u bytes.", dev->parent.name, count);
addr = pos & 0xffff;
flags = (pos >> 16) & 0xffff;
- return rt_i2c_master_recv(bus, addr, flags, buffer, count);
+ return rt_i2c_master_recv(bus, addr, flags, (rt_uint8_t *)buffer, count);
}
static rt_size_t i2c_bus_device_write(rt_device_t dev,
@@ -43,12 +51,12 @@ static rt_size_t i2c_bus_device_write(rt_device_t dev,
RT_ASSERT(bus != RT_NULL);
RT_ASSERT(buffer != RT_NULL);
- i2c_dbg("I2C bus dev [%s] writing %u bytes.\n", dev->parent.name, count);
+ LOG_D("I2C bus dev [%s] writing %u bytes.", dev->parent.name, count);
addr = pos & 0xffff;
flags = (pos >> 16) & 0xffff;
- return rt_i2c_master_send(bus, addr, flags, buffer, count);
+ return rt_i2c_master_send(bus, addr, flags, (const rt_uint8_t *)buffer, count);
}
static rt_err_t i2c_bus_device_control(rt_device_t dev,
diff --git a/components/drivers/include/drivers/audio.h b/components/drivers/include/drivers/audio.h
index 7d2cb36728..86057e7626 100644
--- a/components/drivers/include/drivers/audio.h
+++ b/components/drivers/include/drivers/audio.h
@@ -5,52 +5,30 @@
*
* Change Logs:
* Date Author Notes
- * 2017-05-09 Urey first version
+ * 2017-05-09 Urey first version
+ * 2019-07-09 Zero-Free improve device ops interface and data flows
+ *
*/
#ifndef __AUDIO_H__
#define __AUDIO_H__
+#include "audio_pipe.h"
+
/* AUDIO command */
#define _AUDIO_CTL(a) (0x10 + a)
#define AUDIO_CTL_GETCAPS _AUDIO_CTL(1)
#define AUDIO_CTL_CONFIGURE _AUDIO_CTL(2)
-#define AUDIO_CTL_SHUTDOWN _AUDIO_CTL(3)
-#define AUDIO_CTL_START _AUDIO_CTL(4)
-#define AUDIO_CTL_STOP _AUDIO_CTL(5)
-#define AUDIO_CTL_PAUSE _AUDIO_CTL(6)
-#define AUDIO_CTL_RESUME _AUDIO_CTL(7)
-#define AUDIO_CTL_GETBUFFERINFO _AUDIO_CTL(8)
-#define AUDIO_CTL_ALLOCBUFFER _AUDIO_CTL(9)
-#define AUDIO_CTL_FREEBUFFER _AUDIO_CTL(10)
-#define AUDIO_CTL_HWRESET _AUDIO_CTL(11)
-
+#define AUDIO_CTL_START _AUDIO_CTL(3)
+#define AUDIO_CTL_STOP _AUDIO_CTL(4)
+#define AUDIO_CTL_GETBUFFERINFO _AUDIO_CTL(5)
/* Audio Device Types */
#define AUDIO_TYPE_QUERY 0x00
#define AUDIO_TYPE_INPUT 0x01
#define AUDIO_TYPE_OUTPUT 0x02
#define AUDIO_TYPE_MIXER 0x04
-#define AUDIO_TYPE_SELECTOR 0x08
-#define AUDIO_TYPE_EFFECT 0x10
-
-/* Audio Format Types */
-#define AUDIO_FMT_PCM_U8 0x0001
-#define AUDIO_FMT_PCM_S8 0x0002
-
-#define AUDIO_FMT_PCM_U16_LE 0x0010
-#define AUDIO_FMT_PCM_S16_BE 0x0020
-#define AUDIO_FMT_PCM_S16_LE 0x0040
-#define AUDIO_FMT_PCM_U16_BE 0x0080
-#define AUDIO_FMT_PCM_U24_LE 0x0100
-#define AUDIO_FMT_PCM_S24_BE 0x0200
-#define AUDIO_FMT_PCM_S24_LE 0x0400
-#define AUDIO_FMT_PCM_U24_BE 0x0800
-#define AUDIO_FMT_PCM_U32_LE 0x1000
-#define AUDIO_FMT_PCM_S32_BE 0x2000
-#define AUDIO_FMT_PCM_S32_LE 0x4000
-#define AUDIO_FMT_PCM_U32_BE 0x8000
/* Supported Sampling Rates */
#define AUDIO_SAMP_RATE_8K 0x0001
@@ -76,13 +54,11 @@
#define AUDIO_BIT_RATE_172K 0x40
#define AUDIO_BIT_RATE_192K 0x80
-
-
/* Support Dsp(input/output) Units controls */
#define AUDIO_DSP_PARAM 0 /* get/set all params */
-#define AUDIO_DSP_SAMPLERATE 1 /* 采样频率 */
-#define AUDIO_DSP_FMT 2
-#define AUDIO_DSP_CHANNELS 3
+#define AUDIO_DSP_SAMPLERATE 1 /* samplerate */
+#define AUDIO_DSP_CHANNELS 2 /* channels */
+#define AUDIO_DSP_SAMPLEBITS 3 /* sample bits width */
/* Supported Mixer Units controls */
#define AUDIO_MIXER_QUERY 0x0000
@@ -95,15 +71,13 @@
#define AUDIO_MIXER_LINE 0x0040
#define AUDIO_MIXER_DIGITAL 0x0080
#define AUDIO_MIXER_MIC 0x0100
+#define AUDIO_MIXER_VITURAL 0x0200
+#define AUDIO_MIXER_EXTEND 0x8000 /* extend mixer command */
-#define AUDIO_MIXER_EXTEND 0x8000 //extend mixer command
+#define AUDIO_VOLUME_MAX (100)
+#define AUDIO_VOLUME_MIN (0)
#define CFG_AUDIO_REPLAY_QUEUE_COUNT 4
-#define CFG_AUDIO_RECORD_PIPE_SIZE (8 * 1024)
-#define AUDIO_DEVICE_MP_CNT (4)
-#define AUDIO_DEVICE_DECODE_MP_BLOCK_SZ (4352 * 4)
-#define AUDIO_DEVICE_DECODE_MP_SZ ((AUDIO_DEVICE_DECODE_MP_BLOCK_SZ*2 + 4)*AUDIO_DEVICE_MP_CNT)
-
enum
{
@@ -115,19 +89,10 @@ enum
/* the preferred number and size of audio pipeline buffer for the audio device */
struct rt_audio_buf_info
{
- rt_uint32_t buffer_size; /* Preferred qty of buffers */
- rt_uint32_t buffer_count; /* Preferred size of the buffers */
-};
-struct rt_audio_buf_desc
-{
- rt_uint8_t *data_ptr;
- rt_size_t data_size;
-};
-
-struct rt_audio_frame
-{
- const void *data_ptr;
- rt_size_t data_size;
+ rt_uint8_t *buffer;
+ rt_uint16_t block_size;
+ rt_uint16_t block_count;
+ rt_uint32_t total_size;
};
struct rt_audio_device;
@@ -135,73 +100,68 @@ struct rt_audio_caps;
struct rt_audio_configure;
struct rt_audio_ops
{
- rt_err_t (*getcaps) (struct rt_audio_device *audio,struct rt_audio_caps *caps);
- rt_err_t (*configure) (struct rt_audio_device *audio,struct rt_audio_caps *caps);
-
- rt_err_t (*init) (struct rt_audio_device *audio);
- rt_err_t (*shutdown) (struct rt_audio_device *audio);
- rt_err_t (*start) (struct rt_audio_device *audio,int stream);
- rt_err_t (*stop) (struct rt_audio_device *audio,int stream);
- rt_err_t (*suspend) (struct rt_audio_device *audio,int stream);
- rt_err_t (*resume) (struct rt_audio_device *audio,int stream);
-
- rt_err_t (*control) (struct rt_audio_device *audio, int cmd, void *arg);
- rt_size_t (*transmit) (struct rt_audio_device *audio, const void *writeBuf,void *readBuf, rt_size_t size);
-
- //get page size of codec or private buffer's info
- void (*buffer_info) (struct rt_audio_device *audio,struct rt_audio_buf_info *info );
+ rt_err_t (*getcaps)(struct rt_audio_device *audio, struct rt_audio_caps *caps);
+ rt_err_t (*configure)(struct rt_audio_device *audio, struct rt_audio_caps *caps);
+ rt_err_t (*init)(struct rt_audio_device *audio);
+ rt_err_t (*start)(struct rt_audio_device *audio, int stream);
+ rt_err_t (*stop)(struct rt_audio_device *audio, int stream);
+ rt_size_t (*transmit)(struct rt_audio_device *audio, const void *writeBuf, void *readBuf, rt_size_t size);
+ /* get page size of codec or private buffer's info */
+ void (*buffer_info)(struct rt_audio_device *audio, struct rt_audio_buf_info *info);
};
-
struct rt_audio_configure
{
- rt_uint32_t channels;
-
- rt_uint32_t samplefmt;
rt_uint32_t samplerate;
- rt_uint32_t samplefmts;
+ rt_uint16_t channels;
+ rt_uint16_t samplebits;
};
struct rt_audio_caps
{
- int main_type;
- int sub_type;
+ int main_type;
+ int sub_type;
- union
- {
- rt_uint32_t mask;
- int value;
- struct rt_audio_configure config;
- }udata;
+ union
+ {
+ rt_uint32_t mask;
+ int value;
+ struct rt_audio_configure config;
+ } udata;
};
struct rt_audio_replay
{
- rt_bool_t activated;
+ struct rt_mempool *mp;
struct rt_data_queue queue;
+ struct rt_mutex lock;
+ struct rt_completion cmp;
+ struct rt_audio_buf_info buf_info;
+ rt_uint8_t *write_data;
+ rt_uint16_t write_index;
+ rt_uint16_t read_index;
+ rt_uint32_t pos;
+ rt_uint8_t event;
+ rt_bool_t activated;
};
struct rt_audio_record
{
+ struct rt_audio_pipe pipe;
rt_bool_t activated;
};
struct rt_audio_device
{
- struct rt_device parent;
+ struct rt_device parent;
struct rt_audio_ops *ops;
-
- struct rt_mempool mp;
-
struct rt_audio_replay *replay;
struct rt_audio_record *record;
};
-rt_err_t rt_audio_register (struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data);
-void rt_audio_tx_complete (struct rt_audio_device *audio,rt_uint8_t *pbuf);
-void rt_audio_rx_done (struct rt_audio_device *audio,rt_uint8_t *pbuf,rt_size_t len);
-rt_uint32_t rt_audio_format_to_bits (rt_uint32_t format);
-
+rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data);
+void rt_audio_tx_complete(struct rt_audio_device *audio);
+void rt_audio_rx_done(struct rt_audio_device *audio, rt_uint8_t *pbuf, rt_size_t len);
/* Device Control Commands */
#define CODEC_CMD_RESET 0
diff --git a/components/drivers/include/drivers/can.h b/components/drivers/include/drivers/can.h
index c61fb19eaa..d4fcc845b4 100644
--- a/components/drivers/include/drivers/can.h
+++ b/components/drivers/include/drivers/can.h
@@ -221,7 +221,7 @@ struct rt_can_msg
rt_uint32_t rsv : 1;
rt_uint32_t len : 8;
rt_uint32_t priv : 8;
- rt_uint32_t hdr : 8;
+ rt_int32_t hdr : 8;
rt_uint32_t reserved : 8;
rt_uint8_t data[8];
};
@@ -252,7 +252,7 @@ struct rt_can_rx_fifo
#define RT_CAN_EVENT_RX_IND 0x01 /* Rx indication */
#define RT_CAN_EVENT_TX_DONE 0x02 /* Tx complete */
-#define RT_CAN_EVENT_TX_FAIL 0x03 /* Tx complete */
+#define RT_CAN_EVENT_TX_FAIL 0x03 /* Tx fail */
#define RT_CAN_EVENT_RX_TIMEOUT 0x05 /* Rx timeout */
#define RT_CAN_EVENT_RXOF_IND 0x06 /* Rx overflow */
@@ -278,7 +278,7 @@ struct rt_can_ops
int (*recvmsg)(struct rt_can_device *can, void *buf, rt_uint32_t boxno);
};
-rt_err_t rt_hw_can_register(struct rt_can_device *can,
+rt_err_t rt_hw_can_register(struct rt_can_device *can,
const char *name,
const struct rt_can_ops *ops,
void *data);
diff --git a/components/drivers/include/drivers/crypto.h b/components/drivers/include/drivers/crypto.h
new file mode 100644
index 0000000000..5341d9ee48
--- /dev/null
+++ b/components/drivers/include/drivers/crypto.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-17 tyx the first version
+ */
+
+#ifndef __CRYPTO_H__
+#define __CRYPTO_H__
+
+#include <rtthread.h>
+#include <hwcrypto.h>
+#include <hw_symmetric.h>
+#include <hw_rng.h>
+#include <hw_hash.h>
+#include <hw_crc.h>
+#include <hw_gcm.h>
+#include <hw_bignum.h>
+
+#endif
diff --git a/components/drivers/include/drivers/i2c.h b/components/drivers/include/drivers/i2c.h
index e2a9e7d0b8..17d57288cd 100644
--- a/components/drivers/include/drivers/i2c.h
+++ b/components/drivers/include/drivers/i2c.h
@@ -60,11 +60,12 @@ struct rt_i2c_bus_device
void *priv;
};
-#ifdef RT_I2C_DEBUG
-#define i2c_dbg(fmt, ...) rt_kprintf(fmt, ##__VA_ARGS__)
-#else
-#define i2c_dbg(fmt, ...)
-#endif
+struct rt_i2c_client
+{
+ struct rt_device parent;
+ struct rt_i2c_bus_device *bus;
+ rt_uint16_t client_addr;
+};
rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus,
const char *bus_name);
diff --git a/components/drivers/include/drivers/mtd.h b/components/drivers/include/drivers/mtd.h
deleted file mode 100644
index fb7ea4389d..0000000000
--- a/components/drivers/include/drivers/mtd.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- 2018-09-10 heyuanjie87 first version
-
- */
-
-#ifndef __MTD_H__
-#define __MTD_H__
-
-#include <rtthread.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#define MTD_TYPE_NOR 1
-#define MTD_TYPE_NAND 2
-
- /**
- * MTD operation modes
- *
- * @MTD_OPM_PLACE_OOB: OOB data are placed at the given offset (default)
- * @MTD_OPM_AUTO_OOB: OOB data are automatically placed at the free areas
- * @MTD_OPM_RAW: data are transferred as-is, with no error correction;
- */
-enum mtd_opm
-{
- MTD_OPM_PLACE_OOB = 0,
- MTD_OPM_AUTO_OOB = 1,
- MTD_OPM_RAW = 2,
-};
-
-#ifndef loff_t
-typedef long loff_t;
-#endif
-
-struct mtd_oob_region
-{
- uint8_t offset;
- uint8_t length;
-};
-
-typedef struct mtd_info
-{
- struct rt_device parent;
-
- const struct mtd_ops *ops;
-
- uint16_t oob_size;
- uint16_t sector_size; /* Minimal writable flash unit size */
- uint32_t block_size:28; /* Erase size for the device */
- uint32_t type:4;
-
- size_t size; /* Total size of the MTD */
- loff_t offset; /* At which this MTD starts, from the beginning of the MEMORY */
- struct mtd_info *master;
-
- void *priv;
-}rt_mtd_t;
-
-struct mtd_io_desc
-{
- uint8_t mode; /* operation mode(enum mtd_opm) */
- uint8_t ooblen; /* number of oob bytes to write/read */
- uint8_t oobretlen; /* number of oob bytes written/read */
- uint8_t ooboffs; /* offset in the oob area */
- uint8_t *oobbuf;
-
- size_t datlen; /* number of data bytes to write/read */
- size_t datretlen; /* number of data bytes written/read */
- uint8_t *datbuf; /* if NULL only oob are read/written */
-};
-
-struct mtd_ops
-{
- int(*erase)(rt_mtd_t *mtd, loff_t addr, size_t len); /* return 0 if success */
- int(*read) (rt_mtd_t *mtd, loff_t from, struct mtd_io_desc *ops); /* return 0 if success */
- int(*write) (rt_mtd_t *mtd, loff_t to, struct mtd_io_desc *ops); /* return 0 if success */
- int(*isbad) (rt_mtd_t *mtd, uint32_t block); /* return 1 if bad, 0 not bad */
- int(*markbad) (rt_mtd_t *mtd, uint32_t block); /* return 0 if success */
-};
-
-struct mtd_part
-{
- const char *name; /* name of the MTD partion */
- loff_t offset; /* start addr of partion */
- size_t size; /* size of partion */
-};
-
-int rt_mtd_erase(rt_mtd_t *mtd, loff_t addr, size_t size);
-int rt_mtd_block_erase(rt_mtd_t *mtd, uint32_t block);
-int rt_mtd_read_oob(rt_mtd_t *mtd, loff_t from, struct mtd_io_desc *desc);
-int rt_mtd_write_oob(rt_mtd_t *mtd, loff_t to, struct mtd_io_desc *desc);
-int rt_mtd_read(rt_mtd_t *mtd, loff_t from, uint8_t *buf, size_t len);
-int rt_mtd_write(rt_mtd_t *mtd, loff_t to, const uint8_t *buf, size_t len);
-int rt_mtd_block_markbad(rt_mtd_t *mtd, uint32_t block);
-int rt_mtd_block_isbad(rt_mtd_t *mtd, uint32_t block);
-
-rt_mtd_t* rt_mtd_get(const char *name);
-int rt_mtd_register(rt_mtd_t *master, const struct mtd_part *parts, int np);
-
-#endif
diff --git a/components/drivers/include/drivers/mtd_nand.h b/components/drivers/include/drivers/mtd_nand.h
index 8afed000dd..f7675aede6 100644
--- a/components/drivers/include/drivers/mtd_nand.h
+++ b/components/drivers/include/drivers/mtd_nand.h
@@ -21,13 +21,13 @@
struct rt_mtd_nand_driver_ops;
#define RT_MTD_NAND_DEVICE(device) ((struct rt_mtd_nand_device*)(device))
-#define RT_MTD_EOK 0 /* NO error */
-#define RT_MTD_EECC 1 /* ECC error */
-#define RT_MTD_EBUSY 2 /* hardware busy */
-#define RT_MTD_EIO 3 /* generic IO issue */
-#define RT_MTD_ENOMEM 4 /* out of memory */
-#define RT_MTD_ESRC 5 /* source issue */
-#define RT_MTD_EECC_CORRECT 6 /* ECC error but correct */
+#define RT_MTD_EOK 0 /* NO error */
+#define RT_MTD_EECC 101 /* ECC error */
+#define RT_MTD_EBUSY 102 /* hardware busy */
+#define RT_MTD_EIO 103 /* generic IO issue */
+#define RT_MTD_ENOMEM 104 /* out of memory */
+#define RT_MTD_ESRC 105 /* source issue */
+#define RT_MTD_EECC_CORRECT 106 /* ECC error but correct */
struct rt_mtd_nand_device
{
@@ -41,77 +41,97 @@ struct rt_mtd_nand_device
rt_uint32_t pages_per_block; /* The number of page a block */
rt_uint16_t block_total;
+ /* Only be touched by driver */
rt_uint32_t block_start; /* The start of available block*/
rt_uint32_t block_end; /* The end of available block */
/* operations interface */
- const struct rt_mtd_nand_driver_ops* ops;
+ const struct rt_mtd_nand_driver_ops *ops;
};
struct rt_mtd_nand_driver_ops
{
- rt_err_t (*read_id) (struct rt_mtd_nand_device* device);
+ rt_err_t (*read_id)(struct rt_mtd_nand_device *device);
- rt_err_t (*read_page)(struct rt_mtd_nand_device* device,
+ rt_err_t (*read_page)(struct rt_mtd_nand_device *device,
rt_off_t page,
- rt_uint8_t* data, rt_uint32_t data_len,
- rt_uint8_t * spare, rt_uint32_t spare_len);
+ rt_uint8_t *data, rt_uint32_t data_len,
+ rt_uint8_t *spare, rt_uint32_t spare_len);
- rt_err_t (*write_page)(struct rt_mtd_nand_device * device,
+ rt_err_t (*write_page)(struct rt_mtd_nand_device *device,
rt_off_t page,
- const rt_uint8_t * data, rt_uint32_t data_len,
- const rt_uint8_t * spare, rt_uint32_t spare_len);
- rt_err_t (*move_page) (struct rt_mtd_nand_device *device, rt_off_t src_page, rt_off_t dst_page);
+ const rt_uint8_t *data, rt_uint32_t data_len,
+ const rt_uint8_t *spare, rt_uint32_t spare_len);
+ rt_err_t (*move_page)(struct rt_mtd_nand_device *device, rt_off_t src_page, rt_off_t dst_page);
- rt_err_t (*erase_block)(struct rt_mtd_nand_device* device, rt_uint32_t block);
- rt_err_t (*check_block)(struct rt_mtd_nand_device* device, rt_uint32_t block);
- rt_err_t (*mark_badblock)(struct rt_mtd_nand_device* device, rt_uint32_t block);
+ rt_err_t (*erase_block)(struct rt_mtd_nand_device *device, rt_uint32_t block);
+ rt_err_t (*check_block)(struct rt_mtd_nand_device *device, rt_uint32_t block);
+ rt_err_t (*mark_badblock)(struct rt_mtd_nand_device *device, rt_uint32_t block);
};
-rt_err_t rt_mtd_nand_register_device(const char* name, struct rt_mtd_nand_device* device);
+rt_err_t rt_mtd_nand_register_device(const char *name, struct rt_mtd_nand_device *device);
-rt_inline rt_uint32_t rt_mtd_nand_read_id(struct rt_mtd_nand_device* device)
+rt_inline rt_uint32_t rt_mtd_nand_read_id(struct rt_mtd_nand_device *device)
{
+ RT_ASSERT(device->ops->read_id);
return device->ops->read_id(device);
}
rt_inline rt_err_t rt_mtd_nand_read(
- struct rt_mtd_nand_device* device,
+ struct rt_mtd_nand_device *device,
rt_off_t page,
- rt_uint8_t* data, rt_uint32_t data_len,
- rt_uint8_t * spare, rt_uint32_t spare_len)
+ rt_uint8_t *data, rt_uint32_t data_len,
+ rt_uint8_t *spare, rt_uint32_t spare_len)
{
+ RT_ASSERT(device->ops->read_page);
return device->ops->read_page(device, page, data, data_len, spare, spare_len);
}
rt_inline rt_err_t rt_mtd_nand_write(
- struct rt_mtd_nand_device* device,
+ struct rt_mtd_nand_device *device,
rt_off_t page,
- const rt_uint8_t* data, rt_uint32_t data_len,
- const rt_uint8_t * spare, rt_uint32_t spare_len)
+ const rt_uint8_t *data, rt_uint32_t data_len,
+ const rt_uint8_t *spare, rt_uint32_t spare_len)
{
+ RT_ASSERT(device->ops->write_page);
return device->ops->write_page(device, page, data, data_len, spare, spare_len);
}
-rt_inline rt_err_t rt_mtd_nand_move_page(struct rt_mtd_nand_device* device,
- rt_off_t src_page, rt_off_t dst_page)
+rt_inline rt_err_t rt_mtd_nand_move_page(struct rt_mtd_nand_device *device,
+ rt_off_t src_page, rt_off_t dst_page)
{
+ RT_ASSERT(device->ops->move_page);
return device->ops->move_page(device, src_page, dst_page);
}
-rt_inline rt_err_t rt_mtd_nand_erase_block(struct rt_mtd_nand_device* device, rt_uint32_t block)
+rt_inline rt_err_t rt_mtd_nand_erase_block(struct rt_mtd_nand_device *device, rt_uint32_t block)
{
+ RT_ASSERT(device->ops->erase_block);
return device->ops->erase_block(device, block);
}
-rt_inline rt_err_t rt_mtd_nand_check_block(struct rt_mtd_nand_device* device, rt_uint32_t block)
+rt_inline rt_err_t rt_mtd_nand_check_block(struct rt_mtd_nand_device *device, rt_uint32_t block)
{
- return device->ops->check_block(device, block);
+ if (device->ops->check_block)
+ {
+ return device->ops->check_block(device, block);
+ }
+ else
+ {
+ return -RT_ENOSYS;
+ }
}
-rt_inline rt_err_t rt_mtd_nand_mark_badblock(struct rt_mtd_nand_device* device, rt_uint32_t block)
+rt_inline rt_err_t rt_mtd_nand_mark_badblock(struct rt_mtd_nand_device *device, rt_uint32_t block)
{
- return device->ops->mark_badblock(device, block);
+ if (device->ops->mark_badblock)
+ {
+ return device->ops->mark_badblock(device, block);
+ }
+ else
+ {
+ return -RT_ENOSYS;
+ }
}
#endif /* MTD_NAND_H_ */
diff --git a/components/drivers/include/drivers/mtdnand.h b/components/drivers/include/drivers/mtdnand.h
deleted file mode 100644
index 2e836cb2fb..0000000000
--- a/components/drivers/include/drivers/mtdnand.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- 2018-09-10 heyuanjie87 first version
-
- */
-
-#ifndef _MTDNAND_H_
-#define _MTDNAND_H_
-
-#include "mtd.h"
-
- /* Status bits */
-#define NAND_STATUS_FAIL 0x01
-#define NAND_STATUS_FAIL_N1 0x02
-#define NAND_STATUS_WP 0x80
-
-typedef enum
-{
- NAND_CMD_PAGE_RD, /* read data to chip's page buffer,do WaitBusy after this cmd in low driver */
- NAND_CMD_PAGE_WR0, /* write data to chip's page buffer */
- NAND_CMD_PAGE_WR1, /* do flash programe */
- NAND_CMD_BLK_ERASE, /* erase block */
- NAND_CMD_ECC_EN, /* enable gen HWECC */
- NAND_CMD_ECC_DIS /* disable gen HWECC */
-} nand_cmd_t;
-
-typedef enum
-{
- NAND_ECCM_NONE,
- NAND_ECCM_HW,
-} nand_eccmode_t;
-
-struct nand_chip;
-struct nand_ops;
-
-/**
-* struct nand_buffers - buffer structure for read/write
-* @ecccalc: buffer pointer for calculated ECC, size is oobsize.
-* @ecccode: buffer pointer for ECC read from flash, size is oobsize.
-*
-*/
-struct nand_buffers
-{
- uint8_t *ecccalc;
- uint8_t *ecccode;
-};
-
-struct nand_ecc
-{
- uint8_t mode; /* nand_eccmode_t */
- uint8_t bytes; /* gen ecc bytes per ecc step(usually 3) */
- uint16_t stepsize:12; /* min 256 */
- uint16_t _step:4; /* */
-
- /* driver must set the two interface if HWECC */
- void (*calculate)(struct nand_chip *chip, const uint8_t *dat, uint8_t *ecc_code);
- /* return max bit flips if can't correct,return -1 ECC is error(0 success) */
- int(*correct)(struct nand_chip *chip, uint8_t *dat, uint8_t *read_ecc, uint8_t *calc_ecc);
- /* ignore if NONECC */
- const struct mtd_oob_region *layout;
-};
-
-typedef struct nand_chip
-{
- rt_mtd_t parent;
-
- /* driver must init these */
- const struct nand_ops *ops;
- struct nand_ecc ecc;
- const struct mtd_oob_region *freelayout;
-
- /* driver do not touch */
- struct nand_buffers buffers;
- uint8_t *oob_poi;
- uint8_t *pagebuf;
- uint32_t size;
- uint16_t oobsize;
- uint8_t pages_pb;
- uint16_t page_size;
- int(*read_page)(struct nand_chip *chip, uint8_t *buf, int oob_required, int page);
- int(*write_page)(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page);
-}rt_nand_t;
-
-struct nand_ops
-{
- int(*cmdfunc)(rt_nand_t *nand, int cmd, int page, int offset); /* send nand operation cmd, return Status bits(0 success),
- if nand is busy please wait in low driver */
- int(*read_buf)(rt_nand_t *nand, uint8_t *buf, int len); /* read data from nand chip's page buffer */
- int(*write_buf)(rt_nand_t *nand, const uint8_t *buf, int len);/* write data to nand chip's page buffer */
- int(*isbad)(rt_nand_t *nand, uint32_t blk); /* if NULL OOB[0] used as bad mark(not 0xff is bad) */
- int(*markbad)(rt_nand_t *nand, uint32_t blk); /* if NULL OOB[0] used as bad mark(set to 0x00) */
-};
-
-int rt_mtd_nand_init(rt_nand_t *nand, int blk_size, int page_size, int oob_size);
-
-#endif /* MTD_NAND_H_ */
diff --git a/components/drivers/include/drivers/mtdnor.h b/components/drivers/include/drivers/mtdnor.h
deleted file mode 100644
index ccb7466b4b..0000000000
--- a/components/drivers/include/drivers/mtdnor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- 2018-09-10 heyuanjie87 first version
-
- */
-
-#ifndef __MTDNOR_H__
-#define __MTDNOR_H__
-
-#include <drivers/mtd.h>
-
-struct nor_ops;
-
-typedef struct
-{
- rt_mtd_t parent;
-
- const struct nor_ops *ops; /* operations interface */
-}rt_nor_t;
-
-struct nor_ops
-{
- int (*erase)(rt_nor_t *nor, loff_t addr, size_t len); /* return success erased len or error code */
- int (*read)(rt_nor_t *nor, loff_t addr, uint8_t *buf, size_t len); /* return success data size or error code */
- int (*write)(rt_nor_t *nor, loff_t addr, const uint8_t *buf, size_t len); /* return success data size or error code */
-};
-
-int rt_mtd_nor_init(rt_nor_t *nor, int blksize);
-
-#endif
diff --git a/components/drivers/include/drivers/pm.h b/components/drivers/include/drivers/pm.h
index e35b21cd48..dd5875aa1d 100644
--- a/components/drivers/include/drivers/pm.h
+++ b/components/drivers/include/drivers/pm.h
@@ -86,8 +86,8 @@ struct rt_pm;
*/
struct rt_pm_ops
{
- void (*sleep)(struct rt_pm *pm, uint8_t mode);
- void (*run)(struct rt_pm *pm, uint8_t mode);
+ void (*sleep)(struct rt_pm *pm, rt_uint8_t mode);
+ void (*run)(struct rt_pm *pm, rt_uint8_t mode);
void (*timer_start)(struct rt_pm *pm, rt_uint32_t timeout);
void (*timer_stop)(struct rt_pm *pm);
rt_tick_t (*timer_get_tick)(struct rt_pm *pm);
@@ -95,9 +95,9 @@ struct rt_pm_ops
struct rt_device_pm_ops
{
- int (*suspend)(const struct rt_device *device, uint8_t mode);
- void (*resume)(const struct rt_device *device, uint8_t mode);
- int (*frequency_change)(const struct rt_device *device, uint8_t mode);
+ int (*suspend)(const struct rt_device *device, rt_uint8_t mode);
+ void (*resume)(const struct rt_device *device, rt_uint8_t mode);
+ int (*frequency_change)(const struct rt_device *device, rt_uint8_t mode);
};
struct rt_device_pm
@@ -137,22 +137,22 @@ enum
struct rt_pm_notify
{
- void (*notify)(uint8_t event, uint8_t mode, void *data);
+ void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data);
void *data;
};
-void rt_pm_request(uint8_t sleep_mode);
-void rt_pm_release(uint8_t sleep_mode);
-int rt_pm_run_enter(uint8_t run_mode);
+void rt_pm_request(rt_uint8_t sleep_mode);
+void rt_pm_release(rt_uint8_t sleep_mode);
+int rt_pm_run_enter(rt_uint8_t run_mode);
void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops);
void rt_pm_device_unregister(struct rt_device *device);
-void rt_pm_notify_set(void (*notify)(uint8_t event, uint8_t mode, void *data), void *data);
-void rt_pm_default_set(uint8_t sleep_mode);
+void rt_pm_notify_set(void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data), void *data);
+void rt_pm_default_set(rt_uint8_t sleep_mode);
void rt_system_pm_init(const struct rt_pm_ops *ops,
- uint8_t timer_mask,
+ rt_uint8_t timer_mask,
void *user_data);
#endif /* __PM_H__ */
diff --git a/components/drivers/include/drivers/pulse_encoder.h b/components/drivers/include/drivers/pulse_encoder.h
new file mode 100644
index 0000000000..0c7df04cd6
--- /dev/null
+++ b/components/drivers/include/drivers/pulse_encoder.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-08-08 balanceTWK the first version
+ */
+
+#ifndef __PULSE_ENCODER_H__
+#define __PULSE_ENCODER_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* pulse_encoder control command */
+#define PULSE_ENCODER_CMD_GET_TYPE (128 + 0) /* get a pulse_encoder type information */
+#define PULSE_ENCODER_CMD_ENABLE (128 + 1) /* enable pulse_encoder */
+#define PULSE_ENCODER_CMD_DISABLE (128 + 2) /* disable pulse_encoder */
+#define PULSE_ENCODER_CMD_CLEAR_COUNT (128 + 3) /* clear pulse_encoder count */
+
+/* pulse_encoder type */
+enum rt_pulse_encoder_type
+{
+ UNKNOWN_PULSE_ENCODER_TYPE = 0x00, /* Unknown pulse_encoder type */
+ SINGLE_PHASE_PULSE_ENCODER, /* single phase pulse_encoder */
+ AB_PHASE_PULSE_ENCODER /* two phase pulse_encoder */
+};
+
+struct rt_pulse_encoder_device;
+
+struct rt_pulse_encoder_ops
+{
+ rt_err_t (*init)(struct rt_pulse_encoder_device *pulse_encoder);
+ rt_int32_t (*get_count)(struct rt_pulse_encoder_device *pulse_encoder);
+ rt_err_t (*clear_count)(struct rt_pulse_encoder_device *pulse_encoder);
+ rt_err_t (*control)(struct rt_pulse_encoder_device *pulse_encoder, rt_uint32_t cmd, void *args);
+};
+
+struct rt_pulse_encoder_device
+{
+ struct rt_device parent;
+ const struct rt_pulse_encoder_ops *ops;
+ enum rt_pulse_encoder_type type;
+};
+
+rt_err_t rt_device_pulse_encoder_register(struct rt_pulse_encoder_device *pulse_encoder, const char *name, void *user_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PULSE_ENCODER_H__ */
diff --git a/components/drivers/include/drivers/rt_inputcapture.h b/components/drivers/include/drivers/rt_inputcapture.h
new file mode 100644
index 0000000000..0cadf6444c
--- /dev/null
+++ b/components/drivers/include/drivers/rt_inputcapture.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-08-13 balanceTWK first version.
+ */
+
+#ifndef __RT_INPUT_CAPTURE_H__
+#define __RT_INPUT_CAPTURE_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* capture control command */
+#define INPUTCAPTURE_CMD_CLEAR_BUF (128 + 0) /* clear capture buf */
+#define INPUTCAPTURE_CMD_SET_WATERMARK (128 + 1) /* Set the callback threshold */
+
+struct rt_inputcapture_data
+{
+ rt_uint32_t pulsewidth_us;
+ rt_bool_t is_high;
+};
+
+struct rt_inputcapture_device
+{
+ struct rt_device parent;
+
+ const struct rt_inputcapture_ops *ops;
+ struct rt_ringbuffer *ringbuff;
+ rt_size_t watermark;
+};
+
+/**
+ * capture operators
+ */
+struct rt_inputcapture_ops
+{
+ rt_err_t (*init)(struct rt_inputcapture_device *inputcapture);
+ rt_err_t (*open)(struct rt_inputcapture_device *inputcapture);
+ rt_err_t (*close)(struct rt_inputcapture_device *inputcapture);
+ rt_err_t (*get_pulsewidth)(struct rt_inputcapture_device *inputcapture, rt_uint32_t *pulsewidth_us);
+};
+
+void rt_hw_capture_isr(struct rt_inputcapture_device *inputcapture, rt_bool_t level);
+
+rt_err_t rt_device_inputcapture_register(struct rt_inputcapture_device *inputcapture,
+ const char *name,
+ void *data);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RT_INPUT_CAPTURE_H__ */
diff --git a/components/drivers/include/ipc/workqueue.h b/components/drivers/include/ipc/workqueue.h
index 354a30c04e..23e256c420 100644
--- a/components/drivers/include/ipc/workqueue.h
+++ b/components/drivers/include/ipc/workqueue.h
@@ -43,13 +43,13 @@ struct rt_work
void *work_data;
rt_uint16_t flags;
rt_uint16_t type;
+ struct rt_timer timer;
+ struct rt_workqueue *workqueue;
};
struct rt_delayed_work
{
struct rt_work work;
- struct rt_timer timer;
- struct rt_workqueue *workqueue;
};
#ifdef RT_USING_HEAP
@@ -74,6 +74,7 @@ rt_inline void rt_work_init(struct rt_work *work, void (*work_func)(struct rt_wo
rt_list_init(&(work->list));
work->work_func = work_func;
work->work_data = work_data;
+ work->workqueue = RT_NULL;
work->flags = 0;
work->type = 0;
}
@@ -81,6 +82,7 @@ rt_inline void rt_work_init(struct rt_work *work, void (*work_func)(struct rt_wo
void rt_delayed_work_init(struct rt_delayed_work *work, void (*work_func)(struct rt_work *work,
void *work_data), void *work_data);
+int rt_work_sys_workqueue_init(void);
#endif
#endif
diff --git a/components/drivers/include/rtdevice.h b/components/drivers/include/rtdevice.h
index d59b40cc47..623c085430 100644
--- a/components/drivers/include/rtdevice.h
+++ b/components/drivers/include/rtdevice.h
@@ -122,6 +122,18 @@ extern "C" {
#include "drivers/mtdnand.h"
#endif
+#ifdef RT_USING_HWCRYPTO
+#include "drivers/crypto.h"
+#endif
+
+#ifdef RT_USING_PULSE_ENCODER
+#include "drivers/pulse_encoder.h"
+#endif
+
+#ifdef RT_USING_INPUT_CAPTURE
+#include "drivers/rt_inputcapture.h"
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/components/drivers/misc/SConscript b/components/drivers/misc/SConscript
index c45ba524c5..8a9fdb5eb9 100644
--- a/components/drivers/misc/SConscript
+++ b/components/drivers/misc/SConscript
@@ -13,6 +13,12 @@ if GetDepend(['RT_USING_ADC']):
if GetDepend(['RT_USING_PWM']):
src = src + ['rt_drv_pwm.c']
+
+if GetDepend(['RT_USING_PULSE_ENCODER']):
+ src = src + ['pulse_encoder.c']
+
+if GetDepend(['RT_USING_INPUT_CAPTURE']):
+ src = src + ['rt_inputcapture.c']
if len(src):
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
diff --git a/components/drivers/misc/pulse_encoder.c b/components/drivers/misc/pulse_encoder.c
new file mode 100644
index 0000000000..3145c24675
--- /dev/null
+++ b/components/drivers/misc/pulse_encoder.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-08-08 balanceTWK the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+static rt_err_t rt_pulse_encoder_init(struct rt_device *dev)
+{
+ struct rt_pulse_encoder_device *pulse_encoder;
+
+ pulse_encoder = (struct rt_pulse_encoder_device *)dev;
+ if (pulse_encoder->ops->init)
+ {
+ return pulse_encoder->ops->init(pulse_encoder);
+ }
+ else
+ {
+ return -RT_ENOSYS;
+ }
+}
+
+static rt_err_t rt_pulse_encoder_open(struct rt_device *dev, rt_uint16_t oflag)
+{
+ struct rt_pulse_encoder_device *pulse_encoder;
+
+ pulse_encoder = (struct rt_pulse_encoder_device *)dev;
+ if (pulse_encoder->ops->control)
+ {
+ return pulse_encoder->ops->control(pulse_encoder, PULSE_ENCODER_CMD_ENABLE, RT_NULL);
+ }
+ else
+ {
+ return -RT_ENOSYS;
+ }
+}
+
+static rt_err_t rt_pulse_encoder_close(struct rt_device *dev)
+{
+ struct rt_pulse_encoder_device *pulse_encoder;
+
+ pulse_encoder = (struct rt_pulse_encoder_device *)dev;
+ if (pulse_encoder->ops->control)
+ {
+ return pulse_encoder->ops->control(pulse_encoder, PULSE_ENCODER_CMD_DISABLE, RT_NULL);
+ }
+ else
+ {
+ return -RT_ENOSYS;
+ }
+}
+
+static rt_size_t rt_pulse_encoder_read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+ struct rt_pulse_encoder_device *pulse_encoder;
+
+ pulse_encoder = (struct rt_pulse_encoder_device *)dev;
+ if (pulse_encoder->ops->get_count)
+ {
+ *(rt_int32_t *)buffer = pulse_encoder->ops->get_count(pulse_encoder);
+ }
+ return 1;
+}
+
+static rt_err_t rt_pulse_encoder_control(struct rt_device *dev, int cmd, void *args)
+{
+ rt_err_t result;
+ struct rt_pulse_encoder_device *pulse_encoder;
+
+ result = RT_EOK;
+ pulse_encoder = (struct rt_pulse_encoder_device *)dev;
+ switch (cmd)
+ {
+ case PULSE_ENCODER_CMD_CLEAR_COUNT:
+ result = pulse_encoder->ops->clear_count(pulse_encoder);
+ break;
+ case PULSE_ENCODER_CMD_GET_TYPE:
+ *(enum rt_pulse_encoder_type *)args = pulse_encoder->type;
+ break;
+ case PULSE_ENCODER_CMD_ENABLE:
+ case PULSE_ENCODER_CMD_DISABLE:
+ result = pulse_encoder->ops->control(pulse_encoder, cmd, args);
+ break;
+ default:
+ result = -RT_ENOSYS;
+ break;
+ }
+
+ return result;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops pulse_encoder_ops =
+{
+ rt_pulse_encoder_init,
+ rt_pulse_encoder_open,
+ rt_pulse_encoder_close,
+ rt_pulse_encoder_read,
+ RT_NULL,
+ rt_pulse_encoder_control
+};
+#endif
+
+rt_err_t rt_device_pulse_encoder_register(struct rt_pulse_encoder_device *pulse_encoder, const char *name, void *user_data)
+{
+ struct rt_device *device;
+
+ RT_ASSERT(pulse_encoder != RT_NULL);
+ RT_ASSERT(pulse_encoder->ops != RT_NULL);
+
+ device = &(pulse_encoder->parent);
+
+ device->type = RT_Device_Class_Miscellaneous;
+ device->rx_indicate = RT_NULL;
+ device->tx_complete = RT_NULL;
+
+#ifdef RT_USING_DEVICE_OPS
+ device->ops = &pulse_encoder_ops;
+#else
+ device->init = rt_pulse_encoder_init;
+ device->open = rt_pulse_encoder_open;
+ device->close = rt_pulse_encoder_close;
+ device->read = rt_pulse_encoder_read;
+ device->write = RT_NULL;
+ device->control = rt_pulse_encoder_control;
+#endif
+ device->user_data = user_data;
+
+ return rt_device_register(device, name, RT_DEVICE_FLAG_RDONLY | RT_DEVICE_FLAG_STANDALONE);
+}
diff --git a/components/drivers/misc/rt_drv_pwm.c b/components/drivers/misc/rt_drv_pwm.c
index 2b7986b4d8..97d38d51b3 100644
--- a/components/drivers/misc/rt_drv_pwm.c
+++ b/components/drivers/misc/rt_drv_pwm.c
@@ -259,7 +259,7 @@ static int pwm_set(int argc, char **argv)
_exit:
return result;
}
-MSH_CMD_EXPORT(pwm_set, pwm_set 1 100 50);
+MSH_CMD_EXPORT(pwm_set, pwm_set pwm1 1 100 50);
#endif /* FINSH_USING_MSH */
#endif /* RT_USING_FINSH */
diff --git a/components/drivers/misc/rt_inputcapture.c b/components/drivers/misc/rt_inputcapture.c
new file mode 100644
index 0000000000..d1886186d7
--- /dev/null
+++ b/components/drivers/misc/rt_inputcapture.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-08-13 balanceTWK the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <rtdbg.h>
+
+static rt_err_t rt_inputcapture_init(struct rt_device *dev)
+{
+ rt_err_t ret;
+ struct rt_inputcapture_device *inputcapture;
+
+ RT_ASSERT(dev != RT_NULL);
+
+ ret = RT_EOK;
+ inputcapture = (struct rt_inputcapture_device *)dev;
+ inputcapture->watermark = RT_INPUT_CAPTURE_RB_SIZE / 2;
+ if (inputcapture->ops->init)
+ {
+ ret = inputcapture->ops->init(inputcapture);
+ }
+
+ return ret;
+}
+
+static rt_err_t rt_inputcapture_open(struct rt_device *dev, rt_uint16_t oflag)
+{
+ rt_err_t ret;
+ struct rt_inputcapture_device *inputcapture;
+
+ RT_ASSERT(dev != RT_NULL);
+
+ ret = RT_EOK;
+ inputcapture = (struct rt_inputcapture_device *)dev;
+ if (inputcapture->ringbuff == RT_NULL)
+ {
+ inputcapture->ringbuff = rt_ringbuffer_create(sizeof(struct rt_inputcapture_data) * RT_INPUT_CAPTURE_RB_SIZE);
+ }
+ if (inputcapture->ops->open)
+ {
+ ret = inputcapture->ops->open(inputcapture);
+ }
+
+ return ret;
+}
+
+static rt_err_t rt_inputcapture_close(struct rt_device *dev)
+{
+ rt_err_t ret;
+ struct rt_inputcapture_device *inputcapture;
+
+ RT_ASSERT(dev != RT_NULL);
+
+ ret = -RT_ERROR;
+ inputcapture = (struct rt_inputcapture_device *)dev;
+
+ if (inputcapture->ops->close)
+ {
+ ret = inputcapture->ops->close(inputcapture);
+ }
+
+ if (ret != RT_EOK)
+ {
+ return ret;
+ }
+
+ if (inputcapture->ringbuff)
+ {
+ rt_ringbuffer_destroy(inputcapture->ringbuff);
+ inputcapture->ringbuff = RT_NULL;
+ }
+ return ret;
+}
+
+static rt_size_t rt_inputcapture_read(struct rt_device *dev,
+ rt_off_t pos,
+ void *buffer,
+ rt_size_t size)
+{
+ rt_size_t receive_size;
+ struct rt_inputcapture_device *inputcapture;
+
+ RT_ASSERT(dev != RT_NULL);
+
+ inputcapture = (struct rt_inputcapture_device *)dev;
+ receive_size = rt_ringbuffer_get(inputcapture->ringbuff, (rt_uint8_t *)buffer, sizeof(struct rt_inputcapture_data) * size);
+
+ return receive_size / sizeof(struct rt_inputcapture_data);
+}
+
+static rt_err_t rt_inputcapture_control(struct rt_device *dev, int cmd, void *args)
+{
+ rt_err_t result;
+ struct rt_inputcapture_device *inputcapture;
+
+ RT_ASSERT(dev != RT_NULL);
+
+ result = RT_EOK;
+ inputcapture = (struct rt_inputcapture_device *)dev;
+ switch (cmd)
+ {
+ case INPUTCAPTURE_CMD_CLEAR_BUF:
+ if (inputcapture->ringbuff)
+ {
+ rt_ringbuffer_reset(inputcapture->ringbuff);
+ }
+ break;
+ case INPUTCAPTURE_CMD_SET_WATERMARK:
+ inputcapture->watermark = *(rt_size_t *)args;
+ break;
+ default:
+ result = -RT_ENOSYS;
+ break;
+ }
+
+ return result;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops inputcapture_ops =
+{
+ rt_inputcapture_init,
+ rt_inputcapture_open,
+ rt_inputcapture_close,
+ rt_inputcapture_read,
+ RT_NULL,
+ rt_inputcapture_control
+};
+#endif
+
+rt_err_t rt_device_inputcapture_register(struct rt_inputcapture_device *inputcapture, const char *name, void *user_data)
+{
+ struct rt_device *device;
+
+ RT_ASSERT(inputcapture != RT_NULL);
+ RT_ASSERT(inputcapture->ops != RT_NULL);
+ RT_ASSERT(inputcapture->ops->get_pulsewidth != RT_NULL);
+
+ device = &(inputcapture->parent);
+
+ device->type = RT_Device_Class_Miscellaneous;
+ device->rx_indicate = RT_NULL;
+ device->tx_complete = RT_NULL;
+ inputcapture->ringbuff = RT_NULL;
+
+#ifdef RT_USING_DEVICE_OPS
+ device->ops = &inputcapture_ops;
+#else
+ device->init = rt_inputcapture_init;
+ device->open = rt_inputcapture_open;
+ device->close = rt_inputcapture_close;
+ device->read = rt_inputcapture_read;
+ device->write = RT_NULL;
+ device->control = rt_inputcapture_control;
+#endif
+ device->user_data = user_data;
+
+ return rt_device_register(device, name, RT_DEVICE_FLAG_RDONLY | RT_DEVICE_FLAG_STANDALONE);
+}
+
+/**
+ * This function is ISR for inputcapture interrupt.
+ * level: RT_TRUE denotes high level pulse, and RT_FALSE denotes low level pulse.
+ */
+void rt_hw_inputcapture_isr(struct rt_inputcapture_device *inputcapture, rt_bool_t level)
+{
+ struct rt_inputcapture_data data;
+ rt_size_t receive_size;
+ if (inputcapture->ops->get_pulsewidth(inputcapture, &data.pulsewidth_us) != RT_EOK)
+ {
+ return;
+ }
+
+ data.is_high = level;
+ if (rt_ringbuffer_put(inputcapture->ringbuff, (rt_uint8_t *)&data, sizeof(struct rt_inputcapture_data)) == 0)
+ {
+ LOG_W("inputcapture ringbuffer doesn't have enough space.");
+ }
+
+ receive_size = rt_ringbuffer_data_len(inputcapture->ringbuff) / sizeof(struct rt_inputcapture_data);
+
+ if (receive_size >= inputcapture->watermark)
+ {
+ /* indicate to upper layer application */
+ if (inputcapture->parent.rx_indicate != RT_NULL)
+ inputcapture->parent.rx_indicate(&inputcapture->parent, receive_size);
+ }
+}
diff --git a/components/drivers/mtd/SConscript b/components/drivers/mtd/SConscript
index 462c38194c..6f86656187 100644
--- a/components/drivers/mtd/SConscript
+++ b/components/drivers/mtd/SConscript
@@ -1,5 +1,3 @@
-Import('RTT_ROOT')
-Import('rtconfig')
from building import *
cwd = GetCurrentDir()
@@ -9,17 +7,6 @@ depend = []
CPPPATH = [cwd + '/../include']
group = []
-if GetDepend(['RT_USING_MTD']):
- src += ['mtd.c']
- depend += ['RT_USING_MTD']
-
- if GetDepend(['MTD_USING_NOR']):
- src += ['mtdnor.c']
- depend += ['MTD_USING_NOR']
- if GetDepend(['MTD_USING_NAND']):
- src += ['mtdnand.c']
- depend += ['MTD_USING_NAND']
-
if GetDepend(['RT_USING_MTD_NOR']):
src += ['mtd_nor.c']
depend += ['RT_USING_MTD_NOR']
@@ -31,4 +18,4 @@ if GetDepend(['RT_USING_MTD_NAND']):
if src:
group = DefineGroup('DeviceDrivers', src, depend = depend, CPPPATH = CPPPATH)
-Return('group') \ No newline at end of file
+Return('group')
diff --git a/components/drivers/mtd/mtd.c b/components/drivers/mtd/mtd.c
deleted file mode 100644
index 3e7b4f2b54..0000000000
--- a/components/drivers/mtd/mtd.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- 2018-09-10 heyuanjie87 first version
-
- */
-
-#include <drivers/mtd.h>
-
-static rt_mtd_t* mtd_part_alloc(rt_mtd_t *master, const struct mtd_part *part)
-{
- rt_mtd_t *slave;
-
- slave = rt_malloc(sizeof(rt_mtd_t));
- if (slave == RT_NULL)
- goto out;
-
- slave->master = master;
-
- *slave = *master;
- slave->size = part->size;
- slave->offset = part->offset;
-
-out:
-
- return slave;
-}
-
-rt_mtd_t* rt_mtd_get(const char *name)
-{
- rt_mtd_t *mtd;
-
- mtd = (rt_mtd_t *)rt_device_find(name);
- if (mtd == RT_NULL)
- return RT_NULL;
-
- if (mtd->parent.type != RT_Device_Class_MTD)
- return RT_NULL;
-
- return mtd;
-}
-
-/*
- * Register MTD driver
- *
- * @parts partion description
- * @np number of partitions
- * @return number of unregistered partitions
- *
-*/
-int rt_mtd_register(rt_mtd_t *master, const struct mtd_part *parts, int np)
-{
- int ret;
- rt_mtd_t *slave;
-
- master->master = master;
- master->parent.type = RT_Device_Class_MTD;
-
- if (np > 0)
- {
- master->offset = parts->offset;
- master->size = parts->size;
-
- ret = rt_device_register((rt_device_t)master, parts->name, 0);
- if (ret != 0)
- goto _out;
-
- np --;
- parts ++;
- }
-
- while (np > 0)
- {
- slave = mtd_part_alloc(master, parts);
- if (!slave)
- break;
- ret = rt_device_register((rt_device_t)slave, parts->name, 0);
- if (ret)
- break;
- parts ++;
- np --;
- }
-
-_out:
- return np;
-}
-
-int rt_mtd_block_erase(rt_mtd_t *mtd, uint32_t block)
-{
- uint32_t total_blks;
- loff_t addr;
-
- total_blks = mtd->size/mtd->block_size;
- if (block >= total_blks)
- return -EINVAL;
- addr = mtd->offset + mtd->block_size * block;
-
- return mtd->ops->erase(mtd->master, addr, mtd->block_size);
-}
-
-int rt_mtd_block_isbad(rt_mtd_t *mtd, uint32_t block)
-{
- uint32_t total_blks, offset_blk;
-
- if (!mtd->ops->isbad)
- return 0;
-
- total_blks = mtd->size / mtd->block_size;
- if (block >= total_blks)
- return -EINVAL;
- offset_blk = mtd->offset / mtd->block_size;
-
- return mtd->ops->isbad(mtd->master, block + offset_blk);
-}
-
-int rt_mtd_block_markbad(rt_mtd_t *mtd, uint32_t block)
-{
- uint32_t total_blks, offset_blk;
-
- if (!mtd->ops->markbad)
- return -EOPNOTSUPP;
-
- total_blks = mtd->size / mtd->block_size;
- if (block >= total_blks)
- return -EINVAL;
- offset_blk = mtd->offset / mtd->block_size;
-
- return mtd->ops->markbad(mtd->master, block + offset_blk);
-}
-
-int rt_mtd_erase(rt_mtd_t *mtd, loff_t addr, size_t size)
-{
- if (addr > mtd->size || (addr + size) > mtd->size)
- return -EINVAL;
- addr += mtd->offset;
-
- return mtd->ops->erase(mtd->master, addr, size);
-}
-
-/*
-* Read data only
-*
-* @from offset to read from
-* @return success size or error code
-*/
-int rt_mtd_read(rt_mtd_t *mtd, loff_t from, uint8_t *buf, size_t len)
-{
- int ret;
- struct mtd_io_desc desc = {0};
-
- if (from < 0 || from >= (loff_t)mtd->size || len > mtd->size - from)
- return -EINVAL;
- if (!len)
- return 0;
-
- desc.datbuf = buf;
- desc.datlen = len;
- ret = mtd->ops->read(mtd->master, from + mtd->offset, &desc);
- if (ret)
- return ret;
-
- return desc.datretlen;
-}
-
-/**
-* Write data only
-*
-* @to offset to write from
-* @return success size or error code
-*/
-int rt_mtd_write(rt_mtd_t *mtd, loff_t to, const uint8_t *buf, size_t len)
-{
- int ret;
- struct mtd_io_desc desc = {0};
-
- if (to < 0 || to >= (loff_t)mtd->size || len > mtd->size - to)
- return -EINVAL;
- if (!mtd->ops->write)
- return -EROFS;
- if (!len)
- return 0;
-
- desc.datbuf = (uint8_t*)buf;
- desc.datlen = len;
- ret = mtd->ops->write(mtd->master, to + mtd->offset, &desc);
- if (ret)
- return ret;
-
- return desc.datretlen;
-}
-
-/**
-* Read data and/or out-of-band
-*
-* @from offset to read from
-* @desc sector operation description structure
-* @return error code, 0 success
-*/
-int rt_mtd_read_oob(rt_mtd_t *mtd, loff_t from, struct mtd_io_desc *desc)
-{
- desc->datretlen = 0;
- desc->oobretlen = 0;
-
- if (from < 0 || from >= (loff_t)mtd->size)
- return -EINVAL;
-
- if (desc->datbuf && (desc->datlen > (mtd->size - from)))
- return -EINVAL;
-
- return mtd->ops->read(mtd->master, from + mtd->offset, desc);
-}
-
-/**
-* Write data and/or out-of-band
-*
-* @to offset to read from
-* @desc sector operation description structure
-* @return error code, 0 success
-*/
-int rt_mtd_write_oob(rt_mtd_t *mtd, loff_t to, struct mtd_io_desc *desc)
-{
- desc->datretlen = 0;
- desc->oobretlen = 0;
-
- if (to < 0 || to >= (loff_t)mtd->size)
- return -EINVAL;
-
- if (desc->datbuf && (desc->datlen >(mtd->size - to)))
- return -EINVAL;
-
- return mtd->ops->write(mtd->master, to + mtd->offset, desc);
-}
diff --git a/components/drivers/mtd/mtd_nand.c b/components/drivers/mtd/mtd_nand.c
index 3e4582ceaf..ae5aa9c172 100644
--- a/components/drivers/mtd/mtd_nand.c
+++ b/components/drivers/mtd/mtd_nand.c
@@ -56,7 +56,7 @@ static rt_err_t _mtd_control(rt_device_t dev, int cmd, void *args)
}
#ifdef RT_USING_DEVICE_OPS
-const static struct rt_device_ops mtd_nand_ops =
+const static struct rt_device_ops mtd_nand_ops =
{
_mtd_init,
_mtd_open,
@@ -78,7 +78,7 @@ rt_err_t rt_mtd_nand_register_device(const char *name,
/* set device class and generic device interface */
dev->type = RT_Device_Class_MTD;
#ifdef RT_USING_DEVICE_OPS
- dev->ops = &mtd_nand_ops;
+ dev->ops = &mtd_nand_ops;
#else
dev->init = _mtd_init;
dev->open = _mtd_open;
@@ -101,188 +101,262 @@ rt_err_t rt_mtd_nand_register_device(const char *name,
static void mtd_dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
{
- unsigned char *buf = (unsigned char*)ptr;
- int i, j;
- for (i=0; i<buflen; i+=16)
- {
- rt_kprintf("%06x: ", i);
- for (j=0; j<16; j++)
- if (i+j < buflen)
- rt_kprintf("%02x ", buf[i+j]);
- else
- rt_kprintf(" ");
- rt_kprintf(" ");
- for (j=0; j<16; j++)
- if (i+j < buflen)
- rt_kprintf("%c", __is_print(buf[i+j]) ? buf[i+j] : '.');
- rt_kprintf("\n");
- }
+ unsigned char *buf = (unsigned char *)ptr;
+ int i, j;
+ for (i = 0; i < buflen; i += 16)
+ {
+ rt_kprintf("%06x: ", i);
+ for (j = 0; j < 16; j++)
+ if (i + j < buflen)
+ rt_kprintf("%02x ", buf[i + j]);
+ else
+ rt_kprintf(" ");
+ rt_kprintf(" ");
+ for (j = 0; j < 16; j++)
+ if (i + j < buflen)
+ rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
+ rt_kprintf("\n");
+ }
}
-int mtd_nandid(const char* name)
+int mtd_nandid(const char *name)
{
- struct rt_mtd_nand_device *nand;
- nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
- if (nand == RT_NULL)
- {
- rt_kprintf("no nand device found!\n");
- return -RT_ERROR;
- }
+ struct rt_mtd_nand_device *nand;
+ nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
+ if (nand == RT_NULL)
+ {
+ rt_kprintf("no nand device found!\n");
+ return -RT_ERROR;
+ }
- return rt_mtd_nand_read_id(nand);
+ return rt_mtd_nand_read_id(nand);
}
-FINSH_FUNCTION_EXPORT_ALIAS(mtd_nandid, nand_id, read ID - nandid(name));
-int mtd_nand_read(const char* name, int block, int page)
+int mtd_nand_read(const char *name, int block, int page)
{
- rt_err_t result;
- rt_uint8_t *page_ptr;
- rt_uint8_t *oob_ptr;
- struct rt_mtd_nand_device *nand;
+ rt_err_t result;
+ rt_uint8_t *page_ptr;
+ rt_uint8_t *oob_ptr;
+ struct rt_mtd_nand_device *nand;
- nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
- if (nand == RT_NULL)
- {
- rt_kprintf("no nand device found!\n");
- return -RT_ERROR;
- }
+ nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
+ if (nand == RT_NULL)
+ {
+ rt_kprintf("no nand device found!\n");
+ return -RT_ERROR;
+ }
- page_ptr = rt_malloc(nand->page_size + nand->oob_size);
- if (page_ptr == RT_NULL)
- {
- rt_kprintf("out of memory!\n");
- return -RT_ENOMEM;
- }
+ page_ptr = rt_malloc(nand->page_size + nand->oob_size);
+ if (page_ptr == RT_NULL)
+ {
+ rt_kprintf("out of memory!\n");
+ return -RT_ENOMEM;
+ }
- oob_ptr = page_ptr + nand->page_size;
- rt_memset(page_ptr, 0xff, nand->page_size + nand->oob_size);
+ oob_ptr = page_ptr + nand->page_size;
+ rt_memset(page_ptr, 0xff, nand->page_size + nand->oob_size);
- /* calculate the page number */
- page = block * nand->pages_per_block + page;
- result = rt_mtd_nand_read(nand, page, page_ptr, nand->page_size,
- oob_ptr, nand->oob_size);
+ /* calculate the page number */
+ page = block * nand->pages_per_block + page;
+ result = rt_mtd_nand_read(nand, page, page_ptr, nand->page_size,
+ oob_ptr, nand->oob_size);
- rt_kprintf("read page, rc=%d\n", result);
- mtd_dump_hex(page_ptr, nand->page_size);
- mtd_dump_hex(oob_ptr, nand->oob_size);
+ rt_kprintf("read page, rc=%d\n", result);
+ mtd_dump_hex(page_ptr, nand->page_size);
+ mtd_dump_hex(oob_ptr, nand->oob_size);
- rt_free(page_ptr);
- return 0;
+ rt_free(page_ptr);
+ return 0;
}
-FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_read, nand_read, read page in nand - nand_read(name, block, page));
-int mtd_nand_readoob(const char* name, int block, int page)
+int mtd_nand_readoob(const char *name, int block, int page)
{
- struct rt_mtd_nand_device *nand;
- rt_uint8_t *oob_ptr;
+ struct rt_mtd_nand_device *nand;
+ rt_uint8_t *oob_ptr;
- nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
- if (nand == RT_NULL)
- {
- rt_kprintf("no nand device found!\n");
- return -RT_ERROR;
- }
+ nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
+ if (nand == RT_NULL)
+ {
+ rt_kprintf("no nand device found!\n");
+ return -RT_ERROR;
+ }
- oob_ptr = rt_malloc(nand->oob_size);
- if (oob_ptr == RT_NULL)
- {
- rt_kprintf("out of memory!\n");
- return -RT_ENOMEM;
- }
+ oob_ptr = rt_malloc(nand->oob_size);
+ if (oob_ptr == RT_NULL)
+ {
+ rt_kprintf("out of memory!\n");
+ return -RT_ENOMEM;
+ }
- /* calculate the page number */
- page = block * nand->pages_per_block + page;
- rt_mtd_nand_read(nand, page, RT_NULL, nand->page_size,
- oob_ptr, nand->oob_size);
- mtd_dump_hex(oob_ptr, nand->oob_size);
+ /* calculate the page number */
+ page = block * nand->pages_per_block + page;
+ rt_mtd_nand_read(nand, page, RT_NULL, nand->page_size,
+ oob_ptr, nand->oob_size);
+ mtd_dump_hex(oob_ptr, nand->oob_size);
- rt_free(oob_ptr);
- return 0;
+ rt_free(oob_ptr);
+ return 0;
}
-FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_readoob, nand_readoob, read spare data in nand - nand_readoob(name, block, page));
-int mtd_nand_write(const char* name, int block, int page)
+int mtd_nand_write(const char *name, int block, int page)
{
- rt_err_t result;
- rt_uint8_t *page_ptr;
- rt_uint8_t *oob_ptr;
- rt_uint32_t index;
- struct rt_mtd_nand_device *nand;
+ rt_err_t result;
+ rt_uint8_t *page_ptr;
+ rt_uint8_t *oob_ptr;
+ rt_uint32_t index;
+ struct rt_mtd_nand_device *nand;
- nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
- if (nand == RT_NULL)
- {
- rt_kprintf("no nand device found!\n");
- return -RT_ERROR;
- }
+ nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
+ if (nand == RT_NULL)
+ {
+ rt_kprintf("no nand device found!\n");
+ return -RT_ERROR;
+ }
- page_ptr = rt_malloc(nand->page_size + nand->oob_size);
- if (page_ptr == RT_NULL)
- {
- rt_kprintf("out of memory!\n");
- return -RT_ENOMEM;
- }
+ page_ptr = rt_malloc(nand->page_size + nand->oob_size);
+ if (page_ptr == RT_NULL)
+ {
+ rt_kprintf("out of memory!\n");
+ return -RT_ENOMEM;
+ }
- oob_ptr = page_ptr + nand->page_size;
- /* prepare page data */
- for (index = 0; index < nand->page_size; index ++)
- {
- page_ptr[index] = index & 0xff;
- }
- /* prepare oob data */
- for (index = 0; index < nand->oob_size; index ++)
- {
- oob_ptr[index] = index & 0xff;
- }
+ oob_ptr = page_ptr + nand->page_size;
+ /* prepare page data */
+ for (index = 0; index < nand->page_size; index ++)
+ {
+ page_ptr[index] = index & 0xff;
+ }
+ /* prepare oob data */
+ for (index = 0; index < nand->oob_size; index ++)
+ {
+ oob_ptr[index] = index & 0xff;
+ }
- /* calculate the page number */
- page = block * nand->pages_per_block + page;
- result = rt_mtd_nand_write(nand, page, page_ptr, nand->page_size,
- oob_ptr, nand->oob_size);
- if (result != RT_MTD_EOK)
- {
- rt_kprintf("write page failed!, rc=%d\n", result);
- }
+ /* calculate the page number */
+ page = block * nand->pages_per_block + page;
+ result = rt_mtd_nand_write(nand, page, page_ptr, nand->page_size,
+ oob_ptr, nand->oob_size);
+ if (result != RT_MTD_EOK)
+ {
+ rt_kprintf("write page failed!, rc=%d\n", result);
+ }
- rt_free(page_ptr);
- return 0;
+ rt_free(page_ptr);
+ return 0;
}
-FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_write, nand_write, write dump data to nand - nand_write(name, block, page));
-int mtd_nand_erase(const char* name, int block)
+int mtd_nand_erase(const char *name, int block)
{
- struct rt_mtd_nand_device *nand;
- nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
- if (nand == RT_NULL)
- {
- rt_kprintf("no nand device found!\n");
- return -RT_ERROR;
- }
+ struct rt_mtd_nand_device *nand;
+ nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
+ if (nand == RT_NULL)
+ {
+ rt_kprintf("no nand device found!\n");
+ return -RT_ERROR;
+ }
- return rt_mtd_nand_erase_block(nand, block);
+ return rt_mtd_nand_erase_block(nand, block);
}
-FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_erase, nand_erase, nand_erase(name, block));
-int mtd_nand_erase_all(const char* name)
+int mtd_nand_erase_all(const char *name)
{
- rt_uint32_t index = 0;
- struct rt_mtd_nand_device *nand;
-
- nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
- if (nand == RT_NULL)
- {
- rt_kprintf("no nand device found!\n");
- return -RT_ERROR;
- }
+ rt_uint32_t index = 0;
+ struct rt_mtd_nand_device *nand;
- for (index = 0; index < (nand->block_end - nand->block_start); index ++)
- {
- rt_mtd_nand_erase_block(nand, index);
- }
-
- return 0;
+ nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
+ if (nand == RT_NULL)
+ {
+ rt_kprintf("no nand device found!\n");
+ return -RT_ERROR;
+ }
+
+ for (index = 0; index < (nand->block_end - nand->block_start); index ++)
+ {
+ rt_mtd_nand_erase_block(nand, index);
+ }
+
+ return 0;
+}
+
+#ifdef FINSH_USING_MSH
+static void mtd_nand(int argc, char **argv)
+{
+ /* If the number of arguments less than 2 */
+ if (argc < 3)
+ {
+help:
+ rt_kprintf("\n");
+ rt_kprintf("mtd_nand [OPTION] [PARAM ...]\n");
+ rt_kprintf(" id <name> Get nandid by given name\n");
+ rt_kprintf(" read <name> <bn> <pn> Read data on page <pn> of block <bn> of device <name>\n");
+ rt_kprintf(" readoob <name> <bn> <pn> Read oob on page <pn> of block <bn> of device <name>\n");
+ rt_kprintf(" write <name> <bn> <pn> Run write test on page <pn> of block <bn> of device <name>\n");
+ rt_kprintf(" erase <name> <bn> Erase on block <bn> of device <name>\n");
+ rt_kprintf(" eraseall <name> Erase all block on device <name>\n");
+ return ;
+ }
+ else if (!strcmp(argv[1], "id"))
+ {
+ mtd_nandid(argv[2]);
+ }
+ else if (!strcmp(argv[1], "read"))
+ {
+ if (argc < 5)
+ {
+ rt_kprintf("The input parameters are too few!\n");
+ goto help;
+ }
+ mtd_nand_read(argv[2], atoi(argv[3]), atoi(argv[4]));
+ }
+ else if (!strcmp(argv[1], "readoob"))
+ {
+ if (argc < 5)
+ {
+ rt_kprintf("The input parameters are too few!\n");
+ goto help;
+ }
+ mtd_nand_readoob(argv[2], atoi(argv[3]), atoi(argv[4]));
+ }
+ else if (!strcmp(argv[1], "write"))
+ {
+ if (argc < 5)
+ {
+ rt_kprintf("The input parameters are too few!\n");
+ goto help;
+ }
+ mtd_nand_write(argv[2], atoi(argv[3]), atoi(argv[4]));
+ }
+ else if (!strcmp(argv[1], "erase"))
+ {
+ if (argc < 4)
+ {
+ rt_kprintf("The input parameters are too few!\n");
+ goto help;
+ }
+ mtd_nand_erase(argv[2], atoi(argv[3]));
+ }
+ else if (!strcmp(argv[1], "eraseall"))
+ {
+ mtd_nand_erase_all(argv[2]);
+ }
+ else
+ {
+ rt_kprintf("Input parameters are not supported!\n");
+ goto help;
+ }
}
+MSH_CMD_EXPORT(mtd_nand, MTD nand device test function);
+#endif /* FINSH_USING_MSH */
+
+#ifndef FINSH_USING_MSH_ONLY
+FINSH_FUNCTION_EXPORT_ALIAS(mtd_nandid, nand_id, read ID - nandid(name));
+FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_read, nand_read, read page in nand - nand_read(name, block, page));
+FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_readoob, nand_readoob, read spare data in nand - nand_readoob(name, block, page));
+FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_write, nand_write, write dump data to nand - nand_write(name, block, page));
+FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_erase, nand_erase, nand_erase(name, block));
FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_erase_all, nand_erase_all, erase all of nand device - nand_erase_all(name, block));
-#endif
+#endif /* FINSH_USING_MSH_ONLY */
-#endif
+#endif /* defined(RT_MTD_NAND_DEBUG) && defined(RT_USING_FINSH) */
+
+#endif /* RT_USING_MTD_NAND */
diff --git a/components/drivers/mtd/mtdnand.c b/components/drivers/mtd/mtdnand.c
deleted file mode 100644
index 50012219fb..0000000000
--- a/components/drivers/mtd/mtdnand.c
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2018-09-10 heyuanjie87 first version
- */
-
-#include <rtdevice.h>
-
-#define MTDTONAND(x) ((rt_nand_t*)(x))
-#define NOTALIGNED(x) ((x & (chip->page_size - 1)) != 0)
-#ifndef min
-#define min(a,b) (a>b? b:a)
-#endif
-
-static uint8_t *nand_fill_oob(rt_nand_t *chip, uint8_t *oob, size_t len, struct mtd_io_desc *desc)
-{
- rt_memset(chip->oob_poi, 0xff, chip->oobsize);
-
- switch (desc->mode)
- {
- case MTD_OPM_PLACE_OOB:
- case MTD_OPM_RAW:
- rt_memcpy(chip->oob_poi + desc->ooboffs, oob, len);
- return oob + len;
-
- case MTD_OPM_AUTO_OOB:
- {
- const struct mtd_oob_region *free = chip->freelayout;
- uint32_t boffs;
- size_t bytes;
-
- bytes = min(len, free->length);
- boffs = free->offset;
-
- rt_memcpy(chip->oob_poi + boffs, oob, bytes);
- oob += bytes;
-
- return oob;
- }
- }
-
- return NULL;
-}
-
-static uint8_t *nand_transfer_oob(rt_nand_t *chip, uint8_t *oob, struct mtd_io_desc *desc, size_t len)
-{
- switch (desc->mode)
- {
- case MTD_OPM_PLACE_OOB:
- case MTD_OPM_RAW:
- rt_memcpy(oob, chip->oob_poi + desc->ooboffs, len);
- return oob + len;
-
- case MTD_OPM_AUTO_OOB:
- {
- struct mtd_oob_region *free = (struct mtd_oob_region *)chip->freelayout;
- uint32_t boffs = 0, roffs = desc->ooboffs;
- size_t bytes = 0;
-
- for (; free->length && len; free++, len -= bytes)
- {
- /* Read request not from offset 0? */
- if (roffs)
- {
- if (roffs >= free->length)
- {
- roffs -= free->length;
- continue;
- }
- boffs = free->offset + roffs;
- bytes = min(len, (free->length - roffs));
- roffs = 0;
- }
- else
- {
- bytes = min(len, free->length);
- boffs = free->offset;
- }
-
- rt_memcpy(oob, chip->oob_poi + boffs, bytes);
- oob += bytes;
- }
-
- return oob;
- }
- }
-
- return NULL;
-}
-
-static int nand_read_page_raw(rt_nand_t *chip, uint8_t *buf, int oob_required, int page)
-{
- chip->ops->read_buf(chip, buf, chip->page_size);
-
- if (oob_required)
- chip->ops->read_buf(chip, chip->oob_poi, chip->oobsize);
-
- return 0;
-}
-
-static int nand_write_page_raw(rt_nand_t *chip, const uint8_t *buf, int oob_required, int page)
-{
- chip->ops->write_buf(chip, buf, chip->page_size);
-
- if (oob_required)
- chip->ops->write_buf(chip, chip->oob_poi, chip->oobsize);
-
- return 0;
-}
-
-static int nand_write_page_hwecc(rt_nand_t *chip, const uint8_t *buf, int oob_required, int page)
-{
- uint16_t i;
- uint16_t stepsize = chip->ecc.stepsize;
- uint16_t eccbytes = chip->ecc.bytes;
- uint16_t eccsteps = chip->ecc._step;
- uint16_t eccpos = chip->ecc.layout->offset;
- uint8_t *ecc_calc = chip->buffers.ecccalc;
- const uint8_t *p = buf;
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += stepsize)
- {
- chip->ops->cmdfunc(chip, NAND_CMD_ECC_EN, 0, 0);
- chip->ops->write_buf(chip, p, stepsize);
- chip->ecc.calculate(chip, p, &ecc_calc[i]);
- chip->ops->cmdfunc(chip, NAND_CMD_ECC_DIS, 0, 0);
- }
-
- rt_memcpy(&chip->oob_poi[eccpos], ecc_calc, chip->ecc.layout->length);
-
- chip->ops->write_buf(chip, chip->oob_poi, chip->oobsize);
-
- return 0;
-}
-
-static int nand_read_page_hwecc(rt_nand_t *chip, uint8_t *buf, int oob_required, int page)
-{
- uint16_t i;
- uint16_t eccsize = chip->ecc.stepsize;
- uint16_t eccbytes = chip->ecc.bytes;
- uint16_t eccsteps = chip->ecc._step;
- uint16_t eccpos = chip->ecc.layout->offset;
- uint8_t *p = buf;
- uint8_t *ecc_calc = chip->buffers.ecccalc;
- uint8_t *ecc_code = chip->buffers.ecccode;
- int ret = 0;
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
- {
- chip->ops->cmdfunc(chip, NAND_CMD_ECC_EN, 0, 0);
- chip->ops->read_buf(chip, p, eccsize);
- chip->ecc.calculate(chip, p, &ecc_calc[i]);
- chip->ops->cmdfunc(chip, NAND_CMD_ECC_DIS, 0, 0);
- }
-
- chip->ops->read_buf(chip, chip->oob_poi, chip->oobsize);
- rt_memcpy(ecc_code, &chip->oob_poi[eccpos], chip->ecc.layout->length);
-
- eccsteps = chip->ecc._step;
- p = buf;
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
- {
- int stat;
-
- stat = chip->ecc.correct(chip, p, &ecc_code[i], &ecc_calc[i]);
- if (stat != 0)
- ret = -1;
- }
-
- return ret;
-}
-
-static int nand_write_page(rt_nand_t *chip, const uint8_t *buf,
- int oob_required, int page, int raw)
-{
- int status;
-
- chip->ops->cmdfunc(chip, NAND_CMD_PAGE_WR0, page, 0x00);
-
- if (raw)
- {
- nand_write_page_raw(chip, buf, oob_required, page);
- }
- else
- {
- chip->write_page(chip, buf, oob_required, page);
- }
-
- status = chip->ops->cmdfunc(chip, NAND_CMD_PAGE_WR1, -1, -1);
-
- return status;
-}
-
-static int nand_do_read_desc(rt_nand_t *chip, loff_t from, struct mtd_io_desc *desc)
-{
- int page, bytes;
- char oob_required;
- char ecc_fail = 0;
- int ret = 0;
- uint32_t readlen = desc->datlen;
- uint16_t oobreadlen = desc->ooblen;
- uint16_t max_oobsize = desc->mode == MTD_OPM_AUTO_OOB ?
- chip->freelayout->length : chip->oobsize;
-
- uint8_t *oob, *buf, *notalign = 0;
-
- /* Reject reads, which are not page aligned */
- if (NOTALIGNED(from))
- {
- return -EINVAL;
- }
-
- buf = desc->datbuf;
- if (NOTALIGNED(desc->datlen) && !chip->pagebuf)
- {
- chip->pagebuf = rt_malloc(chip->page_size);
- if (!chip->pagebuf)
- return -ENOMEM;
- }
-
- page = (int)(from / chip->page_size);
-
- oob = desc->oobbuf;
- oob_required = oob ? 1 : 0;
-
- while (1)
- {
- bytes = min(chip->page_size, readlen);
-
- chip->ops->cmdfunc(chip, NAND_CMD_PAGE_RD, page, 0x00);
- if (NOTALIGNED(bytes))
- {
- notalign = buf;
- buf = chip->pagebuf;
- }
- /*
- * Now read the page into the buffer. Absent an error,
- * the read methods return max bitflips per ecc step.
- */
- if (desc->mode == MTD_OPM_RAW)
- {
- ret = nand_read_page_raw(chip, buf, oob_required, page);
- }
- else
- {
- ret = chip->read_page(chip, buf, oob_required, page);
- }
-
- if (ret != 0)
- {
- ret = -EBADMSG;
- break;
- }
-
- if (oob)
- {
- int toread = min(oobreadlen, max_oobsize);
-
- if (toread)
- {
- oob = nand_transfer_oob(chip, oob, desc, toread);
- oobreadlen -= toread;
- }
- }
-
- if (notalign)
- {
- rt_memcpy(notalign, buf, bytes);
- }
-
- buf += bytes;
- readlen -= bytes;
-
- if (!readlen)
- break;
-
- page++;
- }
-
- desc->datretlen = desc->datlen - (size_t)readlen;
- if (oob)
- desc->oobretlen = desc->ooblen - oobreadlen;
-
- return ret;
-}
-
-/*
- * write with ECC
- *
-*/
-static int nand_do_write_desc(rt_nand_t *chip, loff_t to, struct mtd_io_desc *desc)
-{
- int page;
- uint16_t writelen = desc->datlen;
- uint16_t oob_required = desc->oobbuf ? 1 : 0;
- uint16_t oobwritelen = desc->ooblen;
- uint16_t oobmaxlen = desc->mode == MTD_OPM_AUTO_OOB ?
- chip->freelayout->length : chip->oobsize;
-
- uint8_t *oob = desc->oobbuf;
- uint8_t *buf = desc->datbuf;
- int ret;
-
- if (!writelen)
- return 0;
-
- /* Reject writes, which are not page aligned */
- if (NOTALIGNED(to))
- {
- return -EINVAL;
- }
-
- page = (int)(to / chip->page_size);
-
- /* Don't allow multipage oob writes with offset */
- if (oob && desc->ooboffs && (desc->ooboffs + desc->ooblen > oobmaxlen))
- {
- ret = -EINVAL;
- goto err_out;
- }
-
- if (NOTALIGNED(desc->datlen) && !chip->pagebuf)
- {
- chip->pagebuf = rt_malloc(chip->page_size);
- if (!chip->pagebuf)
- return -ENOMEM;
- }
-
- while (1)
- {
- uint16_t bytes = min(chip->page_size, writelen);
-
- if (oob)
- {
- size_t len = min(oobwritelen, oobmaxlen);
- oob = nand_fill_oob(chip, oob, len, desc);
- oobwritelen -= len;
- }
- else
- {
- /* We still need to erase leftover OOB data */
- rt_memset(chip->oob_poi, 0xff, chip->oobsize);
- }
-
- if (NOTALIGNED(bytes))
- {
- uint8_t *dbtmp = buf;
- buf = chip->pagebuf;
- rt_memset(&buf[bytes], 0xff, chip->page_size - bytes);
- rt_memcpy(buf, dbtmp, bytes);
- }
- ret = nand_write_page(chip, buf, oob_required, page, (desc->mode == MTD_OPM_RAW));
- if (ret)
- break;
-
- writelen -= bytes;
- if (!writelen)
- break;
-
- buf += bytes;
- page++;
- }
-
- desc->datretlen = desc->datlen - writelen;
- if (oob)
- desc->oobretlen = desc->ooblen;
-
-err_out:
-
- return ret;
-}
-
-static int nand_read_oob_std(rt_nand_t *chip, int page)
-{
- chip->ops->cmdfunc(chip, NAND_CMD_PAGE_RD, page, chip->page_size);
- chip->ops->read_buf(chip, chip->oob_poi, chip->oobsize);
-
- return 0;
-}
-
-/*
- * read one page of OOB
-*/
-static int nand_only_read_oob(rt_nand_t *chip, loff_t from, struct mtd_io_desc *desc)
-{
- int page;
- int readlen = desc->ooblen;
- int len;
- uint8_t *buf = desc->oobbuf;
- int ret = 0;
-
- if (desc->mode == MTD_OPM_AUTO_OOB)
- len = chip->freelayout->length;
- else
- len = chip->oobsize;
-
- if (desc->ooboffs >= len) //attempt to start read outside oob
- {
- return -EINVAL;
- }
-
- page = (int)(from / chip->page_size);
-
- ret = nand_read_oob_std(chip, page);
- if (ret == 0)
- {
- len = min(len, readlen);
- buf = nand_transfer_oob(chip, buf, desc, len);
- desc->oobretlen = len;
- }
-
- return ret;
-}
-
-static int nand_write_oob_std(rt_nand_t *chip, int page)
-{
- int status;
-
- chip->ops->cmdfunc(chip, NAND_CMD_PAGE_WR0, page, chip->page_size);
- chip->ops->write_buf(chip, chip->oob_poi, chip->oobsize);
- /* Send command to program the OOB data */
- status = chip->ops->cmdfunc(chip, NAND_CMD_PAGE_WR1, -1, -1);
-
- return status & NAND_STATUS_FAIL ? -EIO : 0;
-}
-
-static int nand_only_write_oob(rt_nand_t *chip, loff_t to, struct mtd_io_desc *desc)
-{
- int page, ret, len;
-
- if (desc->mode == MTD_OPM_AUTO_OOB)
- len = chip->freelayout->length;
- else
- len = chip->oobsize;
-
- /* Do not allow write past end of page */
- if ((desc->ooboffs + desc->ooblen) > len)
- {
- return -EINVAL;
- }
-
- if (desc->ooblen == 0)
- {
- return -EINVAL;
- }
-
- /* get page */
- page = (int)(to / chip->page_size);
-
- nand_fill_oob(chip, desc->oobbuf, desc->ooblen, desc);
-
- ret = nand_write_oob_std(chip, page);
- if (ret == 0)
- desc->oobretlen = len;
-
- return ret;
-}
-
-static int nand_erase(rt_mtd_t *mtd, loff_t addr, size_t size)
-{
- rt_nand_t *chip;
- int status;
- int page;
- uint32_t blksize;
-
- chip = MTDTONAND(mtd);
- blksize = mtd->block_size;
- page = addr / chip->page_size;
-
- while (size >= blksize)
- {
- status = chip->ops->cmdfunc(chip, NAND_CMD_BLK_ERASE, page, 0);
- if (status & NAND_STATUS_FAIL)
- {
- break;
- }
- size -= blksize;
- page += chip->pages_pb;
- }
-
- return size;
-}
-
-static int nand_read(rt_mtd_t *mtd, loff_t from, struct mtd_io_desc *desc)
-{
- int ret = -ENOTSUP;
- rt_nand_t *chip;
-
- chip = MTDTONAND(mtd);
-
- switch (desc->mode)
- {
- case MTD_OPM_PLACE_OOB:
- case MTD_OPM_AUTO_OOB:
- case MTD_OPM_RAW:
- break;
-
- default:
- goto out;
- }
-
- if (!desc->datbuf || !desc->datlen)
- ret = nand_only_read_oob(chip, from, desc);
- else
- ret = nand_do_read_desc(chip, from, desc);
-
-out:
-
- return ret;
-}
-
-static int nand_write(rt_mtd_t *mtd, loff_t to, struct mtd_io_desc *desc)
-{
- int ret = -ENOTSUP;
- rt_nand_t *chip;
-
- chip = MTDTONAND(mtd);
-
- switch (desc->mode)
- {
- case MTD_OPM_PLACE_OOB:
- case MTD_OPM_AUTO_OOB:
- case MTD_OPM_RAW:
- break;
-
- default:
- goto out;
- }
-
- if (!desc->datbuf || !desc->datlen)
- ret = nand_only_write_oob(chip, to, desc);
- else
- ret = nand_do_write_desc(chip, to, desc);
-
-out:
-
- return ret;
-}
-
-static int nand_block_isbad(rt_mtd_t *mtd, uint32_t blk)
-{
- int ret;
- rt_nand_t *chip = MTDTONAND(mtd);
-
- if (chip->ops->isbad)
- {
- ret = chip->ops->isbad(chip, blk);
- }
- else
- {
- int page;
-
- page = blk * chip->pages_pb;
- nand_read_oob_std(chip, page);
- ret = chip->oob_poi[0] != 0xFF;
- }
-
- return ret;
-}
-
-static int nand_block_markbad(rt_mtd_t *mtd, uint32_t blk)
-{
- int ret;
- rt_nand_t *chip;
-
- chip = MTDTONAND(mtd);
-
- if (chip->ops->markbad)
- {
- ret = chip->ops->markbad(chip, blk);
- }
- else
- {
- int page;
-
- page = blk * chip->pages_pb;
- rt_memset(chip->oob_poi, 0xff, chip->oobsize);
- chip->oob_poi[0] = 0;
- ret = nand_write_oob_std(chip, page);
- }
-
- return ret;
-}
-
-static const struct mtd_ops _ops =
-{
- nand_erase,
- nand_read,
- nand_write,
- nand_block_isbad,
- nand_block_markbad,
-};
-
-int rt_mtd_nand_init(rt_nand_t *nand, int blk_size, int page_size, int oob_size)
-{
- uint8_t *buf;
-
- buf = rt_malloc(oob_size * 3);
- if (buf == RT_NULL)
- return -ENOMEM;
-
- nand->oob_poi = buf;
- buf += oob_size;
- nand->buffers.ecccalc = buf;
- buf += oob_size;
- nand->buffers.ecccode = buf;
- nand->pagebuf = 0; /* alloc when unaligen access */
-
- nand->pages_pb = blk_size / page_size;
- nand->ecc._step = page_size / nand->ecc.stepsize;
- nand->page_size = page_size;
- nand->oobsize = oob_size;
-
- nand->parent.type = MTD_TYPE_NAND;
- nand->parent.ops = &_ops;
- nand->parent.sector_size = page_size;
- nand->parent.block_size = blk_size;
- nand->parent.oob_size = oob_size;
-
- switch (nand->ecc.mode)
- {
- case NAND_ECCM_NONE:
- {
- nand->read_page = nand_read_page_raw;
- nand->write_page = nand_write_page_raw;
- }break;
- case NAND_ECCM_HW:
- {
- nand->read_page = nand_read_page_hwecc;
- nand->write_page = nand_write_page_hwecc;
- }break;
- default:
- {
- rt_free(buf);
- return -1;
- }
- }
-
- return 0;
-}
diff --git a/components/drivers/mtd/mtdnor.c b/components/drivers/mtd/mtdnor.c
deleted file mode 100644
index 481d26167e..0000000000
--- a/components/drivers/mtd/mtdnor.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- 2018-09-10 heyuanjie87 first version
-
- */
-
-#include <drivers/mtdnor.h>
-
-#ifdef MTD_USING_NOR
-static int _nor_erase(rt_mtd_t *mtd, loff_t addr, size_t len)
-{
- rt_nor_t *nor;
-
- nor = (rt_nor_t *)mtd;
- return nor->ops->erase(nor, addr, len);
-}
-
-static int _nor_read(rt_mtd_t *mtd, loff_t from, struct mtd_io_desc *desc)
-{
- rt_nor_t *nor;
- int ret;
-
- nor = (rt_nor_t *)mtd;
- ret = nor->ops->read(nor, from, desc->datbuf, desc->datlen);
- if (ret > 0)
- {
- desc->datretlen = ret;
- ret = 0;
- }
-
- return ret;
-}
-
-static int _nor_write(rt_mtd_t *mtd, loff_t to, struct mtd_io_desc *desc)
-{
- rt_nor_t *nor;
- int ret;
-
- nor = (rt_nor_t *)mtd;
- ret = nor->ops->write(nor, to, desc->datbuf, desc->datlen);
- if (ret > 0)
- {
- desc->datretlen = ret;
- ret = 0;
- }
-
- return ret;
-}
-
-static const struct mtd_ops _ops =
-{
- _nor_erase,
- _nor_read,
- _nor_write,
- 0,
- 0
-};
-
-int rt_mtd_nor_init(rt_nor_t *nor, int blksize)
-{
- nor->parent.sector_size = 1;
- nor->parent.block_size = blksize;
- nor->parent.ops = &_ops;
- nor->parent.type = MTD_TYPE_NOR;
- nor->parent.oob_size = 0;
-
- return 0;
-}
-#endif
diff --git a/components/drivers/pm/pm.c b/components/drivers/pm/pm.c
index 3e9cf56c76..dd7cc2ae63 100644
--- a/components/drivers/pm/pm.c
+++ b/components/drivers/pm/pm.c
@@ -17,18 +17,18 @@
#ifdef RT_USING_PM
static struct rt_pm _pm;
-static uint8_t _pm_default_sleep = RT_PM_DEFAULT_SLEEP_MODE;
+static rt_uint8_t _pm_default_sleep = RT_PM_DEFAULT_SLEEP_MODE;
static struct rt_pm_notify _pm_notify;
-static uint8_t _pm_init_flag = 0;
+static rt_uint8_t _pm_init_flag = 0;
#define RT_PM_TICKLESS_THRESH (2)
-RT_WEAK uint32_t rt_pm_enter_critical(uint8_t sleep_mode)
+RT_WEAK rt_uint32_t rt_pm_enter_critical(rt_uint8_t sleep_mode)
{
return rt_hw_interrupt_disable();
}
-RT_WEAK void rt_pm_exit_critical(uint32_t ctx, uint8_t sleep_mode)
+RT_WEAK void rt_pm_exit_critical(rt_uint32_t ctx, rt_uint8_t sleep_mode)
{
rt_hw_interrupt_enable(ctx);
}
@@ -36,7 +36,7 @@ RT_WEAK void rt_pm_exit_critical(uint32_t ctx, uint8_t sleep_mode)
/**
* This function will suspend all registered devices
*/
-static int _pm_device_suspend(uint8_t mode)
+static int _pm_device_suspend(rt_uint8_t mode)
{
int index, ret = RT_EOK;
@@ -56,7 +56,7 @@ static int _pm_device_suspend(uint8_t mode)
/**
* This function will resume all registered devices
*/
-static void _pm_device_resume(uint8_t mode)
+static void _pm_device_resume(rt_uint8_t mode)
{
int index;
@@ -72,7 +72,7 @@ static void _pm_device_resume(uint8_t mode)
/**
* This function will update the frequency of all registered devices
*/
-static void _pm_device_frequency_change(uint8_t mode)
+static void _pm_device_frequency_change(rt_uint8_t mode)
{
rt_uint32_t index;
@@ -106,10 +106,10 @@ static void _pm_frequency_scaling(struct rt_pm *pm)
/**
* This function selects the sleep mode according to the rt_pm_request/rt_pm_release count.
*/
-static uint8_t _pm_select_sleep_mode(struct rt_pm *pm)
+static rt_uint8_t _pm_select_sleep_mode(struct rt_pm *pm)
{
int index;
- uint8_t mode;
+ rt_uint8_t mode;
mode = _pm_default_sleep;
for (index = PM_SLEEP_MODE_NONE; index < PM_SLEEP_MODE_MAX; index ++)
@@ -128,7 +128,7 @@ static uint8_t _pm_select_sleep_mode(struct rt_pm *pm)
/**
* This function changes the power sleep mode base on the result of selection
*/
-static void _pm_change_sleep_mode(struct rt_pm *pm, uint8_t mode)
+static void _pm_change_sleep_mode(struct rt_pm *pm, rt_uint8_t mode)
{
rt_tick_t timeout_tick, delta_tick;
rt_base_t level;
@@ -214,7 +214,7 @@ static void _pm_change_sleep_mode(struct rt_pm *pm, uint8_t mode)
*/
void rt_system_power_manager(void)
{
- uint8_t mode;
+ rt_uint8_t mode;
if (_pm_init_flag == 0)
return;
@@ -233,7 +233,7 @@ void rt_system_power_manager(void)
*
* @param parameter the parameter of run mode or sleep mode
*/
-void rt_pm_request(uint8_t mode)
+void rt_pm_request(rt_uint8_t mode)
{
rt_base_t level;
struct rt_pm *pm;
@@ -258,7 +258,7 @@ void rt_pm_request(uint8_t mode)
* @param parameter the parameter of run mode or sleep mode
*
*/
-void rt_pm_release(uint8_t mode)
+void rt_pm_release(rt_uint8_t mode)
{
rt_ubase_t level;
struct rt_pm *pm;
@@ -342,7 +342,7 @@ void rt_pm_device_unregister(struct rt_device *device)
/**
* This function set notification callback for application
*/
-void rt_pm_notify_set(void (*notify)(uint8_t event, uint8_t mode, void *data), void *data)
+void rt_pm_notify_set(void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data), void *data)
{
_pm_notify.notify = notify;
_pm_notify.data = data;
@@ -351,7 +351,7 @@ void rt_pm_notify_set(void (*notify)(uint8_t event, uint8_t mode, void *data), v
/**
* This function set default sleep mode when no pm_request
*/
-void rt_pm_default_set(uint8_t sleep_mode)
+void rt_pm_default_set(rt_uint8_t sleep_mode)
{
_pm_default_sleep = sleep_mode;
}
@@ -428,7 +428,7 @@ static rt_err_t _rt_pm_device_control(rt_device_t dev,
return RT_EOK;
}
-int rt_pm_run_enter(uint8_t mode)
+int rt_pm_run_enter(rt_uint8_t mode)
{
rt_base_t level;
struct rt_pm *pm;
@@ -458,6 +458,18 @@ int rt_pm_run_enter(uint8_t mode)
return RT_EOK;
}
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops pm_ops =
+{
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ _rt_pm_device_read,
+ _rt_pm_device_write,
+ _rt_pm_device_control,
+};
+#endif
+
/**
* This function will initialize power management.
*
@@ -479,12 +491,16 @@ void rt_system_pm_init(const struct rt_pm_ops *ops,
device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL;
+#ifdef RT_USING_DEVICE_OPS
+ device->ops = &pm_ops;
+#else
device->init = RT_NULL;
device->open = RT_NULL;
device->close = RT_NULL;
device->read = _rt_pm_device_read;
device->write = _rt_pm_device_write;
device->control = _rt_pm_device_control;
+#endif
device->user_data = user_data;
/* register PM device to the system */
diff --git a/components/drivers/sdio/block_dev.c b/components/drivers/sdio/block_dev.c
index cac4fc5036..5db0f38c08 100644
--- a/components/drivers/sdio/block_dev.c
+++ b/components/drivers/sdio/block_dev.c
@@ -472,7 +472,7 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
}
#ifdef RT_USING_DFS_MNTTABLE
- if (0) // if (blk_dev)
+ if (blk_dev)
{
LOG_I("try to mount file system!");
/* try to mount file system on this block device */
@@ -507,9 +507,10 @@ void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card)
const char * mounted_path = dfs_filesystem_get_mounted_path(&(blk_dev->dev));
if (mounted_path)
{
- dfs_unmount(mounted_path);
+ dfs_unmount(mounted_path);
+ LOG_D("unmount file system %s for device %s.\r\n", mounted_path, blk_dev->dev.parent.name);
}
-
+ rt_sem_delete(blk_dev->part.lock);
rt_device_unregister(&blk_dev->dev);
rt_list_remove(&blk_dev->list);
rt_free(blk_dev);
diff --git a/components/drivers/sdio/mmc.c b/components/drivers/sdio/mmc.c
index 5c7ddcb258..7b1f7ee193 100644
--- a/components/drivers/sdio/mmc.c
+++ b/components/drivers/sdio/mmc.c
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
- * Date Author Notes
- * 2015-06-15 hichard first version
+ * Date Author Notes
+ * 2015-06-15 hichard first version
*/
#include <drivers/mmcsd_core.h>
@@ -182,6 +182,8 @@ static int mmc_get_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t **new_ext_csd)
*/
static int mmc_parse_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd)
{
+ rt_uint64_t card_capacity = 0;
+
if(card == RT_NULL || ext_csd == RT_NULL)
{
LOG_E("emmc parse ext csd fail, invaild args");
@@ -191,9 +193,10 @@ static int mmc_parse_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd)
card->flags |= CARD_FLAG_HIGHSPEED;
card->hs_max_data_rate = 200000000;
- card->card_capacity = *((rt_uint32_t *)&ext_csd[EXT_CSD_SEC_CNT]);
- card->card_capacity *= card->card_blksize;
- card->card_capacity >>= 10; /* unit:KB */
+ card_capacity = *((rt_uint32_t *)&ext_csd[EXT_CSD_SEC_CNT]);
+ card_capacity *= card->card_blksize;
+ card_capacity >>= 10; /* unit:KB */
+ card->card_capacity = card_capacity;
LOG_I("emmc card capacity %d KB.", card->card_capacity);
return 0;
diff --git a/components/drivers/sdio/sdio.c b/components/drivers/sdio/sdio.c
index f31f5b81a8..65bf87b895 100644
--- a/components/drivers/sdio/sdio.c
+++ b/components/drivers/sdio/sdio.c
@@ -709,6 +709,16 @@ static rt_int32_t sdio_initialize_function(struct rt_mmcsd_card *card,
if (ret)
goto err1;
+ /*
+ * product/manufacturer id is optional for function CIS, so
+ * copy it from the card structure as needed.
+ */
+ if (func->product == 0)
+ {
+ func->manufacturer = card->cis.manufacturer;
+ func->product = card->cis.product;
+ }
+
card->sdio_function[func_num] = func;
return 0;
diff --git a/components/drivers/sensors/sensor.c b/components/drivers/sensors/sensor.c
index e76ac51f12..91b256bd66 100644
--- a/components/drivers/sensors/sensor.c
+++ b/components/drivers/sensors/sensor.c
@@ -30,7 +30,7 @@ static char *const sensor_name_str[] =
"hr_", /* Heart Rate */
"tvoc_", /* TVOC Level */
"noi_", /* Noise Loudness */
- "step_" /* Step sensor */
+ "step_", /* Step sensor */
"forc_" /* Force sensor */
};
@@ -44,7 +44,7 @@ void rt_sensor_cb(rt_sensor_t sen)
{
return;
}
-
+
if (sen->irq_handle != RT_NULL)
{
sen->irq_handle(sen);
@@ -69,7 +69,7 @@ void rt_sensor_cb(rt_sensor_t sen)
/* ISR for sensor interrupt */
static void irq_callback(void *args)
{
- rt_sensor_t sensor = args;
+ rt_sensor_t sensor = (rt_sensor_t)args;
rt_uint8_t i;
if (sensor->module)
@@ -116,30 +116,18 @@ static rt_err_t rt_sensor_irq_init(rt_sensor_t sensor)
return 0;
}
-/* Sensor interrupt enable */
-static void rt_sensor_irq_enable(rt_sensor_t sensor)
-{
- if (sensor->config.irq_pin.pin != RT_PIN_NONE)
- {
- rt_pin_irq_enable(sensor->config.irq_pin.pin, RT_TRUE);
- }
-}
-
-/* Sensor interrupt disable */
-static void rt_sensor_irq_disable(rt_sensor_t sensor)
-{
- if (sensor->config.irq_pin.pin != RT_PIN_NONE)
- {
- rt_pin_irq_enable(sensor->config.irq_pin.pin, RT_FALSE);
- }
-}
-
/* RT-Thread Device Interface */
-
-static rt_err_t rt_sensor_init(rt_device_t dev)
+static rt_err_t rt_sensor_open(rt_device_t dev, rt_uint16_t oflag)
{
rt_sensor_t sensor = (rt_sensor_t)dev;
RT_ASSERT(dev != RT_NULL);
+ rt_err_t res = RT_EOK;
+
+ if (sensor->module)
+ {
+ /* take the module mutex */
+ rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER);
+ }
if (sensor->module != RT_NULL && sensor->info.fifo_max > 0 && sensor->data_buf == RT_NULL)
{
@@ -147,55 +135,46 @@ static rt_err_t rt_sensor_init(rt_device_t dev)
sensor->data_buf = rt_malloc(sizeof(struct rt_sensor_data) * sensor->info.fifo_max);
if (sensor->data_buf == RT_NULL)
{
- return -RT_ENOMEM;
+ res = -RT_ENOMEM;
+ goto __exit;
}
}
- return RT_EOK;
-}
-
-static rt_err_t rt_sensor_open(rt_device_t dev, rt_uint16_t oflag)
-{
- rt_sensor_t sensor = (rt_sensor_t)dev;
- RT_ASSERT(dev != RT_NULL);
-
- if (sensor->module)
- {
- /* take the module mutex */
- rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER);
- }
-
if (oflag & RT_DEVICE_FLAG_RDONLY && dev->flag & RT_DEVICE_FLAG_RDONLY)
{
- /* If polling mode is supported, configure it to polling mode */
- if (sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_POLLING) == RT_EOK)
+ if (sensor->ops->control != RT_NULL)
{
- sensor->config.mode = RT_SENSOR_MODE_POLLING;
+ /* If polling mode is supported, configure it to polling mode */
+ sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_POLLING);
}
+ sensor->config.mode = RT_SENSOR_MODE_POLLING;
}
else if (oflag & RT_DEVICE_FLAG_INT_RX && dev->flag & RT_DEVICE_FLAG_INT_RX)
{
- /* If interrupt mode is supported, configure it to interrupt mode */
- if (sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_INT) == RT_EOK)
+ if (sensor->ops->control != RT_NULL)
{
- sensor->config.mode = RT_SENSOR_MODE_INT;
- /* Initialization sensor interrupt */
- rt_sensor_irq_init(sensor);
+ /* If interrupt mode is supported, configure it to interrupt mode */
+ sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_INT);
}
+ /* Initialization sensor interrupt */
+ rt_sensor_irq_init(sensor);
+ sensor->config.mode = RT_SENSOR_MODE_INT;
}
else if (oflag & RT_DEVICE_FLAG_FIFO_RX && dev->flag & RT_DEVICE_FLAG_FIFO_RX)
{
- /* If fifo mode is supported, configure it to fifo mode */
- if (sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_FIFO) == RT_EOK)
+ if (sensor->ops->control != RT_NULL)
{
- sensor->config.mode = RT_SENSOR_MODE_FIFO;
- /* Initialization sensor interrupt */
- rt_sensor_irq_init(sensor);
+ /* If fifo mode is supported, configure it to fifo mode */
+ sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_FIFO);
}
+ /* Initialization sensor interrupt */
+ rt_sensor_irq_init(sensor);
+ sensor->config.mode = RT_SENSOR_MODE_FIFO;
}
else
{
- return -RT_EINVAL;
+ res = -RT_EINVAL;
+ goto __exit;
}
/* Configure power mode to normal mode */
@@ -204,18 +183,21 @@ static rt_err_t rt_sensor_open(rt_device_t dev, rt_uint16_t oflag)
sensor->config.power = RT_SENSOR_POWER_NORMAL;
}
+__exit:
if (sensor->module)
{
/* release the module mutex */
rt_mutex_release(sensor->module->lock);
}
- return RT_EOK;
+ return res;
}
-static rt_err_t rt_sensor_close(rt_device_t dev)
+static rt_err_t rt_sensor_close(rt_device_t dev)
{
rt_sensor_t sensor = (rt_sensor_t)dev;
+ int i;
+
RT_ASSERT(dev != RT_NULL);
if (sensor->module)
@@ -230,8 +212,31 @@ static rt_err_t rt_sensor_close(rt_device_t dev)
}
/* Sensor disable interrupt */
- rt_sensor_irq_disable(sensor);
+ if (sensor->config.irq_pin.pin != RT_PIN_NONE)
+ {
+ rt_pin_irq_enable(sensor->config.irq_pin.pin, RT_FALSE);
+ }
+
+ if (sensor->module != RT_NULL && sensor->info.fifo_max > 0 && sensor->data_buf != RT_NULL)
+ {
+ for (i = 0; i < sensor->module->sen_num; i ++)
+ {
+ if (sensor->module->sen[i]->parent.ref_count > 0)
+ goto __exit;
+ }
+ /* Free memory for the sensor buffer */
+ for (i = 0; i < sensor->module->sen_num; i ++)
+ {
+ if (sensor->module->sen[i]->data_buf != RT_NULL)
+ {
+ rt_free(sensor->module->sen[i]->data_buf);
+ sensor->module->sen[i]->data_buf = RT_NULL;
+ }
+ }
+ }
+
+__exit:
if (sensor->module)
{
rt_mutex_release(sensor->module->lock);
@@ -320,7 +325,7 @@ static rt_err_t rt_sensor_control(rt_device_t dev, int cmd, void *args)
}
break;
case RT_SENSOR_CTRL_SET_ODR:
-
+
/* Configuration data output rate */
result = sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_ODR, args);
if (result == RT_EOK)
@@ -329,27 +334,8 @@ static rt_err_t rt_sensor_control(rt_device_t dev, int cmd, void *args)
LOG_D("set odr %d", sensor->config.odr);
}
break;
- case RT_SENSOR_CTRL_SET_MODE:
-
- /* Configuration sensor work mode */
- result = sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_MODE, args);
- if (result == RT_EOK)
- {
- sensor->config.mode = (rt_uint32_t)args & 0xFF;
- LOG_D("set work mode code:", sensor->config.mode);
-
- if (sensor->config.mode == RT_SENSOR_MODE_POLLING)
- {
- rt_sensor_irq_disable(sensor);
- }
- else if (sensor->config.mode == RT_SENSOR_MODE_INT || sensor->config.mode == RT_SENSOR_MODE_FIFO)
- {
- rt_sensor_irq_enable(sensor);
- }
- }
- break;
case RT_SENSOR_CTRL_SET_POWER:
-
+
/* Configuration sensor power mode */
result = sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_POWER, args);
if (result == RT_EOK)
@@ -359,7 +345,7 @@ static rt_err_t rt_sensor_control(rt_device_t dev, int cmd, void *args)
}
break;
case RT_SENSOR_CTRL_SELF_TEST:
-
+
/* Device self-test */
result = sensor->ops->control(sensor, RT_SENSOR_CTRL_SELF_TEST, args);
break;
@@ -378,7 +364,7 @@ static rt_err_t rt_sensor_control(rt_device_t dev, int cmd, void *args)
#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops rt_sensor_ops =
{
- rt_sensor_init,
+ RT_NULL,
rt_sensor_open,
rt_sensor_close,
rt_sensor_read,
@@ -403,7 +389,7 @@ int rt_hw_sensor_register(rt_sensor_t sensor,
/* Add a type name for the sensor device */
sensor_name = sensor_name_str[sensor->info.type];
- device_name = rt_calloc(1, rt_strlen(sensor_name) + 1 + rt_strlen(name));
+ device_name = (char *)rt_calloc(1, rt_strlen(sensor_name) + 1 + rt_strlen(name));
if (device_name == RT_NULL)
{
LOG_E("device_name calloc failed!");
@@ -429,7 +415,7 @@ int rt_hw_sensor_register(rt_sensor_t sensor,
#ifdef RT_USING_DEVICE_OPS
device->ops = &rt_sensor_ops;
#else
- device->init = rt_sensor_init;
+ device->init = RT_NULL;
device->open = rt_sensor_open;
device->close = rt_sensor_close;
device->read = rt_sensor_read;
@@ -444,10 +430,12 @@ int rt_hw_sensor_register(rt_sensor_t sensor,
result = rt_device_register(device, device_name, flag | RT_DEVICE_FLAG_STANDALONE);
if (result != RT_EOK)
{
+ rt_free(device_name);
LOG_E("rt_sensor register err code: %d", result);
return result;
}
+ rt_free(device_name);
LOG_I("rt_sensor init success");
return RT_EOK;
}
diff --git a/components/drivers/sensors/sensor.h b/components/drivers/sensors/sensor.h
index a9b6684457..9c6e5ecc55 100644
--- a/components/drivers/sensors/sensor.h
+++ b/components/drivers/sensors/sensor.h
@@ -55,6 +55,7 @@ extern "C" {
#define RT_SENSOR_VENDOR_SEMTECH (4) /* Semtech */
#define RT_SENSOR_VENDOR_GOERTEK (5) /* Goertek */
#define RT_SENSOR_VENDOR_MIRAMEMS (6) /* MiraMEMS */
+#define RT_SENSOR_VENDOR_DALLAS (7) /* Dallas */
/* Sensor unit types */
diff --git a/components/drivers/sensors/sensor_cmd.c b/components/drivers/sensors/sensor_cmd.c
index 6babf12db3..dd1aa1ef95 100644
--- a/components/drivers/sensors/sensor_cmd.c
+++ b/components/drivers/sensors/sensor_cmd.c
@@ -4,8 +4,9 @@
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
- * Date Author Notes
- * 2019-01-31 flybreak first version
+ * Date Author Notes
+ * 2019-01-31 flybreak first version
+ * 2019-07-16 WillianChan Increase the output of sensor information
*/
#include "sensor.h"
@@ -55,7 +56,7 @@ static void sensor_show_data(rt_size_t num, rt_sensor_t sensor, struct rt_sensor
}
}
-rt_err_t rx_callback(rt_device_t dev, rt_size_t size)
+static rt_err_t rx_callback(rt_device_t dev, rt_size_t size)
{
rt_sem_release(sensor_rx_sem);
return 0;
@@ -63,15 +64,15 @@ rt_err_t rx_callback(rt_device_t dev, rt_size_t size)
static void sensor_fifo_rx_entry(void *parameter)
{
- rt_device_t dev = parameter;
- rt_sensor_t sensor = parameter;
+ rt_device_t dev = (rt_device_t)parameter;
+ rt_sensor_t sensor = (rt_sensor_t)parameter;
struct rt_sensor_data *data = RT_NULL;
struct rt_sensor_info info;
rt_size_t res, i;
rt_device_control(dev, RT_SENSOR_CTRL_GET_INFO, &info);
- data = rt_malloc(sizeof(struct rt_sensor_data) * info.fifo_max);
+ data = (struct rt_sensor_data *)rt_malloc(sizeof(struct rt_sensor_data) * info.fifo_max);
if (data == RT_NULL)
{
LOG_E("Memory allocation failed!");
@@ -137,8 +138,8 @@ MSH_CMD_EXPORT(sensor_fifo, Sensor fifo mode test function);
static void sensor_irq_rx_entry(void *parameter)
{
- rt_device_t dev = parameter;
- rt_sensor_t sensor = parameter;
+ rt_device_t dev = (rt_device_t)parameter;
+ rt_sensor_t sensor = (rt_sensor_t)parameter;
struct rt_sensor_data data;
rt_size_t res, i = 0;
@@ -268,13 +269,88 @@ static void sensor(int argc, char **argv)
else if (!strcmp(argv[1], "info"))
{
struct rt_sensor_info info;
+ if (dev == RT_NULL)
+ {
+ LOG_W("Please probe sensor device first!");
+ return ;
+ }
rt_device_control(dev, RT_SENSOR_CTRL_GET_INFO, &info);
- rt_kprintf("vendor :%d\n", info.vendor);
- rt_kprintf("model :%s\n", info.model);
- rt_kprintf("unit :%d\n", info.unit);
+ switch (info.vendor)
+ {
+ case RT_SENSOR_VENDOR_UNKNOWN:
+ rt_kprintf("vendor :unknown vendor\n");
+ break;
+ case RT_SENSOR_VENDOR_STM:
+ rt_kprintf("vendor :STMicroelectronics\n");
+ break;
+ case RT_SENSOR_VENDOR_BOSCH:
+ rt_kprintf("vendor :Bosch\n");
+ break;
+ case RT_SENSOR_VENDOR_INVENSENSE:
+ rt_kprintf("vendor :Invensense\n");
+ break;
+ case RT_SENSOR_VENDOR_SEMTECH:
+ rt_kprintf("vendor :Semtech\n");
+ break;
+ case RT_SENSOR_VENDOR_GOERTEK:
+ rt_kprintf("vendor :Goertek\n");
+ break;
+ case RT_SENSOR_VENDOR_MIRAMEMS:
+ rt_kprintf("vendor :MiraMEMS\n");
+ break;
+ case RT_SENSOR_VENDOR_DALLAS:
+ rt_kprintf("vendor :Dallas\n");
+ break;
+ }
+ rt_kprintf("model :%s\n", info.model);
+ switch (info.unit)
+ {
+ case RT_SENSOR_UNIT_NONE:
+ rt_kprintf("unit :none\n");
+ break;
+ case RT_SENSOR_UNIT_MG:
+ rt_kprintf("unit :mG\n");
+ break;
+ case RT_SENSOR_UNIT_MDPS:
+ rt_kprintf("unit :mdps\n");
+ break;
+ case RT_SENSOR_UNIT_MGAUSS:
+ rt_kprintf("unit :mGauss\n");
+ break;
+ case RT_SENSOR_UNIT_LUX:
+ rt_kprintf("unit :lux\n");
+ break;
+ case RT_SENSOR_UNIT_CM:
+ rt_kprintf("unit :cm\n");
+ break;
+ case RT_SENSOR_UNIT_PA:
+ rt_kprintf("unit :pa\n");
+ break;
+ case RT_SENSOR_UNIT_PERMILLAGE:
+ rt_kprintf("unit :permillage\n");
+ break;
+ case RT_SENSOR_UNIT_DCELSIUS:
+ rt_kprintf("unit :Celsius\n");
+ break;
+ case RT_SENSOR_UNIT_HZ:
+ rt_kprintf("unit :HZ\n");
+ break;
+ case RT_SENSOR_UNIT_ONE:
+ rt_kprintf("unit :1\n");
+ break;
+ case RT_SENSOR_UNIT_BPM:
+ rt_kprintf("unit :bpm\n");
+ break;
+ case RT_SENSOR_UNIT_MM:
+ rt_kprintf("unit :mm\n");
+ break;
+ case RT_SENSOR_UNIT_MN:
+ rt_kprintf("unit :mN\n");
+ break;
+ }
rt_kprintf("range_max :%d\n", info.range_max);
rt_kprintf("range_min :%d\n", info.range_min);
- rt_kprintf("period_min:%d\n", info.period_min);
+ rt_kprintf("period_min:%dms\n", info.period_min);
rt_kprintf("fifo_max :%d\n", info.fifo_max);
}
else if (!strcmp(argv[1], "read"))
diff --git a/components/drivers/serial/serial.c b/components/drivers/serial/serial.c
index c3e96fc77b..50dd7e188b 100644
--- a/components/drivers/serial/serial.c
+++ b/components/drivers/serial/serial.c
@@ -327,6 +327,18 @@ rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t *
return size - length;
}
+static void _serial_check_buffer_size(void)
+{
+ static rt_bool_t already_output = RT_FALSE;
+
+ if (already_output == RT_FALSE)
+ {
+ LOG_W("Warning: There is no enough buffer for saving data,"
+ " please increase the RT_SERIAL_RB_BUFSZ option.");
+ already_output = RT_TRUE;
+ }
+}
+
#if defined(RT_USING_POSIX) || defined(RT_SERIAL_USING_DMA)
static rt_size_t _serial_fifo_calc_recved_len(struct rt_serial_device *serial)
{
@@ -428,12 +440,11 @@ static void rt_dma_recv_update_put_index(struct rt_serial_device *serial, rt_siz
}
}
- if(rx_fifo->is_full == RT_TRUE)
+ if(rx_fifo->is_full == RT_TRUE)
{
- rx_fifo->get_index = rx_fifo->put_index;
- }
-
- if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
+ _serial_check_buffer_size();
+ rx_fifo->get_index = rx_fifo->put_index;
+ }
}
/*
@@ -791,16 +802,16 @@ static rt_size_t rt_serial_read(struct rt_device *dev,
if (dev->open_flag & RT_DEVICE_FLAG_INT_RX)
{
- return _serial_int_rx(serial, buffer, size);
+ return _serial_int_rx(serial, (rt_uint8_t *)buffer, size);
}
#ifdef RT_SERIAL_USING_DMA
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
{
- return _serial_dma_rx(serial, buffer, size);
+ return _serial_dma_rx(serial, (rt_uint8_t *)buffer, size);
}
#endif /* RT_SERIAL_USING_DMA */
- return _serial_poll_rx(serial, buffer, size);
+ return _serial_poll_rx(serial, (rt_uint8_t *)buffer, size);
}
static rt_size_t rt_serial_write(struct rt_device *dev,
@@ -817,17 +828,17 @@ static rt_size_t rt_serial_write(struct rt_device *dev,
if (dev->open_flag & RT_DEVICE_FLAG_INT_TX)
{
- return _serial_int_tx(serial, buffer, size);
+ return _serial_int_tx(serial, (const rt_uint8_t *)buffer, size);
}
#ifdef RT_SERIAL_USING_DMA
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX)
{
- return _serial_dma_tx(serial, buffer, size);
+ return _serial_dma_tx(serial, (const rt_uint8_t *)buffer, size);
}
#endif /* RT_SERIAL_USING_DMA */
else
{
- return _serial_poll_tx(serial, buffer, size);
+ return _serial_poll_tx(serial, (const rt_uint8_t *)buffer, size);
}
}
@@ -1172,6 +1183,8 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
rx_fifo->get_index += 1;
rx_fifo->is_full = RT_TRUE;
if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
+
+ _serial_check_buffer_size();
}
/* enable interrupt */
diff --git a/components/drivers/spi/SConscript b/components/drivers/spi/SConscript
index b88671ebc9..e19f30861f 100644
--- a/components/drivers/spi/SConscript
+++ b/components/drivers/spi/SConscript
@@ -14,24 +14,9 @@ src_device = []
if GetDepend('RT_USING_SPI_WIFI'):
src_device += ['spi_wifi_rw009.c']
-if GetDepend('RT_USING_W25QXX'):
- src_device += ['spi_flash_w25qxx.c']
-
-if GetDepend('RT_USING_W25QXX_MTD'):
- src_device += ['spi_flash_w25qxx_mtd.c']
-
if GetDepend('RT_USING_ENC28J60'):
src_device += ['enc28j60.c']
-if GetDepend('RT_USING_AT45DBXX'):
- src_device += ['spi_flash_at45dbxx.c']
-
-if GetDepend('RT_USING_SST25VFXX'):
- src_device += ['spi_flash_sst25vfxx.c']
-
-if GetDepend('RT_USING_GD'):
- src_device += ['spi_flash_gd.c']
-
if GetDepend('RT_USING_SPI_MSD'):
src_device += ['spi_msd.c']
diff --git a/components/drivers/spi/device_driver_list.txt b/components/drivers/spi/device_driver_list.txt
index 2c9d6a16b8..939baa7531 100644
--- a/components/drivers/spi/device_driver_list.txt
+++ b/components/drivers/spi/device_driver_list.txt
@@ -5,11 +5,5 @@ http://www.rt-thread.com/
enc28j60.c/enc28j60.h
http://www.microchip.com/
-spi_flash_at45dbxx.c/spi_flash_at45dbxx.h
-http://www.atmel.com/
-
-spi_flash_sst25vfxx.c/spi_flash_sst25vfxx.h
-http://www.microchip.com/
-
-spi_flash_w25qxx.c/spi_flash_w25qxx.h
-http://www.winbond.com/
+spi_flash_sfud: Serial Flash Universal Driver
+https://github.com/armink/SFUD \ No newline at end of file
diff --git a/components/drivers/spi/sfud/inc/sfud_cfg.h b/components/drivers/spi/sfud/inc/sfud_cfg.h
index 051de6d577..3b7860062d 100644
--- a/components/drivers/spi/sfud/inc/sfud_cfg.h
+++ b/components/drivers/spi/sfud/inc/sfud_cfg.h
@@ -59,6 +59,6 @@
#define SFUD_USING_FLASH_INFO_TABLE
#endif
-#define SFUD_FLASH_DEVICE_TABLE {0}
+#define SFUD_FLASH_DEVICE_TABLE {{0}}
#endif /* _SFUD_CFG_H_ */
diff --git a/components/drivers/spi/sfud/inc/sfud_flash_def.h b/components/drivers/spi/sfud/inc/sfud_flash_def.h
index 8922375557..13a0e702a8 100644
--- a/components/drivers/spi/sfud/inc/sfud_flash_def.h
+++ b/components/drivers/spi/sfud/inc/sfud_flash_def.h
@@ -124,6 +124,7 @@ typedef struct {
{"AT45DB161E", SFUD_MF_ID_ATMEL, 0x26, 0x00, 2L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_DUAL_BUFFER, 512, 0x81}, \
{"W25Q40BV", SFUD_MF_ID_WINBOND, 0x40, 0x13, 512L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q16BV", SFUD_MF_ID_WINBOND, 0x40, 0x15, 2L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
+ {"W25Q64DW", SFUD_MF_ID_WINBOND, 0x60, 0x17, 8L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q128BV", SFUD_MF_ID_WINBOND, 0x40, 0x18, 16L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q256FV", SFUD_MF_ID_WINBOND, 0x40, 0x19, 32L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"SST25VF016B", SFUD_MF_ID_SST, 0x25, 0x41, 2L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \
diff --git a/components/drivers/spi/spi_flash_at45dbxx.c b/components/drivers/spi/spi_flash_at45dbxx.c
deleted file mode 100644
index 0a30f0a328..0000000000
--- a/components/drivers/spi/spi_flash_at45dbxx.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2011-12-16 aozima the first version
- */
-
-#include <stdint.h>
-#include "spi_flash_at45dbxx.h"
-
-#define FLASH_DEBUG
-#define DMA_BUFFER_SIZE 512
-
-#ifdef FLASH_DEBUG
-#define FLASH_TRACE rt_kprintf
-#else
-#define FLASH_TRACE(...)
-#endif /**< #ifdef FLASH_DEBUG */
-
-/* JEDEC Manufacturer’s ID */
-#define MF_ID (0x1F) /* atmel */
-#define DENSITY_CODE_011D (0x02) /* AT45DB011D Density Code : 00010 = 1-Mbit */
-#define DENSITY_CODE_021D (0x03) /* AT45DB021D Density Code : 00011 = 2-Mbit */
-#define DENSITY_CODE_041D (0x04) /* AT45DB041D Density Code : 00100 = 4-Mbit */
-#define DENSITY_CODE_081D (0x05) /* AT45DB081D Density Code : 00101 = 8-Mbit */
-#define DENSITY_CODE_161D (0x06) /* AT45DB161D Density Code : 00110 = 16-Mbit */
-#define DENSITY_CODE_321D (0x07) /* AT45DB321D Density Code : 00111 = 32-Mbit */
-#define DENSITY_CODE_642D (0x08) /* AT45DB642D Density Code : 01000 = 64-Mbit */
-
-struct JEDEC_ID
-{
- uint8_t manufacturer_id; /* Manufacturer ID */
- uint8_t density_code:5; /* Density Code */
- uint8_t family_code:3; /* Family Code */
- uint8_t version_code:5; /* Product Version Code */
- uint8_t mlc_code:3; /* MLC Code */
- uint8_t byte_count; /* Byte Count */
-};
-
-#define AT45DB_BUFFER_1_WRITE 0x84
-#define AT45DB_BUFFER_2_WRITE 0x87
-#define AT45DB_BUFFER_1_READ 0xD4
-#define AT45DB_BUFFER_2_READ 0xD6
-#define AT45DB_B1_TO_MM_PAGE_PROG_WITH_ERASE 0x83
-#define AT45DB_B2_TO_MM_PAGE_PROG_WITH_ERASE 0x86
-#define AT45DB_MM_PAGE_TO_B1_XFER 0x53
-#define AT45DB_MM_PAGE_TO_B2_XFER 0x55
-#define AT45DB_PAGE_ERASE 0x81
-#define AT45DB_SECTOR_ERASE 0x7C
-#define AT45DB_READ_STATE_REGISTER 0xD7
-#define AT45DB_MM_PAGE_READ 0xD2
-#define AT45DB_MM_PAGE_PROG_THRU_BUFFER1 0x82
-#define AT45DB_CMD_JEDEC_ID 0x9F
-
-static struct spi_flash_at45dbxx spi_flash_at45dbxx;
-
-/*****************************************************************************/
-/*Status Register Format: */
-/* ------------------------------------------------------------------------- */
-/* | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | */
-/* |--------|--------|--------|--------|--------|--------|--------|--------| */
-/* |RDY/BUSY| COMP | device density | X | X | */
-/* ------------------------------------------------------------------------- */
-/* 0:busy | | AT45DB041:0111 | protect|page size */
-/* 1:ready | | AT45DB161:1011 | */
-/* --------------------------------------------------------------------------*/
-/*****************************************************************************/
-static uint8_t AT45DB_StatusRegisterRead(void)
-{
- return rt_spi_sendrecv8(spi_flash_at45dbxx.rt_spi_device, AT45DB_READ_STATE_REGISTER);
-}
-
-static void wait_busy(void)
-{
- uint16_t i = 0;
- while (i++ < 10000)
- {
- if (AT45DB_StatusRegisterRead() & 0x80)
- {
- return;
- }
- }
- FLASH_TRACE("\r\nSPI_FLASH timeout!!!\r\n");
-}
-
-/* RT-Thread Device Driver Interface */
-static rt_err_t AT45DB_flash_init(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t AT45DB_flash_open(rt_device_t dev, rt_uint16_t oflag)
-{
-
- return RT_EOK;
-}
-
-static rt_err_t AT45DB_flash_close(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t AT45DB_flash_control(rt_device_t dev, int cmd, void *args)
-{
- RT_ASSERT(dev != RT_NULL);
-
- if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
- {
- struct rt_device_blk_geometry *geometry;
-
- geometry = (struct rt_device_blk_geometry *)args;
- if (geometry == RT_NULL) return -RT_ERROR;
-
- geometry->bytes_per_sector = 512;
- geometry->sector_count = 4096;
- geometry->block_size = 4096; /* block erase: 4k */
- }
-
- return RT_EOK;
-}
-
-static rt_size_t AT45DB_flash_read_page_256(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
-{
- uint32_t index, nr;
- uint8_t * read_buffer = buffer;
- uint32_t page = pos;
-
- nr = size;
-
- for (index = 0; index < nr; index++)
- {
- uint8_t send_buffer[8];
- uint32_t i;
-
- for(i=0; i<sizeof(send_buffer); i++)
- {
- send_buffer[i] = 0;
- }
-
- send_buffer[0] = AT45DB_MM_PAGE_READ;
- send_buffer[1] = (uint8_t)(page >> 7);
- send_buffer[2] = (uint8_t)(page << 1);
-
- rt_spi_send_then_recv(spi_flash_at45dbxx.rt_spi_device, send_buffer, 8, read_buffer, 256);
- read_buffer += 256;
- page++;
- }
-
- return size;
-}
-
-static rt_size_t AT45DB_flash_read_page_512(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
-{
- uint32_t index, nr;
- uint8_t * read_buffer = buffer;
- uint32_t page = pos;
-
- nr = size;
-
- for (index = 0; index < nr; index++)
- {
- uint8_t send_buffer[8];
- uint32_t i;
-
- for(i=0; i<sizeof(send_buffer); i++)
- {
- send_buffer[i] = 0;
- }
-
- send_buffer[0] = AT45DB_MM_PAGE_READ;
- send_buffer[1] = (uint8_t)(page >> 6);
- send_buffer[2] = (uint8_t)(page << 2);
-
- rt_spi_send_then_recv(spi_flash_at45dbxx.rt_spi_device, send_buffer, 8, read_buffer, 512);
- read_buffer += 512;
- page++;
- }
-
- return size;
-}
-
-static rt_size_t AT45DB_flash_read_page_1024(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
-{
- uint32_t index, nr;
- uint8_t * read_buffer = buffer;
- uint32_t page = pos;
-
- nr = size;
-
- for (index = 0; index < nr; index++)
- {
- uint8_t send_buffer[8];
- uint32_t i;
-
- for(i=0; i<sizeof(send_buffer); i++)
- {
- send_buffer[i] = 0;
- }
-
- send_buffer[0] = AT45DB_MM_PAGE_READ;
- send_buffer[1] = (uint8_t)(page >> 5);
- send_buffer[2] = (uint8_t)(page << 3);
-
- rt_spi_send_then_recv(spi_flash_at45dbxx.rt_spi_device, send_buffer, 8, read_buffer, 1024);
- read_buffer += 1024;
- page++;
- }
-
- return size;
-}
-
-static rt_size_t AT45DB_flash_write_page_256(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
-{
- rt_uint32_t index, nr;
- const uint8_t * write_buffer = buffer;
- uint32_t page = pos;
-
- nr = size;
-
- for (index = 0; index < nr; index++)
- {
- uint8_t send_buffer[4];
-
- send_buffer[0] = AT45DB_MM_PAGE_PROG_THRU_BUFFER1;
- send_buffer[1] = (uint8_t) (page >> 7);
- send_buffer[2] = (uint8_t) (page << 1);
- send_buffer[3] = 0;
-
- rt_spi_send_then_send(spi_flash_at45dbxx.rt_spi_device, send_buffer, 4, write_buffer, 256);
-
- write_buffer += 256;
- page++;
-
- wait_busy();
- }
-
- return size;
-}
-
-static rt_size_t AT45DB_flash_write_page_512(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
-{
- rt_uint32_t index, nr;
- const uint8_t * write_buffer = buffer;
- uint32_t page = pos;
-
- nr = size;
-
- for (index = 0; index < nr; index++)
- {
- uint8_t send_buffer[4];
-
- send_buffer[0] = AT45DB_MM_PAGE_PROG_THRU_BUFFER1;
- send_buffer[1] = (uint8_t) (page >> 6);
- send_buffer[2] = (uint8_t) (page << 2);
- send_buffer[3] = 0;
-
- rt_spi_send_then_send(spi_flash_at45dbxx.rt_spi_device, send_buffer, 4, write_buffer, 512);
-
- write_buffer += 512;
- page++;
-
- wait_busy();
- }
-
- return size;
-}
-
-static rt_size_t AT45DB_flash_write_page_1024(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
-{
- rt_uint32_t index, nr;
- const uint8_t * write_buffer = buffer;
- uint32_t page = pos;
-
- nr = size;
-
- for (index = 0; index < nr; index++)
- {
- uint8_t send_buffer[4];
-
- send_buffer[0] = AT45DB_MM_PAGE_PROG_THRU_BUFFER1;
- send_buffer[1] = (uint8_t) (page >> 5);
- send_buffer[2] = (uint8_t) (page << 3);
- send_buffer[3] = 0;
-
- rt_spi_send_then_send(spi_flash_at45dbxx.rt_spi_device, send_buffer, 4, write_buffer, 1024);
-
- write_buffer += 1024;
- page++;
-
- wait_busy();
- }
-
- return size;
-}
-
-rt_err_t at45dbxx_init(const char * flash_device_name, const char * spi_device_name)
-{
- struct rt_spi_device * rt_spi_device;
- struct JEDEC_ID * JEDEC_ID;
-
- rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
- if(rt_spi_device == RT_NULL)
- {
- FLASH_TRACE("spi device %s not found!\r\n", spi_device_name);
- return -RT_ENOSYS;
- }
- spi_flash_at45dbxx.rt_spi_device = rt_spi_device;
-
- /* config spi */
- {
- struct rt_spi_configuration cfg;
- cfg.data_width = 8;
- cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 and 3 */
- cfg.max_hz = 66000000; /* Atmel RapidS Serial Interface: 66MHz Maximum Clock Frequency */
- rt_spi_configure(spi_flash_at45dbxx.rt_spi_device, &cfg);
- }
-
- /* read JEDEC ID */
- {
- uint8_t cmd;
- uint8_t id_recv[6];
- JEDEC_ID = (struct JEDEC_ID *)id_recv;
-
- cmd = AT45DB_CMD_JEDEC_ID;
- rt_spi_send_then_recv(spi_flash_at45dbxx.rt_spi_device, &cmd, 1, id_recv, 6);
-
- /**< 1FH = Atmel */
- /**< 001 = Atmel DataFlash */
- if(JEDEC_ID->manufacturer_id != 0x1F || JEDEC_ID->family_code != 0x01)
- {
- FLASH_TRACE("Manufacturer’s ID or Memory Type error!\r\n");
- FLASH_TRACE("JEDEC Read-ID Data : %02X %02X %02X\r\n", id_recv[0], id_recv[1], id_recv[2]);
- return -RT_ENOSYS;
- }
-
- if(JEDEC_ID->density_code == DENSITY_CODE_011D)
- {
- /**< AT45DB011D Density Code : 00010 = 1-Mbit */
- FLASH_TRACE("AT45DB011D detection\r\n");
- spi_flash_at45dbxx.geometry.bytes_per_sector = 256; /* Page Erase (256 Bytes) */
- spi_flash_at45dbxx.geometry.sector_count = 512; /* 1-Mbit / 8 / 256 = 512 */
- spi_flash_at45dbxx.geometry.block_size = 1024*2; /* Block Erase (2-Kbytes) */
- }
- else if(JEDEC_ID->density_code == DENSITY_CODE_021D)
- {
- /**< AT45DB021D Density Code : 00011 = 2-Mbit */
- FLASH_TRACE("AT45DB021D detection\r\n");
- spi_flash_at45dbxx.geometry.bytes_per_sector = 256; /* Page Erase (256 Bytes) */
- spi_flash_at45dbxx.geometry.sector_count = 512*2; /* 2-Mbit / 8 / 256 = 1024 */
- spi_flash_at45dbxx.geometry.block_size = 1024*2; /* Block Erase (2-Kbytes) */
- }
- else if(JEDEC_ID->density_code == DENSITY_CODE_041D)
- {
- /**< AT45DB041D Density Code : 00100 = 4-Mbit */
- FLASH_TRACE("AT45DB041D detection\r\n");
- spi_flash_at45dbxx.geometry.bytes_per_sector = 256; /* Page Erase (256 Bytes) */
- spi_flash_at45dbxx.geometry.sector_count = 512*4; /* 4-Mbit / 8 / 256 = 2048 */
- spi_flash_at45dbxx.geometry.block_size = 1024*2; /* Block Erase (2-Kbytes) */
- }
- else if(JEDEC_ID->density_code == DENSITY_CODE_081D)
- {
- /**< AT45DB081D Density Code : 00101 = 8-Mbit */
- FLASH_TRACE("AT45DB081D detection\r\n");
- spi_flash_at45dbxx.geometry.bytes_per_sector = 256; /* Page Erase (256 Bytes) */
- spi_flash_at45dbxx.geometry.sector_count = 512*8; /* 8-Mbit / 8 / 256 = 4096 */
- spi_flash_at45dbxx.geometry.block_size = 1024*2; /* Block Erase (2-Kbytes) */
- }
- else if(JEDEC_ID->density_code == DENSITY_CODE_161D)
- {
- /**< AT45DB161D Density Code : 00110 = 16-Mbit */
- FLASH_TRACE("AT45DB161D detection\r\n");
- spi_flash_at45dbxx.geometry.bytes_per_sector = 512; /* Page Erase (512 Bytes) */
- spi_flash_at45dbxx.geometry.sector_count = 256*16; /* 16-Mbit / 8 / 512 = 4096 */
- spi_flash_at45dbxx.geometry.block_size = 1024*4; /* Block Erase (4-Kbytes) */
- }
- else if(JEDEC_ID->density_code == DENSITY_CODE_321D)
- {
- /**< AT45DB321D Density Code : 00111 = 32-Mbit */
- FLASH_TRACE("AT45DB321D detection\r\n");
- spi_flash_at45dbxx.geometry.bytes_per_sector = 512; /* Page Erase (512 Bytes) */
- spi_flash_at45dbxx.geometry.sector_count = 256*32; /* 32-Mbit / 8 / 512 = 8192 */
- spi_flash_at45dbxx.geometry.block_size = 1024*4; /* Block Erase (4-Kbytes) */
- }
- else if(JEDEC_ID->density_code == DENSITY_CODE_642D)
- {
- /**< AT45DB642D Density Code : 01000 = 64-Mbit */
- FLASH_TRACE("AT45DB642D detection\r\n");
- spi_flash_at45dbxx.geometry.bytes_per_sector = 1024; /* Page Erase (1 Kbyte) */
- spi_flash_at45dbxx.geometry.sector_count = 128*64; /* 64-Mbit / 8 / 1024 = 8192 */
- spi_flash_at45dbxx.geometry.block_size = 1024*8; /* Block Erase (8 Kbytes) */
- }
- else
- {
- FLASH_TRACE("Memory Capacity error!\r\n");
- return -RT_ENOSYS;
- }
- }
-
- /* register device */
- spi_flash_at45dbxx.flash_device.type = RT_Device_Class_Block;
- spi_flash_at45dbxx.flash_device.init = AT45DB_flash_init;
- spi_flash_at45dbxx.flash_device.open = AT45DB_flash_open;
- spi_flash_at45dbxx.flash_device.close = AT45DB_flash_close;
- spi_flash_at45dbxx.flash_device.control = AT45DB_flash_control;
-
- if(JEDEC_ID->density_code == DENSITY_CODE_642D)
- {
- spi_flash_at45dbxx.flash_device.read = AT45DB_flash_read_page_1024;
- spi_flash_at45dbxx.flash_device.write = AT45DB_flash_write_page_1024;
- }
- else if(JEDEC_ID->density_code == DENSITY_CODE_161D
- || JEDEC_ID->density_code == DENSITY_CODE_321D )
- {
- spi_flash_at45dbxx.flash_device.read = AT45DB_flash_read_page_512;
- spi_flash_at45dbxx.flash_device.write = AT45DB_flash_write_page_512;
- }
- else
- {
- spi_flash_at45dbxx.flash_device.read = AT45DB_flash_read_page_256;
- spi_flash_at45dbxx.flash_device.write = AT45DB_flash_write_page_256;
- }
-
- /* no private */
- spi_flash_at45dbxx.flash_device.user_data = RT_NULL;
-
- rt_device_register(&spi_flash_at45dbxx.flash_device, flash_device_name,
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
-
- return RT_EOK;
-}
diff --git a/components/drivers/spi/spi_flash_at45dbxx.h b/components/drivers/spi/spi_flash_at45dbxx.h
deleted file mode 100644
index d1bc1a2aeb..0000000000
--- a/components/drivers/spi/spi_flash_at45dbxx.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2011-12-16 aozima the first version
- */
-
-#ifndef SPI_FLASH_AT45DBXX_H_INCLUDED
-#define SPI_FLASH_AT45DBXX_H_INCLUDED
-
-#include <rtthread.h>
-#include <drivers/spi.h>
-
-struct spi_flash_at45dbxx
-{
- struct rt_device flash_device;
- struct rt_device_blk_geometry geometry;
- struct rt_spi_device * rt_spi_device;
-};
-
-extern rt_err_t at45dbxx_init(const char * flash_device_name, const char * spi_device_name);
-
-
-#endif // SPI_FLASH_AT45DBXX_H_INCLUDED
diff --git a/components/drivers/spi/spi_flash_gd.c b/components/drivers/spi/spi_flash_gd.c
deleted file mode 100644
index 3c52035372..0000000000
--- a/components/drivers/spi/spi_flash_gd.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2015-10-11 fullhan copy from winbond flash
- */
-
-#include <stdint.h>
-#include <rtthread.h>
-#include <rtdevice.h>
-
-#include "spi_flash.h"
-#include "spi_flash_gd.h"
-
-#define FLASH_DEBUG
-
-#ifdef FLASH_DEBUG
-#define FLASH_TRACE rt_kprintf
-#else
-#define FLASH_TRACE(...)
-#endif /* #ifdef FLASH_DEBUG */
-
-#define PAGE_SIZE 4096
-
-/* JEDEC Manufacturer's ID */
-#define MF_ID (0xC8)
-/* JEDEC Device ID: Memory type and Capacity */
-#define MTC_GD25Q128 (0x4018)
-
-/* command list */
-#define CMD_WRSR (0x01) /* Write Status Register */
-#define CMD_PP (0x02) /* Page Program */
-#define CMD_READ (0x03) /* Read Data */
-#define CMD_WRDI (0x04) /* Write Disable */
-#define CMD_RDSR1 (0x05) /* Read Status Register-1 */
-#define CMD_WREN (0x06) /* Write Enable */
-#define CMD_FAST_READ (0x0B) /* Fast Read */
-#define CMD_ERASE_4K (0x20) /* Sector Erase:4K */
-#define CMD_RDSR2 (0x35) /* Read Status Register-2 */
-#define CMD_ERASE_32K (0x52) /* 32KB Block Erase */
-#define CMD_JEDEC_ID (0x9F) /* Read JEDEC ID */
-#define CMD_ERASE_full (0xC7) /* Chip Erase */
-#define CMD_ERASE_64K (0xD8) /* 64KB Block Erase */
-
-#define DUMMY (0xFF)
-
-static struct spi_flash_device spi_flash_device;
-
-static void flash_lock(struct spi_flash_device * flash_device)
-{
- rt_mutex_take(&flash_device->lock, RT_WAITING_FOREVER);
-}
-
-static void flash_unlock(struct spi_flash_device * flash_device)
-{
- rt_mutex_release(&flash_device->lock);
-}
-
-static uint8_t w25qxx_read_status(void)
-{
- return rt_spi_sendrecv8(spi_flash_device.rt_spi_device, CMD_RDSR1);
-}
-
-static void w25qxx_wait_busy(void)
-{
- while( w25qxx_read_status() & (0x01));
-}
-
-/** \brief read [size] byte from [offset] to [buffer]
- *
- * \param offset uint32_t unit : byte
- * \param buffer uint8_t*
- * \param size uint32_t unit : byte
- * \return uint32_t byte for read
- *
- */
-static uint32_t w25qxx_read(uint32_t offset, uint8_t * buffer, uint32_t size)
-{
- uint8_t send_buffer[4];
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_READ;
- send_buffer[1] = (uint8_t)(offset>>16);
- send_buffer[2] = (uint8_t)(offset>>8);
- send_buffer[3] = (uint8_t)(offset);
-
- rt_spi_send_then_recv(spi_flash_device.rt_spi_device,
- send_buffer, 4,
- buffer, size);
-
- return size;
-}
-
-/** \brief write N page on [page]
- *
- * \param page_addr uint32_t unit : byte (4096 * N,1 page = 4096byte)
- * \param buffer const uint8_t*
- * \return uint32_t
- *
- */
-static uint32_t w25qxx_page_write(uint32_t page_addr, const uint8_t* buffer)
-{
- uint32_t index;
- uint8_t send_buffer[4];
-
- RT_ASSERT((page_addr&0xFF) == 0); /* page addr must align to 256byte. */
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_ERASE_4K;
- send_buffer[1] = (page_addr >> 16);
- send_buffer[2] = (page_addr >> 8);
- send_buffer[3] = (page_addr);
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 4);
-
- w25qxx_wait_busy(); // wait erase done.
-
- for(index=0; index < (PAGE_SIZE / 256); index++)
- {
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_PP;
- send_buffer[1] = (uint8_t)(page_addr >> 16);
- send_buffer[2] = (uint8_t)(page_addr >> 8);
- send_buffer[3] = (uint8_t)(page_addr);
-
- rt_spi_send_then_send(spi_flash_device.rt_spi_device,
- send_buffer,
- 4,
- buffer,
- 256);
-
- buffer += 256;
- page_addr += 256;
- w25qxx_wait_busy();
- }
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- return PAGE_SIZE;
-}
-
-/* RT-Thread device interface */
-static rt_err_t w25qxx_flash_init(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t w25qxx_flash_open(rt_device_t dev, rt_uint16_t oflag)
-{
- uint8_t send_buffer[3];
-
- flash_lock((struct spi_flash_device *)dev);
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_WRSR;
- send_buffer[1] = 0;
- send_buffer[2] = 0;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 3);
-
- w25qxx_wait_busy();
-
- flash_unlock((struct spi_flash_device *)dev);
-
- return RT_EOK;
-}
-
-static rt_err_t w25qxx_flash_close(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t w25qxx_flash_control(rt_device_t dev, int cmd, void *args)
-{
- RT_ASSERT(dev != RT_NULL);
-
- if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
- {
- struct rt_device_blk_geometry *geometry;
-
- geometry = (struct rt_device_blk_geometry *)args;
- if (geometry == RT_NULL) return -RT_ERROR;
-
- geometry->bytes_per_sector = spi_flash_device.geometry.bytes_per_sector;
- geometry->sector_count = spi_flash_device.geometry.sector_count;
- geometry->block_size = spi_flash_device.geometry.block_size;
- }
-
- return RT_EOK;
-}
-
-static rt_size_t w25qxx_flash_read(rt_device_t dev,
- rt_off_t pos,
- void* buffer,
- rt_size_t size)
-{
- flash_lock((struct spi_flash_device *)dev);
-
- w25qxx_read(pos*spi_flash_device.geometry.bytes_per_sector,
- buffer,
- size*spi_flash_device.geometry.bytes_per_sector);
-
- flash_unlock((struct spi_flash_device *)dev);
-
- return size;
-}
-
-static rt_size_t w25qxx_flash_write(rt_device_t dev,
- rt_off_t pos,
- const void* buffer,
- rt_size_t size)
-{
- rt_size_t i = 0;
- rt_size_t block = size;
- const uint8_t * ptr = buffer;
-
- flash_lock((struct spi_flash_device *)dev);
-
- while(block--)
- {
- w25qxx_page_write((pos + i)*spi_flash_device.geometry.bytes_per_sector,
- ptr);
- ptr += PAGE_SIZE;
- i++;
- }
-
- flash_unlock((struct spi_flash_device *)dev);
-
- return size;
-}
-
-#ifdef RT_USING_DEVICE_OPS
-const static struct rt_device_ops gd_device_ops =
-{
- w25qxx_flash_init,
- w25qxx_flash_open,
- w25qxx_flash_close,
- w25qxx_flash_read,
- w25qxx_flash_write,
- w25qxx_flash_control
-};
-#endif
-
-rt_err_t gd_init(const char * flash_device_name, const char * spi_device_name)
-{
- struct rt_spi_device * rt_spi_device;
-
- /* initialize mutex */
- if (rt_mutex_init(&spi_flash_device.lock, spi_device_name, RT_IPC_FLAG_FIFO) != RT_EOK)
- {
- rt_kprintf("init sd lock mutex failed\n");
- return -RT_ENOSYS;
- }
-
- rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
- if(rt_spi_device == RT_NULL)
- {
- FLASH_TRACE("spi device %s not found!\r\n", spi_device_name);
- return -RT_ENOSYS;
- }
- spi_flash_device.rt_spi_device = rt_spi_device;
-
- /* config spi */
- {
- struct rt_spi_configuration cfg;
- cfg.data_width = 8;
- cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
- cfg.max_hz = 50 * 1000 * 1000; /* 50M */
- rt_spi_configure(spi_flash_device.rt_spi_device, &cfg);
- }
-
- /* init flash */
- {
- rt_uint8_t cmd;
- rt_uint8_t id_recv[3];
- uint16_t memory_type_capacity;
-
- flash_lock(&spi_flash_device);
-
- cmd = 0xFF; /* reset SPI FLASH, cancel all cmd in processing. */
- rt_spi_send(spi_flash_device.rt_spi_device, &cmd, 1);
-
- cmd = CMD_WRDI;
- rt_spi_send(spi_flash_device.rt_spi_device, &cmd, 1);
-
- /* read flash id */
- cmd = CMD_JEDEC_ID;
- rt_spi_send_then_recv(spi_flash_device.rt_spi_device, &cmd, 1, id_recv, 3);
-
- flash_unlock(&spi_flash_device);
-
- if(id_recv[0] != MF_ID)
- {
- FLASH_TRACE("Manufacturers ID error!\r\n");
- FLASH_TRACE("JEDEC Read-ID Data : %02X %02X %02X\r\n", id_recv[0], id_recv[1], id_recv[2]);
- return -RT_ENOSYS;
- }
-
- spi_flash_device.geometry.bytes_per_sector = 4096;
- spi_flash_device.geometry.block_size = 4096; /* block erase: 4k */
-
- /* get memory type and capacity */
- memory_type_capacity = id_recv[1];
- memory_type_capacity = (memory_type_capacity << 8) | id_recv[2];
-
- if(memory_type_capacity == MTC_GD25Q128)
- {
- FLASH_TRACE("GD128 detection\r\n");
- spi_flash_device.geometry.sector_count = 4096;
- }
- else
- {
- FLASH_TRACE("Memory Capacity error!\r\n");
- return -RT_ENOSYS;
- }
- }
-
- /* register device */
- spi_flash_device.flash_device.type = RT_Device_Class_Block;
-#ifdef RT_USING_DEVICE_OPS
- spi_flash_device.flash_device.ops = &gd_device_ops;
-#else
- spi_flash_device.flash_device.init = w25qxx_flash_init;
- spi_flash_device.flash_device.open = w25qxx_flash_open;
- spi_flash_device.flash_device.close = w25qxx_flash_close;
- spi_flash_device.flash_device.read = w25qxx_flash_read;
- spi_flash_device.flash_device.write = w25qxx_flash_write;
- spi_flash_device.flash_device.control = w25qxx_flash_control;
-#endif
- /* no private */
- spi_flash_device.flash_device.user_data = RT_NULL;
-
- rt_device_register(&spi_flash_device.flash_device, flash_device_name,
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
-
- return RT_EOK;
-}
diff --git a/components/drivers/spi/spi_flash_gd.h b/components/drivers/spi/spi_flash_gd.h
deleted file mode 100644
index 904d976ed0..0000000000
--- a/components/drivers/spi/spi_flash_gd.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2015-10-11 fullhan copy from winbond flash
- */
-
-#ifndef SPI_FLASH_GD_H_
-#define SPI_FLASH_GD_H_
-
-#include <rtthread.h>
-
-extern rt_err_t gd_init(const char * flash_device_name, const char * spi_device_name);
-
-#endif /* SPI_FLASH_GD_H_ */
diff --git a/components/drivers/spi/spi_flash_sfud.c b/components/drivers/spi/spi_flash_sfud.c
index 7fa7de6ad5..ce67ce9a72 100644
--- a/components/drivers/spi/spi_flash_sfud.c
+++ b/components/drivers/spi/spi_flash_sfud.c
@@ -22,12 +22,17 @@
#endif /* RT_DEBUG_SFUD */
#ifndef RT_SFUD_DEFAULT_SPI_CFG
+
+#ifndef RT_SFUD_SPI_MAX_HZ
+#define RT_SFUD_SPI_MAX_HZ 50000000
+#endif
+
/* read the JEDEC SFDP command must run at 50 MHz or less */
#define RT_SFUD_DEFAULT_SPI_CFG \
{ \
.mode = RT_SPI_MODE_0 | RT_SPI_MSB, \
.data_width = 8, \
- .max_hz = 50 * 1000 * 1000, \
+ .max_hz = RT_SFUD_SPI_MAX_HZ, \
}
#endif
diff --git a/components/drivers/spi/spi_flash_sst25vfxx.c b/components/drivers/spi/spi_flash_sst25vfxx.c
deleted file mode 100644
index bd618a8e9b..0000000000
--- a/components/drivers/spi/spi_flash_sst25vfxx.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2011-12-16 aozima the first version
- */
-
-#include <stdint.h>
-#include "spi_flash_sst25vfxx.h"
-
-#define FLASH_DEBUG
-
-#ifdef FLASH_DEBUG
-#define FLASH_TRACE rt_kprintf
-#else
-#define FLASH_TRACE(...)
-#endif /* #ifdef FLASH_DEBUG */
-
-/* JEDEC Manufacturer’s ID */
-#define MF_ID (0xBF)
-/* JEDEC Device ID : Memory Type */
-#define MT_ID (0x25)
-/* JEDEC Device ID: Memory Capacity */
-#define MC_ID_SST25VF020B (0x8C) /* 2Mbit */
-#define MC_ID_SST25VF040B (0x8D) /* 4Mbit */
-#define MC_ID_SST25VF080B (0x8E) /* 8Mbit */
-#define MC_ID_SST25VF016B (0x41) /* 16Mbit */
-#define MC_ID_SST25VF032B (0x4A) /* 32Mbit */
-#define MC_ID_SST25VF064C (0x4B) /* 64Mbit */
-
-/* command list */
-#define CMD_RDSR (0x05)
-#define CMD_WRSR (0x01)
-#define CMD_EWSR (0x50)
-#define CMD_WRDI (0x04)
-#define CMD_WREN (0x06)
-#define CMD_READ (0x03)
-#define CMD_FAST_READ (0x0B)
-#define CMD_BP (0x02)
-#define CMD_AAIP (0xAD)
-#define CMD_ERASE_4K (0x20)
-#define CMD_ERASE_32K (0x52)
-#define CMD_ERASE_64K (0xD8)
-#define CMD_ERASE_full (0xC7)
-#define CMD_JEDEC_ID (0x9F)
-#define CMD_EBSY (0x70)
-#define CMD_DBSY (0x80)
-
-#define DUMMY (0xFF)
-
-static struct spi_flash_sst25vfxx spi_flash_sst25vfxx;
-
-static uint8_t sst25vfxx_read_status(struct spi_flash_sst25vfxx * spi_flash)
-{
- return rt_spi_sendrecv8(spi_flash->rt_spi_device, CMD_RDSR);
-}
-
-static void sst25vfxx_wait_busy(struct spi_flash_sst25vfxx * spi_flash)
-{
- while( sst25vfxx_read_status(spi_flash) & (0x01));
-}
-
-/** \brief write N page on [page]
- *
- * \param page uint32_t unit : byte (4096 * N,1 page = 4096byte)
- * \param buffer const uint8_t*
- * \param size uint32_t unit : byte ( 4096*N )
- * \return uint32_t
- *
- */
-static uint32_t sst25vfxx_page_write(struct spi_flash_sst25vfxx * spi_flash, uint32_t page, const uint8_t * buffer, uint32_t size)
-{
- uint32_t index;
- uint32_t need_wirte = size;
- uint8_t send_buffer[6];
-
- page &= ~0xFFF; // page size = 4096byte
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_ERASE_4K;
- send_buffer[1] = (page >> 16);
- send_buffer[2] = (page >> 8);
- send_buffer[3] = (page);
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 4);
-
- sst25vfxx_wait_busy(spi_flash); // wait erase done.
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_AAIP;
- send_buffer[1] = (uint8_t)(page >> 16);
- send_buffer[2] = (uint8_t)(page >> 8);
- send_buffer[3] = (uint8_t)(page);
- send_buffer[4] = *buffer++;
- send_buffer[5] = *buffer++;
- need_wirte -= 2;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 6);
-
- sst25vfxx_wait_busy(spi_flash);
-
- for(index=0; index < need_wirte/2; index++)
- {
- send_buffer[0] = CMD_AAIP;
- send_buffer[1] = *buffer++;
- send_buffer[2] = *buffer++;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 3);
- sst25vfxx_wait_busy(spi_flash);
- }
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 1);
-
- return size;
-}
-
-/* RT-Thread device interface */
-static rt_err_t sst25vfxx_flash_init(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t sst25vfxx_flash_open(rt_device_t dev, rt_uint16_t oflag)
-{
- rt_err_t result;
- uint8_t send_buffer[2];
- struct spi_flash_sst25vfxx * spi_flash = (struct spi_flash_sst25vfxx *)dev;
-
- /* lock spi flash */
- result = rt_mutex_take(&(spi_flash->lock), RT_WAITING_FOREVER);
- if(result != RT_EOK)
- {
- return result;
- }
-
- send_buffer[0] = CMD_DBSY;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_EWSR;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_WRSR;
- send_buffer[1] = 0;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 2);
-
- /* release lock */
- rt_mutex_release(&(spi_flash->lock));
-
- return RT_EOK;
-}
-
-static rt_err_t sst25vfxx_flash_close(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t sst25vfxx_flash_control(rt_device_t dev, int cmd, void *args)
-{
- struct spi_flash_sst25vfxx * spi_flash;
-
- spi_flash = (struct spi_flash_sst25vfxx *)dev;
-
- RT_ASSERT(dev != RT_NULL);
-
- if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
- {
- struct rt_device_blk_geometry *geometry;
-
- geometry = (struct rt_device_blk_geometry *)args;
- if (geometry == RT_NULL) return -RT_ERROR;
-
- geometry->bytes_per_sector = spi_flash->geometry.bytes_per_sector;
- geometry->sector_count = spi_flash->geometry.sector_count;
- geometry->block_size = spi_flash->geometry.block_size;
- }
-
- return RT_EOK;
-}
-
-static rt_size_t sst25vfxx_flash_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
-{
- rt_err_t result;
- uint8_t send_buffer[4];
- struct spi_flash_sst25vfxx * spi_flash = (struct spi_flash_sst25vfxx *)dev;
- uint32_t offset = pos * spi_flash->geometry.bytes_per_sector;
-
- /* lock spi flash */
- result = rt_mutex_take(&(spi_flash->lock), RT_WAITING_FOREVER);
- if(result != RT_EOK)
- {
- return 0;
- }
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_READ;
- send_buffer[1] = (uint8_t)(offset>>16);
- send_buffer[2] = (uint8_t)(offset>>8);
- send_buffer[3] = (uint8_t)(offset);
- rt_spi_send_then_recv(spi_flash->rt_spi_device, send_buffer, 4, buffer, size * spi_flash->geometry.bytes_per_sector);
-
- /* release lock */
- rt_mutex_release(&(spi_flash->lock));
-
- return size;
-}
-
-static rt_size_t sst25vfxx_flash_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
-{
- uint32_t i;
- rt_err_t result;
- const uint8_t * write_buffer = buffer;
- struct spi_flash_sst25vfxx * spi_flash = (struct spi_flash_sst25vfxx *)dev;
-
- /* lock spi flash */
- result = rt_mutex_take(&(spi_flash->lock), RT_WAITING_FOREVER);
- if(result != RT_EOK)
- {
- return 0;
- }
-
- for(i=0; i<size; i++)
- {
- sst25vfxx_page_write(spi_flash,
- (pos + i) * spi_flash->geometry.bytes_per_sector,
- write_buffer,
- spi_flash->geometry.bytes_per_sector);
- write_buffer += spi_flash->geometry.bytes_per_sector;
- }
-
- /* release lock */
- rt_mutex_release(&(spi_flash->lock));
-
- return size;
-}
-
-#ifdef RT_USING_DEVICE_OPS
-const static struct rt_device_ops sst25vfxx_device_ops =
-{
- sst25vfxx_flash_init,
- sst25vfxx_flash_open,
- sst25vfxx_flash_close,
- sst25vfxx_flash_read,
- sst25vfxx_flash_write,
- sst25vfxx_flash_control
-};
-#endif
-
-rt_err_t sst25vfxx_init(const char * flash_device_name, const char * spi_device_name)
-{
- struct rt_spi_device * rt_spi_device;
- struct spi_flash_sst25vfxx * spi_flash = &spi_flash_sst25vfxx;
-
- rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
- if(rt_spi_device == RT_NULL)
- {
- FLASH_TRACE("spi device %s not found!\r\n", spi_device_name);
- return -RT_ENOSYS;
- }
- spi_flash->rt_spi_device = rt_spi_device;
-
- /* config spi */
- {
- struct rt_spi_configuration cfg;
- cfg.data_width = 8;
- cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
- cfg.max_hz = 50000000; /* 50M */
- rt_spi_configure(spi_flash->rt_spi_device, &cfg);
- }
-
- /* init flash */
- {
- rt_uint8_t cmd;
- rt_uint8_t id_recv[3];
-
- cmd = CMD_WRDI;
- rt_spi_send(spi_flash->rt_spi_device, &cmd, 1);
-
- /* read flash id */
- cmd = CMD_JEDEC_ID;
- rt_spi_send_then_recv(spi_flash->rt_spi_device, &cmd, 1, id_recv, 3);
-
- if(id_recv[0] != MF_ID || id_recv[1] != MT_ID)
- {
- FLASH_TRACE("Manufacturer’s ID or Memory Type error!\r\n");
- FLASH_TRACE("JEDEC Read-ID Data : %02X %02X %02X\r\n", id_recv[0], id_recv[1], id_recv[2]);
- return -RT_ENOSYS;
- }
-
- spi_flash->geometry.bytes_per_sector = 4096;
- spi_flash->geometry.block_size = 4096; /* block erase: 4k */
-
- if(id_recv[2] == MC_ID_SST25VF020B)
- {
- FLASH_TRACE("SST25VF020B detection\r\n");
- spi_flash->geometry.sector_count = 64;
- }
- else if(id_recv[2] == MC_ID_SST25VF040B)
- {
- FLASH_TRACE("SST25VF040B detection\r\n");
- spi_flash->geometry.sector_count = 128;
- }
- else if(id_recv[2] == MC_ID_SST25VF080B)
- {
- FLASH_TRACE("SST25VF080B detection\r\n");
- spi_flash->geometry.sector_count = 256;
- }
- else if(id_recv[2] == MC_ID_SST25VF016B)
- {
- FLASH_TRACE("SST25VF016B detection\r\n");
- spi_flash->geometry.sector_count = 512;
- }
- else if(id_recv[2] == MC_ID_SST25VF032B)
- {
- FLASH_TRACE("SST25VF032B detection\r\n");
- spi_flash->geometry.sector_count = 1024;
- }
- else if(id_recv[2] == MC_ID_SST25VF064C)
- {
- FLASH_TRACE("SST25VF064C detection\r\n");
- spi_flash->geometry.sector_count = 2048;
- }
- else
- {
- FLASH_TRACE("Memory Capacity error!\r\n");
- return -RT_ENOSYS;
- }
- }
-
- /* initialize mutex lock */
- rt_mutex_init(&spi_flash->lock, flash_device_name, RT_IPC_FLAG_PRIO);
-
- /* register device */
- spi_flash->flash_device.type = RT_Device_Class_Block;
-#ifdef RT_USING_DEVICE_OPS
- spi_flash->flash_device.ops = &sst25vfxx_device_ops;
-#else
- spi_flash->flash_device.init = sst25vfxx_flash_init;
- spi_flash->flash_device.open = sst25vfxx_flash_open;
- spi_flash->flash_device.close = sst25vfxx_flash_close;
- spi_flash->flash_device.read = sst25vfxx_flash_read;
- spi_flash->flash_device.write = sst25vfxx_flash_write;
- spi_flash->flash_device.control = sst25vfxx_flash_control;
-#endif
- /* no private */
- spi_flash->flash_device.user_data = RT_NULL;
-
- rt_device_register(&spi_flash->flash_device, flash_device_name,
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
-
- return RT_EOK;
-}
diff --git a/components/drivers/spi/spi_flash_sst25vfxx.h b/components/drivers/spi/spi_flash_sst25vfxx.h
deleted file mode 100644
index 7a7283f753..0000000000
--- a/components/drivers/spi/spi_flash_sst25vfxx.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2011-12-16 aozima the first version
- */
-
-#ifndef SPI_FLASH_SST25VFXX_H_INCLUDED
-#define SPI_FLASH_SST25VFXX_H_INCLUDED
-
-#include <rtthread.h>
-#include <drivers/spi.h>
-
-struct spi_flash_sst25vfxx
-{
- struct rt_device flash_device;
- struct rt_device_blk_geometry geometry;
- struct rt_spi_device * rt_spi_device;
- struct rt_mutex lock;
-};
-
-extern rt_err_t sst25vfxx_init(const char * flash_device_name, const char * spi_device_name);
-
-
-#endif // SPI_FLASH_SST25VFXX_H_INCLUDED
diff --git a/components/drivers/spi/spi_flash_w25qxx.c b/components/drivers/spi/spi_flash_w25qxx.c
deleted file mode 100644
index bba9c0b5cc..0000000000
--- a/components/drivers/spi/spi_flash_w25qxx.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2011-12-16 aozima the first version
- * 2012-05-06 aozima can page write.
- * 2012-08-23 aozima add flash lock.
- * 2012-08-24 aozima fixed write status register BUG.
- */
-
-#include <stdint.h>
-#include <rtdevice.h>
-
-#include "spi_flash.h"
-#include "spi_flash_w25qxx.h"
-
-#define FLASH_DEBUG
-
-#ifdef FLASH_DEBUG
-#define FLASH_TRACE rt_kprintf
-#else
-#define FLASH_TRACE(...)
-#endif /* #ifdef FLASH_DEBUG */
-
-#define PAGE_SIZE 4096
-
-/* JEDEC Manufacturer ID */
-#define MF_ID (0xEF)
-
-/* JEDEC Device ID: Memory type and Capacity */
-#define MTC_W25Q80_BV (0x4014) /* W25Q80BV */
-#define MTC_W25Q16_BV_CL_CV (0x4015) /* W25Q16BV W25Q16CL W25Q16CV */
-#define MTC_W25Q16_DW (0x6015) /* W25Q16DW */
-#define MTC_W25Q32_BV (0x4016) /* W25Q32BV */
-#define MTC_W25Q32_DW (0x6016) /* W25Q32DW */
-#define MTC_W25Q64_BV_CV (0x4017) /* W25Q64BV W25Q64CV */
-#define MTC_W25Q64_DW (0x4017) /* W25Q64DW */
-#define MTC_W25Q128_BV (0x4018) /* W25Q128BV */
-#define MTC_W25Q256_FV (TBD) /* W25Q256FV */
-
-/* command list */
-#define CMD_WRSR (0x01) /* Write Status Register */
-#define CMD_PP (0x02) /* Page Program */
-#define CMD_READ (0x03) /* Read Data */
-#define CMD_WRDI (0x04) /* Write Disable */
-#define CMD_RDSR1 (0x05) /* Read Status Register-1 */
-#define CMD_WREN (0x06) /* Write Enable */
-#define CMD_FAST_READ (0x0B) /* Fast Read */
-#define CMD_ERASE_4K (0x20) /* Sector Erase:4K */
-#define CMD_RDSR2 (0x35) /* Read Status Register-2 */
-#define CMD_ERASE_32K (0x52) /* 32KB Block Erase */
-#define CMD_JEDEC_ID (0x9F) /* Read JEDEC ID */
-#define CMD_ERASE_full (0xC7) /* Chip Erase */
-#define CMD_ERASE_64K (0xD8) /* 64KB Block Erase */
-
-#define DUMMY (0xFF)
-
-static struct spi_flash_device spi_flash_device;
-
-static void flash_lock(struct spi_flash_device * flash_device)
-{
- rt_mutex_take(&flash_device->lock, RT_WAITING_FOREVER);
-}
-
-static void flash_unlock(struct spi_flash_device * flash_device)
-{
- rt_mutex_release(&flash_device->lock);
-}
-
-static uint8_t w25qxx_read_status(void)
-{
- return rt_spi_sendrecv8(spi_flash_device.rt_spi_device, CMD_RDSR1);
-}
-
-static void w25qxx_wait_busy(void)
-{
- while( w25qxx_read_status() & (0x01));
-}
-
-/** \brief read [size] byte from [offset] to [buffer]
- *
- * \param offset uint32_t unit : byte
- * \param buffer uint8_t*
- * \param size uint32_t unit : byte
- * \return uint32_t byte for read
- *
- */
-static uint32_t w25qxx_read(uint32_t offset, uint8_t * buffer, uint32_t size)
-{
- uint8_t send_buffer[4];
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_READ;
- send_buffer[1] = (uint8_t)(offset>>16);
- send_buffer[2] = (uint8_t)(offset>>8);
- send_buffer[3] = (uint8_t)(offset);
-
- rt_spi_send_then_recv(spi_flash_device.rt_spi_device,
- send_buffer, 4,
- buffer, size);
-
- return size;
-}
-
-/** \brief write N page on [page]
- *
- * \param page_addr uint32_t unit : byte (4096 * N,1 page = 4096byte)
- * \param buffer const uint8_t*
- * \return uint32_t
- *
- */
-uint32_t w25qxx_page_write(uint32_t page_addr, const uint8_t* buffer)
-{
- uint32_t index;
- uint8_t send_buffer[4];
-
- RT_ASSERT((page_addr&0xFF) == 0); /* page addr must align to 256byte. */
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_ERASE_4K;
- send_buffer[1] = (page_addr >> 16);
- send_buffer[2] = (page_addr >> 8);
- send_buffer[3] = (page_addr);
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 4);
-
- w25qxx_wait_busy(); // wait erase done.
-
- for(index=0; index < (PAGE_SIZE / 256); index++)
- {
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_PP;
- send_buffer[1] = (uint8_t)(page_addr >> 16);
- send_buffer[2] = (uint8_t)(page_addr >> 8);
- send_buffer[3] = (uint8_t)(page_addr);
-
- rt_spi_send_then_send(spi_flash_device.rt_spi_device,
- send_buffer,
- 4,
- buffer,
- 256);
-
- buffer += 256;
- page_addr += 256;
- w25qxx_wait_busy();
- }
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- return PAGE_SIZE;
-}
-
-/* RT-Thread device interface */
-static rt_err_t w25qxx_flash_init(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t w25qxx_flash_open(rt_device_t dev, rt_uint16_t oflag)
-{
- uint8_t send_buffer[3];
-
- flash_lock((struct spi_flash_device *)dev);
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_WRSR;
- send_buffer[1] = 0;
- send_buffer[2] = 0;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 3);
-
- w25qxx_wait_busy();
-
- flash_unlock((struct spi_flash_device *)dev);
-
- return RT_EOK;
-}
-
-static rt_err_t w25qxx_flash_close(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t w25qxx_flash_control(rt_device_t dev, int cmd, void *args)
-{
- RT_ASSERT(dev != RT_NULL);
-
- if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
- {
- struct rt_device_blk_geometry *geometry;
-
- geometry = (struct rt_device_blk_geometry *)args;
- if (geometry == RT_NULL) return -RT_ERROR;
-
- geometry->bytes_per_sector = spi_flash_device.geometry.bytes_per_sector;
- geometry->sector_count = spi_flash_device.geometry.sector_count;
- geometry->block_size = spi_flash_device.geometry.block_size;
- }
-
- return RT_EOK;
-}
-
-static rt_size_t w25qxx_flash_read(rt_device_t dev,
- rt_off_t pos,
- void* buffer,
- rt_size_t size)
-{
- flash_lock((struct spi_flash_device *)dev);
-
- w25qxx_read(pos*spi_flash_device.geometry.bytes_per_sector,
- buffer,
- size*spi_flash_device.geometry.bytes_per_sector);
-
- flash_unlock((struct spi_flash_device *)dev);
-
- return size;
-}
-
-static rt_size_t w25qxx_flash_write(rt_device_t dev,
- rt_off_t pos,
- const void* buffer,
- rt_size_t size)
-{
- rt_size_t i = 0;
- rt_size_t block = size;
- const uint8_t * ptr = buffer;
-
- flash_lock((struct spi_flash_device *)dev);
-
- while(block--)
- {
- w25qxx_page_write((pos + i)*spi_flash_device.geometry.bytes_per_sector,
- ptr);
- ptr += PAGE_SIZE;
- i++;
- }
-
- flash_unlock((struct spi_flash_device *)dev);
-
- return size;
-}
-
-#ifdef RT_USING_DEVICE_OPS
-const static struct rt_device_ops w25qxx_device_ops =
-{
- w25qxx_flash_init,
- w25qxx_flash_open,
- w25qxx_flash_close,
- w25qxx_flash_read,
- w25qxx_flash_write,
- w25qxx_flash_control
-};
-#endif
-
-rt_err_t w25qxx_init(const char * flash_device_name, const char * spi_device_name)
-{
- struct rt_spi_device * rt_spi_device;
-
- /* initialize mutex */
- if (rt_mutex_init(&spi_flash_device.lock, spi_device_name, RT_IPC_FLAG_FIFO) != RT_EOK)
- {
- rt_kprintf("init sd lock mutex failed\n");
- return -RT_ENOSYS;
- }
-
- rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
- if(rt_spi_device == RT_NULL)
- {
- FLASH_TRACE("spi device %s not found!\r\n", spi_device_name);
- return -RT_ENOSYS;
- }
- spi_flash_device.rt_spi_device = rt_spi_device;
-
- /* config spi */
- {
- struct rt_spi_configuration cfg;
- cfg.data_width = 8;
- cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
- cfg.max_hz = 50 * 1000 * 1000; /* 50M */
- rt_spi_configure(spi_flash_device.rt_spi_device, &cfg);
- }
-
- /* init flash */
- {
- rt_uint8_t cmd;
- rt_uint8_t id_recv[3];
- uint16_t memory_type_capacity;
-
- flash_lock(&spi_flash_device);
-
- cmd = 0xFF; /* reset SPI FLASH, cancel all cmd in processing. */
- rt_spi_send(spi_flash_device.rt_spi_device, &cmd, 1);
-
- cmd = CMD_WRDI;
- rt_spi_send(spi_flash_device.rt_spi_device, &cmd, 1);
-
- /* read flash id */
- cmd = CMD_JEDEC_ID;
- rt_spi_send_then_recv(spi_flash_device.rt_spi_device, &cmd, 1, id_recv, 3);
-
- flash_unlock(&spi_flash_device);
-
- if(id_recv[0] != MF_ID)
- {
- FLASH_TRACE("Manufacturers ID error!\r\n");
- FLASH_TRACE("JEDEC Read-ID Data : %02X %02X %02X\r\n", id_recv[0], id_recv[1], id_recv[2]);
- return -RT_ENOSYS;
- }
-
- spi_flash_device.geometry.bytes_per_sector = 4096;
- spi_flash_device.geometry.block_size = 4096; /* block erase: 4k */
-
- /* get memory type and capacity */
- memory_type_capacity = id_recv[1];
- memory_type_capacity = (memory_type_capacity << 8) | id_recv[2];
-
- if(memory_type_capacity == MTC_W25Q128_BV)
- {
- FLASH_TRACE("W25Q128BV detection\r\n");
- spi_flash_device.geometry.sector_count = 4096;
- }
- else if(memory_type_capacity == MTC_W25Q64_BV_CV)
- {
- FLASH_TRACE("W25Q64BV or W25Q64CV detection\r\n");
- spi_flash_device.geometry.sector_count = 2048;
- }
- else if(memory_type_capacity == MTC_W25Q64_DW)
- {
- FLASH_TRACE("W25Q64DW detection\r\n");
- spi_flash_device.geometry.sector_count = 2048;
- }
- else if(memory_type_capacity == MTC_W25Q32_BV)
- {
- FLASH_TRACE("W25Q32BV detection\r\n");
- spi_flash_device.geometry.sector_count = 1024;
- }
- else if(memory_type_capacity == MTC_W25Q32_DW)
- {
- FLASH_TRACE("W25Q32DW detection\r\n");
- spi_flash_device.geometry.sector_count = 1024;
- }
- else if(memory_type_capacity == MTC_W25Q16_BV_CL_CV)
- {
- FLASH_TRACE("W25Q16BV or W25Q16CL or W25Q16CV detection\r\n");
- spi_flash_device.geometry.sector_count = 512;
- }
- else if(memory_type_capacity == MTC_W25Q16_DW)
- {
- FLASH_TRACE("W25Q16DW detection\r\n");
- spi_flash_device.geometry.sector_count = 512;
- }
- else if(memory_type_capacity == MTC_W25Q80_BV)
- {
- FLASH_TRACE("W25Q80BV detection\r\n");
- spi_flash_device.geometry.sector_count = 256;
- }
- else
- {
- FLASH_TRACE("Memory Capacity error!\r\n");
- return -RT_ENOSYS;
- }
- }
-
- /* register device */
- spi_flash_device.flash_device.type = RT_Device_Class_Block;
-#ifdef RT_USING_DEVICE_OPS
- spi_flash_device.flash_device.ops = &w25qxx_device_ops;
-#else
- spi_flash_device.flash_device.init = w25qxx_flash_init;
- spi_flash_device.flash_device.open = w25qxx_flash_open;
- spi_flash_device.flash_device.close = w25qxx_flash_close;
- spi_flash_device.flash_device.read = w25qxx_flash_read;
- spi_flash_device.flash_device.write = w25qxx_flash_write;
- spi_flash_device.flash_device.control = w25qxx_flash_control;
-#endif
- /* no private */
- spi_flash_device.flash_device.user_data = RT_NULL;
-
- rt_device_register(&spi_flash_device.flash_device, flash_device_name,
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
-
- return RT_EOK;
-}
diff --git a/components/drivers/spi/spi_flash_w25qxx.h b/components/drivers/spi/spi_flash_w25qxx.h
deleted file mode 100644
index 14837bc87c..0000000000
--- a/components/drivers/spi/spi_flash_w25qxx.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2011-12-16 aozima the first version
- * 2012-08-23 aozima add flash lock.
- */
-
-#ifndef SPI_FLASH_W25QXX_H_INCLUDED
-#define SPI_FLASH_W25QXX_H_INCLUDED
-
-#include <rtthread.h>
-
-extern rt_err_t w25qxx_init(const char * flash_device_name,
- const char * spi_device_name);
-
-#endif // SPI_FLASH_W25QXX_H_INCLUDED
diff --git a/components/drivers/spi/spi_flash_w25qxx_mtd.c b/components/drivers/spi/spi_flash_w25qxx_mtd.c
deleted file mode 100644
index 9f1ef802f6..0000000000
--- a/components/drivers/spi/spi_flash_w25qxx_mtd.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- */
-#include <rtthread.h>
-#include <rtdevice.h>
-
-#include "spi_flash.h"
-#include "spi_flash_w25qxx_mtd.h"
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define FLASH_DEBUG
-
-#ifdef FLASH_DEBUG
-#define FLASH_TRACE printf
-#else
-#define FLASH_TRACE(...)
-#endif /* #ifdef FLASH_DEBUG */
-
-/* JEDEC Manufacturer’s ID */
-#define MF_ID (0xEF)
-/* JEDEC Device ID: Memory type and Capacity */
-#define MTC_W25Q80_BV (0x4014) /* W25Q80BV */
-#define MTC_W25Q16_BV_CL_CV (0x4015) /* W25Q16BV W25Q16CL W25Q16CV */
-#define MTC_W25Q16_DW (0x6015) /* W25Q16DW */
-#define MTC_W25Q32_BV (0x4016) /* W25Q32BV */
-#define MTC_W25Q32_DW (0x6016) /* W25Q32DW */
-#define MTC_W25Q64_BV_CV (0x4017) /* W25Q64BV W25Q64CV */
-#define MTC_W25Q64_DW (0x4017) /* W25Q64DW */
-#define MTC_W25Q128_BV (0x4018) /* W25Q128BV */
-#define MTC_W25Q256_FV (TBD) /* W25Q256FV */
-
-#define MTC_W25X80 (0x3014)
-
-/* command list */
-#define CMD_WRSR (0x01) /* Write Status Register */
-#define CMD_PP (0x02) /* Page Program */
-#define CMD_READ (0x03) /* Read Data */
-#define CMD_WRDI (0x04) /* Write Disable */
-#define CMD_RDSR1 (0x05) /* Read Status Register-1 */
-#define CMD_WREN (0x06) /* Write Enable */
-#define CMD_FAST_READ (0x0B) /* Fast Read */
-#define CMD_ERASE_4K (0x20) /* Sector Erase:4K */
-#define CMD_RDSR2 (0x35) /* Read Status Register-2 */
-#define CMD_ERASE_32K (0x52) /* 32KB Block Erase */
-#define CMD_JEDEC_ID (0x9F) /* Read JEDEC ID */
-#define CMD_ERASE_full (0xC7) /* Chip Erase */
-#define CMD_ERASE_64K (0xD8) /* 64KB Block Erase */
-#define CMD_MANU_ID (0x90)
-
-#define DUMMY (0xFF)
-
-#define FLASH_ERASE_CMD CMD_ERASE_4K
-#define FLASH_BLOCK_SIZE 4096
-#define FLASH_PAGE_SIZE 256
-
-static void w25qxx_lock(struct rt_mtd_nor_device *device)
-{
- struct spi_flash_mtd *mtd = (struct spi_flash_mtd *)device;
- rt_mutex_take(&mtd->lock, RT_WAITING_FOREVER);
-}
-
-static void w25qxx_unlock(struct rt_mtd_nor_device *device)
-{
- struct spi_flash_mtd *mtd = (struct spi_flash_mtd *)device;
- rt_mutex_release(&mtd->lock);
-}
-
-static rt_uint8_t w25qxx_read_status(struct rt_mtd_nor_device *device)
-{
- struct spi_flash_mtd *mtd = (struct spi_flash_mtd *)device;
- return rt_spi_sendrecv8(mtd->rt_spi_device, CMD_RDSR1);
-}
-
-static void w25qxx_wait_busy(struct rt_mtd_nor_device *device)
-{
- while( w25qxx_read_status(device) & (0x01));
-}
-
-static rt_err_t w25qxx_read_id(struct rt_mtd_nor_device *device)
-{
- rt_uint8_t cmd;
- rt_uint8_t id_recv[3];
-
- struct spi_flash_mtd *mtd = (struct spi_flash_mtd *)device;
-
- w25qxx_lock(device);
-
- cmd = 0xFF; /* reset SPI FLASH, cancel all cmd in processing. */
- rt_spi_send(mtd->rt_spi_device, &cmd, 1);
-
- cmd = CMD_WRDI;
- rt_spi_send(mtd->rt_spi_device, &cmd, 1);
-
- /* read flash id */
- cmd = CMD_JEDEC_ID;
- rt_spi_send_then_recv(mtd->rt_spi_device, &cmd, 1, id_recv, 3);
-
- w25qxx_unlock(device);
-
- return (rt_uint32_t)(id_recv[0] << 16) | (id_recv[1] << 8) | id_recv[2];
-}
-
-static rt_size_t w25qxx_read(struct rt_mtd_nor_device *device, rt_off_t offset, rt_uint8_t *buffer, rt_size_t length)
-{
- struct spi_flash_mtd *mtd = (struct spi_flash_mtd *)device;
- rt_uint8_t send_buffer[4];
-
- if((offset + length) > device->block_end * FLASH_BLOCK_SIZE)
- return 0;
-
-
- w25qxx_lock(device);
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_READ;
- send_buffer[1] = (rt_uint8_t)(offset>>16);
- send_buffer[2] = (rt_uint8_t)(offset>>8);
- send_buffer[3] = (rt_uint8_t)(offset);
- rt_spi_send_then_recv(mtd->rt_spi_device,
- send_buffer, 4,
- buffer, length);
-
- w25qxx_unlock(device);
- return length;
-}
-
-static rt_size_t w25qxx_write(struct rt_mtd_nor_device *device, rt_off_t offset, const rt_uint8_t *buffer, rt_size_t length)
-{
- struct spi_flash_mtd *mtd = (struct spi_flash_mtd *)device;
- rt_uint8_t send_buffer[4];
- rt_uint8_t *write_ptr ;
- rt_size_t write_size,write_total;
-
- if((offset + length) > device->block_end * FLASH_BLOCK_SIZE)
- return 0;
-
- w25qxx_lock(device);
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 1);
- w25qxx_wait_busy(device); // wait erase done.
-
- write_size = 0;
- write_total = 0;
- write_ptr = (rt_uint8_t *)buffer;
- while(write_total < length)
- {
- send_buffer[0] = CMD_WREN;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 1);
-
- //write first page...
- send_buffer[0] = CMD_PP;
- send_buffer[1] = (rt_uint8_t)(offset >> 16);
- send_buffer[2] = (rt_uint8_t)(offset >> 8);
- send_buffer[3] = (rt_uint8_t)(offset);
-
- //address % FLASH_PAGE_SIZE + length
- if(((offset & (FLASH_PAGE_SIZE - 1)) + (length - write_total)) > FLASH_PAGE_SIZE)
- {
- write_size = FLASH_PAGE_SIZE - (offset & (FLASH_PAGE_SIZE - 1));
- }
- else
- {
- write_size = (length - write_total);
- }
-
- rt_spi_send_then_send(mtd->rt_spi_device,
- send_buffer, 4,
- write_ptr + write_total, write_size);
- w25qxx_wait_busy(device);
-
-
- offset += write_size;
- write_total += write_size;
- }
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 1);
-
- w25qxx_unlock(device);
-
- return length;
-}
-
-static rt_err_t w25qxx_erase_block(struct rt_mtd_nor_device *device, rt_off_t offset, rt_uint32_t length)
-{
- struct spi_flash_mtd *mtd = (struct spi_flash_mtd *)device;
- rt_uint8_t send_buffer[4];
- rt_uint32_t erase_size = 0;
-
- //offset must be ALIGN_DOWN to BLOCKSIZE
- if(offset != RT_ALIGN_DOWN(offset,FLASH_BLOCK_SIZE))
- return 0;
-
- if((offset + length) > device->block_end * FLASH_BLOCK_SIZE)
- return 0;
-
- /* check length must align to block size */
- if(length % device->block_size != 0)
- {
- rt_kprintf("param length = %d ,error\n",length);
- return 0;
- }
-
- w25qxx_lock(device);
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 1);
- w25qxx_wait_busy(device); // wait erase done.
- while (erase_size < length)
- {
- send_buffer[0] = CMD_ERASE_4K;
- send_buffer[1] = (rt_uint8_t) (offset >> 16);
- send_buffer[2] = (rt_uint8_t) (offset >> 8);
- send_buffer[3] = (rt_uint8_t) (offset);
- rt_spi_send(mtd->rt_spi_device, send_buffer, 4);
- w25qxx_wait_busy(device); // wait erase done.
-
- erase_size += 4096;
- offset += 4096;
- }
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 1);
-
- w25qxx_unlock(device);
- return RT_EOK;
-}
-
-const static struct rt_mtd_nor_driver_ops w25qxx_mtd_ops =
-{
- w25qxx_read_id,
- w25qxx_read,
- w25qxx_write,
- w25qxx_erase_block,
-};
-
-rt_err_t w25qxx_mtd_init(const char *mtd_name,const char * spi_device_name)
-{
- rt_err_t result = RT_EOK;
- rt_uint32_t id;
- rt_uint8_t send_buffer[3];
-
- struct rt_spi_device* rt_spi_device;
- struct spi_flash_mtd* mtd = (struct spi_flash_mtd *)rt_malloc(sizeof(struct spi_flash_mtd));
-
- RT_ASSERT(mtd != RT_NULL);
-
- /* initialize mutex */
- if (rt_mutex_init(&mtd->lock, mtd_name, RT_IPC_FLAG_FIFO) != RT_EOK)
- {
- FLASH_TRACE("init mtd lock mutex failed\n");
- result = -RT_ENOSYS;
-
- goto _error_exit;
- }
-
- rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
- if(rt_spi_device == RT_NULL)
- {
- FLASH_TRACE("spi device %s not found!\r\n", spi_device_name);
- result = -RT_ENOSYS;
-
- goto _error_exit;
- }
- mtd->rt_spi_device = rt_spi_device;
- /* config spi */
- {
- struct rt_spi_configuration cfg;
- cfg.data_width = 8;
- cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
- cfg.max_hz = 20 * 1000 * 1000; /* 20 */
- rt_spi_configure(rt_spi_device, &cfg);
- }
-
- /* Init Flash device */
- {
- w25qxx_lock(&mtd->mtd_device);
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 1);
- w25qxx_wait_busy(&mtd->mtd_device);
-
- send_buffer[0] = CMD_WRSR;
- send_buffer[1] = 0;
- send_buffer[2] = 0;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 3);
- w25qxx_wait_busy(&mtd->mtd_device);
-
- w25qxx_unlock(&mtd->mtd_device);
- }
-
- id = w25qxx_read_id(&mtd->mtd_device);
-
- mtd->mtd_device.block_size = 4096;
- mtd->mtd_device.block_start = 0;
- switch(id & 0xFFFF)
- {
- case MTC_W25Q80_BV: /* W25Q80BV */
- mtd->mtd_device.block_end = 256;
- break;
- case MTC_W25Q16_BV_CL_CV: /* W25Q16BV W25Q16CL W25Q16CV */
- case MTC_W25Q16_DW: /* W25Q16DW */
- mtd->mtd_device.block_end = 512;
- break;
- case MTC_W25Q32_BV: /* W25Q32BV */
- case MTC_W25Q32_DW: /* W25Q32DW */
- mtd->mtd_device.block_end = 1024;
- break;
- case MTC_W25Q64_BV_CV: /* W25Q64BV W25Q64CV */
- mtd->mtd_device.block_end = 2048;
- break;
- case MTC_W25Q128_BV: /* W25Q128BV */
- mtd->mtd_device.block_end = 4086;
- break;
- }
- mtd->mtd_device.ops = &w25qxx_mtd_ops;
- rt_mtd_nor_register_device(mtd_name,&mtd->mtd_device);
-
- return RT_EOK;
-
-_error_exit:
- if(mtd != RT_NULL)
- rt_free(mtd);
- return result;
-}
diff --git a/components/drivers/spi/spi_flash_w25qxx_mtd.h b/components/drivers/spi/spi_flash_w25qxx_mtd.h
deleted file mode 100644
index 28f6828ffb..0000000000
--- a/components/drivers/spi/spi_flash_w25qxx_mtd.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2011-12-16 aozima the first version
- * 2012-08-23 aozima add flash lock.
- * 2017-02-11 urey add mtd fucntion
- */
-
-#ifndef SPI_FLASH_W25QXX_H_INCLUDED
-#define SPI_FLASH_W25QXX_H_INCLUDED
-
-#include <rtthread.h>
-
-extern rt_err_t w25qxx_mtd_init(const char *mtd_name,const char * spi_device_name);
-
-#endif // SPI_FLASH_W25QXX_H_INCLUDED
diff --git a/components/drivers/src/pipe.c b/components/drivers/src/pipe.c
index 16fb82dbfb..b682c351ad 100644
--- a/components/drivers/src/pipe.c
+++ b/components/drivers/src/pipe.c
@@ -425,7 +425,7 @@ rt_pipe_t *rt_pipe_create(const char *name, int bufsz)
rt_pipe_t *pipe;
rt_device_t dev;
- pipe = rt_malloc(sizeof(rt_pipe_t));
+ pipe = (rt_pipe_t *)rt_malloc(sizeof(rt_pipe_t));
if (pipe == RT_NULL) return RT_NULL;
rt_memset(pipe, 0, sizeof(rt_pipe_t));
diff --git a/components/drivers/src/ringblk_buf.c b/components/drivers/src/ringblk_buf.c
index 74ced674fe..86e812cd4c 100644
--- a/components/drivers/src/ringblk_buf.c
+++ b/components/drivers/src/ringblk_buf.c
@@ -134,16 +134,16 @@ rt_rbb_blk_t rt_rbb_blk_alloc(rt_rbb_t rbb, rt_size_t blk_size)
{
rt_base_t level;
rt_size_t empty1 = 0, empty2 = 0;
- rt_rbb_blk_t head, tail, new = NULL;
+ rt_rbb_blk_t head, tail, new_rbb = NULL;
RT_ASSERT(rbb);
RT_ASSERT(blk_size < (1L << 24));
level = rt_hw_interrupt_disable();
- new = find_empty_blk_in_set(rbb);
+ new_rbb = find_empty_blk_in_set(rbb);
- if (rt_slist_len(&rbb->blk_list) < rbb->blk_max_num && new)
+ if (rt_slist_len(&rbb->blk_list) < rbb->blk_max_num && new_rbb)
{
if (rt_slist_len(&rbb->blk_list) > 0)
{
@@ -163,22 +163,22 @@ rt_rbb_blk_t rt_rbb_blk_alloc(rt_rbb_t rbb, rt_size_t blk_size)
if (empty1 >= blk_size)
{
- rt_slist_append(&rbb->blk_list, &new->list);
- new->status = RT_RBB_BLK_INITED;
- new->buf = tail->buf + tail->size;
- new->size = blk_size;
+ rt_slist_append(&rbb->blk_list, &new_rbb->list);
+ new_rbb->status = RT_RBB_BLK_INITED;
+ new_rbb->buf = tail->buf + tail->size;
+ new_rbb->size = blk_size;
}
else if (empty2 >= blk_size)
{
- rt_slist_append(&rbb->blk_list, &new->list);
- new->status = RT_RBB_BLK_INITED;
- new->buf = rbb->buf;
- new->size = blk_size;
+ rt_slist_append(&rbb->blk_list, &new_rbb->list);
+ new_rbb->status = RT_RBB_BLK_INITED;
+ new_rbb->buf = rbb->buf;
+ new_rbb->size = blk_size;
}
else
{
/* no space */
- new = NULL;
+ new_rbb = NULL;
}
}
else
@@ -194,35 +194,35 @@ rt_rbb_blk_t rt_rbb_blk_alloc(rt_rbb_t rbb, rt_size_t blk_size)
if (empty1 >= blk_size)
{
- rt_slist_append(&rbb->blk_list, &new->list);
- new->status = RT_RBB_BLK_INITED;
- new->buf = tail->buf + tail->size;
- new->size = blk_size;
+ rt_slist_append(&rbb->blk_list, &new_rbb->list);
+ new_rbb->status = RT_RBB_BLK_INITED;
+ new_rbb->buf = tail->buf + tail->size;
+ new_rbb->size = blk_size;
}
else
{
/* no space */
- new = NULL;
+ new_rbb = NULL;
}
}
}
else
{
/* the list is empty */
- rt_slist_append(&rbb->blk_list, &new->list);
- new->status = RT_RBB_BLK_INITED;
- new->buf = rbb->buf;
- new->size = blk_size;
+ rt_slist_append(&rbb->blk_list, &new_rbb->list);
+ new_rbb->status = RT_RBB_BLK_INITED;
+ new_rbb->buf = rbb->buf;
+ new_rbb->size = blk_size;
}
}
else
{
- new = NULL;
+ new_rbb = NULL;
}
rt_hw_interrupt_enable(level);
- return new;
+ return new_rbb;
}
RTM_EXPORT(rt_rbb_blk_alloc);
diff --git a/components/drivers/src/ringbuffer.c b/components/drivers/src/ringbuffer.c
index 0acdbbd38c..c6a491a7cc 100644
--- a/components/drivers/src/ringbuffer.c
+++ b/components/drivers/src/ringbuffer.c
@@ -332,11 +332,11 @@ struct rt_ringbuffer* rt_ringbuffer_create(rt_uint16_t size)
size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE);
- rb = rt_malloc(sizeof(struct rt_ringbuffer));
+ rb = (struct rt_ringbuffer *)rt_malloc(sizeof(struct rt_ringbuffer));
if (rb == RT_NULL)
goto exit;
- pool = rt_malloc(size);
+ pool = (rt_uint8_t *)rt_malloc(size);
if (pool == RT_NULL)
{
rt_free(rb);
diff --git a/components/drivers/src/workqueue.c b/components/drivers/src/workqueue.c
index 7bf4bd81a7..2e0280df3a 100644
--- a/components/drivers/src/workqueue.c
+++ b/components/drivers/src/workqueue.c
@@ -71,6 +71,7 @@ static void _workqueue_thread_entry(void *parameter)
rt_list_remove(&(work->list));
queue->work_current = work;
work->flags &= ~RT_WORK_STATE_PENDING;
+ work->workqueue = RT_NULL;
rt_hw_interrupt_enable(level);
/* do work */
@@ -141,7 +142,7 @@ static rt_err_t _workqueue_cancel_work(struct rt_workqueue *queue, struct rt_wor
return RT_EOK;
}
-static rt_err_t _workqueue_cancel_delayed_work(struct rt_delayed_work *work)
+static rt_err_t _workqueue_cancel_delayed_work(struct rt_work *work)
{
rt_base_t level;
int ret = RT_EOK;
@@ -152,10 +153,10 @@ static rt_err_t _workqueue_cancel_delayed_work(struct rt_delayed_work *work)
goto __exit;
}
- if (work->work.flags & RT_WORK_STATE_PENDING)
+ if (work->flags & RT_WORK_STATE_PENDING)
{
/* Remove from the queue if already submitted */
- ret = rt_workqueue_cancel_work(work->workqueue, &(work->work));
+ ret = _workqueue_cancel_work(work->workqueue, work);
if (ret)
{
goto __exit;
@@ -163,12 +164,12 @@ static rt_err_t _workqueue_cancel_delayed_work(struct rt_delayed_work *work)
}
else
{
- if (work->work.flags & RT_WORK_STATE_SUBMITTING)
+ if (work->flags & RT_WORK_STATE_SUBMITTING)
{
level = rt_hw_interrupt_disable();
rt_timer_stop(&(work->timer));
rt_timer_detach(&(work->timer));
- work->work.flags &= ~RT_WORK_STATE_SUBMITTING;
+ work->flags &= ~RT_WORK_STATE_SUBMITTING;
rt_hw_interrupt_enable(level);
}
}
@@ -176,7 +177,7 @@ static rt_err_t _workqueue_cancel_delayed_work(struct rt_delayed_work *work)
level = rt_hw_interrupt_disable();
/* Detach from workqueue */
work->workqueue = RT_NULL;
- work->work.flags &= ~(RT_WORK_STATE_PENDING);
+ work->flags &= ~(RT_WORK_STATE_PENDING);
rt_hw_interrupt_enable(level);
__exit:
@@ -184,11 +185,10 @@ __exit:
}
static rt_err_t _workqueue_submit_delayed_work(struct rt_workqueue *queue,
- struct rt_delayed_work *work, rt_tick_t ticks)
+ struct rt_work *work, rt_tick_t ticks)
{
rt_base_t level;
- int ret = RT_EOK;
-
+ rt_err_t ret = RT_EOK;
/* Work cannot be active in multiple queues */
if (work->workqueue && work->workqueue != queue)
@@ -215,13 +215,13 @@ static rt_err_t _workqueue_submit_delayed_work(struct rt_workqueue *queue,
if (!ticks)
{
/* Submit work if no ticks is 0 */
- _workqueue_submit_work(work->workqueue, &(work->work));
+ ret = _workqueue_submit_work(work->workqueue, work);
}
else
{
level = rt_hw_interrupt_disable();
/* Add timeout */
- work->work.flags |= RT_WORK_STATE_SUBMITTING;
+ work->flags |= RT_WORK_STATE_SUBMITTING;
rt_timer_init(&(work->timer), "work", _delayed_work_timeout_handler, work, ticks,
RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
rt_hw_interrupt_enable(level);
@@ -234,16 +234,17 @@ __exit:
static void _delayed_work_timeout_handler(void *parameter)
{
- struct rt_delayed_work *delayed_work;
+ struct rt_work *delayed_work;
rt_base_t level;
- delayed_work = (struct rt_delayed_work *)parameter;
+ delayed_work = (struct rt_work *)parameter;
level = rt_hw_interrupt_disable();
rt_timer_stop(&(delayed_work->timer));
rt_timer_detach(&(delayed_work->timer));
- delayed_work->work.flags &= ~RT_WORK_STATE_SUBMITTING;
+ delayed_work->flags &= ~RT_WORK_STATE_SUBMITTING;
+ delayed_work->type &= ~RT_WORK_TYPE_DELAYED;
rt_hw_interrupt_enable(level);
- _workqueue_submit_work(delayed_work->workqueue, &(delayed_work->work));
+ _workqueue_submit_work(delayed_work->workqueue, delayed_work);
}
struct rt_workqueue *rt_workqueue_create(const char *name, rt_uint16_t stack_size, rt_uint8_t priority)
@@ -295,9 +296,14 @@ rt_err_t rt_workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *wo
RT_ASSERT(queue != RT_NULL);
RT_ASSERT(work != RT_NULL);
+ if (time > 0)
+ {
+ work->type |= RT_WORK_TYPE_DELAYED;
+ }
+
if (work->type & RT_WORK_TYPE_DELAYED)
{
- return _workqueue_submit_delayed_work(queue, (struct rt_delayed_work *)work, time);
+ return _workqueue_submit_delayed_work(queue, work, time);
}
else
{
@@ -341,7 +347,7 @@ rt_err_t rt_workqueue_cancel_work(struct rt_workqueue *queue, struct rt_work *wo
if (work->type & RT_WORK_TYPE_DELAYED)
{
- return _workqueue_cancel_delayed_work((struct rt_delayed_work *)work);
+ return _workqueue_cancel_delayed_work(work);
}
else
{
@@ -391,8 +397,7 @@ rt_err_t rt_workqueue_cancel_all_work(struct rt_workqueue *queue)
void rt_delayed_work_init(struct rt_delayed_work *work, void (*work_func)(struct rt_work *work,
void *work_data), void *work_data)
{
- rt_work_init(&(work->work), work_func, work_data);
- work->work.type = RT_WORK_TYPE_DELAYED;
+ rt_work_init(&work->work, work_func, work_data);
}
#ifdef RT_USING_SYSTEM_WORKQUEUE
@@ -408,8 +413,11 @@ rt_err_t rt_work_cancel(struct rt_work *work)
return rt_workqueue_cancel_work(sys_workq, work);
}
-static int rt_work_sys_workqueue_init(void)
+int rt_work_sys_workqueue_init(void)
{
+ if (sys_workq != RT_NULL)
+ return 0;
+
sys_workq = rt_workqueue_create("sys_work", RT_SYSTEM_WORKQUEUE_STACKSIZE,
RT_SYSTEM_WORKQUEUE_PRIORITY);
diff --git a/components/drivers/touch/SConscript b/components/drivers/touch/SConscript
new file mode 100644
index 0000000000..f370b2aba6
--- /dev/null
+++ b/components/drivers/touch/SConscript
@@ -0,0 +1,11 @@
+# SConscript for touch framework
+
+from building import *
+
+cwd = GetCurrentDir()
+src = ['touch.c']
+CPPPATH = [cwd, cwd + '/../include']
+
+group = DefineGroup('Touch', src, depend = ['RT_USING_TOUCH', 'RT_USING_DEVICE'], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/components/drivers/touch/touch.c b/components/drivers/touch/touch.c
new file mode 100644
index 0000000000..80ba6378bb
--- /dev/null
+++ b/components/drivers/touch/touch.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-20 tyustli the first version
+ */
+
+#include "touch.h"
+#include <string.h>
+
+#define DBG_TAG "touch"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+/* ISR for touch interrupt */
+static void irq_callback(void *args)
+{
+ rt_touch_t touch;
+
+ touch = (rt_touch_t)args;
+
+ if (touch->parent.rx_indicate == RT_NULL)
+ {
+ return;
+ }
+
+ if (touch->irq_handle != RT_NULL)
+ {
+ touch->irq_handle(touch);
+ }
+
+ touch->parent.rx_indicate(&touch->parent, 1);
+}
+
+/* touch interrupt initialization function */
+static rt_err_t rt_touch_irq_init(rt_touch_t touch)
+{
+ if (touch->config.irq_pin.pin == RT_PIN_NONE)
+ {
+ return -RT_EINVAL;
+ }
+
+ rt_pin_mode(touch->config.irq_pin.pin, touch->config.irq_pin.mode);
+
+ if (touch->config.irq_pin.mode == PIN_MODE_INPUT_PULLDOWN)
+ {
+ rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_RISING, irq_callback, (void *)touch);
+ }
+ else if (touch->config.irq_pin.mode == PIN_MODE_INPUT_PULLUP)
+ {
+ rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_FALLING, irq_callback, (void *)touch);
+ }
+ else if (touch->config.irq_pin.mode == PIN_MODE_INPUT)
+ {
+ rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_RISING_FALLING, irq_callback, (void *)touch);
+ }
+
+ rt_pin_irq_enable(touch->config.irq_pin.pin, PIN_IRQ_ENABLE);
+
+ return RT_EOK;
+}
+
+/* touch interrupt enable */
+static void rt_touch_irq_enable(rt_touch_t touch)
+{
+ if (touch->config.irq_pin.pin != RT_PIN_NONE)
+ {
+ rt_pin_irq_enable(touch->config.irq_pin.pin, RT_TRUE);
+ }
+}
+
+/* touch interrupt disable */
+static void rt_touch_irq_disable(rt_touch_t touch)
+{
+ if (touch->config.irq_pin.pin != RT_PIN_NONE)
+ {
+ rt_pin_irq_enable(touch->config.irq_pin.pin, RT_FALSE);
+ }
+}
+
+static rt_err_t rt_touch_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ rt_touch_t touch;
+ RT_ASSERT(dev != RT_NULL);
+ touch = (rt_touch_t)dev;
+
+ if (oflag & RT_DEVICE_FLAG_INT_RX && dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ /* Initialization touch interrupt */
+ rt_touch_irq_init(touch);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_touch_close(rt_device_t dev)
+{
+ rt_touch_t touch;
+ RT_ASSERT(dev != RT_NULL);
+ touch = (rt_touch_t)dev;
+
+ /* touch disable interrupt */
+ rt_touch_irq_disable(touch);
+
+ return RT_EOK;
+}
+
+static rt_size_t rt_touch_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t len)
+{
+ rt_touch_t touch;
+ rt_size_t result = 0;
+ RT_ASSERT(dev != RT_NULL);
+ touch = (rt_touch_t)dev;
+
+ if (buf == NULL || len == 0)
+ {
+ return 0;
+ }
+
+ result = touch->ops->touch_readpoint(touch, buf, len);
+
+ return result;
+}
+
+static rt_err_t rt_touch_control(rt_device_t dev, int cmd, void *args)
+{
+ rt_touch_t touch;
+ rt_err_t result = RT_EOK;
+ RT_ASSERT(dev != RT_NULL);
+ touch = (rt_touch_t)dev;
+
+ switch (cmd)
+ {
+ case RT_TOUCH_CTRL_GET_ID:
+ if (args)
+ {
+ result = touch->ops->touch_control(touch, RT_TOUCH_CTRL_GET_ID, args);
+ }
+ else
+ {
+ result = -RT_ERROR;
+ }
+
+ break;
+ case RT_TOUCH_CTRL_GET_INFO:
+ if (args)
+ {
+ result = touch->ops->touch_control(touch, RT_TOUCH_CTRL_GET_INFO, args);
+ }
+ else
+ {
+ result = -RT_ERROR;
+ }
+
+ break;
+ case RT_TOUCH_CTRL_SET_MODE:
+ result = touch->ops->touch_control(touch, RT_TOUCH_CTRL_SET_MODE, args);
+
+ if (result == RT_EOK)
+ {
+ rt_uint16_t mode;
+ mode = *(rt_uint16_t*)args;
+ if (mode == RT_DEVICE_FLAG_INT_RX)
+ {
+ rt_touch_irq_enable(touch); /* enable interrupt */
+ }
+ }
+
+ break;
+ case RT_TOUCH_CTRL_SET_X_RANGE:
+ result = touch->ops->touch_control(touch, RT_TOUCH_CTRL_SET_X_RANGE, args);
+
+ if (result == RT_EOK)
+ {
+ touch->info.range_x = *(rt_int32_t *)args;
+ LOG_D("set x coordinate range :%d\n", touch->info.range_x);
+ }
+
+ break;
+ case RT_TOUCH_CTRL_SET_Y_RANGE:
+ result = touch->ops->touch_control(touch, RT_TOUCH_CTRL_SET_Y_RANGE, args);
+
+ if (result == RT_EOK)
+ {
+ touch->info.range_y = *(rt_uint32_t *)args;
+ LOG_D("set y coordinate range :%d \n", touch->info.range_x);
+ }
+
+ break;
+ case RT_TOUCH_CTRL_DISABLE_INT:
+ rt_touch_irq_disable(touch);
+ break;
+ case RT_TOUCH_CTRL_ENABLE_INT:
+ rt_touch_irq_enable(touch);
+ break;
+ default:
+ return -RT_ERROR;
+ }
+
+ return result;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops rt_touch_ops =
+{
+ RT_NULL,
+ rt_touch_open,
+ rt_touch_close,
+ rt_touch_read,
+ RT_NULL,
+ rt_touch_control
+};
+#endif
+
+/*
+ * touch register
+ */
+int rt_hw_touch_register(rt_touch_t touch,
+ const char *name,
+ rt_uint32_t flag,
+ void *data)
+{
+ rt_int8_t result;
+ rt_device_t device;
+ RT_ASSERT(touch != RT_NULL);
+
+ device = &touch->parent;
+
+#ifdef RT_USING_DEVICE_OPS
+ device->ops = &rt_touch_ops;
+#else
+ device->init = RT_NULL;
+ device->open = rt_touch_open;
+ device->close = rt_touch_close;
+ device->read = rt_touch_read;
+ device->write = RT_NULL;
+ device->control = rt_touch_control;
+#endif
+ device->type = RT_Device_Class_Touch;
+ device->rx_indicate = RT_NULL;
+ device->tx_complete = RT_NULL;
+ device->user_data = data;
+
+ result = rt_device_register(device, name, flag | RT_DEVICE_FLAG_STANDALONE);
+
+ if (result != RT_EOK)
+ {
+ LOG_E("rt_touch register err code: %d", result);
+ return result;
+ }
+
+ LOG_I("rt_touch init success");
+
+ return RT_EOK;
+}
diff --git a/components/drivers/touch/touch.h b/components/drivers/touch/touch.h
new file mode 100644
index 0000000000..6b7288a5a0
--- /dev/null
+++ b/components/drivers/touch/touch.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-20 tyustli the first version
+ */
+
+#ifndef __TOUCH_H__
+#define __TOUCH_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef RT_USING_RTC
+#define rt_touch_get_ts() time(RT_NULL) /* API for the touch to get the timestamp */
+#else
+#define rt_touch_get_ts() rt_tick_get() /* API for the touch to get the timestamp */
+#endif
+
+#define RT_PIN_NONE 0xFFFF /* RT PIN NONE */
+
+/* Touch vendor types */
+#define RT_TOUCH_VENDOR_UNKNOWN (0) /* unknown */
+#define RT_TOUCH_VENDOR_GT (1) /* GTxx series */
+#define RT_TOUCH_VENDOR_FT (2) /* FTxx series */
+
+/* Touch ic type*/
+#define RT_TOUCH_TYPE_NONE (0) /* touch ic none */
+#define RT_TOUCH_TYPE_CAPACITANCE (1) /* capacitance ic */
+#define RT_TOUCH_TYPE_RESISTANCE (2) /* resistance ic */
+
+/* Touch control cmd types */
+#define RT_TOUCH_CTRL_GET_ID (0) /* Get device id */
+#define RT_TOUCH_CTRL_GET_INFO (1) /* Get touch info */
+#define RT_TOUCH_CTRL_SET_MODE (2) /* Set touch's work mode. ex. RT_TOUCH_MODE_POLLING,RT_TOUCH_MODE_INT */
+#define RT_TOUCH_CTRL_SET_X_RANGE (3) /* Set x coordinate range */
+#define RT_TOUCH_CTRL_SET_Y_RANGE (4) /* Set y coordinate range */
+#define RT_TOUCH_CTRL_SET_X_TO_Y (5) /* Set X Y coordinate exchange */
+#define RT_TOUCH_CTRL_DISABLE_INT (6) /* Disable interrupt */
+#define RT_TOUCH_CTRL_ENABLE_INT (7) /* Enable interrupt */
+
+/* Touch event */
+#define RT_TOUCH_EVENT_NONE (0) /* Touch none */
+#define RT_TOUCH_EVENT_UP (1) /* Touch up event */
+#define RT_TOUCH_EVENT_DOWN (2) /* Touch down event */
+#define RT_TOUCH_EVENT_MOVE (3) /* Touch move event */
+
+struct rt_touch_info
+{
+ rt_uint8_t type; /* The touch type */
+ rt_uint8_t vendor; /* Vendor of touchs */
+ rt_uint8_t point_num; /* Support point num */
+ rt_int32_t range_x; /* X coordinate range */
+ rt_int32_t range_y; /* Y coordinate range */
+};
+
+struct rt_touch_config
+{
+ struct rt_device_pin_mode irq_pin; /* Interrupt pin, The purpose of this pin is to notification read data */
+ char *dev_name; /* The name of the communication device */
+ void *user_data;
+};
+
+typedef struct rt_touch_device *rt_touch_t;
+struct rt_touch_device
+{
+ struct rt_device parent; /* The standard device */
+ struct rt_touch_info info; /* The touch info data */
+ struct rt_touch_config config; /* The touch config data */
+
+ const struct rt_touch_ops *ops; /* The touch ops */
+ rt_err_t (*irq_handle)(rt_touch_t touch); /* Called when an interrupt is generated, registered by the driver */
+};
+
+struct rt_touch_data
+{
+ rt_uint8_t event; /* The touch event of the data */
+ rt_uint8_t track_id; /* Track id of point */
+ rt_uint8_t width; /* Point of width */
+ rt_uint16_t x_coordinate; /* Point of x coordinate */
+ rt_uint16_t y_coordinate; /* Point of y coordinate */
+ rt_tick_t timestamp; /* The timestamp when the data was received */
+};
+
+struct rt_touch_ops
+{
+ rt_size_t (*touch_readpoint)(struct rt_touch_device *touch, void *buf, rt_size_t touch_num);
+ rt_err_t (*touch_control)(struct rt_touch_device *touch, int cmd, void *arg);
+};
+
+int rt_hw_touch_register(rt_touch_t touch,
+ const char *name,
+ rt_uint32_t flag,
+ void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TOUCH_H__ */
diff --git a/components/drivers/usb/usbdevice/SConscript b/components/drivers/usb/usbdevice/SConscript
index be0b0c7b50..010b9837a4 100644
--- a/components/drivers/usb/usbdevice/SConscript
+++ b/components/drivers/usb/usbdevice/SConscript
@@ -24,6 +24,12 @@ if GetDepend('RT_USB_DEVICE_RNDIS'):
if GetDepend('RT_USB_DEVICE_WINUSB'):
src += Glob('class/winusb.c')
+
+if GetDepend('RT_USB_DEVICE_AUDIO_MIC'):
+ src += Glob('class/audio_mic.c')
+
+if GetDepend('RT_USB_DEVICE_AUDIO_SPEAKER'):
+ src += Glob('class/audio_speaker.c')
CPPPATH = [cwd]
diff --git a/components/drivers/usb/usbdevice/class/audio.h b/components/drivers/usb/usbdevice/class/audio.h
new file mode 100644
index 0000000000..4bb8994b47
--- /dev/null
+++ b/components/drivers/usb/usbdevice/class/audio.h
@@ -0,0 +1,676 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * <linux/usb/audio.h> -- USB Audio definitions.
+ *
+ * Copyright (C) 2006 Thumtronics Pty Ltd.
+ * Developed for Thumtronics by Grey Innovation
+ * Ben Williamson <[email protected]>
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * License ("GPL") version 2, as published by the Free Software Foundation.
+ *
+ * This file holds USB constants and structures defined
+ * by the USB Device Class Definition for Audio Devices.
+ * Comments below reference relevant sections of that document:
+ *
+ * http://www.usb.org/developers/devclass_docs/audio10.pdf
+ *
+ * Types and defines in this file are either specific to version 1.0 of
+ * this standard or common for newer versions.
+ */
+
+#ifndef _UAPI__LINUX_USB_AUDIO_H
+#define _UAPI__LINUX_USB_AUDIO_H
+
+//#include <linux/types.h>
+#include <rtthread.h>
+
+typedef int8_t __s8;
+typedef uint8_t __u8;
+typedef int16_t __s16;
+typedef uint16_t __u16;
+typedef int32_t __s32;
+typedef uint32_t __u32;
+typedef int64_t __s64;
+typedef uint64_t __u64;
+
+#define UAC_USE_FEATURE_UNIT 0 /* Feature unit does not support */
+
+/*
+ * Below are truly Linux-specific types that should never collide with
+ * any application/library that wants linux/types.h.
+ */
+
+#ifdef __CHECKER__
+#define __bitwise__ __attribute__((bitwise))
+#else
+#define __bitwise__
+#endif
+#ifdef __CHECK_ENDIAN__
+#define __bitwise __bitwise__
+#else
+#define __bitwise
+#endif
+
+typedef __u16 __bitwise __le16;
+typedef __u16 __bitwise __be16;
+typedef __u32 __bitwise __le32;
+typedef __u32 __bitwise __be32;
+typedef __u64 __bitwise __le64;
+typedef __u64 __bitwise __be64;
+
+typedef __u16 __bitwise __sum16;
+typedef __u32 __bitwise __wsum;
+
+/* bInterfaceProtocol values to denote the version of the standard used */
+#define UAC_VERSION_1 0x00
+#define UAC_VERSION_2 0x20
+#define UAC_VERSION_3 0x30
+
+/* A.2 Audio Interface Subclass Codes */
+#define USB_SUBCLASS_AUDIOCONTROL 0x01
+#define USB_SUBCLASS_AUDIOSTREAMING 0x02
+#define USB_SUBCLASS_MIDISTREAMING 0x03
+
+/* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */
+#define UAC_HEADER 0x01
+#define UAC_INPUT_TERMINAL 0x02
+#define UAC_OUTPUT_TERMINAL 0x03
+#define UAC_MIXER_UNIT 0x04
+#define UAC_SELECTOR_UNIT 0x05
+#define UAC_FEATURE_UNIT 0x06
+#define UAC1_PROCESSING_UNIT 0x07
+#define UAC1_EXTENSION_UNIT 0x08
+
+/* A.6 Audio Class-Specific AS Interface Descriptor Subtypes */
+#define UAC_AS_GENERAL 0x01
+#define UAC_FORMAT_TYPE 0x02
+#define UAC_FORMAT_SPECIFIC 0x03
+
+/* A.7 Processing Unit Process Types */
+#define UAC_PROCESS_UNDEFINED 0x00
+#define UAC_PROCESS_UP_DOWNMIX 0x01
+#define UAC_PROCESS_DOLBY_PROLOGIC 0x02
+#define UAC_PROCESS_STEREO_EXTENDER 0x03
+#define UAC_PROCESS_REVERB 0x04
+#define UAC_PROCESS_CHORUS 0x05
+#define UAC_PROCESS_DYN_RANGE_COMP 0x06
+
+/* A.8 Audio Class-Specific Endpoint Descriptor Subtypes */
+#define UAC_EP_GENERAL 0x01
+
+/* A.9 Audio Class-Specific Request Codes */
+#define UAC_SET_ 0x00
+#define UAC_GET_ 0x80
+
+#define UAC__CUR 0x1
+#define UAC__MIN 0x2
+#define UAC__MAX 0x3
+#define UAC__RES 0x4
+#define UAC__MEM 0x5
+
+#define UAC_SET_CUR (UAC_SET_ | UAC__CUR)
+#define UAC_GET_CUR (UAC_GET_ | UAC__CUR)
+#define UAC_SET_MIN (UAC_SET_ | UAC__MIN)
+#define UAC_GET_MIN (UAC_GET_ | UAC__MIN)
+#define UAC_SET_MAX (UAC_SET_ | UAC__MAX)
+#define UAC_GET_MAX (UAC_GET_ | UAC__MAX)
+#define UAC_SET_RES (UAC_SET_ | UAC__RES)
+#define UAC_GET_RES (UAC_GET_ | UAC__RES)
+#define UAC_SET_MEM (UAC_SET_ | UAC__MEM)
+#define UAC_GET_MEM (UAC_GET_ | UAC__MEM)
+
+#define UAC_GET_STAT 0xff
+
+/* A.10 Control Selector Codes */
+
+/* A.10.1 Terminal Control Selectors */
+#define UAC_TERM_COPY_PROTECT 0x01
+
+/* A.10.2 Feature Unit Control Selectors */
+#define UAC_FU_MUTE 0x01
+#define UAC_FU_VOLUME 0x02
+#define UAC_FU_BASS 0x03
+#define UAC_FU_MID 0x04
+#define UAC_FU_TREBLE 0x05
+#define UAC_FU_GRAPHIC_EQUALIZER 0x06
+#define UAC_FU_AUTOMATIC_GAIN 0x07
+#define UAC_FU_DELAY 0x08
+#define UAC_FU_BASS_BOOST 0x09
+#define UAC_FU_LOUDNESS 0x0a
+
+#define UAC_CONTROL_BIT(CS) (1 << ((CS) - 1))
+
+/* A.10.3.1 Up/Down-mix Processing Unit Controls Selectors */
+#define UAC_UD_ENABLE 0x01
+#define UAC_UD_MODE_SELECT 0x02
+
+/* A.10.3.2 Dolby Prologic (tm) Processing Unit Controls Selectors */
+#define UAC_DP_ENABLE 0x01
+#define UAC_DP_MODE_SELECT 0x02
+
+/* A.10.3.3 3D Stereo Extender Processing Unit Control Selectors */
+#define UAC_3D_ENABLE 0x01
+#define UAC_3D_SPACE 0x02
+
+/* A.10.3.4 Reverberation Processing Unit Control Selectors */
+#define UAC_REVERB_ENABLE 0x01
+#define UAC_REVERB_LEVEL 0x02
+#define UAC_REVERB_TIME 0x03
+#define UAC_REVERB_FEEDBACK 0x04
+
+/* A.10.3.5 Chorus Processing Unit Control Selectors */
+#define UAC_CHORUS_ENABLE 0x01
+#define UAC_CHORUS_LEVEL 0x02
+#define UAC_CHORUS_RATE 0x03
+#define UAC_CHORUS_DEPTH 0x04
+
+/* A.10.3.6 Dynamic Range Compressor Unit Control Selectors */
+#define UAC_DCR_ENABLE 0x01
+#define UAC_DCR_RATE 0x02
+#define UAC_DCR_MAXAMPL 0x03
+#define UAC_DCR_THRESHOLD 0x04
+#define UAC_DCR_ATTACK_TIME 0x05
+#define UAC_DCR_RELEASE_TIME 0x06
+
+/* A.10.4 Extension Unit Control Selectors */
+#define UAC_XU_ENABLE 0x01
+
+/* MIDI - A.1 MS Class-Specific Interface Descriptor Subtypes */
+#define UAC_MS_HEADER 0x01
+#define UAC_MIDI_IN_JACK 0x02
+#define UAC_MIDI_OUT_JACK 0x03
+
+/* MIDI - A.1 MS Class-Specific Endpoint Descriptor Subtypes */
+#define UAC_MS_GENERAL 0x01
+
+/* Terminals - 2.1 USB Terminal Types */
+#define UAC_TERMINAL_UNDEFINED 0x100
+#define UAC_TERMINAL_STREAMING 0x101
+#define UAC_TERMINAL_VENDOR_SPEC 0x1FF
+
+/* Terminal Control Selectors */
+/* 4.3.2 Class-Specific AC Interface Descriptor */
+struct uac1_ac_header_descriptor {
+ __u8 bLength; /* 8 + n */
+ __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
+ __u8 bDescriptorSubtype; /* UAC_MS_HEADER */
+ __le16 bcdADC; /* 0x0100 */
+ __le16 wTotalLength; /* includes Unit and Terminal desc. */
+ __u8 bInCollection; /* n */
+ __u8 baInterfaceNr[]; /* [n] */
+} __attribute__ ((packed));
+
+#define UAC_DT_AC_HEADER_SIZE(n) (8 + (n))
+
+/* As above, but more useful for defining your own descriptors: */
+#define DECLARE_UAC_AC_HEADER_DESCRIPTOR(n) \
+struct uac1_ac_header_descriptor_##n { \
+ __u8 bLength; \
+ __u8 bDescriptorType; \
+ __u8 bDescriptorSubtype; \
+ __le16 bcdADC; \
+ __le16 wTotalLength; \
+ __u8 bInCollection; \
+ __u8 baInterfaceNr[n]; \
+} __attribute__ ((packed))
+
+/* 4.3.2.1 Input Terminal Descriptor */
+struct uac_input_terminal_descriptor {
+ __u8 bLength; /* in bytes: 12 */
+ __u8 bDescriptorType; /* CS_INTERFACE descriptor type */
+ __u8 bDescriptorSubtype; /* INPUT_TERMINAL descriptor subtype */
+ __u8 bTerminalID; /* Constant uniquely terminal ID */
+ __le16 wTerminalType; /* USB Audio Terminal Types */
+ __u8 bAssocTerminal; /* ID of the Output Terminal associated */
+ __u8 bNrChannels; /* Number of logical output channels */
+ __le16 wChannelConfig;
+ __u8 iChannelNames;
+ __u8 iTerminal;
+} __attribute__ ((packed));
+
+#define UAC_DT_INPUT_TERMINAL_SIZE 12
+
+/* Terminals - 2.2 Input Terminal Types */
+#define UAC_INPUT_TERMINAL_UNDEFINED 0x200
+#define UAC_INPUT_TERMINAL_MICROPHONE 0x201
+#define UAC_INPUT_TERMINAL_DESKTOP_MICROPHONE 0x202
+#define UAC_INPUT_TERMINAL_PERSONAL_MICROPHONE 0x203
+#define UAC_INPUT_TERMINAL_OMNI_DIR_MICROPHONE 0x204
+#define UAC_INPUT_TERMINAL_MICROPHONE_ARRAY 0x205
+#define UAC_INPUT_TERMINAL_PROC_MICROPHONE_ARRAY 0x206
+
+/* Terminals - control selectors */
+
+#define UAC_TERMINAL_CS_COPY_PROTECT_CONTROL 0x01
+
+/* 4.3.2.2 Output Terminal Descriptor */
+struct uac1_output_terminal_descriptor {
+ __u8 bLength; /* in bytes: 9 */
+ __u8 bDescriptorType; /* CS_INTERFACE descriptor type */
+ __u8 bDescriptorSubtype; /* OUTPUT_TERMINAL descriptor subtype */
+ __u8 bTerminalID; /* Constant uniquely terminal ID */
+ __le16 wTerminalType; /* USB Audio Terminal Types */
+ __u8 bAssocTerminal; /* ID of the Input Terminal associated */
+ __u8 bSourceID; /* ID of the connected Unit or Terminal*/
+ __u8 iTerminal;
+} __attribute__ ((packed));
+
+#define UAC_DT_OUTPUT_TERMINAL_SIZE 9
+
+/* Terminals - 2.3 Output Terminal Types */
+#define UAC_OUTPUT_TERMINAL_UNDEFINED 0x300
+#define UAC_OUTPUT_TERMINAL_SPEAKER 0x301
+#define UAC_OUTPUT_TERMINAL_HEADPHONES 0x302
+#define UAC_OUTPUT_TERMINAL_HEAD_MOUNTED_DISPLAY_AUDIO 0x303
+#define UAC_OUTPUT_TERMINAL_DESKTOP_SPEAKER 0x304
+#define UAC_OUTPUT_TERMINAL_ROOM_SPEAKER 0x305
+#define UAC_OUTPUT_TERMINAL_COMMUNICATION_SPEAKER 0x306
+#define UAC_OUTPUT_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER 0x307
+
+/* Terminals - 2.4 Bi-directional Terminal Types */
+#define UAC_BIDIR_TERMINAL_UNDEFINED 0x400
+#define UAC_BIDIR_TERMINAL_HANDSET 0x401
+#define UAC_BIDIR_TERMINAL_HEADSET 0x402
+#define UAC_BIDIR_TERMINAL_SPEAKER_PHONE 0x403
+#define UAC_BIDIR_TERMINAL_ECHO_SUPPRESSING 0x404
+#define UAC_BIDIR_TERMINAL_ECHO_CANCELING 0x405
+
+/* Set bControlSize = 2 as default setting */
+#define UAC_DT_FEATURE_UNIT_SIZE(ch) (7 + ((ch) + 1) * 2)
+
+/* As above, but more useful for defining your own descriptors: */
+#define DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(ch) \
+struct uac_feature_unit_descriptor_##ch { \
+ __u8 bLength; \
+ __u8 bDescriptorType; \
+ __u8 bDescriptorSubtype; \
+ __u8 bUnitID; \
+ __u8 bSourceID; \
+ __u8 bControlSize; \
+ __le16 bmaControls[ch + 1]; \
+ __u8 iFeature; \
+} __attribute__ ((packed))
+
+/* 4.3.2.3 Mixer Unit Descriptor */
+struct uac_mixer_unit_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bUnitID;
+ __u8 bNrInPins;
+ __u8 baSourceID[];
+} __attribute__ ((packed));
+
+static inline __u8 uac_mixer_unit_bNrChannels(struct uac_mixer_unit_descriptor *desc)
+{
+ return desc->baSourceID[desc->bNrInPins];
+}
+
+static inline __u32 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc,
+ int protocol)
+{
+ if (protocol == UAC_VERSION_1)
+ return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
+ desc->baSourceID[desc->bNrInPins + 1];
+ else
+ return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
+ (desc->baSourceID[desc->bNrInPins + 3] << 16) |
+ (desc->baSourceID[desc->bNrInPins + 2] << 8) |
+ (desc->baSourceID[desc->bNrInPins + 1]);
+}
+
+static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc,
+ int protocol)
+{
+ return (protocol == UAC_VERSION_1) ?
+ desc->baSourceID[desc->bNrInPins + 3] :
+ desc->baSourceID[desc->bNrInPins + 5];
+}
+
+static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc,
+ int protocol)
+{
+ switch (protocol) {
+ case UAC_VERSION_1:
+ return &desc->baSourceID[desc->bNrInPins + 4];
+ case UAC_VERSION_2:
+ return &desc->baSourceID[desc->bNrInPins + 6];
+ case UAC_VERSION_3:
+ return &desc->baSourceID[desc->bNrInPins + 2];
+ default:
+ return NULL;
+ }
+}
+
+static inline __u16 uac3_mixer_unit_wClusterDescrID(struct uac_mixer_unit_descriptor *desc)
+{
+ return (desc->baSourceID[desc->bNrInPins + 1] << 8) |
+ desc->baSourceID[desc->bNrInPins];
+}
+
+static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc)
+{
+ __u8 *raw = (__u8 *) desc;
+ return raw[desc->bLength - 1];
+}
+
+/* 4.3.2.4 Selector Unit Descriptor */
+struct uac_selector_unit_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bUintID;
+ __u8 bNrInPins;
+ __u8 baSourceID[];
+} __attribute__ ((packed));
+
+static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc)
+{
+ __u8 *raw = (__u8 *) desc;
+ return raw[desc->bLength - 1];
+}
+#if UAC_USE_FEATURE_UNIT
+/* 4.3.2.5 Feature Unit Descriptor */
+struct uac_feature_unit_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bUnitID;
+ __u8 bSourceID;
+ __u8 bControlSize;
+ __u8 bmaControls[0]; /* variable length */
+} __attribute__((packed));
+
+static inline __u8 uac_feature_unit_iFeature(struct uac_feature_unit_descriptor *desc)
+{
+ __u8 *raw = (__u8 *) desc;
+ return raw[desc->bLength - 1];
+}
+#endif
+/* 4.3.2.6 Processing Unit Descriptors */
+struct uac_processing_unit_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bUnitID;
+ __le16 wProcessType;
+ __u8 bNrInPins;
+ __u8 baSourceID[];
+} __attribute__ ((packed));
+
+static inline __u8 uac_processing_unit_bNrChannels(struct uac_processing_unit_descriptor *desc)
+{
+ return desc->baSourceID[desc->bNrInPins];
+}
+
+static inline __u32 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ if (protocol == UAC_VERSION_1)
+ return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
+ desc->baSourceID[desc->bNrInPins + 1];
+ else
+ return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
+ (desc->baSourceID[desc->bNrInPins + 3] << 16) |
+ (desc->baSourceID[desc->bNrInPins + 2] << 8) |
+ (desc->baSourceID[desc->bNrInPins + 1]);
+}
+
+static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ return (protocol == UAC_VERSION_1) ?
+ desc->baSourceID[desc->bNrInPins + 3] :
+ desc->baSourceID[desc->bNrInPins + 5];
+}
+
+static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ switch (protocol) {
+ case UAC_VERSION_1:
+ return desc->baSourceID[desc->bNrInPins + 4];
+ case UAC_VERSION_2:
+ return 2; /* in UAC2, this value is constant */
+ case UAC_VERSION_3:
+ return 4; /* in UAC3, this value is constant */
+ default:
+ return 1;
+ }
+}
+
+static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ switch (protocol) {
+ case UAC_VERSION_1:
+ return &desc->baSourceID[desc->bNrInPins + 5];
+ case UAC_VERSION_2:
+ return &desc->baSourceID[desc->bNrInPins + 6];
+ case UAC_VERSION_3:
+ return &desc->baSourceID[desc->bNrInPins + 2];
+ default:
+ return NULL;
+ }
+}
+
+static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ __u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
+
+ switch (protocol) {
+ case UAC_VERSION_1:
+ case UAC_VERSION_2:
+ default:
+ return *(uac_processing_unit_bmControls(desc, protocol)
+ + control_size);
+ case UAC_VERSION_3:
+ return 0; /* UAC3 does not have this field */
+ }
+}
+
+static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ __u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
+
+ switch (protocol) {
+ case UAC_VERSION_1:
+ case UAC_VERSION_2:
+ default:
+ return uac_processing_unit_bmControls(desc, protocol)
+ + control_size + 1;
+ case UAC_VERSION_3:
+ return uac_processing_unit_bmControls(desc, protocol)
+ + control_size;
+ }
+}
+
+/*
+ * Extension Unit (XU) has almost compatible layout with Processing Unit, but
+ * on UAC2, it has a different bmControls size (bControlSize); it's 1 byte for
+ * XU while 2 bytes for PU. The last iExtension field is a one-byte index as
+ * well as iProcessing field of PU.
+ */
+static inline __u8 uac_extension_unit_bControlSize(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ switch (protocol) {
+ case UAC_VERSION_1:
+ return desc->baSourceID[desc->bNrInPins + 4];
+ case UAC_VERSION_2:
+ return 1; /* in UAC2, this value is constant */
+ case UAC_VERSION_3:
+ return 4; /* in UAC3, this value is constant */
+ default:
+ return 1;
+ }
+}
+
+static inline __u8 uac_extension_unit_iExtension(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ __u8 control_size = uac_extension_unit_bControlSize(desc, protocol);
+
+ switch (protocol) {
+ case UAC_VERSION_1:
+ case UAC_VERSION_2:
+ default:
+ return *(uac_processing_unit_bmControls(desc, protocol)
+ + control_size);
+ case UAC_VERSION_3:
+ return 0; /* UAC3 does not have this field */
+ }
+}
+
+/* 4.5.2 Class-Specific AS Interface Descriptor */
+struct uac1_as_header_descriptor {
+ __u8 bLength; /* in bytes: 7 */
+ __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
+ __u8 bDescriptorSubtype; /* AS_GENERAL */
+ __u8 bTerminalLink; /* Terminal ID of connected Terminal */
+ __u8 bDelay; /* Delay introduced by the data path */
+ __le16 wFormatTag; /* The Audio Data Format */
+} __attribute__ ((packed));
+
+#define UAC_DT_AS_HEADER_SIZE 7
+
+/* Formats - A.1.1 Audio Data Format Type I Codes */
+#define UAC_FORMAT_TYPE_I_UNDEFINED 0x0
+#define UAC_FORMAT_TYPE_I_PCM 0x1
+#define UAC_FORMAT_TYPE_I_PCM8 0x2
+#define UAC_FORMAT_TYPE_I_IEEE_FLOAT 0x3
+#define UAC_FORMAT_TYPE_I_ALAW 0x4
+#define UAC_FORMAT_TYPE_I_MULAW 0x5
+
+struct uac_format_type_i_continuous_descriptor {
+ __u8 bLength; /* in bytes: 8 + (ns * 3) */
+ __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
+ __u8 bDescriptorSubtype; /* FORMAT_TYPE */
+ __u8 bFormatType; /* FORMAT_TYPE_1 */
+ __u8 bNrChannels; /* physical channels in the stream */
+ __u8 bSubframeSize; /* */
+ __u8 bBitResolution;
+ __u8 bSamFreqType;
+ __u8 tLowerSamFreq[3];
+ __u8 tUpperSamFreq[3];
+} __attribute__ ((packed));
+
+#define UAC_FORMAT_TYPE_I_CONTINUOUS_DESC_SIZE 14
+
+struct uac_format_type_i_discrete_descriptor {
+ __u8 bLength; /* in bytes: 8 + (ns * 3) */
+ __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
+ __u8 bDescriptorSubtype; /* FORMAT_TYPE */
+ __u8 bFormatType; /* FORMAT_TYPE_1 */
+ __u8 bNrChannels; /* physical channels in the stream */
+ __u8 bSubframeSize; /* */
+ __u8 bBitResolution;
+ __u8 bSamFreqType;
+ __u8 tSamFreq[][3];
+} __attribute__ ((packed));
+
+#define DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(n) \
+struct uac_format_type_i_discrete_descriptor_##n { \
+ __u8 bLength; \
+ __u8 bDescriptorType; \
+ __u8 bDescriptorSubtype; \
+ __u8 bFormatType; \
+ __u8 bNrChannels; \
+ __u8 bSubframeSize; \
+ __u8 bBitResolution; \
+ __u8 bSamFreqType; \
+ __u8 tSamFreq[n][3]; \
+} __attribute__ ((packed))
+
+#define UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(n) (8 + (n * 3))
+
+struct uac_format_type_i_ext_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bFormatType;
+ __u8 bSubslotSize;
+ __u8 bBitResolution;
+ __u8 bHeaderLength;
+ __u8 bControlSize;
+ __u8 bSideBandProtocol;
+} __attribute__((packed));
+
+/* Formats - Audio Data Format Type I Codes */
+
+#define UAC_FORMAT_TYPE_II_MPEG 0x1001
+#define UAC_FORMAT_TYPE_II_AC3 0x1002
+
+struct uac_format_type_ii_discrete_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bFormatType;
+ __le16 wMaxBitRate;
+ __le16 wSamplesPerFrame;
+ __u8 bSamFreqType;
+ __u8 tSamFreq[][3];
+} __attribute__((packed));
+
+struct uac_format_type_ii_ext_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bFormatType;
+ __le16 wMaxBitRate;
+ __le16 wSamplesPerFrame;
+ __u8 bHeaderLength;
+ __u8 bSideBandProtocol;
+} __attribute__((packed));
+
+/* type III */
+#define UAC_FORMAT_TYPE_III_IEC1937_AC3 0x2001
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG1_LAYER1 0x2002
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_NOEXT 0x2003
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_EXT 0x2004
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_LAYER1_LS 0x2005
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_LAYER23_LS 0x2006
+
+/* Formats - A.2 Format Type Codes */
+#define UAC_FORMAT_TYPE_UNDEFINED 0x0
+#define UAC_FORMAT_TYPE_I 0x1
+#define UAC_FORMAT_TYPE_II 0x2
+#define UAC_FORMAT_TYPE_III 0x3
+#define UAC_EXT_FORMAT_TYPE_I 0x81
+#define UAC_EXT_FORMAT_TYPE_II 0x82
+#define UAC_EXT_FORMAT_TYPE_III 0x83
+
+struct uac_iso_endpoint_descriptor {
+ __u8 bLength; /* in bytes: 7 */
+ __u8 bDescriptorType; /* USB_DT_CS_ENDPOINT */
+ __u8 bDescriptorSubtype; /* EP_GENERAL */
+ __u8 bmAttributes;
+ __u8 bLockDelayUnits;
+ __le16 wLockDelay;
+} __attribute__((packed));
+#define UAC_ISO_ENDPOINT_DESC_SIZE 7
+
+#define UAC_EP_CS_ATTR_SAMPLE_RATE 0x01
+#define UAC_EP_CS_ATTR_PITCH_CONTROL 0x02
+#define UAC_EP_CS_ATTR_FILL_MAX 0x80
+
+/* status word format (3.7.1.1) */
+
+#define UAC1_STATUS_TYPE_ORIG_MASK 0x0f
+#define UAC1_STATUS_TYPE_ORIG_AUDIO_CONTROL_IF 0x0
+#define UAC1_STATUS_TYPE_ORIG_AUDIO_STREAM_IF 0x1
+#define UAC1_STATUS_TYPE_ORIG_AUDIO_STREAM_EP 0x2
+
+#define UAC1_STATUS_TYPE_IRQ_PENDING (1 << 7)
+#define UAC1_STATUS_TYPE_MEM_CHANGED (1 << 6)
+
+struct uac1_status_word {
+ __u8 bStatusType;
+ __u8 bOriginator;
+} __attribute__((packed));
+
+
+#endif /* _UAPI__LINUX_USB_AUDIO_H */
diff --git a/components/drivers/usb/usbdevice/class/audio_mic.c b/components/drivers/usb/usbdevice/class/audio_mic.c
new file mode 100644
index 0000000000..4ac85711ad
--- /dev/null
+++ b/components/drivers/usb/usbdevice/class/audio_mic.c
@@ -0,0 +1,577 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-09-07 flybreak the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtservice.h>
+#include <rtdevice.h>
+
+#include "drivers/usb_device.h"
+#include "audio.h"
+
+#define DBG_TAG "usbd.audio.mic"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#define RECORD_SAMPLERATE 16000
+#define RECORD_CHANNEL 1
+#define RESOLUTION_BITS 16
+
+#define RESOLUTION_BYTE (RESOLUTION_BITS / 8)
+#define RECORD_PER_MS_SZ ((RECORD_SAMPLERATE * RECORD_CHANNEL * RESOLUTION_BYTE) / 1000)
+#define RECORD_BUFFER_SZ (RECORD_PER_MS_SZ * 20) /* 20ms */
+
+#if defined(RT_USBD_MIC_DEVICE_NAME)
+ #define MIC_DEVICE_NAME RT_USBD_MIC_DEVICE_NAME
+#else
+ #define MIC_DEVICE_NAME "mic0"
+#endif
+
+#define EVENT_RECORD_START (1 << 0)
+#define EVENT_RECORD_STOP (1 << 1)
+#define EVENT_RECORD_DATA (1 << 2)
+
+/*
+ * uac mic descriptor define
+ */
+
+#define UAC_CS_INTERFACE 0x24
+#define UAC_CS_ENDPOINT 0x25
+
+#define UAC_MAX_PACKET_SIZE 64
+#define UAC_EP_MAX_PACKET_SIZE 32
+#define UAC_CHANNEL_NUM RECORD_CHANNEL
+#define UAC_INTR_NUM 1
+#define UAC_CH_NUM 1
+#define UAC_FORMAT_NUM 1
+
+struct uac_ac_descriptor
+{
+#ifdef RT_USB_DEVICE_COMPOSITE
+ struct uiad_descriptor iad_desc;
+#endif
+ struct uinterface_descriptor intf_desc;
+ DECLARE_UAC_AC_HEADER_DESCRIPTOR(UAC_INTR_NUM) hdr_desc;
+ struct uac_input_terminal_descriptor it_desc;
+ struct uac1_output_terminal_descriptor ot_desc;
+#if UAC_USE_FEATURE_UNIT
+ DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(UAC_CH_NUM) feature_unit_desc;
+#endif
+};
+
+struct uac_as_descriptor
+{
+ struct uinterface_descriptor intf_desc;
+ struct uac1_as_header_descriptor hdr_desc;
+ DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(UAC_FORMAT_NUM) format_type_desc;
+ struct uendpoint_descriptor ep_desc;
+ struct uac_iso_endpoint_descriptor as_ep_desc;
+};
+
+/*
+ * uac mic device type
+ */
+
+struct uac_audio_mic
+{
+ rt_device_t dev;
+ rt_event_t event;
+ rt_uint8_t open_count;
+
+ rt_uint8_t *buffer;
+ rt_uint32_t buffer_index;
+
+ uep_t ep;
+};
+static struct uac_audio_mic mic;
+
+ALIGN(4)
+static struct udevice_descriptor dev_desc =
+{
+ USB_DESC_LENGTH_DEVICE, //bLength;
+ USB_DESC_TYPE_DEVICE, //type;
+ USB_BCD_VERSION, //bcdUSB;
+ USB_CLASS_DEVICE, //bDeviceClass;
+ 0x00, //bDeviceSubClass;
+ 0x00, //bDeviceProtocol;
+ UAC_MAX_PACKET_SIZE, //bMaxPacketSize0;
+ _VENDOR_ID, //idVendor;
+ _PRODUCT_ID, //idProduct;
+ USB_BCD_DEVICE, //bcdDevice;
+ USB_STRING_MANU_INDEX, //iManufacturer;
+ USB_STRING_PRODUCT_INDEX, //iProduct;
+ USB_STRING_SERIAL_INDEX, //iSerialNumber;Unused.
+ USB_DYNAMIC, //bNumConfigurations;
+};
+
+//FS and HS needed
+ALIGN(4)
+static struct usb_qualifier_descriptor dev_qualifier =
+{
+ sizeof(dev_qualifier), //bLength
+ USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType
+ 0x0200, //bcdUSB
+ USB_CLASS_AUDIO, //bDeviceClass
+ 0x00, //bDeviceSubClass
+ 0x00, //bDeviceProtocol
+ 64, //bMaxPacketSize0
+ 0x01, //bNumConfigurations
+ 0,
+};
+
+ALIGN(4)
+const static char *_ustring[] =
+{
+ "Language",
+ "RT-Thread Team.",
+ "Microphone",
+ "32021919830108",
+ "Configuration",
+ "Interface",
+};
+
+ALIGN(4)
+static struct uac_ac_descriptor ac_desc =
+{
+#ifdef RT_USB_DEVICE_COMPOSITE
+ /* Interface Association Descriptor */
+ {
+ USB_DESC_LENGTH_IAD,
+ USB_DESC_TYPE_IAD,
+ USB_DYNAMIC,
+ 0x02,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOSTREAMING,
+ 0x00,
+ 0x00,
+ },
+#endif
+ /* Interface Descriptor */
+ {
+ USB_DESC_LENGTH_INTERFACE,
+ USB_DESC_TYPE_INTERFACE,
+ USB_DYNAMIC,
+ 0x00,
+ 0x00,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOCONTROL,
+ 0x00,
+ 0x00,
+ },
+ /* Header Descriptor */
+ {
+ UAC_DT_AC_HEADER_SIZE(UAC_INTR_NUM),
+ UAC_CS_INTERFACE,
+ UAC_HEADER,
+ 0x0100, /* Version: 1.00 */
+ 0x001E, /* Total length: 30 */
+ 0x01, /* Total number of interfaces: 1 */
+ {0x01}, /* Interface number: 1 */
+ },
+ /* Input Terminal Descriptor */
+ {
+ UAC_DT_INPUT_TERMINAL_SIZE,
+ UAC_CS_INTERFACE,
+ UAC_INPUT_TERMINAL,
+ 0x01, /* Terminal ID: 1 */
+ 0x0201, /* Terminal Type: Microphone (0x0201) */
+ 0x00, /* Assoc Terminal: 0 */
+ 0x01, /* Number Channels: 1 */
+ 0x0000, /* Channel Config: 0x0000 */
+ 0x00, /* Channel Names: 0 */
+ 0x00, /* Terminal: 0 */
+ },
+ /* Output Terminal Descriptor */
+ {
+ UAC_DT_OUTPUT_TERMINAL_SIZE,
+ UAC_CS_INTERFACE,
+ UAC_OUTPUT_TERMINAL,
+ 0x02, /* Terminal ID: 2 */
+ 0x0101, /* Terminal Type: USB Streaming (0x0101) */
+ 0x00, /* Assoc Terminal: 0 */
+ 0x01, /* Source ID: 1 */
+ 0x00, /* Terminal: 0 */
+ },
+#if UAC_USE_FEATURE_UNIT
+ /* Feature unit Descriptor */
+ {
+ UAC_DT_FEATURE_UNIT_SIZE(UAC_CH_NUM),
+ UAC_CS_INTERFACE,
+ UAC_FEATURE_UNIT,
+ 0x02,
+ 0x0101,
+ 0x00,
+ 0x01,
+ },
+#endif
+};
+
+ALIGN(4)
+static struct uinterface_descriptor as_desc0 =
+{
+ USB_DESC_LENGTH_INTERFACE,
+ USB_DESC_TYPE_INTERFACE,
+ USB_DYNAMIC,
+ 0x00,
+ 0x00,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOSTREAMING,
+ 0x00,
+ 0x00,
+};
+
+ALIGN(4)
+static struct uac_as_descriptor as_desc =
+{
+ /* Interface Descriptor */
+ {
+ USB_DESC_LENGTH_INTERFACE,
+ USB_DESC_TYPE_INTERFACE,
+ USB_DYNAMIC,
+ 0x01,
+ 0x01,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOSTREAMING,
+ 0x00,
+ 0x00,
+ },
+ /* General AS Descriptor */
+ {
+ UAC_DT_AS_HEADER_SIZE,
+ UAC_CS_INTERFACE,
+ UAC_AS_GENERAL,
+ 0x02, /* Terminal ID: 2 */
+ 0x01, /* Interface delay in frames: 1 */
+ UAC_FORMAT_TYPE_I_PCM,
+ },
+ /* Format type i Descriptor */
+ {
+ UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(UAC_FORMAT_NUM),
+ UAC_CS_INTERFACE,
+ UAC_FORMAT_TYPE,
+ UAC_FORMAT_TYPE_I,
+ UAC_CHANNEL_NUM,
+ 2, /* Subframe Size: 2 */
+ RESOLUTION_BITS,
+ 0x01, /* Samples Frequence Type: 1 */
+ {0}, /* Samples Frequence */
+ },
+ /* Endpoint Descriptor */
+ {
+ USB_DESC_LENGTH_ENDPOINT,
+ USB_DESC_TYPE_ENDPOINT,
+ USB_DYNAMIC | USB_DIR_IN,
+ USB_EP_ATTR_ISOC,
+ UAC_EP_MAX_PACKET_SIZE,
+ 0x01,
+ },
+ /* AS Endpoint Descriptor */
+ {
+ UAC_ISO_ENDPOINT_DESC_SIZE,
+ UAC_CS_ENDPOINT,
+ UAC_MS_GENERAL,
+ },
+};
+
+void mic_entry(void *parameter)
+{
+ struct rt_audio_caps caps = {0};
+ rt_uint32_t e, index;
+
+ mic.buffer = rt_malloc(RECORD_BUFFER_SZ);
+ if (mic.buffer == RT_NULL)
+ {
+ LOG_E("malloc failed");
+ goto __exit;
+ }
+
+ mic.dev = rt_device_find(MIC_DEVICE_NAME);
+ if (mic.dev == RT_NULL)
+ {
+ LOG_E("can't find device:%s", MIC_DEVICE_NAME);
+ goto __exit;
+ }
+
+ while (1)
+ {
+ if (rt_event_recv(mic.event, EVENT_RECORD_START | EVENT_RECORD_STOP,
+ RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
+ 1000, &e) != RT_EOK)
+ {
+ continue;
+ }
+ if (mic.open_count == 0)
+ {
+ continue;
+ }
+ LOG_D("record start");
+
+ rt_device_open(mic.dev, RT_DEVICE_OFLAG_RDONLY);
+
+ caps.main_type = AUDIO_TYPE_INPUT;
+ caps.sub_type = AUDIO_DSP_PARAM;
+ caps.udata.config.samplerate = RECORD_SAMPLERATE;
+ caps.udata.config.channels = RECORD_CHANNEL;
+ caps.udata.config.samplebits = RESOLUTION_BITS;
+ rt_device_control(mic.dev, AUDIO_CTL_CONFIGURE, &caps);
+
+ while (1)
+ {
+ if (rt_event_recv(mic.event, EVENT_RECORD_DATA | EVENT_RECORD_STOP,
+ RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
+ 1000, &e) != RT_EOK)
+ {
+ if (mic.open_count > 0)
+ continue;
+ else
+ break;
+ }
+ if (e & EVENT_RECORD_DATA)
+ {
+ index = (mic.buffer_index >= RECORD_BUFFER_SZ / 2) ? 0 : (RECORD_BUFFER_SZ / 2);
+ rt_device_read(mic.dev, 0, mic.buffer + index, RECORD_BUFFER_SZ / 2);
+ }
+ else if (e & EVENT_RECORD_STOP)
+ {
+ break;
+ }
+ }
+ LOG_D("record stop");
+ rt_device_close(mic.dev);
+ }
+
+__exit:
+ if (mic.buffer)
+ rt_free(mic.buffer);
+}
+
+static rt_err_t _record_start(ufunction_t func)
+{
+ mic.ep->request.buffer = RT_NULL;
+ mic.ep->request.size = UAC_EP_MAX_PACKET_SIZE;
+ mic.ep->request.req_type = UIO_REQUEST_WRITE;
+ rt_usbd_io_request(func->device, mic.ep, &mic.ep->request);
+
+ mic.open_count ++;
+ rt_event_send(mic.event, EVENT_RECORD_START);
+ return 0;
+}
+
+static rt_err_t _record_stop(ufunction_t func)
+{
+ mic.open_count --;
+ rt_event_send(mic.event, EVENT_RECORD_STOP);
+ return 0;
+}
+
+static rt_err_t _ep_data_in_handler(ufunction_t func, rt_size_t size)
+{
+ RT_ASSERT(func != RT_NULL);
+ LOG_D("_ep_data_in_handler");
+
+ mic.ep->request.buffer = mic.buffer + mic.buffer_index;
+ mic.ep->request.size = UAC_EP_MAX_PACKET_SIZE;
+ mic.ep->request.req_type = UIO_REQUEST_WRITE;
+ rt_usbd_io_request(func->device, mic.ep, &mic.ep->request);
+
+ mic.buffer_index += UAC_EP_MAX_PACKET_SIZE;
+ if (mic.buffer_index >= RECORD_BUFFER_SZ)
+ {
+ mic.buffer_index = 0;
+ rt_event_send(mic.event, EVENT_RECORD_DATA);
+ }
+ else if (mic.buffer_index == RECORD_BUFFER_SZ / 2)
+ {
+ rt_event_send(mic.event, EVENT_RECORD_DATA);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _interface_as_handler(ufunction_t func, ureq_t setup)
+{
+ RT_ASSERT(func != RT_NULL);
+ RT_ASSERT(func->device != RT_NULL);
+ RT_ASSERT(setup != RT_NULL);
+
+ LOG_D("_interface_as_handler");
+
+ if ((setup->request_type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD)
+ {
+ switch (setup->bRequest)
+ {
+ case USB_REQ_GET_INTERFACE:
+ break;
+ case USB_REQ_SET_INTERFACE:
+ LOG_D("set interface handler");
+ if (setup->wValue == 1)
+ {
+ _record_start(func);
+ }
+ else if (setup->wValue == 0)
+ {
+ _record_stop(func);
+ }
+ break;
+ default:
+ LOG_D("unknown uac request 0x%x", setup->bRequest);
+ return -RT_ERROR;
+ }
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _function_enable(ufunction_t func)
+{
+ RT_ASSERT(func != RT_NULL);
+
+ LOG_D("uac function enable");
+
+ return RT_EOK;
+}
+
+static rt_err_t _function_disable(ufunction_t func)
+{
+ RT_ASSERT(func != RT_NULL);
+
+ LOG_D("uac function disable");
+ _record_stop(func);
+ return RT_EOK;
+}
+
+static struct ufunction_ops ops =
+{
+ _function_enable,
+ _function_disable,
+ RT_NULL,
+};
+/**
+ * This function will configure uac descriptor.
+ *
+ * @param comm the communication interface number.
+ * @param data the data interface number.
+ *
+ * @return RT_EOK on successful.
+ */
+static rt_err_t _uac_descriptor_config(struct uac_ac_descriptor *ac,
+ rt_uint8_t cintf_nr, struct uac_as_descriptor *as, rt_uint8_t sintf_nr)
+{
+ ac->hdr_desc.baInterfaceNr[0] = sintf_nr;
+#ifdef RT_USB_DEVICE_COMPOSITE
+ ac->iad_desc.bFirstInterface = cintf_nr;
+#endif
+
+ return RT_EOK;
+}
+
+static rt_err_t _uac_samplerate_config(struct uac_as_descriptor *as, rt_uint32_t samplerate)
+{
+ as->format_type_desc.tSamFreq[0][2] = samplerate >> 16 & 0xff;
+ as->format_type_desc.tSamFreq[0][1] = samplerate >> 8 & 0xff;
+ as->format_type_desc.tSamFreq[0][0] = samplerate & 0xff;
+ return RT_EOK;
+}
+
+/**
+ * This function will create a uac function instance.
+ *
+ * @param device the usb device object.
+ *
+ * @return RT_EOK on successful.
+ */
+ufunction_t rt_usbd_function_uac_mic_create(udevice_t device)
+{
+ ufunction_t func;
+ uintf_t intf_ac, intf_as;
+ ualtsetting_t setting_as0;
+ ualtsetting_t setting_ac, setting_as;
+ struct uac_as_descriptor *as_desc_t;
+
+ /* parameter check */
+ RT_ASSERT(device != RT_NULL);
+
+ /* set usb device string description */
+ rt_usbd_device_set_string(device, _ustring);
+
+ /* create a uac function */
+ func = rt_usbd_function_new(device, &dev_desc, &ops);
+ //not support HS
+ //rt_usbd_device_set_qualifier(device, &dev_qualifier);
+
+ /* create interface */
+ intf_ac = rt_usbd_interface_new(device, RT_NULL);
+ intf_as = rt_usbd_interface_new(device, _interface_as_handler);
+
+ /* create alternate setting */
+ setting_ac = rt_usbd_altsetting_new(sizeof(struct uac_ac_descriptor));
+ setting_as0 = rt_usbd_altsetting_new(sizeof(struct uinterface_descriptor));
+ setting_as = rt_usbd_altsetting_new(sizeof(struct uac_as_descriptor));
+ /* config desc in alternate setting */
+ rt_usbd_altsetting_config_descriptor(setting_ac, &ac_desc,
+ (rt_off_t) & ((struct uac_ac_descriptor *)0)->intf_desc);
+ rt_usbd_altsetting_config_descriptor(setting_as0, &as_desc0, 0);
+ rt_usbd_altsetting_config_descriptor(setting_as, &as_desc,
+ (rt_off_t) & ((struct uac_as_descriptor *)0)->intf_desc);
+ /* configure the uac interface descriptor */
+ _uac_descriptor_config(setting_ac->desc, intf_ac->intf_num, setting_as->desc, intf_as->intf_num);
+ _uac_samplerate_config(setting_as->desc, RECORD_SAMPLERATE);
+
+ /* create endpoint */
+ as_desc_t = (struct uac_as_descriptor *)setting_as->desc;
+ mic.ep = rt_usbd_endpoint_new(&as_desc_t->ep_desc, _ep_data_in_handler);
+
+ /* add the endpoint to the alternate setting */
+ rt_usbd_altsetting_add_endpoint(setting_as, mic.ep);
+
+ /* add the alternate setting to the interface, then set default setting of the interface */
+ rt_usbd_interface_add_altsetting(intf_ac, setting_ac);
+ rt_usbd_set_altsetting(intf_ac, 0);
+ rt_usbd_interface_add_altsetting(intf_as, setting_as0);
+ rt_usbd_interface_add_altsetting(intf_as, setting_as);
+ rt_usbd_set_altsetting(intf_as, 0);
+
+ /* add the interface to the uac function */
+ rt_usbd_function_add_interface(func, intf_ac);
+ rt_usbd_function_add_interface(func, intf_as);
+
+ return func;
+}
+
+int audio_mic_init(void)
+{
+ rt_thread_t mic_tid;
+ mic.event = rt_event_create("mic_event", RT_IPC_FLAG_FIFO);
+
+ mic_tid = rt_thread_create("mic_thread",
+ mic_entry, RT_NULL,
+ 1024,
+ 5, 10);
+
+ if (mic_tid != RT_NULL)
+ rt_thread_startup(mic_tid);
+ return RT_EOK;
+}
+INIT_COMPONENT_EXPORT(audio_mic_init);
+
+/*
+ * register uac class
+ */
+struct udclass uac_class =
+{
+ .rt_usbd_function_create = rt_usbd_function_uac_mic_create
+};
+
+int rt_usbd_uac_mic_class_register(void)
+{
+ rt_usbd_class_register(&uac_class);
+ return 0;
+}
+INIT_PREV_EXPORT(rt_usbd_uac_mic_class_register);
diff --git a/components/drivers/usb/usbdevice/class/audio_speaker.c b/components/drivers/usb/usbdevice/class/audio_speaker.c
new file mode 100644
index 0000000000..84c36d2053
--- /dev/null
+++ b/components/drivers/usb/usbdevice/class/audio_speaker.c
@@ -0,0 +1,578 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-09-19 flybreak the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtservice.h>
+#include <rtdevice.h>
+
+#include "drivers/usb_device.h"
+#include "audio.h"
+
+#define DBG_TAG "usbd.audio.speaker"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#define AUDIO_SAMPLERATE 16000
+#define AUDIO_CHANNEL 1
+#define RESOLUTION_BITS 16
+
+#define RESOLUTION_BYTE (RESOLUTION_BITS / 8)
+#define AUDIO_PER_MS_SZ ((AUDIO_SAMPLERATE * AUDIO_CHANNEL * RESOLUTION_BYTE) / 1000)
+#define AUDIO_BUFFER_SZ (AUDIO_PER_MS_SZ * 20) /* 20ms */
+
+#if defined(RT_USBD_SPEAKER_DEVICE_NAME)
+ #define SPEAKER_DEVICE_NAME RT_USBD_SPEAKER_DEVICE_NAME
+#else
+ #define SPEAKER_DEVICE_NAME "sound0"
+#endif
+
+#define EVENT_AUDIO_START (1 << 0)
+#define EVENT_AUDIO_STOP (1 << 1)
+#define EVENT_AUDIO_DATA (1 << 2)
+
+/*
+ * uac speaker descriptor define
+ */
+
+#define UAC_CS_INTERFACE 0x24
+#define UAC_CS_ENDPOINT 0x25
+
+#define UAC_MAX_PACKET_SIZE 64
+#define UAC_EP_MAX_PACKET_SIZE 32
+#define UAC_CHANNEL_NUM AUDIO_CHANNEL
+#define UAC_INTR_NUM 1
+#define UAC_CH_NUM 1
+#define UAC_FORMAT_NUM 1
+
+struct uac_ac_descriptor
+{
+#ifdef RT_USB_DEVICE_COMPOSITE
+ struct uiad_descriptor iad_desc;
+#endif
+ struct uinterface_descriptor intf_desc;
+ DECLARE_UAC_AC_HEADER_DESCRIPTOR(UAC_INTR_NUM) hdr_desc;
+ struct uac_input_terminal_descriptor it_desc;
+ struct uac1_output_terminal_descriptor ot_desc;
+#if UAC_USE_FEATURE_UNIT
+ DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(UAC_CH_NUM) feature_unit_desc;
+#endif
+};
+
+struct uac_as_descriptor
+{
+ struct uinterface_descriptor intf_desc;
+ struct uac1_as_header_descriptor hdr_desc;
+ DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(UAC_FORMAT_NUM) format_type_desc;
+ struct uendpoint_descriptor ep_desc;
+ struct uac_iso_endpoint_descriptor as_ep_desc;
+};
+
+/*
+ * uac speaker device type
+ */
+
+struct uac_audio_speaker
+{
+ rt_device_t dev;
+ rt_event_t event;
+ rt_uint8_t open_count;
+
+ rt_uint8_t *buffer;
+ rt_uint32_t buffer_index;
+
+ uep_t ep;
+};
+static struct uac_audio_speaker speaker;
+
+ALIGN(4)
+static struct udevice_descriptor dev_desc =
+{
+ USB_DESC_LENGTH_DEVICE, //bLength;
+ USB_DESC_TYPE_DEVICE, //type;
+ USB_BCD_VERSION, //bcdUSB;
+ USB_CLASS_DEVICE, //bDeviceClass;
+ 0x00, //bDeviceSubClass;
+ 0x00, //bDeviceProtocol;
+ UAC_MAX_PACKET_SIZE, //bMaxPacketSize0;
+ _VENDOR_ID, //idVendor;
+ _PRODUCT_ID, //idProduct;
+ USB_BCD_DEVICE, //bcdDevice;
+ USB_STRING_MANU_INDEX, //iManufacturer;
+ USB_STRING_PRODUCT_INDEX, //iProduct;
+ USB_STRING_SERIAL_INDEX, //iSerialNumber;Unused.
+ USB_DYNAMIC, //bNumConfigurations;
+};
+
+//FS and HS needed
+ALIGN(4)
+static struct usb_qualifier_descriptor dev_qualifier =
+{
+ sizeof(dev_qualifier), //bLength
+ USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType
+ 0x0200, //bcdUSB
+ USB_CLASS_AUDIO, //bDeviceClass
+ 0x00, //bDeviceSubClass
+ 0x00, //bDeviceProtocol
+ 64, //bMaxPacketSize0
+ 0x01, //bNumConfigurations
+ 0,
+};
+
+ALIGN(4)
+const static char *_ustring[] =
+{
+ "Language",
+ "RT-Thread Team.",
+ "RT-Thread Speaker",
+ "32021919830108",
+ "Configuration",
+ "Interface",
+};
+
+ALIGN(4)
+static struct uac_ac_descriptor ac_desc =
+{
+#ifdef RT_USB_DEVICE_COMPOSITE
+ /* Interface Association Descriptor */
+ {
+ USB_DESC_LENGTH_IAD,
+ USB_DESC_TYPE_IAD,
+ USB_DYNAMIC,
+ 0x02,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOSTREAMING,
+ 0x00,
+ 0x00,
+ },
+#endif
+ /* Interface Descriptor */
+ {
+ USB_DESC_LENGTH_INTERFACE,
+ USB_DESC_TYPE_INTERFACE,
+ USB_DYNAMIC,
+ 0x00,
+ 0x00,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOCONTROL,
+ 0x00,
+ 0x00,
+ },
+ /* Header Descriptor */
+ {
+ UAC_DT_AC_HEADER_SIZE(UAC_INTR_NUM),
+ UAC_CS_INTERFACE,
+ UAC_HEADER,
+ 0x0100, /* Version: 1.00 */
+ 0x0027, /* Total length: 39 */
+ 0x01, /* Total number of interfaces: 1 */
+ {0x01}, /* Interface number: 1 */
+ },
+ /* Input Terminal Descriptor */
+ {
+ UAC_DT_INPUT_TERMINAL_SIZE,
+ UAC_CS_INTERFACE,
+ UAC_INPUT_TERMINAL,
+ 0x01, /* Terminal ID: 1 */
+ 0x0101, /* Terminal Type: USB Streaming (0x0101) */
+ 0x00, /* Assoc Terminal: 0 */
+ 0x01, /* Number Channels: 1 */
+ 0x0000, /* Channel Config: 0x0000 */
+ 0x00, /* Channel Names: 0 */
+ 0x00, /* Terminal: 0 */
+ },
+ /* Output Terminal Descriptor */
+ {
+ UAC_DT_OUTPUT_TERMINAL_SIZE,
+ UAC_CS_INTERFACE,
+ UAC_OUTPUT_TERMINAL,
+ 0x02, /* Terminal ID: 2 */
+ 0x0302, /* Terminal Type: Headphones (0x0302) */
+ 0x00, /* Assoc Terminal: 0 */
+ 0x01, /* Source ID: 1 */
+ 0x00, /* Terminal: 0 */
+ },
+#if UAC_USE_FEATURE_UNIT
+ /* Feature unit Descriptor */
+ {
+ UAC_DT_FEATURE_UNIT_SIZE(UAC_CH_NUM),
+ UAC_CS_INTERFACE,
+ UAC_FEATURE_UNIT,
+ 0x02,
+ 0x0101,
+ 0x00,
+ 0x01,
+ },
+#endif
+};
+
+ALIGN(4)
+static struct uinterface_descriptor as_desc0 =
+{
+ USB_DESC_LENGTH_INTERFACE,
+ USB_DESC_TYPE_INTERFACE,
+ USB_DYNAMIC,
+ 0x00,
+ 0x00,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOSTREAMING,
+ 0x00,
+ 0x00,
+};
+
+ALIGN(4)
+static struct uac_as_descriptor as_desc =
+{
+ /* Interface Descriptor */
+ {
+ USB_DESC_LENGTH_INTERFACE,
+ USB_DESC_TYPE_INTERFACE,
+ USB_DYNAMIC,
+ 0x01,
+ 0x01,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOSTREAMING,
+ 0x00,
+ 0x00,
+ },
+ /* General AS Descriptor */
+ {
+ UAC_DT_AS_HEADER_SIZE,
+ UAC_CS_INTERFACE,
+ UAC_AS_GENERAL,
+ 0x01, /* Terminal ID: 1 */
+ 0x01, /* Interface delay in frames: 1 */
+ UAC_FORMAT_TYPE_I_PCM,
+ },
+ /* Format type i Descriptor */
+ {
+ UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(UAC_FORMAT_NUM),
+ UAC_CS_INTERFACE,
+ UAC_FORMAT_TYPE,
+ UAC_FORMAT_TYPE_I,
+ UAC_CHANNEL_NUM,
+ 2, /* Subframe Size: 2 */
+ RESOLUTION_BITS,
+ 0x01, /* Samples Frequence Type: 1 */
+ {0}, /* Samples Frequence */
+ },
+ /* Endpoint Descriptor */
+ {
+ USB_DESC_LENGTH_ENDPOINT,
+ USB_DESC_TYPE_ENDPOINT,
+ USB_DYNAMIC | USB_DIR_OUT,
+ USB_EP_ATTR_ISOC,
+ UAC_EP_MAX_PACKET_SIZE,
+ 0x01,
+ },
+ /* AS Endpoint Descriptor */
+ {
+ UAC_ISO_ENDPOINT_DESC_SIZE,
+ UAC_CS_ENDPOINT,
+ UAC_MS_GENERAL,
+ },
+};
+
+void speaker_entry(void *parameter)
+{
+ struct rt_audio_caps caps = {0};
+ rt_uint32_t e, index;
+
+ speaker.buffer = rt_malloc(AUDIO_BUFFER_SZ);
+ if (speaker.buffer == RT_NULL)
+ {
+ LOG_E("malloc failed");
+ goto __exit;
+ }
+
+ speaker.dev = rt_device_find(SPEAKER_DEVICE_NAME);
+ if (speaker.dev == RT_NULL)
+ {
+ LOG_E("can't find device:%s", SPEAKER_DEVICE_NAME);
+ goto __exit;
+ }
+
+ while (1)
+ {
+ if (rt_event_recv(speaker.event, EVENT_AUDIO_START | EVENT_AUDIO_STOP,
+ RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
+ 1000, &e) != RT_EOK)
+ {
+ continue;
+ }
+ if (speaker.open_count == 0)
+ {
+ continue;
+ }
+ LOG_D("play start");
+
+ rt_device_open(speaker.dev, RT_DEVICE_OFLAG_WRONLY);
+
+ caps.main_type = AUDIO_TYPE_OUTPUT;
+ caps.sub_type = AUDIO_DSP_PARAM;
+ caps.udata.config.samplerate = AUDIO_SAMPLERATE;
+ caps.udata.config.channels = AUDIO_CHANNEL;
+ caps.udata.config.samplebits = RESOLUTION_BITS;
+ rt_device_control(speaker.dev, AUDIO_CTL_CONFIGURE, &caps);
+
+ while (1)
+ {
+ if (rt_event_recv(speaker.event, EVENT_AUDIO_DATA | EVENT_AUDIO_STOP,
+ RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
+ 1000, &e) != RT_EOK)
+ {
+ if (speaker.open_count > 0)
+ continue;
+ else
+ break;
+ }
+ if (e & EVENT_AUDIO_DATA)
+ {
+ index = (speaker.buffer_index >= AUDIO_BUFFER_SZ / 2) ? 0 : (AUDIO_BUFFER_SZ / 2);
+ rt_device_write(speaker.dev, 0, speaker.buffer + index, AUDIO_BUFFER_SZ / 2);
+ }
+ else if (e & EVENT_AUDIO_STOP)
+ {
+ break;
+ }
+ }
+ LOG_D("play stop");
+ rt_device_close(speaker.dev);
+ }
+
+__exit:
+ if (speaker.buffer)
+ rt_free(speaker.buffer);
+}
+
+static rt_err_t _audio_start(ufunction_t func)
+{
+ speaker.ep->request.buffer = speaker.buffer;
+ speaker.ep->request.size = UAC_EP_MAX_PACKET_SIZE;
+ speaker.ep->request.req_type = UIO_REQUEST_READ_FULL;
+ rt_usbd_io_request(func->device, speaker.ep, &speaker.ep->request);
+
+ speaker.open_count ++;
+ rt_event_send(speaker.event, EVENT_AUDIO_START);
+
+ return 0;
+}
+
+static rt_err_t _audio_stop(ufunction_t func)
+{
+ speaker.open_count --;
+ rt_event_send(speaker.event, EVENT_AUDIO_STOP);
+ return 0;
+}
+
+static rt_err_t _ep_data_handler(ufunction_t func, rt_size_t size)
+{
+ RT_ASSERT(func != RT_NULL);
+ LOG_D("_ep_data_handler");
+
+ speaker.ep->request.buffer = speaker.buffer + speaker.buffer_index;
+ speaker.ep->request.size = UAC_EP_MAX_PACKET_SIZE;
+ speaker.ep->request.req_type = UIO_REQUEST_READ_FULL;
+ rt_usbd_io_request(func->device, speaker.ep, &speaker.ep->request);
+
+ speaker.buffer_index += UAC_EP_MAX_PACKET_SIZE;
+ if (speaker.buffer_index >= AUDIO_BUFFER_SZ)
+ {
+ speaker.buffer_index = 0;
+ rt_event_send(speaker.event, EVENT_AUDIO_DATA);
+ }
+ else if (speaker.buffer_index == AUDIO_BUFFER_SZ / 2)
+ {
+ rt_event_send(speaker.event, EVENT_AUDIO_DATA);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _interface_as_handler(ufunction_t func, ureq_t setup)
+{
+ RT_ASSERT(func != RT_NULL);
+ RT_ASSERT(func->device != RT_NULL);
+ RT_ASSERT(setup != RT_NULL);
+
+ LOG_D("_interface_as_handler");
+
+ if ((setup->request_type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD)
+ {
+ switch (setup->bRequest)
+ {
+ case USB_REQ_GET_INTERFACE:
+ break;
+ case USB_REQ_SET_INTERFACE:
+ LOG_D("set interface handler");
+ if (setup->wValue == 1)
+ {
+ _audio_start(func);
+ }
+ else if (setup->wValue == 0)
+ {
+ _audio_stop(func);
+ }
+ break;
+ default:
+ LOG_D("unknown uac request 0x%x", setup->bRequest);
+ return -RT_ERROR;
+ }
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _function_enable(ufunction_t func)
+{
+ RT_ASSERT(func != RT_NULL);
+
+ LOG_D("uac function enable");
+
+ return RT_EOK;
+}
+
+static rt_err_t _function_disable(ufunction_t func)
+{
+ RT_ASSERT(func != RT_NULL);
+
+ LOG_D("uac function disable");
+ _audio_stop(func);
+ return RT_EOK;
+}
+
+static struct ufunction_ops ops =
+{
+ _function_enable,
+ _function_disable,
+ RT_NULL,
+};
+/**
+ * This function will configure uac descriptor.
+ *
+ * @param comm the communication interface number.
+ * @param data the data interface number.
+ *
+ * @return RT_EOK on successful.
+ */
+static rt_err_t _uac_descriptor_config(struct uac_ac_descriptor *ac,
+ rt_uint8_t cintf_nr, struct uac_as_descriptor *as, rt_uint8_t sintf_nr)
+{
+ ac->hdr_desc.baInterfaceNr[0] = sintf_nr;
+#ifdef RT_USB_DEVICE_COMPOSITE
+ ac->iad_desc.bFirstInterface = cintf_nr;
+#endif
+
+ return RT_EOK;
+}
+
+static rt_err_t _uac_samplerate_config(struct uac_as_descriptor *as, rt_uint32_t samplerate)
+{
+ as->format_type_desc.tSamFreq[0][2] = samplerate >> 16 & 0xff;
+ as->format_type_desc.tSamFreq[0][1] = samplerate >> 8 & 0xff;
+ as->format_type_desc.tSamFreq[0][0] = samplerate & 0xff;
+ return RT_EOK;
+}
+
+/**
+ * This function will create a uac function instance.
+ *
+ * @param device the usb device object.
+ *
+ * @return RT_EOK on successful.
+ */
+ufunction_t rt_usbd_function_uac_speaker_create(udevice_t device)
+{
+ ufunction_t func;
+ uintf_t intf_ac, intf_as;
+ ualtsetting_t setting_as0;
+ ualtsetting_t setting_ac, setting_as;
+ struct uac_as_descriptor *as_desc_t;
+
+ /* parameter check */
+ RT_ASSERT(device != RT_NULL);
+
+ /* set usb device string description */
+ rt_usbd_device_set_string(device, _ustring);
+
+ /* create a uac function */
+ func = rt_usbd_function_new(device, &dev_desc, &ops);
+ //not support HS
+ //rt_usbd_device_set_qualifier(device, &dev_qualifier);
+
+ /* create interface */
+ intf_ac = rt_usbd_interface_new(device, RT_NULL);
+ intf_as = rt_usbd_interface_new(device, _interface_as_handler);
+
+ /* create alternate setting */
+ setting_ac = rt_usbd_altsetting_new(sizeof(struct uac_ac_descriptor));
+ setting_as0 = rt_usbd_altsetting_new(sizeof(struct uinterface_descriptor));
+ setting_as = rt_usbd_altsetting_new(sizeof(struct uac_as_descriptor));
+ /* config desc in alternate setting */
+ rt_usbd_altsetting_config_descriptor(setting_ac, &ac_desc,
+ (rt_off_t) & ((struct uac_ac_descriptor *)0)->intf_desc);
+ rt_usbd_altsetting_config_descriptor(setting_as0, &as_desc0, 0);
+ rt_usbd_altsetting_config_descriptor(setting_as, &as_desc,
+ (rt_off_t) & ((struct uac_as_descriptor *)0)->intf_desc);
+ /* configure the uac interface descriptor */
+ _uac_descriptor_config(setting_ac->desc, intf_ac->intf_num, setting_as->desc, intf_as->intf_num);
+ _uac_samplerate_config(setting_as->desc, AUDIO_SAMPLERATE);
+
+ /* create endpoint */
+ as_desc_t = (struct uac_as_descriptor *)setting_as->desc;
+ speaker.ep = rt_usbd_endpoint_new(&as_desc_t->ep_desc, _ep_data_handler);
+
+ /* add the endpoint to the alternate setting */
+ rt_usbd_altsetting_add_endpoint(setting_as, speaker.ep);
+
+ /* add the alternate setting to the interface, then set default setting of the interface */
+ rt_usbd_interface_add_altsetting(intf_ac, setting_ac);
+ rt_usbd_set_altsetting(intf_ac, 0);
+ rt_usbd_interface_add_altsetting(intf_as, setting_as0);
+ rt_usbd_interface_add_altsetting(intf_as, setting_as);
+ rt_usbd_set_altsetting(intf_as, 0);
+
+ /* add the interface to the uac function */
+ rt_usbd_function_add_interface(func, intf_ac);
+ rt_usbd_function_add_interface(func, intf_as);
+
+ return func;
+}
+
+int audio_speaker_init(void)
+{
+ rt_thread_t speaker_tid;
+ speaker.event = rt_event_create("speaker_event", RT_IPC_FLAG_FIFO);
+
+ speaker_tid = rt_thread_create("speaker_thread",
+ speaker_entry, RT_NULL,
+ 1024,
+ 5, 10);
+
+ if (speaker_tid != RT_NULL)
+ rt_thread_startup(speaker_tid);
+ return RT_EOK;
+}
+INIT_COMPONENT_EXPORT(audio_speaker_init);
+
+/*
+ * register uac class
+ */
+static struct udclass uac_speaker_class =
+{
+ .rt_usbd_function_create = rt_usbd_function_uac_speaker_create
+};
+
+int rt_usbd_uac_speaker_class_register(void)
+{
+ rt_usbd_class_register(&uac_speaker_class);
+ return 0;
+}
+INIT_PREV_EXPORT(rt_usbd_uac_speaker_class_register);
diff --git a/components/drivers/usb/usbdevice/class/ecm.c b/components/drivers/usb/usbdevice/class/ecm.c
index cda1a8bf1b..b98b5007f4 100644
--- a/components/drivers/usb/usbdevice/class/ecm.c
+++ b/components/drivers/usb/usbdevice/class/ecm.c
@@ -6,17 +6,16 @@
* Change Logs:
* Date Author Notes
* 2017-11-19 ZYH first version
+ * 2019-06-10 ZYH fix hotplug
*/
#include <rtdevice.h>
+#ifdef RT_USB_DEVICE_ECM
#include "cdc.h"
-
-#ifdef ECM_DEBUG
-#define ECM_PRINTF rt_kprintf("[ECM] "); rt_kprintf
-#else
-#define ECM_PRINTF(...)
-#endif /* ECM_DEBUG */
+#define DBG_LEVEL DBG_WARNING
+#define DBG_SECTION_NAME "ECM"
+#include <rtdbg.h>
/* RT-Thread LWIP ethernet interface */
#include <netif/ethernetif.h>
@@ -216,15 +215,21 @@ static rt_err_t _cdc_send_notifi(ufunction_t func,ucdc_notification_code_t notif
return RT_EOK;
}
+
static rt_err_t _ecm_set_eth_packet_filter(ufunction_t func, ureq_t setup)
{
rt_ecm_eth_t _ecm_eth = (rt_ecm_eth_t)func->user_data;
dcd_ep0_send_status(func->device->dcd);
-
/* send link up. */
eth_device_linkchange(&_ecm_eth->parent, RT_TRUE);
- _cdc_send_notifi(func,UCDC_NOTIFI_NETWORK_CONNECTION,1,0);
+ _cdc_send_notifi(func, UCDC_NOTIFI_NETWORK_CONNECTION, 1, 0);
+
+#ifdef LWIP_USING_DHCPD
+ extern void dhcpd_start(const char *netif_name);
+ dhcpd_start("u0");
+#endif
+
return RT_EOK;
}
/**
@@ -243,10 +248,11 @@ static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
switch(setup->bRequest)
{
case CDC_SET_ETH_PACKET_FILTER:
+ LOG_D("CDC_SET_ETH_PACKET_FILTER");
_ecm_set_eth_packet_filter(func, setup);
break;
default:
- rt_kprintf("setup->bRequest:0x%02X",setup->bRequest);
+ LOG_E("Unknow setup->bRequest: 0x%02X", setup->bRequest);
break;
}
return RT_EOK;
@@ -402,22 +408,26 @@ rt_err_t rt_ecm_eth_tx(rt_device_t dev, struct pbuf* p)
if(!ecm_eth_dev->parent.link_status)
{
- ECM_PRINTF("linkdown, drop pkg\r\n");
+ LOG_D("linkdown, drop pkg");
return RT_EOK;
}
- // RT_ASSERT(p->tot_len < USB_ETH_MTU);
if(p->tot_len > USB_ETH_MTU)
{
- ECM_PRINTF("RNDIS MTU is:%d, but the send packet size is %d\r\n",
+ LOG_W("ECM MTU is:%d, but the send packet size is %d",
USB_ETH_MTU, p->tot_len);
p->tot_len = USB_ETH_MTU;
}
- result = rt_sem_take(&ecm_eth_dev->tx_buffer_free, RT_WAITING_FOREVER);
+
+ result = rt_sem_take(&device->tx_buffer_free, rt_tick_from_millisecond(1000));
if(result != RT_EOK)
{
+ LOG_W("wait for buffer free timeout");
+ /* if cost 1s to wait send done it said that connection is close . drop it */
+ rt_sem_release(&device->tx_buffer_free);
return result;
}
+
pbuffer = (char *)&ecm_eth_dev->tx_buffer;
for (q = p; q != NULL; q = q->next)
{
@@ -461,8 +471,13 @@ static rt_err_t _function_enable(ufunction_t func)
{
cdc_eps_t eps;
rt_ecm_eth_t ecm_device = (rt_ecm_eth_t)func->user_data;
+
+ LOG_D("plugged in");
+
eps = (cdc_eps_t)&ecm_device->eps;
eps->ep_out->buffer = ecm_device->rx_pool;
+
+ /* reset eth rx tx */
ecm_device->rx_size = 0;
ecm_device->rx_offset = 0;
@@ -482,7 +497,14 @@ static rt_err_t _function_enable(ufunction_t func)
*/
static rt_err_t _function_disable(ufunction_t func)
{
+ LOG_D("plugged out");
+
eth_device_linkchange(&((rt_ecm_eth_t)func->user_data)->parent, RT_FALSE);
+
+ /* reset eth rx tx */
+ ((rt_ecm_eth_t)func->user_data)->rx_size = 0;
+ ((rt_ecm_eth_t)func->user_data)->rx_offset = 0;
+
return RT_EOK;
}
@@ -643,3 +665,5 @@ int rt_usbd_ecm_class_register(void)
return 0;
}
INIT_PREV_EXPORT(rt_usbd_ecm_class_register);
+
+#endif /* RT_USB_DEVICE_ECM */
diff --git a/components/drivers/usb/usbdevice/class/hid.c b/components/drivers/usb/usbdevice/class/hid.c
index aea6d802d1..a9b2e62d70 100644
--- a/components/drivers/usb/usbdevice/class/hid.c
+++ b/components/drivers/usb/usbdevice/class/hid.c
@@ -372,7 +372,7 @@ const static char* _ustring[] =
"Interface",
};
-static void dump_data(uint8_t *data, rt_size_t size)
+static void dump_data(rt_uint8_t *data, rt_size_t size)
{
rt_size_t i;
for (i = 0; i < size; i++)
diff --git a/components/drivers/usb/usbdevice/class/rndis.c b/components/drivers/usb/usbdevice/class/rndis.c
index 8996b728e6..93e0ba6ae2 100644
--- a/components/drivers/usb/usbdevice/class/rndis.c
+++ b/components/drivers/usb/usbdevice/class/rndis.c
@@ -13,21 +13,21 @@
* 2013-07-09 aozima support respone chain list.
* 2013-07-18 aozima re-initial respone chain list when RNDIS restart.
* 2017-11-25 ZYH fix it and add OS descriptor
+ * 2019-06-10 ZYH fix hot plug and delay linkup
*/
#include <rtdevice.h>
+#ifdef RT_USB_DEVICE_RNDIS
#include "cdc.h"
#include "rndis.h"
#include "ndis.h"
-//#define RNDIS_DEBUG
-//#define RNDIS_DELAY_LINK_UP
+/* define RNDIS_DELAY_LINK_UP by menuconfig for delay linkup */
+
+#define DBG_LEVEL DBG_WARNING
+#define DBG_SECTION_NAME "RNDIS"
+#include <rtdbg.h>
-#ifdef RNDIS_DEBUG
-#define RNDIS_PRINTF rt_kprintf("[RNDIS] "); rt_kprintf
-#else
-#define RNDIS_PRINTF(...)
-#endif /* RNDIS_DEBUG */
/* RT-Thread LWIP ethernet interface */
#include <netif/ethernetif.h>
@@ -314,7 +314,7 @@ static rt_err_t _rndis_init_response(ufunction_t func, rndis_init_msg_t msg)
if( (response == RT_NULL) || (resp == RT_NULL) )
{
- RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
+ LOG_E("%s,%d: no memory!", __func__, __LINE__);
if(response != RT_NULL)
rt_free(response);
@@ -360,7 +360,7 @@ static rndis_query_cmplt_t _create_resp(rt_size_t size)
if(resp == RT_NULL)
{
- RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
+ LOG_E("%s,%d: no memory!", __func__, __LINE__);
return RT_NULL;
}
@@ -421,7 +421,7 @@ static rt_err_t _rndis_query_response(ufunction_t func,rndis_query_msg_t msg)
case OID_GEN_LINK_SPEED:
resp = _create_resp(4);
if(resp == RT_NULL) break;
- _set_resp(resp, func->device->dcd->device_is_hs ? (480UL * 1000 *1000) : (12UL * 1000 * 1000) / 100);
+ _set_resp(resp, (func->device->dcd->device_is_hs ? (480UL * 1000 *1000) : (12UL * 1000 * 1000)) / 100);
break;
case OID_GEN_MEDIA_CONNECT_STATUS:
@@ -510,7 +510,7 @@ static rt_err_t _rndis_query_response(ufunction_t func,rndis_query_msg_t msg)
break;
default:
- RNDIS_PRINTF("OID %X\n", msg->Oid);
+ LOG_W("Not support OID %X", msg->Oid);
ret = -RT_ERROR;
break;
}
@@ -518,7 +518,7 @@ static rt_err_t _rndis_query_response(ufunction_t func,rndis_query_msg_t msg)
response = rt_malloc(sizeof(struct rt_rndis_response));
if( (response == RT_NULL) || (resp == RT_NULL) )
{
- RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
+ LOG_E("%s,%d: no memory!", __func__, __LINE__);
if(response != RT_NULL)
rt_free(response);
@@ -557,7 +557,7 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
if( (response == RT_NULL) || (resp == RT_NULL) )
{
- RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
+ LOG_E("%s,%d: no memory!", __func__, __LINE__);
if(response != RT_NULL)
rt_free(response);
@@ -577,8 +577,10 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
case OID_GEN_CURRENT_PACKET_FILTER:
oid_packet_filter = *((rt_uint32_t *)((rt_uint8_t *)&(msg->RequestId) + \
msg->InformationBufferOffset));
+ /* TODO: make complier happy */
oid_packet_filter = oid_packet_filter;
- RNDIS_PRINTF("OID_GEN_CURRENT_PACKET_FILTER\r\n");
+
+ LOG_D("OID_GEN_CURRENT_PACKET_FILTER");
#ifdef RNDIS_DELAY_LINK_UP
/* link up. */
@@ -592,6 +594,7 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
break;
default:
+ LOG_W("Unknow rndis set 0x%02X", msg->Oid);
resp->Status = RNDIS_STATUS_FAILURE;
return RT_EOK;
}
@@ -609,6 +612,56 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
return RT_EOK;
}
+static rt_err_t _rndis_reset_response(ufunction_t func,rndis_set_msg_t msg)
+{
+ struct rndis_reset_cmplt * resp;
+ struct rt_rndis_response * response;
+
+ response = rt_malloc(sizeof(struct rt_rndis_response));
+ resp = rt_malloc(sizeof(struct rndis_reset_cmplt));
+
+ if( (response == RT_NULL) || (resp == RT_NULL) )
+ {
+ LOG_E("%s,%d: no memory!", __func__, __LINE__);
+
+ if(response != RT_NULL)
+ rt_free(response);
+
+ if(resp != RT_NULL)
+ rt_free(resp);
+
+ return -RT_ENOMEM;
+ }
+
+ /* reset packet filter */
+
+ oid_packet_filter = 0x0000000;
+
+ /* link down eth */
+
+ eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
+
+ /* reset eth rx tx */
+ ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
+ ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
+
+
+ resp->MessageType = REMOTE_NDIS_RESET_CMPLT;
+ resp->MessageLength = sizeof(struct rndis_reset_cmplt);
+ resp->Status = RNDIS_STATUS_SUCCESS;
+ resp->AddressingReset = 1;
+
+ response->buffer = resp;
+
+ {
+ rt_base_t level = rt_hw_interrupt_disable();
+ rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
+ rt_hw_interrupt_enable(level);
+ }
+
+ return RT_EOK;
+}
+
static rt_err_t _rndis_keepalive_response(ufunction_t func,rndis_keepalive_msg_t msg)
{
rndis_keepalive_cmplt_t resp;
@@ -619,7 +672,7 @@ static rt_err_t _rndis_keepalive_response(ufunction_t func,rndis_keepalive_msg_t
if( (response == RT_NULL) || (resp == RT_NULL) )
{
- RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
+ LOG_E("%s,%d: no memory!", __func__, __LINE__);
if(response != RT_NULL)
rt_free(response);
@@ -652,34 +705,42 @@ static rt_err_t _rndis_msg_parser(ufunction_t func, rt_uint8_t *msg)
switch (((rndis_gen_msg_t) msg)->MessageType)
{
case REMOTE_NDIS_INITIALIZE_MSG:
+ LOG_D("REMOTE_NDIS_INITIALIZE_MSG");
ret = _rndis_init_response(func, (rndis_init_msg_t) msg);
break;
case REMOTE_NDIS_HALT_MSG:
- RNDIS_PRINTF("halt\n");
+ LOG_D("REMOTE_NDIS_HALT_MSG");
/* link down. */
eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
+
+ /* reset eth rx tx */
+ ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
+ ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
break;
case REMOTE_NDIS_QUERY_MSG:
+ LOG_D("REMOTE_NDIS_QUERY_MSG");
ret = _rndis_query_response(func,(rndis_query_msg_t) msg);
break;
case REMOTE_NDIS_SET_MSG:
+ LOG_D("REMOTE_NDIS_SET_MSG");
ret = _rndis_set_response(func,(rndis_set_msg_t) msg);
- RNDIS_PRINTF("set\n");
break;
case REMOTE_NDIS_RESET_MSG:
- RNDIS_PRINTF("reset\n");
+ LOG_D("REMOTE_NDIS_RESET_MSG");
+ ret = _rndis_reset_response(func,(rndis_set_msg_t) msg);
break;
case REMOTE_NDIS_KEEPALIVE_MSG:
+ LOG_D("REMOTE_NDIS_KEEPALIVE_MSG");
ret = _rndis_keepalive_response(func,(rndis_keepalive_msg_t) msg);
break;
default:
- RNDIS_PRINTF("msg %X\n", ((rndis_gen_msg_t) msg)->MessageType);
+ LOG_W("not support RNDIS msg %X", ((rndis_gen_msg_t) msg)->MessageType);
ret = -RT_ERROR;
break;
}
@@ -718,7 +779,7 @@ static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup)
if(rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
{
- RNDIS_PRINTF("response_list is empty!\r\n");
+ LOG_D("response_list is empty!");
((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE;
return RT_EOK;
}
@@ -741,7 +802,7 @@ static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup)
{
rt_uint32_t * data;
- RNDIS_PRINTF("auto append next response!\r\n");
+ LOG_I("auto append next response!");
data = (rt_uint32_t *)((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->buffer;
data[0] = RESPONSE_AVAILABLE;
data[1] = 0;
@@ -758,55 +819,6 @@ static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup)
return RT_EOK;
}
-#ifdef RNDIS_DELAY_LINK_UP
-/**
- * This function will set rndis connect status.
- *
- * @param device the usb device object.
- * @param status the connect status.
- *
- * @return RT_EOK on successful.
- */
-static rt_err_t _rndis_indicate_status_msg(ufunction_t func, rt_uint32_t status)
-{
- rndis_indicate_status_msg_t resp;
- struct rt_rndis_response * response;
-
- response = rt_malloc(sizeof(struct rt_rndis_response));
- resp = rt_malloc(sizeof(struct rndis_indicate_status_msg));
-
- if( (response == RT_NULL) || (resp == RT_NULL) )
- {
- RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
-
- if(response != RT_NULL)
- rt_free(response);
-
- if(resp != RT_NULL)
- rt_free(resp);
-
- return -RT_ENOMEM;
- }
-
- resp->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG;
- resp->MessageLength = 20; /* sizeof(struct rndis_indicate_status_msg) */
- resp->Status = status;
- resp->StatusBufferLength = 0;
- resp->StatusBufferOffset = 0;
-
- response->buffer = resp;
- {
- rt_base_t level = rt_hw_interrupt_disable();
- rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
- rt_hw_interrupt_enable(level);
- }
-
- _rndis_response_available(func);
-
- return RT_EOK;
-}
-#endif /* RNDIS_DELAY_LINK_UP */
-
/**
* This function will handle rndis interface request.
*
@@ -831,7 +843,7 @@ static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
break;
default:
- RNDIS_PRINTF("unkown setup->request!\r\n");
+ LOG_W("unkown setup->request 0x%02X !", setup->bRequest);
break;
}
@@ -933,6 +945,8 @@ static rt_err_t _function_enable(ufunction_t func)
{
cdc_eps_t eps;
+ LOG_I("plugged in");
+
eps = (cdc_eps_t)&((rt_rndis_eth_t)func->user_data)->eps;
eps->ep_in->buffer = ((rt_rndis_eth_t)func->user_data)->tx_pool;
eps->ep_out->buffer = ((rt_rndis_eth_t)func->user_data)->rx_pool;
@@ -945,6 +959,7 @@ static rt_err_t _function_enable(ufunction_t func)
((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
+ // eth_device_ready(&(((rt_rndis_eth_t)func->user_data)->parent));
#ifdef RNDIS_DELAY_LINK_UP
/* stop link up timer. */
@@ -981,7 +996,7 @@ static rt_err_t _function_enable(ufunction_t func)
*/
static rt_err_t _function_disable(ufunction_t func)
{
- RNDIS_PRINTF("plugged out\n");
+ LOG_I("plugged out");
#ifdef RNDIS_DELAY_LINK_UP
/* stop link up timer. */
@@ -996,7 +1011,7 @@ static rt_err_t _function_disable(ufunction_t func)
while(!rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
{
response = (struct rt_rndis_response *)((rt_rndis_eth_t)func->user_data)->response_list.next;
- RNDIS_PRINTF("remove resp chain list!\r\n");
+ LOG_D("remove resp chain list!");
rt_list_remove(&response->list);
rt_free((void *)response->buffer);
@@ -1007,8 +1022,14 @@ static rt_err_t _function_disable(ufunction_t func)
rt_hw_interrupt_enable(level);
}
+
/* link down. */
eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
+
+ /* reset eth rx tx */
+ ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
+ ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
+
return RT_EOK;
}
@@ -1141,22 +1162,25 @@ rt_err_t rt_rndis_eth_tx(rt_device_t dev, struct pbuf* p)
if(!device->parent.link_status)
{
- RNDIS_PRINTF("linkdown, drop pkg\r\n");
+ LOG_I("linkdown, drop pkg");
return RT_EOK;
}
- RT_ASSERT(p->tot_len < sizeof(device->tx_buffer));
+ //RT_ASSERT(p->tot_len < sizeof(device->tx_buffer));
if(p->tot_len > sizeof(device->tx_buffer))
{
- RNDIS_PRINTF("RNDIS MTU is:%d, but the send packet size is %d\r\n",
+ LOG_W("RNDIS MTU is:%d, but the send packet size is %d",
sizeof(device->tx_buffer), p->tot_len);
p->tot_len = sizeof(device->tx_buffer);
}
/* wait for buffer free. */
- result = rt_sem_take(&device->tx_buffer_free, RT_WAITING_FOREVER);
+ result = rt_sem_take(&device->tx_buffer_free, rt_tick_from_millisecond(1000));
if(result != RT_EOK)
{
+ LOG_W("wait for buffer free timeout");
+ /* if cost 1s to wait send done it said that connection is close . drop it */
+ rt_sem_release(&device->tx_buffer_free);
return result;
}
@@ -1215,11 +1239,59 @@ const static struct rt_device_ops rndis_device_ops =
#endif /* RT_USING_LWIP */
#ifdef RNDIS_DELAY_LINK_UP
+
+/**
+ * This function will set rndis connect status.
+ *
+ * @param device the usb device object.
+ * @param status the connect status.
+ *
+ * @return RT_EOK on successful.
+ */
+static rt_err_t _rndis_indicate_status_msg(ufunction_t func, rt_uint32_t status)
+{
+ rndis_indicate_status_msg_t resp;
+ struct rt_rndis_response * response;
+
+ response = rt_malloc(sizeof(struct rt_rndis_response));
+ resp = rt_malloc(sizeof(struct rndis_indicate_status_msg));
+
+ if( (response == RT_NULL) || (resp == RT_NULL) )
+ {
+ LOG_E("%s,%d: no memory!", __func__, __LINE__);
+
+ if(response != RT_NULL)
+ rt_free(response);
+
+ if(resp != RT_NULL)
+ rt_free(resp);
+
+ return -RT_ENOMEM;
+ }
+
+ resp->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG;
+ resp->MessageLength = 20; /* sizeof(struct rndis_indicate_status_msg) */
+ resp->Status = status;
+ resp->StatusBufferLength = 0;
+ resp->StatusBufferOffset = 0;
+
+ response->buffer = resp;
+ {
+ rt_base_t level = rt_hw_interrupt_disable();
+ rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
+ rt_hw_interrupt_enable(level);
+ }
+
+ _rndis_response_available(func);
+
+ return RT_EOK;
+}
+
/* the delay linkup timer handler. */
static void timer_timeout(void* parameter)
{
- RNDIS_PRINTF("delay link up!\r\n");
- _rndis_indicate_status_msg(((rt_rndis_eth_t)parameter)->parent.parent.user_data,
+ LOG_I("delay link up!");
+ _rndis_indicate_status_msg(((rt_rndis_eth_t)parameter)->func,
RNDIS_STATUS_MEDIA_CONNECT);
eth_device_linkchange(&((rt_rndis_eth_t)parameter)->parent, RT_TRUE);
}
@@ -1319,7 +1391,7 @@ ufunction_t rt_usbd_function_rndis_create(udevice_t device)
timer_timeout,
_rndis,
RT_TICK_PER_SECOND * 2,
- RT_TIMER_FLAG_ONE_SHOT);
+ RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
#endif /* RNDIS_DELAY_LINK_UP */
/* OUI 00-00-00, only for test. */
@@ -1372,4 +1444,6 @@ int rt_usbd_rndis_class_register(void)
rt_usbd_class_register(&rndis_class);
return 0;
}
-INIT_PREV_EXPORT(rt_usbd_rndis_class_register); \ No newline at end of file
+INIT_PREV_EXPORT(rt_usbd_rndis_class_register);
+
+#endif /* RT_USB_DEVICE_RNDIS */
diff --git a/components/drivers/usb/usbdevice/class/rndis.h b/components/drivers/usb/usbdevice/class/rndis.h
index 000ea62baf..fcdd249984 100644
--- a/components/drivers/usb/usbdevice/class/rndis.h
+++ b/components/drivers/usb/usbdevice/class/rndis.h
@@ -180,6 +180,15 @@ struct rndis_reset_msg
rt_uint32_t Reserved;
};
+/* Remote NDIS Soft Reset Response */
+struct rndis_reset_cmplt
+{
+ rt_uint32_t MessageType;
+ rt_uint32_t MessageLength;
+ rt_uint32_t Status;
+ rt_uint32_t AddressingReset;
+};
+
/* Remote NDIS Indicate Status Message */
struct rndis_indicate_status_msg
{
diff --git a/components/drivers/usb/usbdevice/core/core.c b/components/drivers/usb/usbdevice/core/core.c
index 4e3a3e9280..584556303f 100644
--- a/components/drivers/usb/usbdevice/core/core.c
+++ b/components/drivers/usb/usbdevice/core/core.c
@@ -237,7 +237,8 @@ static rt_err_t _get_interface(struct udevice* device, ureq_t setup)
{
rt_uint8_t value;
uintf_t intf;
-
+ ufunction_t func;
+
/* parameter check */
RT_ASSERT(device != RT_NULL);
RT_ASSERT(setup != RT_NULL);
@@ -251,12 +252,17 @@ static rt_err_t _get_interface(struct udevice* device, ureq_t setup)
}
/* find the specified interface and its alternate setting */
- intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, RT_NULL);
+ intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, &func);
value = intf->curr_setting->intf_desc->bAlternateSetting;
/* send the interface alternate setting to endpoint 0*/
rt_usbd_ep0_write(device, &value, 1);
+ if (intf->handler)
+ {
+ intf->handler(func, setup);
+ }
+
return RT_EOK;
}
@@ -270,6 +276,7 @@ static rt_err_t _get_interface(struct udevice* device, ureq_t setup)
*/
static rt_err_t _set_interface(struct udevice* device, ureq_t setup)
{
+ ufunction_t func;
uintf_t intf;
uep_t ep;
struct rt_list_node* i;
@@ -288,7 +295,7 @@ static rt_err_t _set_interface(struct udevice* device, ureq_t setup)
}
/* find the specified interface */
- intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, RT_NULL);
+ intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, &func);
/* set alternate setting to the interface */
rt_usbd_set_altsetting(intf, setup->wValue & 0xFF);
@@ -303,6 +310,11 @@ static rt_err_t _set_interface(struct udevice* device, ureq_t setup)
}
dcd_ep0_send_status(device->dcd);
+ if (intf->handler)
+ {
+ intf->handler(func, setup);
+ }
+
return RT_EOK;
}
@@ -995,7 +1007,7 @@ udevice_t rt_usbd_device_new(void)
RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usbd_device_new\n"));
/* allocate memory for the object */
- udevice = rt_malloc(sizeof(struct udevice));
+ udevice = (udevice_t)rt_malloc(sizeof(struct udevice));
if(udevice == RT_NULL)
{
rt_kprintf("alloc memery failed\n");
@@ -1109,7 +1121,7 @@ uconfig_t rt_usbd_config_new(void)
RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usbd_config_new\n"));
/* allocate memory for the object */
- cfg = rt_malloc(sizeof(struct uconfig));
+ cfg = (uconfig_t)rt_malloc(sizeof(struct uconfig));
if(cfg == RT_NULL)
{
rt_kprintf("alloc memery failed\n");
@@ -1488,9 +1500,10 @@ uep_t rt_usbd_find_endpoint(udevice_t device, ufunction_t* pfunc, rt_uint8_t ep_
*/
rt_err_t rt_usbd_device_add_config(udevice_t device, uconfig_t cfg)
{
- struct rt_list_node *i, *j, *k;
+ struct rt_list_node *i, *j, *k, *m;
ufunction_t func;
uintf_t intf;
+ ualtsetting_t altsetting;
uep_t ep;
RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usbd_device_add_config\n"));
@@ -1512,22 +1525,26 @@ rt_err_t rt_usbd_device_add_config(udevice_t device, uconfig_t cfg)
intf = (uintf_t)rt_list_entry(j, struct uinterface, list);
cfg->cfg_desc.bNumInterfaces++;
- /* allocate address for every endpoint in the interface alternate setting */
- for(k=intf->curr_setting->ep_list.next;
- k!=&intf->curr_setting->ep_list; k=k->next)
+ for(k=intf->setting_list.next; k!=&intf->setting_list;k=k->next)
{
- ep = (uep_t)rt_list_entry(k, struct uendpoint, list);
- if(rt_usbd_ep_assign(device, ep) != RT_EOK)
+ altsetting = (ualtsetting_t)rt_list_entry(k, struct ualtsetting, list);
+
+ /* allocate address for every endpoint in the interface alternate setting */
+ for(m=altsetting->ep_list.next; m!=&altsetting->ep_list; m=m->next)
{
- rt_kprintf("endpoint assign error\n");
+ ep = (uep_t)rt_list_entry(m, struct uendpoint, list);
+ if(rt_usbd_ep_assign(device, ep) != RT_EOK)
+ {
+ rt_kprintf("endpoint assign error\n");
+ }
}
- }
- /* construct complete configuration descriptor */
- rt_memcpy((void*)&cfg->cfg_desc.data[cfg->cfg_desc.wTotalLength - USB_DESC_LENGTH_CONFIG],
- (void*)intf->curr_setting->desc,
- intf->curr_setting->desc_size);
- cfg->cfg_desc.wTotalLength += intf->curr_setting->desc_size;
+ /* construct complete configuration descriptor */
+ rt_memcpy((void*)&cfg->cfg_desc.data[cfg->cfg_desc.wTotalLength - USB_DESC_LENGTH_CONFIG],
+ (void*)altsetting->desc,
+ altsetting->desc_size);
+ cfg->cfg_desc.wTotalLength += altsetting->desc_size;
+ }
}
}
@@ -2053,7 +2070,7 @@ rt_size_t rt_usbd_ep0_write(udevice_t device, void *buffer, rt_size_t size)
ep0 = &device->dcd->ep0;
ep0->request.size = size;
- ep0->request.buffer = buffer;
+ ep0->request.buffer = (rt_uint8_t *)buffer;
ep0->request.remain_size = size;
if(size >= ep0->id->maxpacket)
{
@@ -2079,7 +2096,7 @@ rt_size_t rt_usbd_ep0_read(udevice_t device, void *buffer, rt_size_t size,
RT_ASSERT(buffer != RT_NULL);
ep0 = &device->dcd->ep0;
- ep0->request.buffer = buffer;
+ ep0->request.buffer = (rt_uint8_t *)buffer;
ep0->request.remain_size = size;
ep0->rx_indicate = rx_ind;
if(size >= ep0->id->maxpacket)
diff --git a/components/drivers/wlan/SConscript b/components/drivers/wlan/SConscript
index 271ca66a80..f2a6bbdc82 100644
--- a/components/drivers/wlan/SConscript
+++ b/components/drivers/wlan/SConscript
@@ -1,8 +1,30 @@
from building import *
cwd = GetCurrentDir()
-src = Glob('*.c')
CPPPATH = [cwd]
+
+src = Split('''
+ wlan_dev.c
+ ''')
+
+if GetDepend(['RT_WLAN_MANAGE_ENABLE']):
+ src += ['wlan_mgnt.c']
+
+if GetDepend(['RT_WLAN_MSH_CMD_ENABLE']):
+ src += ['wlan_cmd.c']
+
+if GetDepend(['RT_WLAN_PROT_ENABLE']):
+ src += ['wlan_prot.c']
+
+if GetDepend(['RT_WLAN_PROT_LWIP_ENABLE']):
+ src += ['wlan_lwip.c']
+
+if GetDepend(['RT_WLAN_CFG_ENABLE']):
+ src += ['wlan_cfg.c']
+
+if GetDepend(['RT_WLAN_WORK_THREAD_ENABLE']):
+ src += ['wlan_workqueue.c']
+
group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_WIFI'], CPPPATH = CPPPATH)
Return('group')
diff --git a/components/drivers/wlan/wlan_cfg.c b/components/drivers/wlan/wlan_cfg.c
index 126cee40f5..7fa9ecb2da 100644
--- a/components/drivers/wlan/wlan_cfg.c
+++ b/components/drivers/wlan/wlan_cfg.c
@@ -19,6 +19,8 @@
#endif /* RT_WLAN_CFG_DEBUG */
#include <rtdbg.h>
+#ifdef RT_WLAN_CFG_ENABLE
+
#define WLAN_CFG_LOCK() (rt_mutex_take(&cfg_mutex, RT_WAITING_FOREVER))
#define WLAN_CFG_UNLOCK() (rt_mutex_release(&cfg_mutex))
@@ -462,3 +464,5 @@ void rt_wlan_cfg_dump(void)
rt_kprintf("%3d \n", info->channel);
}
}
+
+#endif
diff --git a/components/drivers/wlan/wlan_cmd.c b/components/drivers/wlan/wlan_cmd.c
index b962b63947..fead6a8bf2 100644
--- a/components/drivers/wlan/wlan_cmd.c
+++ b/components/drivers/wlan/wlan_cmd.c
@@ -13,6 +13,8 @@
#include <wlan_cfg.h>
#include <wlan_prot.h>
+#if defined(RT_WLAN_MANAGE_ENABLE) && defined(RT_WLAN_MSH_CMD_ENABLE)
+
struct wifi_cmd_des
{
const char *cmd;
@@ -75,7 +77,7 @@ static int wifi_help(int argc, char *argv[])
{
rt_kprintf("wifi\n");
rt_kprintf("wifi help\n");
- rt_kprintf("wifi scan\n");
+ rt_kprintf("wifi scan [SSID]\n");
rt_kprintf("wifi join [SSID] [PASSWORD]\n");
rt_kprintf("wifi ap SSID [PASSWORD]\n");
rt_kprintf("wifi disc\n");
@@ -143,12 +145,23 @@ static int wifi_status(int argc, char *argv[])
static int wifi_scan(int argc, char *argv[])
{
struct rt_wlan_scan_result *scan_result = RT_NULL;
+ struct rt_wlan_info *info = RT_NULL;
+ struct rt_wlan_info filter;
- if (argc > 2)
+ if (argc > 3)
return -1;
+ if (argc == 3)
+ {
+ INVALID_INFO(&filter);
+ SSID_SET(&filter, argv[2]);
+ info = &filter;
+ }
+
+ /* clean scan result */
+ rt_wlan_scan_result_clean();
/* scan ap info */
- scan_result = rt_wlan_scan_sync();
+ scan_result = rt_wlan_scan_with_info(info);
if (scan_result)
{
int index, num;
@@ -224,8 +237,10 @@ static int wifi_join(int argc, char *argv[])
const char *key = RT_NULL;
struct rt_wlan_cfg_info cfg_info;
+ rt_memset(&cfg_info, 0, sizeof(cfg_info));
if (argc == 2)
{
+#ifdef RT_WLAN_CFG_ENABLE
/* get info to connect */
if (rt_wlan_cfg_read_index(&cfg_info, 0) == 1)
{
@@ -234,8 +249,9 @@ static int wifi_join(int argc, char *argv[])
key = (char *)(&cfg_info.key.val[0]);
}
else
+#endif
{
- rt_kprintf("not find info\n");
+ rt_kprintf("not find connect info\n");
}
}
else if (argc == 3)
@@ -387,8 +403,9 @@ static int wifi_debug_save_cfg(int argc, char *argv[])
rt_memcpy(&cfg_info.key.val[0], password, len);
cfg_info.key.len = len;
}
-
+#ifdef RT_WLAN_CFG_ENABLE
rt_wlan_cfg_save(&cfg_info);
+#endif
return 0;
}
@@ -396,7 +413,9 @@ static int wifi_debug_dump_cfg(int argc, char *argv[])
{
if (argc == 1)
{
+#ifdef RT_WLAN_CFG_ENABLE
rt_wlan_cfg_dump();
+#endif
}
else
{
@@ -409,8 +428,10 @@ static int wifi_debug_clear_cfg(int argc, char *argv[])
{
if (argc == 1)
{
+#ifdef RT_WLAN_CFG_ENABLE
rt_wlan_cfg_delete_all();
rt_wlan_cfg_cache_save();
+#endif
}
else
{
@@ -447,6 +468,10 @@ static int wifi_debug_set_mode(int argc, char *argv[])
{
mode = RT_WLAN_AP;
}
+ else if (rt_strcmp("none", argv[1]) == 0)
+ {
+ mode = RT_WLAN_NONE;
+ }
else
return -1;
@@ -564,3 +589,5 @@ static int wifi_msh(int argc, char *argv[])
#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
FINSH_FUNCTION_EXPORT_ALIAS(wifi_msh, __cmd_wifi, wifi command.);
#endif
+
+#endif
diff --git a/components/drivers/wlan/wlan_dev.c b/components/drivers/wlan/wlan_dev.c
index 82fa4e73e7..cbfd50a6c3 100644
--- a/components/drivers/wlan/wlan_dev.c
+++ b/components/drivers/wlan/wlan_dev.c
@@ -21,6 +21,8 @@
#endif /* RT_WLAN_DEV_DEBUG */
#include <rtdbg.h>
+#if defined(RT_USING_WIFI) || defined(RT_USING_WLAN)
+
#ifndef RT_DEVICE
#define RT_DEVICE(__device) ((rt_device_t)__device)
#endif
@@ -56,6 +58,17 @@ rt_err_t rt_wlan_dev_init(struct rt_wlan_device *device, rt_wlan_mode_t mode)
return -RT_ERROR;
}
+ if (mode == RT_WLAN_AP && device->flags & RT_WLAN_FLAG_STA_ONLY)
+ {
+ LOG_E("F:%s L:%d This wlan device can only be set to sta mode!", __FUNCTION__, __LINE__);
+ return -RT_ERROR;
+ }
+ else if (mode == RT_WLAN_STATION && device->flags & RT_WLAN_FLAG_AP_ONLY)
+ {
+ LOG_E("F:%s L:%d This wlan device can only be set to ap mode!", __FUNCTION__, __LINE__);
+ return -RT_ERROR;
+ }
+
result = rt_device_init(RT_DEVICE(device));
if (result != RT_EOK)
{
@@ -134,8 +147,8 @@ rt_err_t rt_wlan_dev_ap_start(struct rt_wlan_device *device, struct rt_wlan_info
return -RT_ERROR;
}
- if ((password_len >= RT_WLAN_PASSWORD_MAX_LENGTH) ||
- (info->ssid.len >= RT_WLAN_SSID_MAX_LENGTH))
+ if ((password_len > RT_WLAN_PASSWORD_MAX_LENGTH) ||
+ (info->ssid.len > RT_WLAN_SSID_MAX_LENGTH))
{
LOG_E("L:%d password or ssid is to long", __LINE__);
return -RT_ERROR;
@@ -515,15 +528,24 @@ rt_err_t rt_wlan_dev_scan(struct rt_wlan_device *device, struct rt_wlan_info *in
if (info != RT_NULL)
{
- if (info->ssid.len >= RT_WLAN_SSID_MAX_LENGTH)
+ if (info->ssid.len > RT_WLAN_SSID_MAX_LENGTH)
{
LOG_E("L:%d ssid is to long", __LINE__);
return -RT_EINVAL;
}
rt_memcpy(&scan_info.ssid, &info->ssid, sizeof(rt_wlan_ssid_t));
rt_memcpy(scan_info.bssid, info->bssid, RT_WLAN_BSSID_MAX_LENGTH);
- scan_info.channel_min = -1;
- scan_info.channel_max = -1;
+ if (info->channel > 0)
+ {
+ scan_info.channel_min = info->channel;
+ scan_info.channel_max = info->channel;
+ }
+ else
+ {
+ scan_info.channel_min = -1;
+ scan_info.channel_max = -1;
+ }
+ scan_info.passive = info->hidden ? RT_TRUE : RT_FALSE;
p_scan_info = &scan_info;
}
result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_SCAN, p_scan_info);
@@ -545,7 +567,11 @@ rt_err_t rt_wlan_dev_scan_stop(struct rt_wlan_device *device)
rt_err_t rt_wlan_dev_report_data(struct rt_wlan_device *device, void *buff, int len)
{
+#ifdef RT_WLAN_PROT_ENABLE
return rt_wlan_dev_transfer_prot(device, buff, len);
+#else
+ return -RT_ERROR;
+#endif
}
static rt_err_t _rt_wlan_dev_init(rt_device_t dev)
@@ -768,14 +794,15 @@ rt_err_t rt_wlan_dev_register(struct rt_wlan_device *wlan, const char *name, con
{
rt_err_t err = RT_EOK;
- if ((wlan == RT_NULL) || (name == RT_NULL) || (ops == RT_NULL))
+ if ((wlan == RT_NULL) || (name == RT_NULL) || (ops == RT_NULL) ||
+ (flag & RT_WLAN_FLAG_STA_ONLY && flag & RT_WLAN_FLAG_AP_ONLY))
{
LOG_E("F:%s L:%d parameter Wrongful", __FUNCTION__, __LINE__);
return RT_NULL;
}
rt_memset(wlan, 0, sizeof(struct rt_wlan_device));
-
+
#ifdef RT_USING_DEVICE_OPS
wlan->device.ops = &wlan_ops;
#else
@@ -801,3 +828,5 @@ rt_err_t rt_wlan_dev_register(struct rt_wlan_device *wlan, const char *name, con
return err;
}
+
+#endif
diff --git a/components/drivers/wlan/wlan_dev.h b/components/drivers/wlan/wlan_dev.h
index a9300be9d7..43d6506d6f 100644
--- a/components/drivers/wlan/wlan_dev.h
+++ b/components/drivers/wlan/wlan_dev.h
@@ -381,6 +381,11 @@ typedef struct rt_wlan_key rt_wlan_key_t;
(_info)->channel = -1; \
} while(0)
+#define SSID_SET(_info, _ssid) do { \
+ rt_strncpy((char *)(_info)->ssid.val, (_ssid), RT_WLAN_SSID_MAX_LENGTH); \
+ (_info)->ssid.len = rt_strlen((char *)(_info)->ssid.val); \
+ } while(0)
+
struct rt_wlan_info
{
/* security type */
@@ -442,6 +447,7 @@ struct rt_wlan_device
rt_wlan_pormisc_callback_t pormisc_callback;
const struct rt_wlan_dev_ops *ops;
rt_uint32_t flags;
+ struct netdev *netdev;
void *prot;
void *user_data;
};
@@ -470,6 +476,7 @@ struct rt_scan_info
rt_uint8_t bssid[6];
rt_int16_t channel_min;
rt_int16_t channel_max;
+ rt_bool_t passive;
};
struct rt_wlan_dev_ops
diff --git a/components/drivers/wlan/wlan_lwip.c b/components/drivers/wlan/wlan_lwip.c
index 84b448c68f..3c4e4dd598 100644
--- a/components/drivers/wlan/wlan_lwip.c
+++ b/components/drivers/wlan/wlan_lwip.c
@@ -14,12 +14,17 @@
#include <wlan_prot.h>
#include <wlan_workqueue.h>
+#if defined(RT_WLAN_PROT_ENABLE) && defined(RT_WLAN_PROT_LWIP_ENABLE)
+
#ifdef RT_USING_LWIP
#include <netif/ethernetif.h>
#include <lwip/netifapi.h>
#ifdef LWIP_USING_DHCPD
#include <dhcp_server.h>
#endif
+#ifdef RT_USING_NETDEV
+#include <netdev.h>
+#endif
#define DBG_TAG "WLAN.lwip"
#ifdef RT_WLAN_LWIP_DEBUG
@@ -33,6 +38,10 @@
#define IPADDR_STRLEN_MAX (32)
#endif
+#ifndef RT_WLAN_PROT_LWIP_NAME
+#define RT_WLAN_PROT_LWIP_NAME ("lwip")
+#endif
+
struct lwip_prot_des
{
struct rt_wlan_prot prot;
@@ -47,12 +56,16 @@ static void netif_is_ready(struct rt_work *work, void *parameter)
ip_addr_t ip_addr_zero = { 0 };
struct rt_wlan_device *wlan = parameter;
struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)wlan->prot;
- struct eth_device *eth_dev = &lwip_prot->eth;
+ struct eth_device *eth_dev;
rt_base_t level;
struct rt_wlan_buff buff;
rt_uint32_t ip_addr[4];
char str[IPADDR_STRLEN_MAX];
+ if (lwip_prot == RT_NULL)
+ return;
+
+ eth_dev = &lwip_prot->eth;
rt_timer_stop(&lwip_prot->timer);
if (ip_addr_cmp(&(eth_dev->netif->ip_addr), &ip_addr_zero) != 0)
{
@@ -100,18 +113,26 @@ static void netif_is_ready(struct rt_work *work, void *parameter)
LOG_I("Got IP address : %s", str);
exit:
level = rt_hw_interrupt_disable();
- rt_memset(work, 0, sizeof(struct rt_work));
+ if (work)
+ {
+ rt_memset(work, 0, sizeof(struct rt_work));
+ }
rt_hw_interrupt_enable(level);
}
static void timer_callback(void *parameter)
{
+#ifdef RT_WLAN_WORK_THREAD_ENABLE
struct rt_workqueue *workqueue;
struct rt_wlan_device *wlan = parameter;
struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)wlan->prot;
- struct rt_work *work = &lwip_prot->work;
+ struct rt_work *work;
rt_base_t level;
+ if (lwip_prot == RT_NULL)
+ return;
+
+ work = &lwip_prot->work;
workqueue = rt_wlan_get_workqueue();
if (workqueue != RT_NULL)
{
@@ -125,13 +146,22 @@ static void timer_callback(void *parameter)
rt_hw_interrupt_enable(level);
}
}
+#else
+ netif_is_ready(RT_NULL, parameter);
+#endif
+
}
static void netif_set_connected(void *parameter)
{
struct rt_wlan_device *wlan = parameter;
struct lwip_prot_des *lwip_prot = wlan->prot;
- struct eth_device *eth_dev = &lwip_prot->eth;
+ struct eth_device *eth_dev;
+
+ if (lwip_prot == RT_NULL)
+ return;
+
+ eth_dev = &lwip_prot->eth;
if (lwip_prot->connected_flag)
{
@@ -151,14 +181,10 @@ static void netif_set_connected(void *parameter)
netifapi_netif_common(eth_dev->netif, netif_set_link_up, NULL);
#ifdef LWIP_USING_DHCPD
{
- char netif_name[8];
- int i;
+ char netif_name[RT_NAME_MAX];
rt_memset(netif_name, 0, sizeof(netif_name));
- for (i = 0; i < sizeof(eth_dev->netif->name); i++)
- {
- netif_name[i] = eth_dev->netif->name[i];
- }
+ rt_memcpy(netif_name, eth_dev->netif->name, sizeof(eth_dev->netif->name));
dhcpd_start(netif_name);
}
#endif
@@ -166,24 +192,24 @@ static void netif_set_connected(void *parameter)
}
else
{
- if (wlan->mode == RT_WLAN_STATION)
- {
- LOG_D("F:%s L:%d dhcp stop run", __FUNCTION__, __LINE__);
- netifapi_netif_common(eth_dev->netif, netif_set_link_down, NULL);
+ LOG_D("F:%s L:%d set linkdown", __FUNCTION__, __LINE__);
+ netifapi_netif_common(eth_dev->netif, netif_set_link_down, NULL);
+ rt_timer_stop(&lwip_prot->timer);
#ifdef RT_LWIP_DHCP
- {
- ip_addr_t ip_addr = { 0 };
- dhcp_stop(eth_dev->netif);
- netif_set_addr(eth_dev->netif, &ip_addr, &ip_addr, &ip_addr);
- }
-#endif
- rt_timer_stop(&lwip_prot->timer);
+ {
+ ip_addr_t ip_addr = { 0 };
+ dhcp_stop(eth_dev->netif);
+ netif_set_addr(eth_dev->netif, &ip_addr, &ip_addr, &ip_addr);
}
- else if (wlan->mode == RT_WLAN_AP)
+#endif
+#ifdef LWIP_USING_DHCPD
{
- LOG_D("F:%s L:%d dhcpd stop run", __FUNCTION__, __LINE__);
- netifapi_netif_common(eth_dev->netif, netif_set_link_down, NULL);
+ char netif_name[RT_NAME_MAX];
+ rt_memset(netif_name, 0, sizeof(netif_name));
+ rt_memcpy(netif_name, lwip_prot->eth.netif->name, sizeof(lwip_prot->eth.netif->name));
+ dhcpd_stop(netif_name);
}
+#endif
}
}
@@ -192,6 +218,9 @@ static void rt_wlan_lwip_event_handle(struct rt_wlan_prot *port, struct rt_wlan_
struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)wlan->prot;
rt_bool_t flag_old;
+ if (lwip_prot == RT_NULL)
+ return;
+
flag_old = lwip_prot->connected_flag;
switch (event)
@@ -238,8 +267,11 @@ static void rt_wlan_lwip_event_handle(struct rt_wlan_prot *port, struct rt_wlan_
}
if (flag_old != lwip_prot->connected_flag)
{
+#ifdef RT_WLAN_WORK_THREAD_ENABLE
rt_wlan_workqueue_dowork(netif_set_connected, wlan);
- // netif_set_connected(wlan);
+#else
+ netif_set_connected(wlan);
+#endif
}
}
@@ -385,7 +417,7 @@ const static struct rt_device_ops wlan_lwip_ops =
static struct rt_wlan_prot *rt_wlan_lwip_protocol_register(struct rt_wlan_prot *prot, struct rt_wlan_device *wlan)
{
struct eth_device *eth = RT_NULL;
- static rt_uint8_t id = 0;
+ rt_uint8_t id = 0;
char eth_name[4], timer_name[16];
rt_device_t device = RT_NULL;
struct lwip_prot_des *lwip_prot;
@@ -452,22 +484,43 @@ static struct rt_wlan_prot *rt_wlan_lwip_protocol_register(struct rt_wlan_prot *
return RT_NULL;
}
rt_memcpy(&lwip_prot->prot, prot, sizeof(struct rt_wlan_prot));
- if (wlan->mode == RT_WLAN_STATION)
- {
- rt_sprintf(timer_name, "timer_%s", eth_name);
- rt_timer_init(&lwip_prot->timer, timer_name, timer_callback, wlan, rt_tick_from_millisecond(1000),
- RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT);
- }
+ rt_sprintf(timer_name, "timer_%s", eth_name);
+ rt_timer_init(&lwip_prot->timer, timer_name, timer_callback, wlan, rt_tick_from_millisecond(1000),
+ RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT);
netif_set_up(eth->netif);
LOG_I("eth device init ok name:%s", eth_name);
-
+#ifdef RT_USING_NETDEV
+ wlan->netdev = netdev_get_by_name(eth_name);
+#endif
return &lwip_prot->prot;
}
static void rt_wlan_lwip_protocol_unregister(struct rt_wlan_prot *prot, struct rt_wlan_device *wlan)
{
- /*TODO*/
+ struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)prot;
+
LOG_D("F:%s L:%d is run wlan:0x%08x", __FUNCTION__, __LINE__, wlan);
+#if !defined(RT_USING_LWIP141)
+ wlan->prot = RT_NULL;
+ if (lwip_prot == RT_NULL)
+ {
+ return;
+ }
+
+#ifdef LWIP_USING_DHCPD
+ {
+ char netif_name[RT_NAME_MAX];
+ rt_memset(netif_name, 0, sizeof(netif_name));
+ rt_memcpy(netif_name, lwip_prot->eth.netif->name, sizeof(lwip_prot->eth.netif->name));
+ dhcpd_stop(netif_name);
+ }
+#endif
+ eth_device_deinit(&lwip_prot->eth);
+ rt_device_close((rt_device_t)wlan);
+ rt_timer_detach(&lwip_prot->timer);
+ wlan->netdev = RT_NULL;
+ rt_free(lwip_prot);
+#endif
}
static struct rt_wlan_prot_ops ops =
@@ -483,7 +536,7 @@ int rt_wlan_lwip_init(void)
rt_wlan_prot_event_t event;
rt_memset(&prot, 0, sizeof(prot));
- rt_strncpy(&prot.name[0], RT_WLAN_PROT_LWIP, RT_WLAN_PROT_NAME_LEN);
+ rt_strncpy(&prot.name[0], RT_WLAN_PROT_LWIP_NAME, RT_WLAN_PROT_NAME_LEN);
prot.ops = &ops;
if (rt_wlan_prot_regisetr(&prot) != RT_EOK)
@@ -502,3 +555,4 @@ int rt_wlan_lwip_init(void)
INIT_PREV_EXPORT(rt_wlan_lwip_init);
#endif
+#endif
diff --git a/components/drivers/wlan/wlan_mgnt.c b/components/drivers/wlan/wlan_mgnt.c
index 91a77e43d0..cf2204c6b3 100644
--- a/components/drivers/wlan/wlan_mgnt.c
+++ b/components/drivers/wlan/wlan_mgnt.c
@@ -24,6 +24,8 @@
#endif /* RT_WLAN_MGNT_DEBUG */
#include <rtdbg.h>
+#ifdef RT_WLAN_MANAGE_ENABLE
+
#ifndef RT_WLAN_DEVICE
#define RT_WLAN_DEVICE(__device) ((struct rt_wlan_device *)__device)
#endif
@@ -48,13 +50,16 @@
#define COMPLETE_LOCK() (rt_mutex_take(&complete_mutex, RT_WAITING_FOREVER))
#define COMPLETE_UNLOCK() (rt_mutex_release(&complete_mutex))
+#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
#define TIME_STOP() (rt_timer_stop(&reconnect_time))
#define TIME_START() (rt_timer_start(&reconnect_time))
-
-#define DISCONNECT_RESPONSE_TICK (2000)
+#else
+#define TIME_STOP()
+#define TIME_START()
+#endif
#if RT_WLAN_EBOX_NUM < 1
-#error "event box num Too little"
+#error "event box num Too few"
#endif
struct rt_wlan_mgnt_des
@@ -113,8 +118,11 @@ static struct rt_wlan_event_desc event_tab[RT_WLAN_EVT_MAX];
static struct rt_wlan_complete_des *complete_tab[5];
static struct rt_mutex complete_mutex;
+static struct rt_wlan_info *scan_filter;
+#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
static struct rt_timer reconnect_time;
+#endif
rt_inline int _sta_is_null(void)
{
@@ -145,9 +153,97 @@ rt_inline rt_bool_t _is_do_connect(void)
return RT_TRUE;
}
-static void rt_wlan_mgnt_work(void *parameter);
+#ifdef RT_WLAN_WORK_THREAD_ENABLE
+
+static rt_bool_t rt_wlan_info_isequ(struct rt_wlan_info *info1, struct rt_wlan_info *info2)
+{
+ rt_bool_t is_equ = 1;
+ rt_uint8_t bssid_zero[RT_WLAN_BSSID_MAX_LENGTH] = { 0 };
+
+ if (is_equ && (info1->security != SECURITY_UNKNOWN) && (info2->security != SECURITY_UNKNOWN))
+ {
+ is_equ &= info2->security == info1->security;
+ }
+ if (is_equ && ((info1->ssid.len > 0) && (info2->ssid.len > 0)))
+ {
+ is_equ &= info1->ssid.len == info2->ssid.len;
+ is_equ &= rt_memcmp(&info2->ssid.val[0], &info1->ssid.val[0], info1->ssid.len) == 0;
+ }
+ if (is_equ && (rt_memcmp(&info1->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)) &&
+ (rt_memcmp(&info2->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)))
+ {
+ is_equ &= rt_memcmp(&info1->bssid[0], &info2->bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0;
+ }
+ if (is_equ && info1->datarate && info2->datarate)
+ {
+ is_equ &= info1->datarate == info2->datarate;
+ }
+ if (is_equ && (info1->channel >= 0) && (info2->channel >= 0))
+ {
+ is_equ &= info1->channel == info2->channel;
+ }
+ if (is_equ && (info1->rssi < 0) && (info2->rssi < 0))
+ {
+ is_equ &= info1->rssi == info2->rssi;
+ }
+ return is_equ;
+}
+
+static void rt_wlan_mgnt_work(void *parameter)
+{
+ struct rt_wlan_msg *msg = parameter;
+ void *user_parameter;
+ rt_wlan_event_handler handler = RT_NULL;
+ struct rt_wlan_buff user_buff = { 0 };
+ rt_base_t level;
+
+ /* Get user callback */
+ if (msg->event < RT_WLAN_EVT_MAX)
+ {
+ level = rt_hw_interrupt_disable();
+ handler = event_tab[msg->event].handler;
+ user_parameter = event_tab[msg->event].parameter;
+ rt_hw_interrupt_enable(level);
+ }
+
+ /* run user callback fun */
+ if (handler)
+ {
+ user_buff.data = msg->buff;
+ user_buff.len = msg->len;
+ RT_WLAN_LOG_D("wlan work thread run user callback, event:%d", msg->event);
+ handler(msg->event, &user_buff, user_parameter);
+ }
+
+ switch (msg->event)
+ {
+ case RT_WLAN_EVT_STA_CONNECTED:
+ {
+ struct rt_wlan_cfg_info cfg_info;
+
+ rt_memset(&cfg_info, 0, sizeof(cfg_info));
+ /* save config */
+ if (rt_wlan_is_connected() == RT_TRUE)
+ {
+ rt_enter_critical();
+ cfg_info.info = _sta_mgnt.info;
+ cfg_info.key = _sta_mgnt.key;
+ rt_exit_critical();
+ RT_WLAN_LOG_D("run save config! ssid:%s len%d", _sta_mgnt.info.ssid.val, _sta_mgnt.info.ssid.len);
+#ifdef RT_WLAN_CFG_ENABLE
+ rt_wlan_cfg_save(&cfg_info);
+#endif
+ }
+ break;
+ }
+ default :
+ break;
+ }
+
+ rt_free(msg);
+}
-static rt_err_t rt_wlan_send_msg(rt_wlan_dev_event_t event, void *buff, int len)
+static rt_err_t rt_wlan_send_to_thread(rt_wlan_event_t event, void *buff, int len)
{
struct rt_wlan_msg *msg;
@@ -164,7 +260,8 @@ static rt_err_t rt_wlan_send_msg(rt_wlan_dev_event_t event, void *buff, int len)
msg->event = event;
if (len != 0)
{
- msg->buff = ((char *)msg) + sizeof(struct rt_wlan_msg);
+ msg->buff = (void *)&msg[1];
+ rt_memcpy(msg->buff, buff, len);
msg->len = len;
}
@@ -177,14 +274,16 @@ static rt_err_t rt_wlan_send_msg(rt_wlan_dev_event_t event, void *buff, int len)
}
return RT_EOK;
}
+#endif
static rt_err_t rt_wlan_scan_result_cache(struct rt_wlan_info *info, int timeout)
{
struct rt_wlan_info *ptable;
rt_err_t err = RT_EOK;
int i, insert = -1;
+ rt_base_t level;
- if (_sta_is_null() || (info == RT_NULL)) return RT_EOK;
+ if (_sta_is_null() || (info == RT_NULL) || (info->ssid.len == 0)) return RT_EOK;
RT_WLAN_LOG_D("ssid:%s len:%d mac:%02x:%02x:%02x:%02x:%02x:%02x", info->ssid.val, info->ssid.len,
info->bssid[0], info->bssid[1], info->bssid[2], info->bssid[3], info->bssid[4], info->bssid[5]);
@@ -193,6 +292,23 @@ static rt_err_t rt_wlan_scan_result_cache(struct rt_wlan_info *info, int timeout
if (err != RT_EOK)
return err;
+ /* scanning result filtering */
+ level = rt_hw_interrupt_disable();
+ if (scan_filter)
+ {
+ struct rt_wlan_info _tmp_info = *scan_filter;
+ rt_hw_interrupt_enable(level);
+ if (rt_wlan_info_isequ(&_tmp_info, info) != RT_TRUE)
+ {
+ rt_mutex_release(&scan_result_mutex);
+ return RT_EOK;
+ }
+ }
+ else
+ {
+ rt_hw_interrupt_enable(level);
+ }
+
/* de-duplicatio */
for (i = 0; i < scan_result.num; i++)
{
@@ -381,7 +497,7 @@ static rt_err_t rt_wlan_sta_info_del_all(int timeout)
sta_info.node = RT_NULL;
return err;
}
-
+#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
static void rt_wlan_auto_connect_run(struct rt_work *work, void *parameter)
{
static rt_uint32_t id = 0;
@@ -413,12 +529,12 @@ static void rt_wlan_auto_connect_run(struct rt_work *work, void *parameter)
if (id >= rt_wlan_cfg_get_num()) id = 0;
- if ((cfg_info.key.len > 0) && (cfg_info.key.len < RT_WLAN_PASSWORD_MAX_LENGTH))
+ if ((cfg_info.key.len > 0) && (cfg_info.key.len <= RT_WLAN_PASSWORD_MAX_LENGTH))
{
cfg_info.key.val[cfg_info.key.len] = '\0';
password = (char *)(&cfg_info.key.val[0]);
}
- rt_wlan_connect_adv(&cfg_info.info, password);
+ rt_wlan_connect((char *)cfg_info.info.ssid.val, password);
exit:
rt_mutex_release(&mgnt_mutex);
level = rt_hw_interrupt_disable();
@@ -449,41 +565,10 @@ static void rt_wlan_cyclic_check(void *parameter)
}
}
}
-
-static void rt_wlan_mgnt_work(void *parameter)
-{
- struct rt_wlan_msg *msg = parameter;
-
- switch (msg->event)
- {
- case RT_WLAN_DEV_EVT_CONNECT:
- {
- struct rt_wlan_cfg_info cfg_info;
-
- /* save config */
- if (rt_wlan_is_connected() == RT_TRUE)
- {
- rt_enter_critical();
- cfg_info.info = _sta_mgnt.info;
- cfg_info.key = _sta_mgnt.key;
- rt_exit_critical();
- RT_WLAN_LOG_D("run save config! ssid:%s len%d", _sta_mgnt.info.ssid.val, _sta_mgnt.info.ssid.len);
- rt_wlan_cfg_save(&cfg_info);
- }
- break;
- }
- default :
- break;
- }
-
- rt_free(msg);
-}
+#endif
static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_event_t event, struct rt_wlan_buff *buff, void *parameter)
{
- rt_base_t level;
- void *user_parameter;
- rt_wlan_event_handler handler = RT_NULL;
rt_err_t err = RT_NULL;
rt_wlan_event_t user_event = RT_WLAN_EVT_MAX;
int i;
@@ -503,7 +588,6 @@ static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_ev
_sta_mgnt.state &= ~RT_WLAN_STATE_CONNECTING;
user_event = RT_WLAN_EVT_STA_CONNECTED;
TIME_STOP();
- rt_wlan_send_msg(event, RT_NULL, 0);
user_buff.data = &_sta_mgnt.info;
user_buff.len = sizeof(struct rt_wlan_info);
RT_WLAN_LOG_I("wifi connect success ssid:%s", &_sta_mgnt.info.ssid.val[0]);
@@ -518,7 +602,10 @@ static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_ev
user_event = RT_WLAN_EVT_STA_CONNECTED_FAIL;
user_buff.data = &_sta_mgnt.info;
user_buff.len = sizeof(struct rt_wlan_info);
- TIME_START();
+ if (rt_wlan_get_autoreconnect_mode())
+ {
+ TIME_START();
+ }
break;
}
case RT_WLAN_DEV_EVT_DISCONNECT:
@@ -529,7 +616,10 @@ static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_ev
user_event = RT_WLAN_EVT_STA_DISCONNECTED;
user_buff.data = &_sta_mgnt.info;
user_buff.len = sizeof(struct rt_wlan_info);
- TIME_START();
+ if (rt_wlan_get_autoreconnect_mode())
+ {
+ TIME_START();
+ }
break;
}
case RT_WLAN_DEV_EVT_AP_START:
@@ -622,20 +712,30 @@ static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_ev
}
}
COMPLETE_UNLOCK();
- /* Get user callback */
- if (user_event < RT_WLAN_EVT_MAX)
+#ifdef RT_WLAN_WORK_THREAD_ENABLE
+ rt_wlan_send_to_thread(user_event, RT_NULL, 0);
+#else
{
- level = rt_hw_interrupt_disable();
- handler = event_tab[user_event].handler;
- user_parameter = event_tab[user_event].parameter;
- rt_hw_interrupt_enable(level);
- }
+ void *user_parameter;
+ rt_wlan_event_handler handler = RT_NULL;
+ rt_base_t level;
+ /* Get user callback */
+ if (user_event < RT_WLAN_EVT_MAX)
+ {
+ level = rt_hw_interrupt_disable();
+ handler = event_tab[user_event].handler;
+ user_parameter = event_tab[user_event].parameter;
+ rt_hw_interrupt_enable(level);
+ }
- /* run user callback fun */
- if (handler)
- {
- handler(user_event, &user_buff, user_parameter);
+ /* run user callback fun */
+ if (handler)
+ {
+ RT_WLAN_LOG_D("unknown thread run user callback, event:%d", user_event);
+ handler(user_event, &user_buff, user_parameter);
+ }
}
+#endif
}
static struct rt_wlan_complete_des *rt_wlan_complete_create(const char *name)
@@ -820,14 +920,30 @@ rt_err_t rt_wlan_set_mode(const char *dev_name, rt_wlan_mode_t mode)
/* update dev event handle */
if (up_event_flag == 1)
{
- rt_wlan_dev_event_t event;
- for (event = RT_WLAN_DEV_EVT_INIT_DONE; event < RT_WLAN_DEV_EVT_MAX; event++)
+ if (handler)
{
- if (handler)
+ if (mode == RT_WLAN_STATION)
+ {
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_CONNECT, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_CONNECT_FAIL, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_DISCONNECT, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_SCAN_REPORT, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_SCAN_DONE, handler, RT_NULL);
+ }
+ else if (mode == RT_WLAN_AP)
{
- rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), event, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_START, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_STOP, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_ASSOCIATED, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_DISASSOCIATED, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_ASSOCIATE_FAILED, handler, RT_NULL);
}
- else
+ }
+ else
+ {
+ rt_wlan_dev_event_t event;
+ handler = rt_wlan_event_dispatch;
+ for (event = RT_WLAN_DEV_EVT_INIT_DONE; event < RT_WLAN_DEV_EVT_MAX; event++)
{
rt_wlan_dev_unregister_event_handler(RT_WLAN_DEVICE(device), event, handler);
}
@@ -836,8 +952,11 @@ rt_err_t rt_wlan_set_mode(const char *dev_name, rt_wlan_mode_t mode)
MGNT_UNLOCK();
/* Mount protocol */
-#ifdef RT_WLAN_DEFAULT_PROT
- rt_wlan_prot_attach(dev_name, RT_WLAN_DEFAULT_PROT);
+#if defined(RT_WLAN_PROT_ENABLE) && defined(RT_WLAN_DEFAULT_PROT)
+ if (err == RT_EOK)
+ {
+ rt_wlan_prot_attach(dev_name, RT_WLAN_DEFAULT_PROT);
+ }
#endif
return err;
}
@@ -932,6 +1051,7 @@ rt_err_t rt_wlan_connect(const char *ssid, const char *password)
struct rt_wlan_info info;
struct rt_wlan_complete_des *complete;
rt_uint32_t set = 0, recved = 0;
+ rt_uint32_t scan_retry = RT_WLAN_SCAN_RETRY_CNT;
/* sta dev Can't be NULL */
if (_sta_is_null())
@@ -960,12 +1080,11 @@ rt_err_t rt_wlan_connect(const char *ssid, const char *password)
/* get info from cache */
INVALID_INFO(&info);
MGNT_LOCK();
- if (rt_wlan_find_best_by_cache(ssid, &info) != RT_TRUE)
+ while (scan_retry-- && rt_wlan_find_best_by_cache(ssid, &info) != RT_TRUE)
{
rt_wlan_scan_sync();
- rt_wlan_find_best_by_cache(ssid, &info);
- rt_wlan_scan_result_clean();
}
+ rt_wlan_scan_result_clean();
if (info.ssid.len <= 0)
{
@@ -1216,10 +1335,13 @@ rt_err_t rt_wlan_get_info(struct rt_wlan_info *info)
}
RT_WLAN_LOG_D("%s is run", __FUNCTION__);
- rt_enter_critical();
- *info = _sta_mgnt.info;
- rt_exit_critical();
- return RT_EOK;
+ if (rt_wlan_is_connected() == RT_TRUE)
+ {
+ *info = _sta_mgnt.info;
+ info->rssi = rt_wlan_get_rssi();
+ return RT_EOK;
+ }
+ return -RT_ERROR;
}
int rt_wlan_get_rssi(void)
@@ -1268,6 +1390,7 @@ rt_err_t rt_wlan_start_ap(const char *ssid, const char *password)
rt_memcpy(&info.ssid.val, ssid, ssid_len);
info.ssid.len = ssid_len;
info.channel = 6;
+ info.band = RT_802_11_BAND_2_4GHZ;
/* Initializing events that need to wait */
MGNT_LOCK();
@@ -1427,8 +1550,12 @@ rt_err_t rt_wlan_ap_get_info(struct rt_wlan_info *info)
}
RT_WLAN_LOG_D("%s is run", __FUNCTION__);
- *info = _ap_mgnt.info;
- return RT_EOK;
+ if (rt_wlan_ap_is_active() == RT_TRUE)
+ {
+ *info = _ap_mgnt.info;
+ return RT_EOK;
+ }
+ return -RT_ERROR;
}
/* get sta number */
@@ -1555,27 +1682,35 @@ rt_country_code_t rt_wlan_ap_get_country(void)
void rt_wlan_config_autoreconnect(rt_bool_t enable)
{
+#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
RT_WLAN_LOG_D("%s is run enable:%d", __FUNCTION__, enable);
MGNT_LOCK();
if (enable)
{
+ TIME_START();
_sta_mgnt.flags |= RT_WLAN_STATE_AUTOEN;
}
else
{
+ TIME_STOP();
_sta_mgnt.flags &= ~RT_WLAN_STATE_AUTOEN;
}
MGNT_UNLOCK();
+#endif
}
rt_bool_t rt_wlan_get_autoreconnect_mode(void)
{
+#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
rt_bool_t enable = 0;
enable = _sta_mgnt.flags & RT_WLAN_STATE_AUTOEN ? 1 : 0;
RT_WLAN_LOG_D("%s is run enable:%d", __FUNCTION__, enable);
return enable;
+#else
+ return RT_FALSE;
+#endif
}
/* Call the underlying scan function, which is asynchronous.
@@ -1612,6 +1747,9 @@ struct rt_wlan_scan_result *rt_wlan_scan_with_info(struct rt_wlan_info *info)
rt_err_t err = RT_EOK;
struct rt_wlan_complete_des *complete;
rt_uint32_t set = 0, recved = 0;
+ static struct rt_wlan_info scan_filter_info;
+ rt_base_t level;
+ struct rt_wlan_scan_result *result;
if (_sta_is_null())
{
@@ -1633,14 +1771,23 @@ struct rt_wlan_scan_result *rt_wlan_scan_with_info(struct rt_wlan_info *info)
return &scan_result;
}
+ /* add scan info filter */
+ if (info)
+ {
+ scan_filter_info = *info;
+ level = rt_hw_interrupt_disable();
+ scan_filter = &scan_filter_info;
+ rt_hw_interrupt_enable(level);
+ }
+
/* run scan */
err = rt_wlan_dev_scan(STA_DEVICE(), info);
if (err != RT_EOK)
{
rt_wlan_complete_delete(complete);
RT_WLAN_LOG_E("scan sync fail");
- MGNT_UNLOCK();
- return RT_NULL;
+ result = RT_NULL;
+ goto scan_exit;
}
/* Initializing events that need to wait */
@@ -1653,12 +1800,17 @@ struct rt_wlan_scan_result *rt_wlan_scan_with_info(struct rt_wlan_info *info)
if (!(recved & set))
{
RT_WLAN_LOG_E("scan wait timeout!");
- MGNT_UNLOCK();
- return &scan_result;
+ result = &scan_result;
+ goto scan_exit;
}
+scan_exit:
MGNT_UNLOCK();
- return &scan_result;
+ level = rt_hw_interrupt_disable();
+ scan_filter = RT_NULL;
+ rt_hw_interrupt_enable(level);
+ result = &scan_result;
+ return result;
}
int rt_wlan_scan_get_info_num(void)
@@ -1709,8 +1861,7 @@ int rt_wlan_scan_find_cache(struct rt_wlan_info *info, struct rt_wlan_info *out_
{
int i = 0, count = 0;
struct rt_wlan_info *scan_info;
- rt_bool_t is_equ = 1;
- rt_uint8_t bssid_zero[RT_WLAN_BSSID_MAX_LENGTH] = { 0 };
+ rt_bool_t is_equ;
if ((out_info == RT_NULL) || (info == RT_NULL) || (num <= 0))
{
@@ -1721,31 +1872,7 @@ int rt_wlan_scan_find_cache(struct rt_wlan_info *info, struct rt_wlan_info *out_
for (i = 0; (i < scan_result.num) && (count < num); i++)
{
scan_info = &scan_result.info[i];
-
- if (is_equ && (info->security != SECURITY_UNKNOWN))
- {
- is_equ &= info->security == scan_info->security;
- }
- if (is_equ && ((info->ssid.len > 0) && (info->ssid.len == scan_info->ssid.len)))
- {
- is_equ &= rt_memcmp(&info->ssid.val[0], &scan_info->ssid.val[0], scan_info->ssid.len) == 0;
- }
- if (is_equ && (rt_memcmp(&info->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)))
- {
- is_equ &= rt_memcmp(&info->bssid[0], &scan_info->bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0;
- }
- if (is_equ && info->datarate)
- {
- is_equ &= info->datarate == scan_info->datarate;
- }
- if (is_equ && (info->channel >= 0))
- {
- is_equ &= info->channel == scan_info->channel;
- }
- if (is_equ && (info->rssi < 0))
- {
- is_equ &= info->rssi == scan_info->rssi;
- }
+ is_equ = rt_wlan_info_isequ(scan_info, info);
/* Determine whether to find */
if (is_equ)
{
@@ -1840,8 +1967,6 @@ void rt_wlan_mgnt_unlock(void)
int rt_wlan_prot_ready_event(struct rt_wlan_device *wlan, struct rt_wlan_buff *buff)
{
rt_base_t level;
- void *user_parameter;
- rt_wlan_event_handler handler = RT_NULL;
if ((wlan == RT_NULL) || (_sta_mgnt.device != wlan) ||
(!(_sta_mgnt.state & RT_WLAN_STATE_CONNECT)))
@@ -1854,13 +1979,24 @@ int rt_wlan_prot_ready_event(struct rt_wlan_device *wlan, struct rt_wlan_buff *b
}
level = rt_hw_interrupt_disable();
_sta_mgnt.state |= RT_WLAN_STATE_READY;
- handler = event_tab[RT_WLAN_EVT_READY].handler;
- user_parameter = event_tab[RT_WLAN_EVT_READY].parameter;
rt_hw_interrupt_enable(level);
- if (handler)
+#ifdef RT_WLAN_WORK_THREAD_ENABLE
+ rt_wlan_send_to_thread(RT_WLAN_EVT_READY, buff->data, buff->len);
+#else
{
- handler(RT_WLAN_EVT_READY, buff, user_parameter);
+ void *user_parameter;
+ rt_wlan_event_handler handler = RT_NULL;
+
+ level = rt_hw_interrupt_disable();
+ handler = event_tab[RT_WLAN_EVT_READY].handler;
+ user_parameter = event_tab[RT_WLAN_EVT_READY].parameter;
+ rt_hw_interrupt_enable(level);
+ if (handler)
+ {
+ handler(RT_WLAN_EVT_READY, buff, user_parameter);
+ }
}
+#endif
return 0;
}
@@ -1879,10 +2015,15 @@ int rt_wlan_init(void)
rt_mutex_init(&scan_result_mutex, "scan", RT_IPC_FLAG_FIFO);
rt_mutex_init(&sta_info_mutex, "sta", RT_IPC_FLAG_FIFO);
rt_mutex_init(&complete_mutex, "complete", RT_IPC_FLAG_FIFO);
- rt_timer_init(&reconnect_time, "wifi_tim", rt_wlan_cyclic_check, RT_NULL, DISCONNECT_RESPONSE_TICK, RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER);
- rt_timer_start(&reconnect_time);
+#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
+ rt_timer_init(&reconnect_time, "wifi_tim", rt_wlan_cyclic_check, RT_NULL,
+ rt_tick_from_millisecond(AUTO_CONNECTION_PERIOD_MS),
+ RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER);
+#endif
_init_flag = 1;
}
return 0;
}
INIT_PREV_EXPORT(rt_wlan_init);
+
+#endif
diff --git a/components/drivers/wlan/wlan_mgnt.h b/components/drivers/wlan/wlan_mgnt.h
index f4d9e0cff9..df0827bb7b 100644
--- a/components/drivers/wlan/wlan_mgnt.h
+++ b/components/drivers/wlan/wlan_mgnt.h
@@ -37,6 +37,14 @@ extern "C" {
#define RT_WLAN_EBOX_NUM (10)
#endif
+#ifndef RT_WLAN_SCAN_RETRY_CNT
+#define RT_WLAN_SCAN_RETRY_CNT (3)
+#endif
+
+#ifndef AUTO_CONNECTION_PERIOD_MS
+#define AUTO_CONNECTION_PERIOD_MS (2000)
+#endif
+
/*state fot station*/
#define RT_WLAN_STATE_CONNECT (1UL << 0)
#define RT_WLAN_STATE_CONNECTING (1UL << 1)
diff --git a/components/drivers/wlan/wlan_prot.c b/components/drivers/wlan/wlan_prot.c
index 0402962e01..b1a1b5de99 100644
--- a/components/drivers/wlan/wlan_prot.c
+++ b/components/drivers/wlan/wlan_prot.c
@@ -21,6 +21,8 @@
#endif /* RT_WLAN_PROT_DEBUG */
#include <rtdbg.h>
+#ifdef RT_WLAN_PROT_ENABLE
+
#if RT_WLAN_PROT_NAME_LEN < 4
#error "The name is too short"
#endif
@@ -160,7 +162,7 @@ rt_err_t rt_wlan_prot_attach_dev(struct rt_wlan_device *wlan, const char *prot_n
{
int i = 0;
struct rt_wlan_prot *prot = wlan->prot;
- rt_wlan_dev_event_t event;
+ rt_wlan_dev_event_handler handler = rt_wlan_prot_event_handle;
if (wlan == RT_NULL)
{
@@ -180,7 +182,7 @@ rt_err_t rt_wlan_prot_attach_dev(struct rt_wlan_device *wlan, const char *prot_n
rt_wlan_prot_detach_dev(wlan);
#ifdef RT_WLAN_PROT_LWIP_PBUF_FORCE
- if (rt_strcmp(RT_WLAN_PROT_LWIP, prot_name) != 0)
+ if (rt_strcmp(RT_WLAN_PROT_LWIP_NAME, prot_name) != 0)
{
return -RT_ERROR;
}
@@ -202,13 +204,12 @@ rt_err_t rt_wlan_prot_attach_dev(struct rt_wlan_device *wlan, const char *prot_n
return -RT_ERROR;
}
- for (event = RT_WLAN_DEV_EVT_INIT_DONE; event < RT_WLAN_DEV_EVT_MAX; event ++)
- {
- if (rt_wlan_dev_register_event_handler(wlan, event, rt_wlan_prot_event_handle, RT_NULL) != RT_EOK)
- {
- LOG_E("prot register event filed:%d", event);
- }
- }
+ rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_CONNECT, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_DISCONNECT, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_START, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_STOP, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_ASSOCIATED, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_DISASSOCIATED, handler, RT_NULL);
return RT_EOK;
}
@@ -360,3 +361,4 @@ void rt_wlan_prot_dump(void)
}
}
}
+#endif
diff --git a/components/drivers/wlan/wlan_prot.h b/components/drivers/wlan/wlan_prot.h
index 34c5bae7fd..2df979270f 100644
--- a/components/drivers/wlan/wlan_prot.h
+++ b/components/drivers/wlan/wlan_prot.h
@@ -25,8 +25,6 @@ extern "C" {
#define RT_LWAN_ID_PREFIX (0x5054)
-#define RT_WLAN_PROT_LWIP ("lwip")
-
typedef enum
{
RT_WLAN_PROT_EVT_INIT_DONE = 0,
diff --git a/components/drivers/wlan/wlan_workqueue.c b/components/drivers/wlan/wlan_workqueue.c
index ec21243d60..4cd98346d2 100644
--- a/components/drivers/wlan/wlan_workqueue.c
+++ b/components/drivers/wlan/wlan_workqueue.c
@@ -17,6 +17,8 @@
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
+#ifdef RT_WLAN_WORK_THREAD_ENABLE
+
struct rt_wlan_work
{
struct rt_work work;
@@ -95,3 +97,5 @@ int rt_wlan_workqueue_init(void)
return 0;
}
INIT_PREV_EXPORT(rt_wlan_workqueue_init);
+
+#endif
diff --git a/components/finsh/SConscript b/components/finsh/SConscript
index e1e2b3bbdb..be04c56616 100644
--- a/components/finsh/SConscript
+++ b/components/finsh/SConscript
@@ -4,7 +4,6 @@ from building import *
cwd = GetCurrentDir()
src = Split('''
shell.c
-symbol.c
cmd.c
''')
@@ -21,19 +20,20 @@ finsh_vm.c
finsh_token.c
''')
-msh_src = Split('''
-msh.c
-msh_cmd.c
-msh_file.c
-''')
+msh_src = Glob('msh.c')
-CPPPATH = [cwd]
+if GetDepend('RT_USING_DFS'):
+ msh_src += ['msh_file.c']
+if not GetDepend('FINSH_USING_SYMTAB'):
+ src += ['symbol.c']
if GetDepend('FINSH_USING_MSH'):
src = src + msh_src
if not GetDepend('FINSH_USING_MSH_ONLY'):
src = src + fsh_src
+CPPPATH = [cwd]
+
group = DefineGroup('finsh', src, depend = ['RT_USING_FINSH'], CPPPATH = CPPPATH)
Return('group')
diff --git a/components/finsh/cmd.c b/components/finsh/cmd.c
index ba0292d81a..ebef0eac1c 100644
--- a/components/finsh/cmd.c
+++ b/components/finsh/cmd.c
@@ -440,8 +440,16 @@ static long _list_mempool(struct rt_list_node *list)
rt_kprintf( " ---- ---- ---- --------------\n");
for (node = list->next; node != list; node = node->next)
{
+ int suspend_thread_count;
+ rt_list_t *temp_node;
mp = (struct rt_mempool *)rt_list_entry(node, struct rt_object, list);
- if (mp->suspend_thread_count > 0)
+ suspend_thread_count = 0;
+ rt_list_for_each(temp_node, &mp->suspend_thread)
+ {
+ suspend_thread_count++;
+ }
+
+ if (suspend_thread_count > 0)
{
rt_kprintf("%-*.*s %04d %04d %04d %d:",
maxlen, RT_NAME_MAX,
@@ -449,7 +457,7 @@ static long _list_mempool(struct rt_list_node *list)
mp->block_size,
mp->block_total_count,
mp->block_free_count,
- mp->suspend_thread_count);
+ suspend_thread_count);
show_wait_queue(&(mp->suspend_thread));
rt_kprintf("\n");
}
@@ -461,7 +469,7 @@ static long _list_mempool(struct rt_list_node *list)
mp->block_size,
mp->block_total_count,
mp->block_free_count,
- mp->suspend_thread_count);
+ suspend_thread_count);
}
}
@@ -547,6 +555,7 @@ static long _list_device(struct rt_list_node *list)
"Timer Device",
"Miscellaneous Device",
"Sensor Device",
+ "Touch Device",
"Unknown"
};
const char *item_title = "device";
@@ -598,7 +607,7 @@ long list(void)
/* skip the internal command */
if (strncmp((char *)index->name, "__", 2) == 0) continue;
-#ifdef FINSH_USING_DESCRIPTION
+#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
rt_kprintf("%-16s -- %s\n", index->name, index->desc);
#else
rt_kprintf("%s\n", index->name);
diff --git a/components/finsh/finsh_vm.c b/components/finsh/finsh_vm.c
index fcd58494a9..7c56407084 100644
--- a/components/finsh/finsh_vm.c
+++ b/components/finsh/finsh_vm.c
@@ -78,28 +78,6 @@ void finsh_syscall_append(const char* name, syscall_func func)
}
#endif
-#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
-struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call)
-{
- unsigned int *ptr;
- ptr = (unsigned int*) (call + 1);
- while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _syscall_table_end))
- ptr ++;
-
- return (struct finsh_syscall*)ptr;
-}
-
-struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call)
-{
- unsigned int *ptr;
- ptr = (unsigned int*) (call + 1);
- while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _sysvar_table_end))
- ptr ++;
-
- return (struct finsh_sysvar*)ptr;
-}
-#endif
-
struct finsh_syscall* finsh_syscall_lookup(const char* name)
{
struct finsh_syscall* index;
diff --git a/components/finsh/msh.c b/components/finsh/msh.c
index fd1ee1198d..79f1e3c87f 100644
--- a/components/finsh/msh.c
+++ b/components/finsh/msh.c
@@ -89,6 +89,37 @@ int msh_help(int argc, char **argv)
}
FINSH_FUNCTION_EXPORT_ALIAS(msh_help, __cmd_help, RT-Thread shell help.);
+int cmd_ps(int argc, char **argv)
+{
+ extern long list_thread(void);
+ extern int list_module(void);
+
+#ifdef RT_USING_MODULE
+ if ((argc == 2) && (strcmp(argv[1], "-m") == 0))
+ list_module();
+ else
+#endif
+ list_thread();
+ return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(cmd_ps, __cmd_ps, List threads in the system.);
+
+#ifdef RT_USING_HEAP
+int cmd_free(int argc, char **argv)
+{
+ extern void list_mem(void);
+ extern void list_memheap(void);
+
+#ifdef RT_USING_MEMHEAP_AS_HEAP
+ list_memheap();
+#else
+ list_mem();
+#endif
+ return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(cmd_free, __cmd_free, Show the memory usage in the system.);
+#endif
+
static int msh_split(char *cmd, rt_size_t length, char *argv[FINSH_ARG_MAX])
{
char *ptr;
diff --git a/components/finsh/msh_cmd.c b/components/finsh/msh_cmd.c
deleted file mode 100644
index 4a9c67fa75..0000000000
--- a/components/finsh/msh_cmd.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2013-03-30 Bernard the first verion for FinSH
- * 2015-08-28 Bernard Add mkfs command.
- */
-
-#include <rtthread.h>
-
-#ifdef FINSH_USING_MSH
-
-#include <finsh.h>
-#include "msh.h"
-
-#ifdef RT_USING_DFS
-#include <dfs_posix.h>
-
-#ifdef DFS_USING_WORKDIR
-extern char working_directory[];
-#endif
-
-int cmd_ls(int argc, char **argv)
-{
- extern void ls(const char *pathname);
-
- if (argc == 1)
- {
-#ifdef DFS_USING_WORKDIR
- ls(working_directory);
-#else
- ls("/");
-#endif
- }
- else
- {
- ls(argv[1]);
- }
-
- return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_ls, __cmd_ls, List information about the FILEs.);
-
-int cmd_cp(int argc, char **argv)
-{
- void copy(const char *src, const char *dst);
-
- if (argc != 3)
- {
- rt_kprintf("Usage: cp SOURCE DEST\n");
- rt_kprintf("Copy SOURCE to DEST.\n");
- }
- else
- {
- copy(argv[1], argv[2]);
- }
-
- return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_cp, __cmd_cp, Copy SOURCE to DEST.);
-
-int cmd_mv(int argc, char **argv)
-{
- if (argc != 3)
- {
- rt_kprintf("Usage: mv SOURCE DEST\n");
- rt_kprintf("Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n");
- }
- else
- {
- int fd;
- char *dest = RT_NULL;
-
- rt_kprintf("%s => %s\n", argv[1], argv[2]);
-
- fd = open(argv[2], O_DIRECTORY, 0);
- if (fd >= 0)
- {
- char *src;
-
- close(fd);
-
- /* it's a directory */
- dest = (char *)rt_malloc(DFS_PATH_MAX);
- if (dest == RT_NULL)
- {
- rt_kprintf("out of memory\n");
- return -RT_ENOMEM;
- }
-
- src = argv[1] + rt_strlen(argv[1]);
- while (src != argv[1])
- {
- if (*src == '/') break;
- src --;
- }
-
- rt_snprintf(dest, DFS_PATH_MAX - 1, "%s/%s", argv[2], src);
- }
- else
- {
- fd = open(argv[2], O_RDONLY, 0);
- if (fd >= 0)
- {
- close(fd);
-
- unlink(argv[2]);
- }
-
- dest = argv[2];
- }
-
- rename(argv[1], dest);
- if (dest != RT_NULL && dest != argv[2]) rt_free(dest);
- }
-
- return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_mv, __cmd_mv, Rename SOURCE to DEST.);
-
-int cmd_cat(int argc, char **argv)
-{
- int index;
- extern void cat(const char *filename);
-
- if (argc == 1)
- {
- rt_kprintf("Usage: cat [FILE]...\n");
- rt_kprintf("Concatenate FILE(s)\n");
- return 0;
- }
-
- for (index = 1; index < argc; index ++)
- {
- cat(argv[index]);
- }
-
- return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_cat, __cmd_cat, Concatenate FILE(s));
-
-int cmd_rm(int argc, char **argv)
-{
- int index;
-
- if (argc == 1)
- {
- rt_kprintf("Usage: rm FILE...\n");
- rt_kprintf("Remove (unlink) the FILE(s).\n");
- return 0;
- }
-
- for (index = 1; index < argc; index ++)
- {
- unlink(argv[index]);
- }
-
- return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_rm, __cmd_rm, Remove(unlink) the FILE(s).);
-
-#ifdef DFS_USING_WORKDIR
-int cmd_cd(int argc, char **argv)
-{
- if (argc == 1)
- {
- rt_kprintf("%s\n", working_directory);
- }
- else if (argc == 2)
- {
- if (chdir(argv[1]) != 0)
- {
- rt_kprintf("No such directory: %s\n", argv[1]);
- }
- }
-
- return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_cd, __cmd_cd, Change the shell working directory.);
-
-int cmd_pwd(int argc, char **argv)
-{
- rt_kprintf("%s\n", working_directory);
- return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_pwd, __cmd_pwd, Print the name of the current working directory.);
-#endif
-
-int cmd_mkdir(int argc, char **argv)
-{
- if (argc == 1)
- {
- rt_kprintf("Usage: mkdir [OPTION] DIRECTORY\n");
- rt_kprintf("Create the DIRECTORY, if they do not already exist.\n");
- }
- else
- {
- mkdir(argv[1], 0);
- }
-
- return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_mkdir, __cmd_mkdir, Create the DIRECTORY.);
-
-int cmd_mkfs(int argc, char **argv)
-{
- int result = 0;
- char *type = "elm"; /* use the default file system type as 'fatfs' */
-
- if (argc == 2)
- {
- result = dfs_mkfs(type, argv[1]);
- }
- else if (argc == 4)
- {
- if (strcmp(argv[1], "-t") == 0)
- {
- type = argv[2];
- result = dfs_mkfs(type, argv[3]);
- }
- }
- else
- {
- rt_kprintf("Usage: mkfs [-t type] device\n");
- return 0;
- }
-
- if (result != RT_EOK)
- {
- rt_kprintf("mkfs failed, result=%d\n", result);
- }
-
- return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_mkfs, __cmd_mkfs, format disk with file system);
-
-extern int df(const char *path);
-int cmd_df(int argc, char** argv)
-{
- if (argc != 2)
- {
- df("/");
- }
- else
- {
- if ((strcmp(argv[1], "--help") == 0) || (strcmp(argv[1], "-h") == 0))
- {
- rt_kprintf("df [path]\n");
- }
- else
- {
- df(argv[1]);
- }
- }
-
- return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_df, __cmd_df, disk free);
-
-int cmd_echo(int argc, char** argv)
-{
- if (argc == 2)
- {
- rt_kprintf("%s\n", argv[1]);
- }
- else if (argc == 3)
- {
- int fd;
-
- fd = open(argv[2], O_RDWR | O_APPEND | O_CREAT, 0);
- if (fd >= 0)
- {
- write (fd, argv[1], strlen(argv[1]));
- close(fd);
- }
- else
- {
- rt_kprintf("open file:%s failed!\n", argv[2]);
- }
- }
- else
- {
- rt_kprintf("Usage: echo \"string\" [filename]\n");
- }
-
- return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_echo, __cmd_echo, echo string to file);
-#endif
-
-int cmd_ps(int argc, char **argv)
-{
- extern long list_thread(void);
- extern int list_module(void);
-
-#ifdef RT_USING_MODULE
- if ((argc == 2) && (strcmp(argv[1], "-m") == 0))
- list_module();
- else
-#endif
- list_thread();
- return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_ps, __cmd_ps, List threads in the system.);
-
-int cmd_time(int argc, char **argv)
-{
- return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_time, __cmd_time, Execute command with time.);
-
-#ifdef RT_USING_HEAP
-int cmd_free(int argc, char **argv)
-{
- extern void list_mem(void);
- extern void list_memheap(void);
-
-#ifdef RT_USING_MEMHEAP_AS_HEAP
- list_memheap();
-#else
- list_mem();
-#endif
- return 0;
-}
-FINSH_FUNCTION_EXPORT_ALIAS(cmd_free, __cmd_free, Show the memory usage in the system.);
-#endif
-
-#endif /* FINSH_USING_MSH */
diff --git a/components/finsh/msh_file.c b/components/finsh/msh_file.c
index d8eec0a71a..10251b4cb5 100644
--- a/components/finsh/msh_file.c
+++ b/components/finsh/msh_file.c
@@ -137,5 +137,276 @@ int msh_exec_script(const char *cmd_line, int size)
return ret;
}
+#ifdef DFS_USING_WORKDIR
+extern char working_directory[];
+#endif
+
+int cmd_ls(int argc, char **argv)
+{
+ extern void ls(const char *pathname);
+
+ if (argc == 1)
+ {
+#ifdef DFS_USING_WORKDIR
+ ls(working_directory);
+#else
+ ls("/");
+#endif
+ }
+ else
+ {
+ ls(argv[1]);
+ }
+
+ return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(cmd_ls, __cmd_ls, List information about the FILEs.);
+
+int cmd_cp(int argc, char **argv)
+{
+ void copy(const char *src, const char *dst);
+
+ if (argc != 3)
+ {
+ rt_kprintf("Usage: cp SOURCE DEST\n");
+ rt_kprintf("Copy SOURCE to DEST.\n");
+ }
+ else
+ {
+ copy(argv[1], argv[2]);
+ }
+
+ return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(cmd_cp, __cmd_cp, Copy SOURCE to DEST.);
+
+int cmd_mv(int argc, char **argv)
+{
+ if (argc != 3)
+ {
+ rt_kprintf("Usage: mv SOURCE DEST\n");
+ rt_kprintf("Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.\n");
+ }
+ else
+ {
+ int fd;
+ char *dest = RT_NULL;
+
+ rt_kprintf("%s => %s\n", argv[1], argv[2]);
+
+ fd = open(argv[2], O_DIRECTORY, 0);
+ if (fd >= 0)
+ {
+ char *src;
+
+ close(fd);
+
+ /* it's a directory */
+ dest = (char *)rt_malloc(DFS_PATH_MAX);
+ if (dest == RT_NULL)
+ {
+ rt_kprintf("out of memory\n");
+ return -RT_ENOMEM;
+ }
+
+ src = argv[1] + rt_strlen(argv[1]);
+ while (src != argv[1])
+ {
+ if (*src == '/') break;
+ src --;
+ }
+
+ rt_snprintf(dest, DFS_PATH_MAX - 1, "%s/%s", argv[2], src);
+ }
+ else
+ {
+ fd = open(argv[2], O_RDONLY, 0);
+ if (fd >= 0)
+ {
+ close(fd);
+
+ unlink(argv[2]);
+ }
+
+ dest = argv[2];
+ }
+
+ rename(argv[1], dest);
+ if (dest != RT_NULL && dest != argv[2]) rt_free(dest);
+ }
+
+ return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(cmd_mv, __cmd_mv, Rename SOURCE to DEST.);
+
+int cmd_cat(int argc, char **argv)
+{
+ int index;
+ extern void cat(const char *filename);
+
+ if (argc == 1)
+ {
+ rt_kprintf("Usage: cat [FILE]...\n");
+ rt_kprintf("Concatenate FILE(s)\n");
+ return 0;
+ }
+
+ for (index = 1; index < argc; index ++)
+ {
+ cat(argv[index]);
+ }
+
+ return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(cmd_cat, __cmd_cat, Concatenate FILE(s));
+
+int cmd_rm(int argc, char **argv)
+{
+ int index;
+
+ if (argc == 1)
+ {
+ rt_kprintf("Usage: rm FILE...\n");
+ rt_kprintf("Remove (unlink) the FILE(s).\n");
+ return 0;
+ }
+
+ for (index = 1; index < argc; index ++)
+ {
+ unlink(argv[index]);
+ }
+
+ return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(cmd_rm, __cmd_rm, Remove(unlink) the FILE(s).);
+
+#ifdef DFS_USING_WORKDIR
+int cmd_cd(int argc, char **argv)
+{
+ if (argc == 1)
+ {
+ rt_kprintf("%s\n", working_directory);
+ }
+ else if (argc == 2)
+ {
+ if (chdir(argv[1]) != 0)
+ {
+ rt_kprintf("No such directory: %s\n", argv[1]);
+ }
+ }
+
+ return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(cmd_cd, __cmd_cd, Change the shell working directory.);
+
+int cmd_pwd(int argc, char **argv)
+{
+ rt_kprintf("%s\n", working_directory);
+ return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(cmd_pwd, __cmd_pwd, Print the name of the current working directory.);
+#endif
+
+int cmd_mkdir(int argc, char **argv)
+{
+ if (argc == 1)
+ {
+ rt_kprintf("Usage: mkdir [OPTION] DIRECTORY\n");
+ rt_kprintf("Create the DIRECTORY, if they do not already exist.\n");
+ }
+ else
+ {
+ mkdir(argv[1], 0);
+ }
+
+ return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(cmd_mkdir, __cmd_mkdir, Create the DIRECTORY.);
+
+int cmd_mkfs(int argc, char **argv)
+{
+ int result = 0;
+ char *type = "elm"; /* use the default file system type as 'fatfs' */
+
+ if (argc == 2)
+ {
+ result = dfs_mkfs(type, argv[1]);
+ }
+ else if (argc == 4)
+ {
+ if (strcmp(argv[1], "-t") == 0)
+ {
+ type = argv[2];
+ result = dfs_mkfs(type, argv[3]);
+ }
+ }
+ else
+ {
+ rt_kprintf("Usage: mkfs [-t type] device\n");
+ return 0;
+ }
+
+ if (result != RT_EOK)
+ {
+ rt_kprintf("mkfs failed, result=%d\n", result);
+ }
+
+ return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(cmd_mkfs, __cmd_mkfs, format disk with file system);
+
+extern int df(const char *path);
+int cmd_df(int argc, char** argv)
+{
+ if (argc != 2)
+ {
+ df("/");
+ }
+ else
+ {
+ if ((strcmp(argv[1], "--help") == 0) || (strcmp(argv[1], "-h") == 0))
+ {
+ rt_kprintf("df [path]\n");
+ }
+ else
+ {
+ df(argv[1]);
+ }
+ }
+
+ return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(cmd_df, __cmd_df, disk free);
+
+int cmd_echo(int argc, char** argv)
+{
+ if (argc == 2)
+ {
+ rt_kprintf("%s\n", argv[1]);
+ }
+ else if (argc == 3)
+ {
+ int fd;
+
+ fd = open(argv[2], O_RDWR | O_APPEND | O_CREAT, 0);
+ if (fd >= 0)
+ {
+ write (fd, argv[1], strlen(argv[1]));
+ close(fd);
+ }
+ else
+ {
+ rt_kprintf("open file:%s failed!\n", argv[2]);
+ }
+ }
+ else
+ {
+ rt_kprintf("Usage: echo \"string\" [filename]\n");
+ }
+
+ return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(cmd_echo, __cmd_echo, echo string to file);
+
#endif /* defined(FINSH_USING_MSH) && defined(RT_USING_DFS) */
diff --git a/components/finsh/shell.c b/components/finsh/shell.c
index 53dcd11c66..852d3e7ac7 100644
--- a/components/finsh/shell.c
+++ b/components/finsh/shell.c
@@ -15,7 +15,7 @@
* 2011-02-23 Bernard fix variable section end issue of finsh shell
* initialization when use GNU GCC compiler.
* 2016-11-26 armink add password authentication
- * 2018-07-02 aozima add custome prompt support.
+ * 2018-07-02 aozima add custom prompt support.
*/
#include <rthw.h>
@@ -41,9 +41,39 @@ static char finsh_thread_stack[FINSH_THREAD_STACK_SIZE];
struct finsh_shell _shell;
#endif
+/* finsh symtab */
+#ifdef FINSH_USING_SYMTAB
+struct finsh_syscall *_syscall_table_begin = NULL;
+struct finsh_syscall *_syscall_table_end = NULL;
+struct finsh_sysvar *_sysvar_table_begin = NULL;
+struct finsh_sysvar *_sysvar_table_end = NULL;
+#endif
+
struct finsh_shell *shell;
static char *finsh_prompt_custom = RT_NULL;
+#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
+struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call)
+{
+ unsigned int *ptr;
+ ptr = (unsigned int*) (call + 1);
+ while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _syscall_table_end))
+ ptr ++;
+
+ return (struct finsh_syscall*)ptr;
+}
+
+struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call)
+{
+ unsigned int *ptr;
+ ptr = (unsigned int*) (call + 1);
+ while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _sysvar_table_end))
+ ptr ++;
+
+ return (struct finsh_sysvar*)ptr;
+}
+#endif /* defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__)) */
+
#ifdef RT_USING_HEAP
int finsh_set_prompt(const char * prompt)
{
@@ -56,7 +86,7 @@ int finsh_set_prompt(const char * prompt)
/* strdup */
if(prompt)
{
- finsh_prompt_custom = rt_malloc(strlen(prompt)+1);
+ finsh_prompt_custom = (char *)rt_malloc(strlen(prompt)+1);
if(finsh_prompt_custom)
{
strcpy(finsh_prompt_custom, prompt);
@@ -136,6 +166,7 @@ void finsh_set_prompt_mode(rt_uint32_t prompt_mode)
static int finsh_getchar(void)
{
+#ifdef RT_USING_DEVICE
#ifdef RT_USING_POSIX
return getchar();
#else
@@ -147,9 +178,13 @@ static int finsh_getchar(void)
return (int)ch;
#endif
+#else
+ extern char rt_hw_console_getchar(void);
+ return rt_hw_console_getchar();
+#endif
}
-#ifndef RT_USING_POSIX
+#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE)
static rt_err_t finsh_rx_ind(rt_device_t dev, rt_size_t size)
{
RT_ASSERT(shell != RT_NULL);
@@ -309,8 +344,8 @@ static void finsh_wait_auth(void)
else if (ch == '\b' && cur_pos > 0)
{
/* backspace */
- password[cur_pos] = '\0';
cur_pos--;
+ password[cur_pos] = '\0';
rt_kprintf("\b \b");
}
else if (ch == '\r' || ch == '\n')
@@ -477,7 +512,7 @@ void finsh_thread_entry(void *parameter)
finsh_init(&shell->parser);
#endif
-#ifndef RT_USING_POSIX
+#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE)
/* set console device as shell device */
if (shell->device == RT_NULL)
{
diff --git a/components/finsh/shell.h b/components/finsh/shell.h
index 2cf2c9b833..8741759ed4 100644
--- a/components/finsh/shell.h
+++ b/components/finsh/shell.h
@@ -79,10 +79,10 @@ struct finsh_shell
#endif
char line[FINSH_CMD_SIZE];
- rt_uint8_t line_position;
- rt_uint8_t line_curpos;
+ rt_uint16_t line_position;
+ rt_uint16_t line_curpos;
-#ifndef RT_USING_POSIX
+#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE)
rt_device_t device;
#endif
diff --git a/components/finsh/symbol.c b/components/finsh/symbol.c
index e500637bdd..78df9fac5c 100644
--- a/components/finsh/symbol.c
+++ b/components/finsh/symbol.c
@@ -10,7 +10,7 @@
#include <rtthread.h>
-#ifdef RT_USING_FINSH
+#if defined(RT_USING_FINSH) && !defined(FINSH_USING_SYMTAB)
#include "finsh.h"
@@ -27,12 +27,6 @@ long list_msgqueue(void);
long list_mempool(void);
long list_timer(void);
-#ifdef FINSH_USING_SYMTAB
-struct finsh_syscall *_syscall_table_begin = NULL;
-struct finsh_syscall *_syscall_table_end = NULL;
-struct finsh_sysvar *_sysvar_table_begin = NULL;
-struct finsh_sysvar *_sysvar_table_end = NULL;
-#else
struct finsh_syscall _syscall_table[] =
{
{"hello", hello},
@@ -67,7 +61,6 @@ struct finsh_syscall *_syscall_table_end = &_syscall_table[sizeof(_syscall_tab
struct finsh_sysvar *_sysvar_table_begin = NULL;
struct finsh_sysvar *_sysvar_table_end = NULL;
-#endif
-#endif /* RT_USING_FINSH */
+#endif /* RT_USING_FINSH && !FINSH_USING_SYMTAB */
diff --git a/components/libc/Kconfig b/components/libc/Kconfig
index 43d9330102..2d1e9315f1 100644
--- a/components/libc/Kconfig
+++ b/components/libc/Kconfig
@@ -39,4 +39,10 @@ if RT_USING_LIBC && RT_USING_DFS
default n
endif
+if RT_USING_LIBC != y
+ config RT_LIBC_USING_TIME
+ bool "Enable TIME FUNCTIONS WITHOUT COMPILER'S LIBC"
+ default y
+endif
+
endmenu
diff --git a/components/libc/compilers/armlibc/libc.h b/components/libc/compilers/armlibc/libc.h
index 158fe06c3e..b9b1b6212d 100644
--- a/components/libc/compilers/armlibc/libc.h
+++ b/components/libc/compilers/armlibc/libc.h
@@ -12,11 +12,17 @@
#include <stddef.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
int libc_system_init(void);
int libc_stdio_set_console(const char* device_name, int mode);
int libc_stdio_get_console(void);
-int libc_stdio_read (void *buffer, size_t size);
-int libc_stdio_write(const void *buffer, size_t size);
+int libc_stdio_read(void* buffer, size_t size);
+int libc_stdio_write(const void* buffer, size_t size);
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/components/libc/compilers/armlibc/sys/time.h b/components/libc/compilers/armlibc/sys/time.h
deleted file mode 100644
index bac122e183..0000000000
--- a/components/libc/compilers/armlibc/sys/time.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- */
-#ifndef _SYS_TIME_H_
-#define _SYS_TIME_H_
-
-#include <time.h>
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _TIMEVAL_DEFINED
-#define _TIMEVAL_DEFINED
-/*
- * Structure returned by gettimeofday(2) system call,
- * and used in other calls.
- */
-struct timeval {
- long tv_sec; /* seconds */
- long tv_usec; /* and microseconds */
-};
-#endif /* _TIMEVAL_DEFINED */
-
-#ifndef _TIMESPEC_DEFINED
-#define _TIMESPEC_DEFINED
-/*
- * Structure defined by POSIX.1b to be like a timeval.
- */
-struct timespec {
- time_t tv_sec; /* seconds */
- long tv_nsec; /* and nanoseconds */
-};
-#endif /* _TIMESPEC_DEFINED */
-
-struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* type of dst correction */
-};
-
-int gettimeofday(struct timeval *tp, void *ignore);
-struct tm *gmtime_r(const time_t *timep, struct tm *r);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SYS_TIME_H_ */
diff --git a/components/libc/compilers/armlibc/sys/types.h b/components/libc/compilers/armlibc/sys/types.h
index 4c76dfc429..001ace4dd2 100644
--- a/components/libc/compilers/armlibc/sys/types.h
+++ b/components/libc/compilers/armlibc/sys/types.h
@@ -15,6 +15,10 @@
typedef rt_int32_t clockid_t;
typedef rt_int32_t key_t; /* Used for interprocess communication. */
typedef rt_int32_t pid_t; /* Used for process IDs and process group IDs. */
-typedef signed long ssize_t; /* Used for a count of bytes or an error indication. */
+#ifndef ARCH_CPU_64BIT
+typedef signed int ssize_t; /* Used for a count of bytes or an error indication. */
+#else
+typedef long signed int ssize_t; /* Used for a count of bytes or an error indication. */
+#endif
#endif
diff --git a/components/libc/compilers/armlibc/time.c b/components/libc/compilers/armlibc/time.c
deleted file mode 100644
index f099d51330..0000000000
--- a/components/libc/compilers/armlibc/time.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- */
-#include <sys/time.h>
-#include <rtthread.h>
-
-#ifdef RT_USING_DEVICE
-int gettimeofday(struct timeval *tp, void *ignore)
-{
- time_t time;
- rt_device_t device;
-
- device = rt_device_find("rtc");
- RT_ASSERT(device != RT_NULL);
-
- rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time);
- if (tp != RT_NULL)
- {
- tp->tv_sec = time;
- tp->tv_usec = 0;
- }
-
- return time;
-}
-#endif
-
-/**
- * Returns the current time.
- *
- * @param time_t * t the timestamp pointer, if not used, keep NULL.
- *
- * @return time_t return timestamp current.
- *
- */
-/* for IAR 6.2 later Compiler */
-#if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000
-#pragma module_name = "?time"
-time_t (__time32)(time_t *t) /* Only supports 32-bit timestamp */
-#else
-time_t time(time_t *t)
-#endif
-{
- time_t time_now = 0;
-
-#ifdef RT_USING_RTC
- static rt_device_t device = RT_NULL;
-
- /* optimization: find rtc device only first. */
- if (device == RT_NULL)
- {
- device = rt_device_find("rtc");
- }
-
- /* read timestamp from RTC device. */
- if (device != RT_NULL)
- {
- if (rt_device_open(device, 0) == RT_EOK)
- {
- rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now);
- rt_device_close(device);
- }
- }
-#endif /* RT_USING_RTC */
-
- /* if t is not NULL, write timestamp to *t */
- if (t != RT_NULL)
- {
- *t = time_now;
- }
-
- return time_now;
-}
-
-RT_WEAK clock_t clock(void)
-{
- return rt_tick_get();
-}
diff --git a/components/libc/compilers/common/SConscript b/components/libc/compilers/common/SConscript
index 02bf49941d..a8d2606820 100644
--- a/components/libc/compilers/common/SConscript
+++ b/components/libc/compilers/common/SConscript
@@ -2,11 +2,18 @@ from building import *
Import('rtconfig')
-src = Glob('*.c')
+src = []
cwd = GetCurrentDir()
group = []
CPPPATH = [cwd]
-group = DefineGroup('libc', src, depend = ['RT_USING_LIBC'], CPPPATH = CPPPATH)
+if GetDepend('RT_USING_LIBC'):
+ src += Glob('*.c')
+else:
+ if GetDepend('RT_LIBC_USING_TIME'):
+ src += ['time.c']
+
+if (rtconfig.PLATFORM == 'armcc' or rtconfig.PLATFORM == 'iar') and rtconfig.ARCH != 'sim' :
+ group = DefineGroup('libc', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
diff --git a/components/libc/compilers/common/gmtime_r.c b/components/libc/compilers/common/gmtime_r.c
deleted file mode 100644
index dff251ab6c..0000000000
--- a/components/libc/compilers/common/gmtime_r.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2018-10-26 zylx first version
- */
-
-#if defined(__CC_ARM) || defined(__CLANG_ARM) || defined (__IAR_SYSTEMS_ICC__)
-#include <sys/time.h>
-
-/* seconds per day */
-#define SPD 24*60*60
-
-/* days per month -- nonleap! */
-const short __spm[13] =
-{
- 0,
- (31),
- (31 + 28),
- (31 + 28 + 31),
- (31 + 28 + 31 + 30),
- (31 + 28 + 31 + 30 + 31),
- (31 + 28 + 31 + 30 + 31 + 30),
- (31 + 28 + 31 + 30 + 31 + 30 + 31),
- (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31),
- (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30),
- (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31),
- (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30),
- (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31),
-};
-
-int __isleap(int year)
-{
- /* every fourth year is a leap year except for century years that are
- * not divisible by 400. */
- /* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */
- return (!(year % 4) && ((year % 100) || !(year % 400)));
-}
-
-/**
- * This function will convert Time (Restartable)
- *
- * @param timep the timestamp
- * @param the structure to stores information
- *
- * @return the structure to stores information
- *
- */
-struct tm *gmtime_r(const time_t *timep, struct tm *r)
-{
- time_t i;
- register time_t work = *timep % (SPD);
- r->tm_sec = work % 60;
- work /= 60;
- r->tm_min = work % 60;
- r->tm_hour = work / 60;
- work = *timep / (SPD);
- r->tm_wday = (4 + work) % 7;
- for (i = 1970;; ++i)
- {
- register time_t k = __isleap(i) ? 366 : 365;
- if (work >= k)
- work -= k;
- else
- break;
- }
- r->tm_year = i - 1900;
- r->tm_yday = work;
-
- r->tm_mday = 1;
- if (__isleap(i) && (work > 58))
- {
- if (work == 59)
- r->tm_mday = 2; /* 29.2. */
- work -= 1;
- }
-
- for (i = 11; i && (__spm[i] > work); --i)
- ;
- r->tm_mon = i;
- r->tm_mday += work - __spm[i];
- return r;
-}
-#endif /* end of __CC_ARM or __CLANG_ARM or __IAR_SYSTEMS_ICC__ */
-
diff --git a/components/libc/compilers/dlib/sys/time.h b/components/libc/compilers/common/sys/time.h
index baf566936b..1d68eeafa3 100644
--- a/components/libc/compilers/dlib/sys/time.h
+++ b/components/libc/compilers/common/sys/time.h
@@ -10,7 +10,6 @@
#define _SYS_TIME_H_
#include <time.h>
-#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
diff --git a/components/libc/compilers/common/time.c b/components/libc/compilers/common/time.c
new file mode 100644
index 0000000000..50a800b259
--- /dev/null
+++ b/components/libc/compilers/common/time.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-08-21 zhangjun copy from minilibc
+ */
+
+#include <sys/time.h>
+#include <rtthread.h>
+
+#if !defined (__IAR_SYSTEMS_ICC__)
+
+/* days per month -- nonleap! */
+const short __spm[13] =
+{
+ 0,
+ (31),
+ (31 + 28),
+ (31 + 28 + 31),
+ (31 + 28 + 31 + 30),
+ (31 + 28 + 31 + 30 + 31),
+ (31 + 28 + 31 + 30 + 31 + 30),
+ (31 + 28 + 31 + 30 + 31 + 30 + 31),
+ (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31),
+ (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30),
+ (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31),
+ (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30),
+ (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31),
+};
+static const char days[] = "Sun Mon Tue Wed Thu Fri Sat ";
+static const char months[] = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ";
+
+/* seconds per day */
+#define SPD 24*60*60
+
+int __isleap(int year)
+{
+ /* every fourth year is a leap year except for century years that are
+ * not divisible by 400. */
+ /* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */
+ return (!(year % 4) && ((year % 100) || !(year % 400)));
+}
+
+struct tm *gmtime_r(const time_t *timep, struct tm *r)
+{
+ time_t i;
+ register time_t work = *timep % (SPD);
+ r->tm_sec = work % 60;
+ work /= 60;
+ r->tm_min = work % 60;
+ r->tm_hour = work / 60;
+ work = *timep / (SPD);
+ r->tm_wday = (4 + work) % 7;
+ for (i = 1970;; ++i)
+ {
+ register time_t k = __isleap(i) ? 366 : 365;
+ if (work >= k)
+ work -= k;
+ else
+ break;
+ }
+ r->tm_year = i - 1900;
+ r->tm_yday = work;
+
+ r->tm_mday = 1;
+ if (__isleap(i) && (work > 58))
+ {
+ if (work == 59)
+ r->tm_mday = 2; /* 29.2. */
+ work -= 1;
+ }
+
+ for (i = 11; i && (__spm[i] > work); --i)
+ ;
+ r->tm_mon = i;
+ r->tm_mday += work - __spm[i];
+ return r;
+}
+
+struct tm* gmtime(const time_t* t)
+{
+ static struct tm tmp;
+ return gmtime_r(t, &tmp);
+}
+
+/*TODO timezone is not supprt now */
+struct tm* localtime_r(const time_t* t, struct tm* r)
+{
+ return gmtime_r(t, r);
+}
+
+struct tm* localtime(const time_t* t)
+{
+ static struct tm tmp;
+ return localtime_r(t, &tmp);
+}
+
+time_t mktime(struct tm * const t)
+{
+ register time_t day;
+ register time_t i;
+ register time_t years = t->tm_year - 70;
+
+ if (t->tm_sec > 60)
+ {
+ t->tm_min += t->tm_sec / 60;
+ t->tm_sec %= 60;
+ }
+ if (t->tm_min > 60)
+ {
+ t->tm_hour += t->tm_min / 60;
+ t->tm_min %= 60;
+ }
+ if (t->tm_hour > 24)
+ {
+ t->tm_mday += t->tm_hour / 24;
+ t->tm_hour %= 24;
+ }
+ if (t->tm_mon > 12)
+ {
+ t->tm_year += t->tm_mon / 12;
+ t->tm_mon %= 12;
+ }
+ while (t->tm_mday > __spm[1 + t->tm_mon])
+ {
+ if (t->tm_mon == 1 && __isleap(t->tm_year + 1900))
+ {
+ --t->tm_mday;
+ }
+ t->tm_mday -= __spm[t->tm_mon];
+ ++t->tm_mon;
+ if (t->tm_mon > 11)
+ {
+ t->tm_mon = 0;
+ ++t->tm_year;
+ }
+ }
+
+ if (t->tm_year < 70)
+ return (time_t) - 1;
+
+ /* Days since 1970 is 365 * number of years + number of leap years since 1970 */
+ day = years * 365 + (years + 1) / 4;
+
+ /* After 2100 we have to substract 3 leap years for every 400 years
+ This is not intuitive. Most mktime implementations do not support
+ dates after 2059, anyway, so we might leave this out for it's
+ bloat. */
+ if (years >= 131)
+ {
+ years -= 131;
+ years /= 100;
+ day -= (years >> 2) * 3 + 1;
+ if ((years &= 3) == 3)
+ years--;
+ day -= years;
+ }
+
+ day += t->tm_yday = __spm[t->tm_mon] + t->tm_mday - 1 +
+ (__isleap(t->tm_year + 1900) & (t->tm_mon > 1));
+
+ /* day is now the number of days since 'Jan 1 1970' */
+ i = 7;
+ t->tm_wday = (day + 4) % i; /* Sunday=0, Monday=1, ..., Saturday=6 */
+
+ i = 24;
+ day *= i;
+ i = 60;
+ return ((day + t->tm_hour) * i + t->tm_min) * i + t->tm_sec;
+}
+
+static void num2str(char *c, int i)
+{
+ c[0] = i / 10 + '0';
+ c[1] = i % 10 + '0';
+}
+
+char* asctime_r(const struct tm *t, char *buf)
+{
+ /* "Wed Jun 30 21:49:08 1993\n" */
+ *(int*) buf = *(int*) (days + (t->tm_wday << 2));
+ *(int*) (buf + 4) = *(int*) (months + (t->tm_mon << 2));
+ num2str(buf + 8, t->tm_mday);
+ if (buf[8] == '0')
+ buf[8] = ' ';
+ buf[10] = ' ';
+ num2str(buf + 11, t->tm_hour);
+ buf[13] = ':';
+ num2str(buf + 14, t->tm_min);
+ buf[16] = ':';
+ num2str(buf + 17, t->tm_sec);
+ buf[19] = ' ';
+ num2str(buf + 20, (t->tm_year + 1900) / 100);
+ num2str(buf + 22, (t->tm_year + 1900) % 100);
+ buf[24] = '\n';
+ return buf;
+}
+
+char* asctime(const struct tm *timeptr)
+{
+ static char buf[25];
+ return asctime_r(timeptr, buf);
+}
+
+char* ctime(const time_t *timep)
+{
+ return asctime(localtime(timep));
+}
+
+#endif /* __IAR_SYSTEMS_ICC__ */
+
+int gettimeofday(struct timeval *tp, void *ignore)
+{
+ time_t time = 0;
+#ifdef RT_USING_DEVICE
+ rt_device_t device;
+ device = rt_device_find("rtc");
+ RT_ASSERT(device != RT_NULL);
+ rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time);
+ if (tp != RT_NULL)
+ {
+ tp->tv_sec = time;
+ tp->tv_usec = 0;
+ }
+#else
+ tv->tv_sec = 0;
+ tv->tv_usec = 0;
+#endif
+
+ return time;
+}
+
+
+/**
+ * Returns the current time.
+ *
+ * @param time_t * t the timestamp pointer, if not used, keep NULL.
+ *
+ * @return time_t return timestamp current.
+ *
+ */
+/* for IAR 6.2 later Compiler */
+#if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000
+#pragma module_name = "?time"
+#if _DLIB_TIME_USES_64
+time_t __time64(time_t *t)
+#else
+time_t __time32(time_t *t)
+#endif
+#else
+time_t time(time_t *t)
+#endif
+{
+ time_t time_now = 0;
+
+#ifdef RT_USING_RTC
+ static rt_device_t device = RT_NULL;
+
+ /* optimization: find rtc device only first. */
+ if (device == RT_NULL)
+ {
+ device = rt_device_find("rtc");
+ }
+
+ /* read timestamp from RTC device. */
+ if (device != RT_NULL)
+ {
+ if (rt_device_open(device, 0) == RT_EOK)
+ {
+ rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now);
+ rt_device_close(device);
+ }
+ }
+#endif /* RT_USING_RTC */
+
+ /* if t is not NULL, write timestamp to *t */
+ if (t != RT_NULL)
+ {
+ *t = time_now;
+ }
+
+ return time_now;
+}
+
+RT_WEAK clock_t clock(void)
+{
+ return rt_tick_get();
+}
diff --git a/components/libc/compilers/dlib/libc.h b/components/libc/compilers/dlib/libc.h
index 7b2665c32b..5b46bee0c8 100644
--- a/components/libc/compilers/dlib/libc.h
+++ b/components/libc/compilers/dlib/libc.h
@@ -13,11 +13,17 @@
#include <stddef.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
int libc_system_init(void);
int libc_stdio_set_console(const char* device_name, int mode);
int libc_stdio_get_console(void);
-int libc_stdio_read (void *buffer, size_t size);
-int libc_stdio_write(const void *buffer, size_t size);
+int libc_stdio_read(void* buffer, size_t size);
+int libc_stdio_write(const void* buffer, size_t size);
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/components/libc/compilers/dlib/sys/errno.h b/components/libc/compilers/dlib/sys/errno.h
new file mode 100644
index 0000000000..1ad4c8acc0
--- /dev/null
+++ b/components/libc/compilers/dlib/sys/errno.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-07-08 Bernard The first version
+ */
+
+#ifndef SYS_ERRNO_H__
+#define SYS_ERRNO_H__
+
+#include <errno.h>
+
+#endif
diff --git a/components/libc/compilers/dlib/sys/signal.h b/components/libc/compilers/dlib/sys/signal.h
new file mode 100644
index 0000000000..22adb1228b
--- /dev/null
+++ b/components/libc/compilers/dlib/sys/signal.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-07-08 Bernard The first version
+ */
+
+#ifndef SYS_SIGNAL_H__
+#define SYS_SIGNAL_H__
+
+#include <libc/libc_signal.h>
+
+#endif
diff --git a/components/libc/compilers/dlib/sys/types.h b/components/libc/compilers/dlib/sys/types.h
index 4c76dfc429..001ace4dd2 100644
--- a/components/libc/compilers/dlib/sys/types.h
+++ b/components/libc/compilers/dlib/sys/types.h
@@ -15,6 +15,10 @@
typedef rt_int32_t clockid_t;
typedef rt_int32_t key_t; /* Used for interprocess communication. */
typedef rt_int32_t pid_t; /* Used for process IDs and process group IDs. */
-typedef signed long ssize_t; /* Used for a count of bytes or an error indication. */
+#ifndef ARCH_CPU_64BIT
+typedef signed int ssize_t; /* Used for a count of bytes or an error indication. */
+#else
+typedef long signed int ssize_t; /* Used for a count of bytes or an error indication. */
+#endif
#endif
diff --git a/components/libc/compilers/dlib/sys/unistd.h b/components/libc/compilers/dlib/sys/unistd.h
index 5985a42996..29f68f24f8 100644
--- a/components/libc/compilers/dlib/sys/unistd.h
+++ b/components/libc/compilers/dlib/sys/unistd.h
@@ -34,14 +34,6 @@
#define _FNDELAY _FNONBLOCK /* non blocking I/O (4.2 style) */
#define _FNOCTTY 0x8000 /* don't assign a ctty on this open */
-#define O_RDONLY 0 /* +1 == FREAD */
-#define O_WRONLY 1 /* +1 == FWRITE */
-#define O_RDWR 2 /* +1 == FREAD|FWRITE */
-#define O_APPEND _FAPPEND
-#define O_CREAT _FCREAT
-#define O_TRUNC _FTRUNC
-#define O_EXCL _FEXCL
-#define O_SYNC _FSYNC
#endif
#endif /* _SYS_UNISTD_H */
diff --git a/components/libc/compilers/dlib/time.c b/components/libc/compilers/dlib/time.c
deleted file mode 100644
index df35313b0e..0000000000
--- a/components/libc/compilers/dlib/time.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- */
-#include <sys/time.h>
-#include <rtthread.h>
-
-#ifdef RT_USING_DEVICE
-int gettimeofday(struct timeval *tp, void *ignore)
-{
- time_t time;
- rt_device_t device;
-
- device = rt_device_find("rtc");
- RT_ASSERT(device != RT_NULL);
-
- rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time);
- if (tp != RT_NULL)
- {
- tp->tv_sec = time;
- tp->tv_usec = 0;
- }
-
- return time;
-}
-#endif
-
-/**
- * Returns the current time.
- *
- * @param time_t * t the timestamp pointer, if not used, keep NULL.
- *
- * @return time_t return timestamp current.
- *
- */
-#pragma module_name = "?time"
-#if _DLIB_TIME_USES_64
-time_t __time64(time_t *t)
-#else
-/* for IAR 6.2 later Compiler */
-#if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000
-time_t __time32(time_t *t)
-#else
-time_t time(time_t *t)
-#endif
-#endif
-{
- time_t time_now = 0;
-
-#ifdef RT_USING_RTC
- static rt_device_t device = RT_NULL;
-
- /* optimization: find rtc device only first. */
- if (device == RT_NULL)
- {
- device = rt_device_find("rtc");
- }
-
- /* read timestamp from RTC device. */
- if (device != RT_NULL)
- {
- if (rt_device_open(device, 0) == RT_EOK)
- {
- rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now);
- rt_device_close(device);
- }
- }
-#endif /* RT_USING_RTC */
-
- /* if t is not NULL, write timestamp to *t */
- if (t != RT_NULL)
- {
- *t = time_now;
- }
-
- return time_now;
-}
-
-RT_WEAK clock_t clock(void)
-{
- return rt_tick_get();
-}
diff --git a/components/libc/compilers/minilibc/math.h b/components/libc/compilers/minilibc/math.h
index 9ddb9c859b..49b80d8219 100644
--- a/components/libc/compilers/minilibc/math.h
+++ b/components/libc/compilers/minilibc/math.h
@@ -14,4 +14,7 @@
double sin(double x);
double cos(double x);
+typedef float float_t;
+typedef double double_t;
+
#endif
diff --git a/components/libc/compilers/minilibc/sys/types.h b/components/libc/compilers/minilibc/sys/types.h
index 460baab623..d3abc6bb38 100644
--- a/components/libc/compilers/minilibc/sys/types.h
+++ b/components/libc/compilers/minilibc/sys/types.h
@@ -11,8 +11,14 @@
#include <rtconfig.h>
typedef long off_t;
-typedef unsigned long size_t;
-typedef signed long ssize_t; /* Used for a count of bytes or an error indication. */
+
+#ifndef ARCH_CPU_64BIT
+typedef unsigned int size_t;
+typedef signed int ssize_t; /* Used for a count of bytes or an error indication. */
+#else
+typedef long unsigned int size_t;
+typedef long signed int ssize_t; /* Used for a count of bytes or an error indication. */
+#endif
typedef unsigned char u_char;
typedef unsigned short u_short;
diff --git a/components/libc/compilers/newlib/libc.h b/components/libc/compilers/newlib/libc.h
index ab9334fe26..fdf2ab4f60 100644
--- a/components/libc/compilers/newlib/libc.h
+++ b/components/libc/compilers/newlib/libc.h
@@ -27,13 +27,19 @@
#define MICROSECOND_PER_TICK (MICROSECOND_PER_SECOND / RT_TICK_PER_SECOND)
#define NANOSECOND_PER_TICK (NANOSECOND_PER_SECOND / RT_TICK_PER_SECOND)
+#ifdef __cplusplus
+extern "C" {
+#endif
int libc_system_init(void);
int libc_stdio_set_console(const char* device_name, int mode);
int libc_stdio_get_console(void);
/* some time related function */
-int libc_set_time(const struct timespec *time);
-int libc_get_time(struct timespec *time);
-int libc_time_to_tick(const struct timespec *time);
+int libc_set_time(const struct timespec* time);
+int libc_get_time(struct timespec* time);
+int libc_time_to_tick(const struct timespec* time);
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/components/libc/compilers/newlib/syscalls.c b/components/libc/compilers/newlib/syscalls.c
index 9919e11727..59c1881ad1 100644
--- a/components/libc/compilers/newlib/syscalls.c
+++ b/components/libc/compilers/newlib/syscalls.c
@@ -442,3 +442,18 @@ void abort(void)
while (1);
}
+
+uid_t getuid(void)
+{
+ return 0;
+}
+
+mode_t umask(mode_t mask)
+{
+ return 022;
+}
+
+int flock(int fd, int operation)
+{
+ return 0;
+}
diff --git a/components/libc/pthreads/pthread.c b/components/libc/pthreads/pthread.c
index 7ecf304038..5d3bc0796a 100644
--- a/components/libc/pthreads/pthread.c
+++ b/components/libc/pthreads/pthread.c
@@ -102,7 +102,7 @@ void _pthread_data_destroy(pthread_t pth)
rt_sem_delete(ptd->joinable_sem);
/* release thread resource */
- if (ptd->attr.stackaddr == RT_NULL)
+ if (ptd->attr.stackaddr == RT_NULL && ptd->tid->stack_addr != RT_NULL)
{
/* release thread allocated stack */
rt_free(ptd->tid->stack_addr);
@@ -219,20 +219,6 @@ int pthread_create(pthread_t *pid,
}
rt_snprintf(name, sizeof(name), "pth%02d", pthread_number ++);
- if (ptd->attr.stackaddr == 0)
- {
- stack = (void *)rt_malloc(ptd->attr.stacksize);
- }
- else
- {
- stack = (void *)(ptd->attr.stackaddr);
- }
-
- if (stack == RT_NULL)
- {
- ret = ENOMEM;
- goto __exit;
- }
/* pthread is a static thread object */
ptd->tid = (rt_thread_t) rt_malloc(sizeof(struct rt_thread));
@@ -241,6 +227,7 @@ int pthread_create(pthread_t *pid,
ret = ENOMEM;
goto __exit;
}
+ memset(ptd->tid, 0, sizeof(struct rt_thread));
if (ptd->attr.detachstate == PTHREAD_CREATE_JOINABLE)
{
@@ -260,6 +247,22 @@ int pthread_create(pthread_t *pid,
ptd->thread_entry = start;
ptd->thread_parameter = parameter;
+ /* stack */
+ if (ptd->attr.stackaddr == 0)
+ {
+ stack = (void *)rt_malloc(ptd->attr.stacksize);
+ }
+ else
+ {
+ stack = (void *)(ptd->attr.stackaddr);
+ }
+
+ if (stack == RT_NULL)
+ {
+ ret = ENOMEM;
+ goto __exit;
+ }
+
/* initial this pthread to system */
if (rt_thread_init(ptd->tid, name, pthread_entry_stub, ptd,
stack, ptd->attr.stacksize,
diff --git a/components/net/Kconfig b/components/net/Kconfig
index 68737176ed..4436934f09 100644
--- a/components/net/Kconfig
+++ b/components/net/Kconfig
@@ -1,18 +1,17 @@
menu "Network"
menu "Socket abstraction layer"
-
+
config RT_USING_SAL
bool "Enable socket abstraction layer"
select RT_USING_NETDEV
- select RT_USING_LIBC
select RT_USING_SYSTEM_WORKQUEUE
default n
if RT_USING_SAL
if RT_USING_LWIP || AT_USING_SOCKET
-
+
menu "protocol stack implement"
config SAL_USING_LWIP
@@ -24,29 +23,30 @@ config RT_USING_SAL
bool "Support AT Commands stack"
default y
depends on AT_USING_SOCKET
-
+
config SAL_USING_TLS
bool "Support MbedTLS protocol"
default y
depends on PKG_USING_MBEDTLS
endmenu
-
+
endif
config SAL_USING_POSIX
bool "Enable BSD socket operated by file system API"
default n
select RT_USING_DFS
+ select RT_USING_LIBC
select RT_USING_POSIX
help
Let BSD socket operated by file system API, such as read/write and involveed in select/poll POSIX APIs.
-
+
if !SAL_USING_POSIX
-
+
config SAL_SOCKETS_NUM
int "the maximum number of sockets"
default 16
-
+
endif
endif
@@ -68,7 +68,7 @@ config RT_USING_NETDEV
config NETDEV_USING_PING
bool "Enable ping features"
default y
-
+
config NETDEV_USING_NETSTAT
bool "Enable netstat features"
default y
@@ -76,6 +76,25 @@ config RT_USING_NETDEV
config NETDEV_USING_AUTO_DEFAULT
bool "Enable default netdev automatic change features"
default y
+
+ config NETDEV_USING_IPV6
+ bool "Enable IPV6 protocol support"
+ default n
+
+ config NETDEV_IPV4
+ int
+ default 1
+
+ config NETDEV_IPV6
+ int
+ default 1 if NETDEV_USING_IPV6
+ default 0 if !NETDEV_USING_IPV6
+
+ config NETDEV_IPV6_SCOPES
+ bool
+ help
+ Defined to synchronize the ip6_addr structure state
+ default n
endif
endmenu
@@ -104,11 +123,11 @@ config RT_USING_LWIP
endchoice
if (RT_USING_LWIP210 || RT_USING_LWIP202)
- if (!RT_USING_NETDEV || (RT_USING_NETDEV && NETDEV_IPV6))
- config RT_USING_LWIP_IPV6
- bool "IPV6 protocol"
- default n
- endif
+ config RT_USING_LWIP_IPV6
+ bool "IPV6 protocol"
+ default n
+ select NETDEV_USING_IPV6
+ select NETDEV_IPV6_SCOPES if RT_USING_LWIP210
endif
config RT_LWIP_IGMP
@@ -258,7 +277,7 @@ config RT_USING_LWIP
config LWIP_NETIF_STATUS_CALLBACK
int "Enable netif status callback"
default 1
-
+
config LWIP_NETIF_LINK_CALLBACK
int "Enable netif link status callback"
default 1
@@ -295,7 +314,7 @@ config RT_USING_LWIP
config RT_LWIP_USING_HW_CHECKSUM
bool "Enable hardware checksum"
default n
-
+
config RT_LWIP_USING_PING
bool "Enable ping features"
default y
@@ -427,8 +446,6 @@ config RT_USING_LWIP
endmenu
-source "$RTT_DIR/components/net/freemodbus/Kconfig"
-
source "$RTT_DIR/components/net/at/Kconfig"
if RT_USING_LWIP
diff --git a/components/net/at/Kconfig b/components/net/at/Kconfig
index 5a4a644761..50de005545 100644
--- a/components/net/at/Kconfig
+++ b/components/net/at/Kconfig
@@ -9,11 +9,11 @@ if RT_USING_AT
config AT_DEBUG
bool "Enable debug log output"
default n
-
+
config AT_USING_SERVER
bool "Enable AT commands server"
default n
-
+
if AT_USING_SERVER
config AT_SERVER_DEVICE
@@ -44,33 +44,32 @@ if RT_USING_AT
endchoice
endif
-
+
config AT_USING_CLIENT
bool "Enable AT commands client"
default n
-
+
if AT_USING_CLIENT
config AT_CLIENT_NUM_MAX
int "The maximum number of supported clients"
default 1
range 1 65535
-
+
config AT_USING_SOCKET
bool "Enable BSD Socket API support by AT commnads"
- select RT_USING_LIBC
select RT_USING_SAL
default n
-
+
endif
if AT_USING_SERVER || AT_USING_CLIENT
-
+
config AT_USING_CLI
bool "Enable CLI(Command-Line Interface) for AT commands"
default y
depends on FINSH_USING_MSH
-
+
config AT_PRINT_RAW_CMD
bool "Enable print RAW format AT command communication data"
default n
@@ -78,7 +77,7 @@ if RT_USING_AT
config AT_CMD_MAX_LEN
int "The maximum lenght of AT Commonds buffer"
default 128
-
+
endif
config AT_SW_VERSION_NUM
diff --git a/components/net/at/at_socket/at_socket.c b/components/net/at/at_socket/at_socket.c
index 993ec33506..11be4e23c0 100644
--- a/components/net/at/at_socket/at_socket.c
+++ b/components/net/at/at_socket/at_socket.c
@@ -54,7 +54,6 @@ static rt_slist_t _socket_list = RT_SLIST_OBJECT_INIT(_socket_list);
struct at_socket *at_get_socket(int socket)
{
rt_base_t level;
- size_t list_num = 0;
rt_slist_t *node = RT_NULL;
struct at_socket *at_sock = RT_NULL;
@@ -62,9 +61,9 @@ struct at_socket *at_get_socket(int socket)
rt_slist_for_each(node, &_socket_list)
{
- if (socket == (list_num++))
+ at_sock = rt_slist_entry(node, struct at_socket, list);
+ if (socket == at_sock->socket)
{
- at_sock = rt_slist_entry(node, struct at_socket, list);
if (at_sock && at_sock->magic == AT_SOCKET_MAGIC)
{
rt_hw_interrupt_enable(level);
@@ -275,6 +274,34 @@ static void at_do_event_clean(struct at_socket *sock, at_event_t event)
}
}
+static int alloc_empty_socket(rt_slist_t *l)
+{
+ rt_base_t level;
+ rt_slist_t *node = RT_NULL;
+ rt_slist_t *pre_node = &_socket_list;
+ struct at_socket *at_sock = RT_NULL;
+ int idx = 0;
+
+ level = rt_hw_interrupt_disable();
+
+ rt_slist_init(l);
+
+ rt_slist_for_each(node, &_socket_list)
+ {
+ at_sock = rt_slist_entry(node, struct at_socket, list);
+ if(at_sock->socket != idx)
+ break;
+ idx++;
+ pre_node = node;
+ }
+
+ rt_slist_insert(pre_node, l);
+
+ rt_hw_interrupt_enable(level);
+
+ return idx;
+}
+
static struct at_socket *alloc_socket_by_device(struct at_device *device)
{
static rt_mutex_t at_slock = RT_NULL;
@@ -304,21 +331,9 @@ static struct at_socket *alloc_socket_by_device(struct at_device *device)
goto __err;
}
- /* add device socket to global socket list */
- {
- rt_base_t level;
-
- level = rt_hw_interrupt_disable();
-
- rt_slist_init(&(device->sockets[idx].list));
- rt_slist_append(&_socket_list, &(device->sockets[idx].list));
-
- rt_hw_interrupt_enable(level);
- }
-
sock = &(device->sockets[idx]);
/* the socket descriptor is the number of sockte lists */
- sock->socket = rt_slist_len(&_socket_list) - 1;
+ sock->socket = alloc_empty_socket(&(sock->list));
/* the socket operations is the specify operations of the device */
sock->ops = device->class->socket_ops;
/* the user-data is the at device socket descriptor */
@@ -446,7 +461,6 @@ static int free_socket(struct at_socket *sock)
/* delect socket from socket list */
{
rt_base_t level;
- int list_num = 0;
rt_slist_t *node = RT_NULL;
struct at_socket *at_sock = RT_NULL;
@@ -454,10 +468,10 @@ static int free_socket(struct at_socket *sock)
rt_slist_for_each(node, &_socket_list)
{
- if (sock->socket == (list_num++))
+ at_sock = rt_slist_entry(node, struct at_socket, list);
+ if (sock->socket == at_sock->socket)
{
- at_sock = rt_slist_entry(node, struct at_socket, list);
- if (at_sock)
+ if (at_sock && at_sock->magic == AT_SOCKET_MAGIC)
{
rt_slist_remove(&_socket_list, &at_sock->list);
break;
@@ -540,11 +554,12 @@ static int socketaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t
const struct sockaddr_in* sin = (const struct sockaddr_in*) (const void *) sockaddr;
#if NETDEV_IPV4 && NETDEV_IPV6
- (*addr).u_addr.ip4.addr = sin->sin_addr.s_addr;
+ addr->u_addr.ip4.addr = sin->sin_addr.s_addr;
+ addr->type = IPADDR_TYPE_V4;
#elif NETDEV_IPV4
- (*addr).addr = sin->sin_addr.s_addr;
+ addr->addr = sin->sin_addr.s_addr;
#elif NETDEV_IPV6
- LOG_E("not support IPV6.");
+#error "not support IPV6."
#endif /* NETDEV_IPV4 && NETDEV_IPV6 */
*port = (uint16_t) HTONS_PORT(sin->sin_port);
@@ -855,7 +870,7 @@ int at_recv(int s, void *mem, size_t len, int flags)
int at_sendto(int socket, const void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)
{
struct at_socket *sock = RT_NULL;
- int len, result = 0;
+ int len = 0, result = 0;
if (data == RT_NULL || size == 0)
{
@@ -1126,10 +1141,11 @@ struct hostent *at_gethostbyname(const char *name)
#if NETDEV_IPV4 && NETDEV_IPV6
addr.u_addr.ip4.addr = ipstr_to_u32(ipstr);
+ addr.type = IPADDR_TYPE_V4;
#elif NETDEV_IPV4
addr.addr = ipstr_to_u32(ipstr);
#elif NETDEV_IPV6
- LOG_E("not support IPV6.");
+#error "not support IPV6."
#endif /* NETDEV_IPV4 && NETDEV_IPV6 */
/* fill hostent structure */
@@ -1202,7 +1218,7 @@ int at_getaddrinfo(const char *nodename, const char *servname,
if ((hints != RT_NULL) && (hints->ai_flags & AI_NUMERICHOST))
{
/* no DNS lookup, just parse for an address string */
- if (!inet_aton(nodename, (ip4_addr_t * )&addr))
+ if (!inet_aton(nodename, &addr))
{
return EAI_NONAME;
}
@@ -1240,7 +1256,7 @@ int at_getaddrinfo(const char *nodename, const char *servname,
#elif NETDEV_IPV4
addr.addr = ipstr_to_u32(ip_str);
#elif NETDEV_IPV6
- LOG_E("not support IPV6.");
+ #error "not support IPV6."
#endif /* NETDEV_IPV4 && NETDEV_IPV6 */
}
}
@@ -1275,10 +1291,11 @@ int at_getaddrinfo(const char *nodename, const char *servname,
/* set up sockaddr */
#if NETDEV_IPV4 && NETDEV_IPV6
sa4->sin_addr.s_addr = addr.u_addr.ip4.addr;
+ sa4->type = IPADDR_TYPE_V4;
#elif NETDEV_IPV4
sa4->sin_addr.s_addr = addr.addr;
#elif NETDEV_IPV6
- LOG_E("not support IPV6.");
+#error "not support IPV6."
#endif /* NETDEV_IPV4 && NETDEV_IPV6 */
sa4->sin_family = AF_INET;
sa4->sin_len = sizeof(struct sockaddr_in);
diff --git a/components/net/at/include/at.h b/components/net/at/include/at.h
index dc2abef353..a7a6aeca7a 100644
--- a/components/net/at/include/at.h
+++ b/components/net/at/include/at.h
@@ -96,7 +96,7 @@ struct at_server
rt_device_t device;
at_status_t status;
- char (*get_char)(void);
+ rt_err_t (*get_char)(struct at_server *server, char *ch, rt_int32_t timeout);
rt_bool_t echo_mode;
char recv_buffer[AT_SERVER_RECV_BUFF_LEN];
@@ -194,6 +194,8 @@ int at_server_init(void);
void at_server_printf(const char *format, ...);
void at_server_printfln(const char *format, ...);
void at_server_print_result(at_result_t result);
+rt_size_t at_server_send(at_server_t server, const char *buf, rt_size_t size);
+rt_size_t at_server_recv(at_server_t server, char *buf, rt_size_t size, rt_int32_t timeout);
/* AT server request arguments parse */
int at_req_parse_args(const char *req_args, const char *req_expr, ...);
diff --git a/components/net/at/src/at_cli.c b/components/net/at/src/at_cli.c
index 80af613fa6..e39a913357 100644
--- a/components/net/at/src/at_cli.c
+++ b/components/net/at/src/at_cli.c
@@ -100,6 +100,12 @@ void at_cli_deinit(void)
}
#ifdef AT_USING_SERVER
+static rt_err_t at_server_console_getchar(struct at_server *server, char *ch, rt_int32_t timeout)
+{
+ *ch = console_getchar();
+ return RT_EOK;
+}
+
static void server_cli_parser(void)
{
extern at_server_t at_get_server(void);
@@ -107,7 +113,7 @@ static void server_cli_parser(void)
at_server_t server = at_get_server();
rt_base_t int_lvl;
static rt_device_t device_bak;
- static char (*getchar_bak)(void);
+ static rt_err_t (*getchar_bak)(struct at_server *server, char *ch, rt_int32_t timeout);
static char endmark_back[AT_END_MARK_LEN];
/* backup server device and getchar function */
@@ -122,7 +128,7 @@ static void server_cli_parser(void)
/* setup server device as console device */
server->device = rt_console_get_device();
- server->get_char = console_getchar;
+ server->get_char = at_server_console_getchar;
memset(server->end_mark, 0x00, AT_END_MARK_LEN);
server->end_mark[0] = '\r';
diff --git a/components/net/at/src/at_server.c b/components/net/at/src/at_server.c
index 31f1bec96f..81d00951f5 100644
--- a/components/net/at/src/at_server.c
+++ b/components/net/at/src/at_server.c
@@ -167,6 +167,79 @@ void rt_at_server_print_all_cmd(void)
}
}
+/**
+ * Send data to AT Client by uart device.
+ *
+ * @param server current AT server object
+ * @param buf send data buffer
+ * @param size send fixed data size
+ *
+ * @return >0: send data size
+ * =0: send failed
+ */
+rt_size_t at_server_send(at_server_t server, const char *buf, rt_size_t size)
+{
+ RT_ASSERT(buf);
+
+ if (server == RT_NULL)
+ {
+ LOG_E("input AT Server object is NULL, please create or get AT Server object!");
+ return 0;
+ }
+
+ return rt_device_write(server->device, 0, buf, size);
+}
+
+/**
+ * AT Server receive fixed-length data.
+ *
+ * @param client current AT Server object
+ * @param buf receive data buffer
+ * @param size receive fixed data size
+ * @param timeout receive data timeout (ms)
+ *
+ * @note this function can only be used in execution function of AT commands
+ *
+ * @return >0: receive data size
+ * =0: receive failed
+ */
+rt_size_t at_server_recv(at_server_t server, char *buf, rt_size_t size, rt_int32_t timeout)
+{
+ rt_size_t read_idx = 0;
+ rt_err_t result = RT_EOK;
+ char ch = 0;
+
+ RT_ASSERT(buf);
+
+ if (server == RT_NULL)
+ {
+ LOG_E("input AT Server object is NULL, please create or get AT Server object!");
+ return 0;
+ }
+
+ while (1)
+ {
+ if (read_idx < size)
+ {
+ /* check get data value */
+ result = server->get_char(server, &ch, timeout);
+ if (result != RT_EOK)
+ {
+ LOG_E("AT Server receive failed, uart device get data error.");
+ return 0;
+ }
+
+ buf[read_idx++] = ch;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ return read_idx;
+}
+
at_server_t at_get_server(void)
{
RT_ASSERT(at_server_local);
@@ -339,17 +412,21 @@ static rt_err_t at_cmd_get_name(const char *cmd_buffer, char *cmd_name)
return -RT_ERROR;
}
-static char at_server_gerchar(void)
+static rt_err_t at_server_gerchar(at_server_t server, char *ch, rt_int32_t timeout)
{
- char ch;
+ rt_err_t result = RT_EOK;
- while (rt_device_read(at_server_local->device, 0, &ch, 1) == 0)
+ while (rt_device_read(at_server_local->device, 0, ch, 1) == 0)
{
rt_sem_control(at_server_local->rx_notice, RT_IPC_CMD_RESET, RT_NULL);
- rt_sem_take(at_server_local->rx_notice, RT_WAITING_FOREVER);
+ result = rt_sem_take(at_server_local->rx_notice, rt_tick_from_millisecond(timeout));
+ if (result != RT_EOK)
+ {
+ return result;
+ }
}
- return ch;
+ return result;
}
static void server_parser(at_server_t server)
@@ -365,14 +442,24 @@ static void server_parser(at_server_t server)
RT_ASSERT(server);
RT_ASSERT(server->status != AT_STATUS_UNINITIALIZED);
- while (ESC_KEY != (ch = server->get_char()))
+ while (1)
{
+ server->get_char(server, &ch, RT_WAITING_FOREVER);
+ if (ESC_KEY == ch)
+ {
+ break;
+ }
+
if (server->echo_mode)
{
if (ch == AT_CMD_CR || (ch == AT_CMD_LF && last_ch != AT_CMD_CR))
{
at_server_printf("%c%c", AT_CMD_CR, AT_CMD_LF);
}
+ else if (ch == AT_CMD_LF)
+ {
+ // skip the end sign check
+ }
else if (ch == BACKSPACE_KEY || ch == DELECT_KEY)
{
if (server->cur_recv_len)
diff --git a/components/net/freemodbus/Changelog.txt b/components/net/freemodbus/Changelog.txt
deleted file mode 100644
index 2816ea30f3..0000000000
--- a/components/net/freemodbus/Changelog.txt
+++ /dev/null
@@ -1,329 +0,0 @@
-2013-10-17 (REL_1_6_0) Armink <[email protected]>
- Notes: Added modbus master.
-
-2010-05-06 (REL_1_5_0) Christian Walter <[email protected]>
- Notes: Added support for Atmel AT91SAM3S (Cortex M3) for IAR.
-
- Detailed notes:
- - FEATURES (ATSAM3S) : Added new port.
-
-2007-08-28 (REL_1_4_0) Christian Walter <[email protected]>:
- Notes: Added support for HCS08. Fixed some small bugs in the documentation
- for the porting layer.
-
- Detailed notes:
- - FEATURES (HCS08) : Added new port.
- - BUGS (ALL) : Fixed some small bugs in the porting guide.
-
-2007-07-17 (REL_1_3_0) Christian Walter <[email protected]>:
- Notes: Added ARM7/AT91SAM7X port. Added Linux/TCP port from Steven Guo.
-
- Detailed notes:
- - FEATURES (ARM7): Added ARM7/AT91SAM7x port.
- - FEATURES (LINUX): Added Linux/TCP port from Steven Guo.
- - BUGS (ALL): Fixed bug in <eMBFuncReadInputRegister> where the high
- byte of the register count was ignored. This does not have a
- practical impact because the actual number of registers is always
- lower.
-
-2007-07-17 (REL_1_3_0) Christian Walter <[email protected]>:
- Notes: Added Linux/TCP port. Fixed bug in MSP430 port.
- Detailted notes:
- - FEATURE (LINUX): Added Linux/TCP port.
- - BUGS (MSP430): Fixed bug with calculating the timer value.
-
-2007-04-25 (REL_1_2_0) Christian Walter <[email protected]>:
- Notes: Added LPC214X ARM port with Keil compiler. Added Z8Encore port for
- Z8F6422 microcontroller.
-
- Detailed notes:
- - FEATURE (ARM): Added LPC214X ARM port for Keil ARM 2.41.
- - FEATURE (Z8ENCORE): Added Z8F6422 for Z8Encore using the ZDS II - Z8
- Encore! development tools.
-
-2007-02-18 (REL_1_1_2) Christian Walter <[email protected]>:
- Notes: Fixed typo with the defined defining the supported Modbus
- functions. Fixed bug when illegal slave address was passed to eMBInit
- where the error was not detected. Fixed typo in the holding registers
- where the frame for write multiple registers was parsed with the wrong
- constants. The fix is not critical because the values matched. Fixed bug
- in discrete input registers implementation where the frame was not parsed
- correctly. Added new support for a CodeWarrior Coldfire port.
-
- Detailed notes:
- - BUG (ALL): Modbus functions are compiled into the stack conditionally
- by changing the MB_FUNC_XXX defines to either true(1) or false(0).
- The defines for MB_FUNC_READ_HOLDING and MB_FUNC_WRITE_HOLDING
- were wrong.
- - BUG (ALL): eMBInit did not correctly check for addresses. Therefore
- is was possible to start the Modbus stack with an address of 0
- or one > 247.
- - BUG (ALL): eMBFuncWriteHoldingRegister should use
- MB_PDU_FUNC_WRITE_MUL_ADDR_OFF and not MB_PDU_FUNC_READ_ADDR_OFF.
- - BUG (ALL): eMBFuncReadDiscreteInputs calculated the number of discrete
- registers to read wrong.
- - FEATURE (ALL): Fixed some warnings in the code.
-
-2006-11-19 (REL_1_1_1) Christian Walter <[email protected]>:
- Notes: Fixed bug in Read/Write Multiple Registers function where
- the registers addresses where calculated wrong.
- Fixed bug in RTU and ASCII with the resource allocation in case of
- an error.
- Changed license to BSD style licsense.
-
- Detailed notes:
- - OTHER (ALL): License is now BSD for protocol stack.
- - BUG (ALL): The registers address received in a Modbus frame
- must be converted to application addresses. The code for this
- conversion was missing and therefore has lead to error when
- this function was used (Registers of by one, Start at > 1).
- - BUG (ALL): If the serial initialization within the porting fails
- a timer is still allocated in eMBRTUInit and eMBASCIIInit. This
- can lead to a memory leak depending upon the implementation of the
- porting layer.
- - FEATURE (MCF5235): Added sample shell scripts for testing.
- - FEATURE (MSP430): Added sample shell script for testing and
- changed default values to match the other ports.
-
-2006-10-30 (REL_1_1_0) Christian Walter <[email protected]>:
- Notes: Added support for Read/Write Multiple Registers function
- (0x17). Added some tips to reduce memory requirements.
- Added MSP430 Port for GCC and Rowley Crossworks.
-
- Detailed notes:
- - FEATURE (MSP430): Added new MSP430 port.
- - FEATURE (ALL): Added support for Read/Write Multiple Registers
- function (0x17). The implementation simply makes two callbacks
- to the eMBRegHoldingCB function where first the values are
- written and then the other register values are read.
- - FEATURE (ALL): Added some tips on reducing memory requirements
- with the protocol stack.
-
-2006-10-30 (REL_1_0_5) Christian Walter <[email protected]>:
- Notes: eMBDisable and eMBClose can now be called multiple times
- which makes shutdown of the protocol stack easier.
- Fixed bug in RTU state machine where we switched from the
- error state immediately to the idle state. Correct behaviour
- would be to wait till the end of frame.
- Added new STR71X GCC port which uses only freely available tools
- like GNU ARM, OpenOCD (Wiggler) and GDB.
-
- Detailed notes:
- - FEATURE (STR71X): Added GCC standalone port which does not
- depend on the Rowley Crosswork tools.
- - FEATURE (ALL): eMBDisable can now be called multiple times
- and returns MB_ENOERR in case is was already disabled.
- eMBClose also supports beeing called multiple times in
- which pvMBFrameCloseCur( ) is called when the protocol stack
- is in state STATE_DISABLED.
- - BUG (RTU): Fixed bug in xMBRTUReceiveFSM where the error
- state is immediately left because of a missing break. Instead
- we should wait till the damaged frame is finished.
-
-2006-10-11 (REL_1_0_4) Christian Walter <[email protected]>:
- Notes: Fixed bug when more than 255 coils are requested. Fixed bug in
- Linux/Cygwin port when not all bytes could be written by the first
- call to write. Added support for removing previously registered
- function handlers.
-
- Detailed notes:
- - BUG (ALL): mbfunccoils contained a bug which limited the amount
- of coils to read to 255.
- - BUG (LINUX): prvbMBPortSerialWrite contained a bug in the loop
- which writes the RTU/ASCII frame to the serial file descriptor.
- If not all bytes where written in the first call or write was
- interrupted the sent frame is corrupted.
- - FEATURE (ALL): eMBRegisterCB now supports NULL as handler
- argument in which case a previously registered function
- handler is deregistered from the protocol stack.
-
-2006-09-27 (REL_1_0_3) Christian Walter <[email protected]>:
- Notes: Added new functions to support registering of custom callback
- handlers. This makes it possible to implement new Modbus function
- codes without touching the protocol stack.
- New port for ATMega128 added. Thanks to Richard C Sandoz Jr. for
- the patches.
-
- Detailed notes:
- - FEATURE (ALL): Added support for registering new functions handlers
- with eMBRegisterCB.
- - FEATURE (AVR): Added patches from Richard C Sandoz Jr. for ATMega128
-
-2006-09-06 (REL_1_0_2) Christian Walter <[email protected]>:
- Notes: Fixed bug in FreeRTOS porting layer for STR71X/lwIP target where
- memory is not freed in the sys_arch_thread_remove function.
- Synched MCF5235TCP port with the FreeRTOS/lwIP port for the STR71X.
-
- Detailed notes:
- - BUG (STR71XTCP): Sys_arch_thread_remove did not free the memory from
- the TCB.
- - BUG (STR71XTCP): Unnecessary call to vTaskSuspendAll removed.
- - BUG (STR71XTCP): Bug with counting variable. The first to lwIP tasks
- got the same name (lwIP0).
- - FEATURE (MCF5235TCP): Enhanced functions from the STR71X/lwIP port
- merged into the Coldfire port.
-
-2006-09-04 (REL_1_0_1) Christian Walter <[email protected]>:
- Notes: Fixed bug in serial driver for STR71x target when the ring buffer
- overflows.
-
- Detailed notes:
- - BUG (STR71XTCP): Under high load the ring buffer in the serial driver
- functions might overflow. There was an error with counting the number
- of received characters which corrupted received frames.
- Now receiver correctly recovers in case of dropped bytes.
-
-2006-09-04 (REL_1_0) Christian Walter <[email protected]>:
- Notes: Added support for ATmega8, ATmega16, ATmega32, ATmega169 and
- RS485 drivers in the AVR support. Special thanks to Tran Minh Hoang
- for his contribution.
- Added a new lwIP port for the STR71X target which uses one serial
- interface for a PPP connection. This can be used for remote Modbus/TCP
- devices in combination with a Modem (E.g. GPRS or Analog).
-
- Detailed notes:
- - FEATURES (AVR): Integrated patches from Tran Minh Hoang to support the
- ATmega8, ATmega16, ATmega32, ATmega169 controllers.
- - FEATURES (AVR): Added support for RS485 drivers in the AVR code. The
- example supports the DS76176.
- - FEATURES (STR71XTCP): implemented function in STR71X/lwIP porting layer
- to remove running tasks.
- - FEATURES (STR71XTCP): added new thread creation function in STR71X/lwIP
- porting layer which allows specifing the stack size.
- - BUGS (STR71XTCP): pppOpen defined in ppp.c does not check the return
- value of sys_thread_new. If task creation fails the system crashes.
- - BUGS (STR71XTCP): pppMain must not return - Instead it should remove
- its task from the scheduler.
-
-2006-08-30 (REL_9) Christian Walter <[email protected]>:
- Notes: Added lwIP port for the MCF5235 target. The lwIP part is
- generic and therefore FreeModbus now works on any target with
- lwIP support.
-
- Detailed notes:
- - FEATURES: Incoperated MCF5235 FreeRTOS/lwIP port done by the
- author in this project.
- - FEATURES: Added lwIP port for FreeModbus
- - FEATURES: Added demo application for FreeModbus and lwIP.
-
-2006-08-22 (REL_0_82) Christian Walter <[email protected]>
- Notes: Fixed bug with Modbus ASCII support
-
- Detailed notes:
- - BUG: During the last upgrade an error was introduced in the
- initialization code of Modbus ASCII and therefore ASCII
- support was broken. The bug is fixed now and was tested with
- the Win32 port.
-
-2006-08-22 (REL_0_81) Christian Walter <[email protected]>
- Notes: Added porting guide
-
- Detailed notes:
- - OTHER: Added a new porting guide to the documentation.
- - OTHER: Added a empty example for new ports to the project as a
- starting point.
-
-2006-08-01 (REL_0_8) Christian Walter <[email protected]>
- Notes: Added Linux RTU/ASCII port.
-
- Detailed notes:
- - FEATURES: Added a new Linux RTU/ASCII port. The port should work
- on any Linux distribution and it should be possible to run it
- on uCLinux.
-
-2006-06-26 (REL_0_7) Christian Walter <[email protected]>
- Notes: Changed the WIN32 serial port to better fit into the design.
-
- Detailed notes:
- - OTHER: Design of the WIN32 serial port changed. The polling function
- for the serial device are now called from the event loop.
- - OTHER: Debugging uses the same interface as the WIN32/TCP port.
-
-2006-06-25 Christian Walter <[email protected]>
-
- Notes: Initial work on a Modbus/TCP port is available. The port includes
- an example for a Win32 port which uses the Winsock API.
-
- Detailed notes:
- - FEATURES: added required functions to core protocol stack to support
- a Modbus/TCP implementation.
- - FEATURES: added a Win32 port for the Modbus/TCP core. The port is
- currently limited to one concurrent client.
- - OTHER: The implementation of eMBClose to shutdown the protocol stack
- was changed to unify it with the new Modbus/TCP code.
- -
-
-2006-06-18 Christian Walter <[email protected]>
-
- Detailed notes:
- - OTHER: while working on the Win32 port some line feeds got
- wrong. Also some source files used tabs instead of spaces.
- - OTHER: prototypes for xMBUtilSetBits and xMBUtilGetBits fixed.
- usNBits should be ucNBits by convention.
-
-2006-06-17 Christian Walter <[email protected]>
-
- Notes: Fixed various bugs with the Win32 port
-
- Detailed notes:
- - FEATURES: implement shutdown functionality for protocol stack.
- - FEATURES: protocol stack can be enabled and disabled during runtime.
- - FEATURES: interface functions now do more error checking. For
- example if eMBPool is called in an uninitialized state.
- - FEATURES: extended Win32 demo application to use the new features.
- - BUG: fixed bug in Win32 demo for ASCII mode.
-
-2006-06-16 Christian Walter <[email protected]>
- Notes: The new version includes a new port for the
- Win32 platform
-
- Detailed notes:
- - FEATURES: added Win32 platform
-
-2006-05-14 Christian Walter <[email protected]>
- Notes: The new version includes a new port for the
- Freescale MCF5235 processor.
-
- Detailed notes:
- - FEATURES: added new MCF5235 port.
- - OTHER: fixed some missing code headers.
-
-2006-05-01 Christian Walter <[email protected]>
- Notes: This version removes the t1.5 timers from the Modbus RTU
- implementation because no one actually uses it and the CPU
- load is very high. T
- In addition some documentation cleanups has been done and the
- ARM demo has been updated.
-
- Detailed notes:
-
- - FEATURES: the t1.5 timeout has been removed. Therefore only
- one timer is required.
- - BUG: the ARM demo project missed some files in the project
- workspace and did not compile cleanly
-
-2006-02-28 Christian Walter <[email protected]>
- Notes: This version includes support for two new command
- (write multiple coils, read discrete input)
-
- Detailed notes:
- - BUG: some function used the wrong data types
- - FEATURES: added support for write multiple coils function.
- - FEATURES: added support for read discrete input.
- - OTHER: some code cleanups with lint tool.
-
-2006-02-28 Christian Walter <[email protected]>
-
- Notes: The new version 0.31 adds support for reading and writing the
- coil registers and add some bug fixes.
-
- Detailed notes:
- - BUG: fixed bug with to small modbus requests being ignored.
- - FEATURES: added support for write single coil function.
- - FEATURES: added support for working with byte packed bit fields
- to support coils and discrete inputs better.
- - API: API for set slave id functions changed.
-
-2006-02-26 Christian Walter <[email protected]>
-
- Notes: First public release which includes an ARM and AVR port.
diff --git a/components/net/freemodbus/Kconfig b/components/net/freemodbus/Kconfig
deleted file mode 100644
index 9a84efa0c5..0000000000
--- a/components/net/freemodbus/Kconfig
+++ /dev/null
@@ -1,27 +0,0 @@
-menu "Modbus master and slave stack"
-
-config RT_USING_MODBUS
- bool "Enable Modbus stack"
- default n
-
- if RT_USING_MODBUS
- config RT_MODBUS_MASTER_RTU
- bool "RTU master mode"
- default n
-
- config RT_MODBUS_SLAVE_RTU
- bool "RTU slave mode"
- default n
- if RT_MODBUS_SLAVE_RTU
- config RT_MODBUS_SLAVE_USE_CONTROL_PIN
- bool "Use Contorl Pin"
- default n
- if RT_MODBUS_SLAVE_USE_CONTROL_PIN
- config MODBUS_SLAVE_RT_CONTROL_PIN_INDEX
- int "pin index for RS485 TX/RX select"
- default 10
- endif
- endif
- endif
-
-endmenu
diff --git a/components/net/freemodbus/SConscript b/components/net/freemodbus/SConscript
deleted file mode 100644
index d613a9f398..0000000000
--- a/components/net/freemodbus/SConscript
+++ /dev/null
@@ -1,77 +0,0 @@
-Import('RTT_ROOT')
-from building import *
-
-src = Split("""
-modbus/functions/mbfuncdiag.c
-modbus/functions/mbutils.c
-modbus/functions/mbfuncother.c
-modbus/rtu/mbcrc.c
-port/port.c
-""")
-
-master_rtu_src = Split("""
-modbus/functions/mbfunccoils_m.c
-modbus/functions/mbfuncdisc_m.c
-modbus/functions/mbfuncholding_m.c
-modbus/functions/mbfuncinput_m.c
-modbus/rtu/mbrtu_m.c
-modbus/mb_m.c
-port/portevent_m.c
-port/portserial_m.c
-port/porttimer_m.c
-port/user_mb_app_m.c
-""")
-
-slave_rtu_src = Split("""
-modbus/functions/mbfunccoils.c
-modbus/functions/mbfuncdisc.c
-modbus/functions/mbfuncholding.c
-modbus/functions/mbfuncinput.c
-modbus/rtu/mbrtu.c
-modbus/mb.c
-port/portevent.c
-port/portserial.c
-port/porttimer.c
-port/user_mb_app.c
-""")
-
-master_slave_rtu_src = Split("""
-modbus/functions/mbfunccoils.c
-modbus/functions/mbfunccoils_m.c
-modbus/functions/mbfuncdisc.c
-modbus/functions/mbfuncdisc_m.c
-modbus/functions/mbfuncholding.c
-modbus/functions/mbfuncholding_m.c
-modbus/functions/mbfuncinput.c
-modbus/functions/mbfuncinput_m.c
-modbus/rtu/mbrtu.c
-modbus/rtu/mbrtu_m.c
-modbus/mb.c
-modbus/mb_m.c
-port/portevent.c
-port/portevent_m.c
-port/portserial.c
-port/portserial_m.c
-port/porttimer.c
-port/porttimer_m.c
-port/user_mb_app.c
-port/user_mb_app_m.c
-""")
-
-# The set of source files associated with this SConscript file.
-path = [GetCurrentDir() + '/modbus/include',
- GetCurrentDir() + '/modbus/rtu',
- GetCurrentDir() + '/port']
-
-if GetDepend(['RT_MODBUS_MASTER_RTU']):
- src += master_rtu_src
-
-if GetDepend(['RT_MODBUS_SLAVE_RTU']):
- src += slave_rtu_src
-
-if GetDepend(['RT_MODBUS_MASTER_SLAVE_RTU']):
- src += master_slave_rtu_src
-
-group = DefineGroup('FreeModbus', src, depend = ['RT_USING_MODBUS'], CPPPATH = path)
-
-Return('group')
diff --git a/components/net/freemodbus/bsd.txt b/components/net/freemodbus/bsd.txt
deleted file mode 100644
index 362d3e37c8..0000000000
--- a/components/net/freemodbus/bsd.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2006 Christian Walter <[email protected]>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/components/net/freemodbus/gpl.txt b/components/net/freemodbus/gpl.txt
deleted file mode 100644
index 3912109b5c..0000000000
--- a/components/net/freemodbus/gpl.txt
+++ /dev/null
@@ -1,340 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 51 Franklin St, 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.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, 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 or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-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 give any other recipients of the Program a copy of this License
-along with the Program.
-
-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 Program or any portion
-of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-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 Program, 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 Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) 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; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, 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 executable. However, as a
-special exception, the source code 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.
-
-If distribution of executable or 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 counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program 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.
-
- 5. 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 Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program 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 to
-this License.
-
- 7. 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 Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program 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 Program.
-
-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.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program 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.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the 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 Program
-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 Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, 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
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), 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 Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. 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.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/components/net/freemodbus/lgpl.txt b/components/net/freemodbus/lgpl.txt
deleted file mode 100644
index 8add30ad59..0000000000
--- a/components/net/freemodbus/lgpl.txt
+++ /dev/null
@@ -1,504 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin St, 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.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- 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 St, 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!
-
-
diff --git a/components/net/freemodbus/modbus/ascii/mbascii.c b/components/net/freemodbus/modbus/ascii/mbascii.c
deleted file mode 100644
index b0f3bc05d2..0000000000
--- a/components/net/freemodbus/modbus/ascii/mbascii.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbascii.c,v 1.15 2007/02/18 23:46:48 wolti Exp $
- */
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mbconfig.h"
-#include "mbascii.h"
-#include "mbframe.h"
-
-#include "mbcrc.h"
-#include "mbport.h"
-
-#if MB_SLAVE_ASCII_ENABLED > 0
-
-/* ----------------------- Defines ------------------------------------------*/
-#define MB_ASCII_DEFAULT_CR '\r' /*!< Default CR character for Modbus ASCII. */
-#define MB_ASCII_DEFAULT_LF '\n' /*!< Default LF character for Modbus ASCII. */
-#define MB_SER_PDU_SIZE_MIN 3 /*!< Minimum size of a Modbus ASCII frame. */
-#define MB_SER_PDU_SIZE_MAX 256 /*!< Maximum size of a Modbus ASCII frame. */
-#define MB_SER_PDU_SIZE_LRC 1 /*!< Size of LRC field in PDU. */
-#define MB_SER_PDU_ADDR_OFF 0 /*!< Offset of slave address in Ser-PDU. */
-#define MB_SER_PDU_PDU_OFF 1 /*!< Offset of Modbus-PDU in Ser-PDU. */
-
-/* ----------------------- Type definitions ---------------------------------*/
-typedef enum
-{
- STATE_RX_IDLE, /*!< Receiver is in idle state. */
- STATE_RX_RCV, /*!< Frame is beeing received. */
- STATE_RX_WAIT_EOF /*!< Wait for End of Frame. */
-} eMBRcvState;
-
-typedef enum
-{
- STATE_TX_IDLE, /*!< Transmitter is in idle state. */
- STATE_TX_START, /*!< Starting transmission (':' sent). */
- STATE_TX_DATA, /*!< Sending of data (Address, Data, LRC). */
- STATE_TX_END, /*!< End of transmission. */
- STATE_TX_NOTIFY /*!< Notify sender that the frame has been sent. */
-} eMBSndState;
-
-typedef enum
-{
- BYTE_HIGH_NIBBLE, /*!< Character for high nibble of byte. */
- BYTE_LOW_NIBBLE /*!< Character for low nibble of byte. */
-} eMBBytePos;
-
-/* ----------------------- Static functions ---------------------------------*/
-static UCHAR prvucMBCHAR2BIN( UCHAR ucCharacter );
-
-static UCHAR prvucMBBIN2CHAR( UCHAR ucByte );
-
-static UCHAR prvucMBLRC( UCHAR * pucFrame, USHORT usLen );
-
-/* ----------------------- Static variables ---------------------------------*/
-static volatile eMBSndState eSndState;
-static volatile eMBRcvState eRcvState;
-
-/* We reuse the Modbus RTU buffer because only one buffer is needed and the
- * RTU buffer is bigger. */
-extern volatile UCHAR ucRTUBuf[];
-static volatile UCHAR *ucASCIIBuf = ucRTUBuf;
-
-static volatile USHORT usRcvBufferPos;
-static volatile eMBBytePos eBytePos;
-
-static volatile UCHAR *pucSndBufferCur;
-static volatile USHORT usSndBufferCount;
-
-static volatile UCHAR ucLRC;
-static volatile UCHAR ucMBLFCharacter;
-
-/* ----------------------- Start implementation -----------------------------*/
-eMBErrorCode
-eMBASCIIInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
-{
- eMBErrorCode eStatus = MB_ENOERR;
- ( void )ucSlaveAddress;
-
- ENTER_CRITICAL_SECTION( );
- ucMBLFCharacter = MB_ASCII_DEFAULT_LF;
-
- if( xMBPortSerialInit( ucPort, ulBaudRate, 7, eParity ) != TRUE )
- {
- eStatus = MB_EPORTERR;
- }
- else if( xMBPortTimersInit( MB_ASCII_TIMEOUT_SEC * 20000UL ) != TRUE )
- {
- eStatus = MB_EPORTERR;
- }
-
- EXIT_CRITICAL_SECTION( );
-
- return eStatus;
-}
-
-void
-eMBASCIIStart( void )
-{
- ENTER_CRITICAL_SECTION( );
- vMBPortSerialEnable( TRUE, FALSE );
- eRcvState = STATE_RX_IDLE;
- EXIT_CRITICAL_SECTION( );
-
- /* No special startup required for ASCII. */
- ( void )xMBPortEventPost( EV_READY );
-}
-
-void
-eMBASCIIStop( void )
-{
- ENTER_CRITICAL_SECTION( );
- vMBPortSerialEnable( FALSE, FALSE );
- vMBPortTimersDisable( );
- EXIT_CRITICAL_SECTION( );
-}
-
-eMBErrorCode
-eMBASCIIReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
-{
- eMBErrorCode eStatus = MB_ENOERR;
-
- ENTER_CRITICAL_SECTION( );
- assert( usRcvBufferPos < MB_SER_PDU_SIZE_MAX );
-
- /* Length and CRC check */
- if( ( usRcvBufferPos >= MB_SER_PDU_SIZE_MIN )
- && ( prvucMBLRC( ( UCHAR * ) ucASCIIBuf, usRcvBufferPos ) == 0 ) )
- {
- /* Save the address field. All frames are passed to the upper layed
- * and the decision if a frame is used is done there.
- */
- *pucRcvAddress = ucASCIIBuf[MB_SER_PDU_ADDR_OFF];
-
- /* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
- * size of address field and CRC checksum.
- */
- *pusLength = ( USHORT )( usRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_LRC );
-
- /* Return the start of the Modbus PDU to the caller. */
- *pucFrame = ( UCHAR * ) & ucASCIIBuf[MB_SER_PDU_PDU_OFF];
- }
- else
- {
- eStatus = MB_EIO;
- }
- EXIT_CRITICAL_SECTION( );
- return eStatus;
-}
-
-eMBErrorCode
-eMBASCIISend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
-{
- eMBErrorCode eStatus = MB_ENOERR;
- UCHAR usLRC;
-
- ENTER_CRITICAL_SECTION( );
- /* Check if the receiver is still in idle state. If not we where to
- * slow with processing the received frame and the master sent another
- * frame on the network. We have to abort sending the frame.
- */
- if( eRcvState == STATE_RX_IDLE )
- {
- /* First byte before the Modbus-PDU is the slave address. */
- pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
- usSndBufferCount = 1;
-
- /* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */
- pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress;
- usSndBufferCount += usLength;
-
- /* Calculate LRC checksum for Modbus-Serial-Line-PDU. */
- usLRC = prvucMBLRC( ( UCHAR * ) pucSndBufferCur, usSndBufferCount );
- ucASCIIBuf[usSndBufferCount++] = usLRC;
-
- /* Activate the transmitter. */
- eSndState = STATE_TX_START;
- vMBPortSerialEnable( FALSE, TRUE );
- }
- else
- {
- eStatus = MB_EIO;
- }
- EXIT_CRITICAL_SECTION( );
- return eStatus;
-}
-
-BOOL
-xMBASCIIReceiveFSM( void )
-{
- BOOL xNeedPoll = FALSE;
- UCHAR ucByte;
- UCHAR ucResult;
-
- assert( eSndState == STATE_TX_IDLE );
-
- ( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte );
- switch ( eRcvState )
- {
- /* A new character is received. If the character is a ':' the input
- * buffer is cleared. A CR-character signals the end of the data
- * block. Other characters are part of the data block and their
- * ASCII value is converted back to a binary representation.
- */
- case STATE_RX_RCV:
- /* Enable timer for character timeout. */
- vMBPortTimersEnable( );
- if( ucByte == ':' )
- {
- /* Empty receive buffer. */
- eBytePos = BYTE_HIGH_NIBBLE;
- usRcvBufferPos = 0;
- }
- else if( ucByte == MB_ASCII_DEFAULT_CR )
- {
- eRcvState = STATE_RX_WAIT_EOF;
- }
- else
- {
- ucResult = prvucMBCHAR2BIN( ucByte );
- switch ( eBytePos )
- {
- /* High nibble of the byte comes first. We check for
- * a buffer overflow here. */
- case BYTE_HIGH_NIBBLE:
- if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX )
- {
- ucASCIIBuf[usRcvBufferPos] = ( UCHAR )( ucResult << 4 );
- eBytePos = BYTE_LOW_NIBBLE;
- break;
- }
- else
- {
- /* not handled in Modbus specification but seems
- * a resonable implementation. */
- eRcvState = STATE_RX_IDLE;
- /* Disable previously activated timer because of error state. */
- vMBPortTimersDisable( );
- }
- break;
-
- case BYTE_LOW_NIBBLE:
- ucASCIIBuf[usRcvBufferPos++] |= ucResult;
- eBytePos = BYTE_HIGH_NIBBLE;
- break;
- }
- }
- break;
-
- case STATE_RX_WAIT_EOF:
- if( ucByte == ucMBLFCharacter )
- {
- /* Disable character timeout timer because all characters are
- * received. */
- vMBPortTimersDisable( );
- /* Receiver is again in idle state. */
- eRcvState = STATE_RX_IDLE;
-
- /* Notify the caller of eMBASCIIReceive that a new frame
- * was received. */
- xNeedPoll = xMBPortEventPost( EV_FRAME_RECEIVED );
- }
- else if( ucByte == ':' )
- {
- /* Empty receive buffer and back to receive state. */
- eBytePos = BYTE_HIGH_NIBBLE;
- usRcvBufferPos = 0;
- eRcvState = STATE_RX_RCV;
-
- /* Enable timer for character timeout. */
- vMBPortTimersEnable( );
- }
- else
- {
- /* Frame is not okay. Delete entire frame. */
- eRcvState = STATE_RX_IDLE;
- }
- break;
-
- case STATE_RX_IDLE:
- if( ucByte == ':' )
- {
- /* Enable timer for character timeout. */
- vMBPortTimersEnable( );
- /* Reset the input buffers to store the frame. */
- usRcvBufferPos = 0;;
- eBytePos = BYTE_HIGH_NIBBLE;
- eRcvState = STATE_RX_RCV;
- }
- break;
- }
-
- return xNeedPoll;
-}
-
-BOOL
-xMBASCIITransmitFSM( void )
-{
- BOOL xNeedPoll = FALSE;
- UCHAR ucByte;
-
- assert( eRcvState == STATE_RX_IDLE );
- switch ( eSndState )
- {
- /* Start of transmission. The start of a frame is defined by sending
- * the character ':'. */
- case STATE_TX_START:
- ucByte = ':';
- xMBPortSerialPutByte( ( CHAR )ucByte );
- eSndState = STATE_TX_DATA;
- eBytePos = BYTE_HIGH_NIBBLE;
- break;
-
- /* Send the data block. Each data byte is encoded as a character hex
- * stream with the high nibble sent first and the low nibble sent
- * last. If all data bytes are exhausted we send a '\r' character
- * to end the transmission. */
- case STATE_TX_DATA:
- if( usSndBufferCount > 0 )
- {
- switch ( eBytePos )
- {
- case BYTE_HIGH_NIBBLE:
- ucByte = prvucMBBIN2CHAR( ( UCHAR )( *pucSndBufferCur >> 4 ) );
- xMBPortSerialPutByte( ( CHAR ) ucByte );
- eBytePos = BYTE_LOW_NIBBLE;
- break;
-
- case BYTE_LOW_NIBBLE:
- ucByte = prvucMBBIN2CHAR( ( UCHAR )( *pucSndBufferCur & 0x0F ) );
- xMBPortSerialPutByte( ( CHAR )ucByte );
- pucSndBufferCur++;
- eBytePos = BYTE_HIGH_NIBBLE;
- usSndBufferCount--;
- break;
- }
- }
- else
- {
- xMBPortSerialPutByte( MB_ASCII_DEFAULT_CR );
- eSndState = STATE_TX_END;
- }
- break;
-
- /* Finish the frame by sending a LF character. */
- case STATE_TX_END:
- xMBPortSerialPutByte( ( CHAR )ucMBLFCharacter );
- /* We need another state to make sure that the CR character has
- * been sent. */
- eSndState = STATE_TX_NOTIFY;
- break;
-
- /* Notify the task which called eMBASCIISend that the frame has
- * been sent. */
- case STATE_TX_NOTIFY:
- eSndState = STATE_TX_IDLE;
- xNeedPoll = xMBPortEventPost( EV_FRAME_SENT );
-
- /* Disable transmitter. This prevents another transmit buffer
- * empty interrupt. */
- vMBPortSerialEnable( TRUE, FALSE );
- eSndState = STATE_TX_IDLE;
- break;
-
- /* We should not get a transmitter event if the transmitter is in
- * idle state. */
- case STATE_TX_IDLE:
- /* enable receiver/disable transmitter. */
- vMBPortSerialEnable( TRUE, FALSE );
- break;
- }
-
- return xNeedPoll;
-}
-
-BOOL
-xMBASCIITimerT1SExpired( void )
-{
- switch ( eRcvState )
- {
- /* If we have a timeout we go back to the idle state and wait for
- * the next frame.
- */
- case STATE_RX_RCV:
- case STATE_RX_WAIT_EOF:
- eRcvState = STATE_RX_IDLE;
- break;
-
- default:
- assert( ( eRcvState == STATE_RX_RCV ) || ( eRcvState == STATE_RX_WAIT_EOF ) );
- break;
- }
- vMBPortTimersDisable( );
-
- /* no context switch required. */
- return FALSE;
-}
-
-
-static UCHAR
-prvucMBCHAR2BIN( UCHAR ucCharacter )
-{
- if( ( ucCharacter >= '0' ) && ( ucCharacter <= '9' ) )
- {
- return ( UCHAR )( ucCharacter - '0' );
- }
- else if( ( ucCharacter >= 'A' ) && ( ucCharacter <= 'F' ) )
- {
- return ( UCHAR )( ucCharacter - 'A' + 0x0A );
- }
- else
- {
- return 0xFF;
- }
-}
-
-static UCHAR
-prvucMBBIN2CHAR( UCHAR ucByte )
-{
- if( ucByte <= 0x09 )
- {
- return ( UCHAR )( '0' + ucByte );
- }
- else if( ( ucByte >= 0x0A ) && ( ucByte <= 0x0F ) )
- {
- return ( UCHAR )( ucByte - 0x0A + 'A' );
- }
- else
- {
- /* Programming error. */
- assert( 0 );
- }
- return '0';
-}
-
-
-static UCHAR
-prvucMBLRC( UCHAR * pucFrame, USHORT usLen )
-{
- UCHAR ucLRC = 0; /* LRC char initialized */
-
- while( usLen-- )
- {
- ucLRC += *pucFrame++; /* Add buffer byte without carry */
- }
-
- /* Return twos complement */
- ucLRC = ( UCHAR ) ( -( ( CHAR ) ucLRC ) );
- return ucLRC;
-}
-
-#endif
diff --git a/components/net/freemodbus/modbus/ascii/mbascii.h b/components/net/freemodbus/modbus/ascii/mbascii.h
deleted file mode 100644
index cdec83ff00..0000000000
--- a/components/net/freemodbus/modbus/ascii/mbascii.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbascii.h,v 1.8 2006/12/07 22:10:34 wolti Exp $
- */
-
-#ifndef _MB_ASCII_H
-#define _MB_ASCII_H
-
-#ifdef __cplusplus
-PR_BEGIN_EXTERN_C
-#endif
-
-#if MB_SLAVE_ASCII_ENABLED > 0
-eMBErrorCode eMBASCIIInit( UCHAR slaveAddress, UCHAR ucPort,
- ULONG ulBaudRate, eMBParity eParity );
-void eMBASCIIStart( void );
-void eMBASCIIStop( void );
-
-eMBErrorCode eMBASCIIReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame,
- USHORT * pusLength );
-eMBErrorCode eMBASCIISend( UCHAR slaveAddress, const UCHAR * pucFrame,
- USHORT usLength );
-BOOL xMBASCIIReceiveFSM( void );
-BOOL xMBASCIITransmitFSM( void );
-BOOL xMBASCIITimerT1SExpired( void );
-#endif
-
-#ifdef __cplusplus
-PR_END_EXTERN_C
-#endif
-#endif
diff --git a/components/net/freemodbus/modbus/functions/mbfunccoils.c b/components/net/freemodbus/modbus/functions/mbfunccoils.c
deleted file mode 100644
index 681bd50656..0000000000
--- a/components/net/freemodbus/modbus/functions/mbfunccoils.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbfunccoils.c,v 1.8 2007/02/18 23:47:16 wolti Exp $
- */
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mbframe.h"
-#include "mbproto.h"
-#include "mbconfig.h"
-
-/* ----------------------- Defines ------------------------------------------*/
-#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF )
-#define MB_PDU_FUNC_READ_COILCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_FUNC_READ_SIZE ( 4 )
-#define MB_PDU_FUNC_READ_COILCNT_MAX ( 0x07D0 )
-
-#define MB_PDU_FUNC_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF )
-#define MB_PDU_FUNC_WRITE_VALUE_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_FUNC_WRITE_SIZE ( 4 )
-
-#define MB_PDU_FUNC_WRITE_MUL_ADDR_OFF ( MB_PDU_DATA_OFF )
-#define MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF ( MB_PDU_DATA_OFF + 4 )
-#define MB_PDU_FUNC_WRITE_MUL_VALUES_OFF ( MB_PDU_DATA_OFF + 5 )
-#define MB_PDU_FUNC_WRITE_MUL_SIZE_MIN ( 5 )
-#define MB_PDU_FUNC_WRITE_MUL_COILCNT_MAX ( 0x07B0 )
-
-/* ----------------------- Static functions ---------------------------------*/
-eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
-
-/* ----------------------- Start implementation -----------------------------*/
-
-#if MB_FUNC_READ_COILS_ENABLED > 0
-
-eMBException
-eMBFuncReadCoils( UCHAR * pucFrame, USHORT * usLen )
-{
- USHORT usRegAddress;
- USHORT usCoilCount;
- UCHAR ucNBytes;
- UCHAR *pucFrameCur;
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
- {
- usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
- usRegAddress++;
-
- usCoilCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF] << 8 );
- usCoilCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF + 1] );
-
- /* Check if the number of registers to read is valid. If not
- * return Modbus illegal data value exception.
- */
- if( ( usCoilCount >= 1 ) &&
- ( usCoilCount < MB_PDU_FUNC_READ_COILCNT_MAX ) )
- {
- /* Set the current PDU data pointer to the beginning. */
- pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
- *usLen = MB_PDU_FUNC_OFF;
-
- /* First byte contains the function code. */
- *pucFrameCur++ = MB_FUNC_READ_COILS;
- *usLen += 1;
-
- /* Test if the quantity of coils is a multiple of 8. If not last
- * byte is only partially field with unused coils set to zero. */
- if( ( usCoilCount & 0x0007 ) != 0 )
- {
- ucNBytes = ( UCHAR )( usCoilCount / 8 + 1 );
- }
- else
- {
- ucNBytes = ( UCHAR )( usCoilCount / 8 );
- }
- *pucFrameCur++ = ucNBytes;
- *usLen += 1;
-
- eRegStatus =
- eMBRegCoilsCB( pucFrameCur, usRegAddress, usCoilCount,
- MB_REG_READ );
-
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- else
- {
- /* The response contains the function code, the starting address
- * and the quantity of registers. We reuse the old values in the
- * buffer because they are still valid. */
- *usLen += ucNBytes;;
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- else
- {
- /* Can't be a valid read coil register request because the length
- * is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-#endif
-
-#if MB_FUNC_WRITE_COIL_ENABLED > 0
-eMBException
-eMBFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen )
-{
- USHORT usRegAddress;
- UCHAR ucBuf[2];
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- if( *usLen == ( MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN ) )
- {
- usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1] );
- usRegAddress++;
-
- if( ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF + 1] == 0x00 ) &&
- ( ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF ) ||
- ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0x00 ) ) )
- {
- ucBuf[1] = 0;
- if( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF )
- {
- ucBuf[0] = 1;
- }
- else
- {
- ucBuf[0] = 0;
- }
- eRegStatus =
- eMBRegCoilsCB( &ucBuf[0], usRegAddress, 1, MB_REG_WRITE );
-
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- else
- {
- /* Can't be a valid write coil register request because the length
- * is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-
-#endif
-
-#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
-eMBException
-eMBFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen )
-{
- USHORT usRegAddress;
- USHORT usCoilCnt;
- UCHAR ucByteCount;
- UCHAR ucByteCountVerify;
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- if( *usLen > ( MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN ) )
- {
- usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1] );
- usRegAddress++;
-
- usCoilCnt = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF] << 8 );
- usCoilCnt |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF + 1] );
-
- ucByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF];
-
- /* Compute the number of expected bytes in the request. */
- if( ( usCoilCnt & 0x0007 ) != 0 )
- {
- ucByteCountVerify = ( UCHAR )( usCoilCnt / 8 + 1 );
- }
- else
- {
- ucByteCountVerify = ( UCHAR )( usCoilCnt / 8 );
- }
-
- if( ( usCoilCnt >= 1 ) &&
- ( usCoilCnt <= MB_PDU_FUNC_WRITE_MUL_COILCNT_MAX ) &&
- ( ucByteCountVerify == ucByteCount ) )
- {
- eRegStatus =
- eMBRegCoilsCB( &pucFrame[MB_PDU_FUNC_WRITE_MUL_VALUES_OFF],
- usRegAddress, usCoilCnt, MB_REG_WRITE );
-
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- else
- {
- /* The response contains the function code, the starting address
- * and the quantity of registers. We reuse the old values in the
- * buffer because they are still valid. */
- *usLen = MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF;
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- else
- {
- /* Can't be a valid write coil register request because the length
- * is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-
-#endif
diff --git a/components/net/freemodbus/modbus/functions/mbfunccoils_m.c b/components/net/freemodbus/modbus/functions/mbfunccoils_m.c
deleted file mode 100644
index 93801de06f..0000000000
--- a/components/net/freemodbus/modbus/functions/mbfunccoils_m.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (C) 2013 Armink <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbfunccoils_m.c,v 1.60 2013/10/12 15:10:12 Armink Add Master Functions
- */
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mb_m.h"
-#include "mbframe.h"
-#include "mbproto.h"
-#include "mbconfig.h"
-
-/* ----------------------- Defines ------------------------------------------*/
-#define MB_PDU_REQ_READ_ADDR_OFF ( MB_PDU_DATA_OFF + 0 )
-#define MB_PDU_REQ_READ_COILCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_REQ_READ_SIZE ( 4 )
-#define MB_PDU_FUNC_READ_COILCNT_OFF ( MB_PDU_DATA_OFF + 0 )
-#define MB_PDU_FUNC_READ_VALUES_OFF ( MB_PDU_DATA_OFF + 1 )
-#define MB_PDU_FUNC_READ_SIZE_MIN ( 1 )
-
-#define MB_PDU_REQ_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF )
-#define MB_PDU_REQ_WRITE_VALUE_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_REQ_WRITE_SIZE ( 4 )
-#define MB_PDU_FUNC_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF )
-#define MB_PDU_FUNC_WRITE_VALUE_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_FUNC_WRITE_SIZE ( 4 )
-
-#define MB_PDU_REQ_WRITE_MUL_ADDR_OFF ( MB_PDU_DATA_OFF )
-#define MB_PDU_REQ_WRITE_MUL_COILCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_REQ_WRITE_MUL_BYTECNT_OFF ( MB_PDU_DATA_OFF + 4 )
-#define MB_PDU_REQ_WRITE_MUL_VALUES_OFF ( MB_PDU_DATA_OFF + 5 )
-#define MB_PDU_REQ_WRITE_MUL_SIZE_MIN ( 5 )
-#define MB_PDU_REQ_WRITE_MUL_COILCNT_MAX ( 0x07B0 )
-#define MB_PDU_FUNC_WRITE_MUL_ADDR_OFF ( MB_PDU_DATA_OFF )
-#define MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_FUNC_WRITE_MUL_SIZE ( 5 )
-
-/* ----------------------- Static functions ---------------------------------*/
-eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
-
-/* ----------------------- Start implementation -----------------------------*/
-#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
-#if MB_FUNC_READ_COILS_ENABLED > 0
-
-/**
- * This function will request read coil.
- *
- * @param ucSndAddr salve address
- * @param usCoilAddr coil start address
- * @param usNCoils coil total number
- * @param lTimeOut timeout (-1 will waiting forever)
- *
- * @return error code
- */
-eMBMasterReqErrCode
-eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils ,LONG lTimeOut )
-{
- UCHAR *ucMBFrame;
- eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
-
- if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
- else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
- else
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- vMBMasterSetDestAddress(ucSndAddr);
- ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_READ_COILS;
- ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] = usCoilAddr >> 8;
- ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF + 1] = usCoilAddr;
- ucMBFrame[MB_PDU_REQ_READ_COILCNT_OFF ] = usNCoils >> 8;
- ucMBFrame[MB_PDU_REQ_READ_COILCNT_OFF + 1] = usNCoils;
- vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
- ( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
- eErrStatus = eMBMasterWaitRequestFinish( );
-
- }
- return eErrStatus;
-}
-
-eMBException
-eMBMasterFuncReadCoils( UCHAR * pucFrame, USHORT * usLen )
-{
- UCHAR *ucMBFrame;
- USHORT usRegAddress;
- USHORT usCoilCount;
- UCHAR ucByteCount;
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- /* If this request is broadcast, and it's read mode. This request don't need execute. */
- if ( xMBMasterRequestIsBroadcast() )
- {
- eStatus = MB_EX_NONE;
- }
- else if ( *usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE_MIN )
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF + 1] );
- usRegAddress++;
-
- usCoilCount = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_COILCNT_OFF] << 8 );
- usCoilCount |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_COILCNT_OFF + 1] );
-
- /* Test if the quantity of coils is a multiple of 8. If not last
- * byte is only partially field with unused coils set to zero. */
- if( ( usCoilCount & 0x0007 ) != 0 )
- {
- ucByteCount = ( UCHAR )( usCoilCount / 8 + 1 );
- }
- else
- {
- ucByteCount = ( UCHAR )( usCoilCount / 8 );
- }
-
- /* Check if the number of registers to read is valid. If not
- * return Modbus illegal data value exception.
- */
- if( ( usCoilCount >= 1 ) &&
- ( ucByteCount == pucFrame[MB_PDU_FUNC_READ_COILCNT_OFF] ) )
- {
- /* Make callback to fill the buffer. */
- eRegStatus = eMBMasterRegCoilsCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usCoilCount, MB_REG_READ );
-
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- else
- {
- /* Can't be a valid read coil register request because the length
- * is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-#endif
-
-#if MB_FUNC_WRITE_COIL_ENABLED > 0
-
-/**
- * This function will request write one coil.
- *
- * @param ucSndAddr salve address
- * @param usCoilAddr coil start address
- * @param usCoilData data to be written
- * @param lTimeOut timeout (-1 will waiting forever)
- *
- * @return error code
- *
- * @see eMBMasterReqWriteMultipleCoils
- */
-eMBMasterReqErrCode
-eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData, LONG lTimeOut )
-{
- UCHAR *ucMBFrame;
- eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
-
- if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
- else if ( ( usCoilData != 0xFF00 ) && ( usCoilData != 0x0000 ) ) eErrStatus = MB_MRE_ILL_ARG;
- else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
- else
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- vMBMasterSetDestAddress(ucSndAddr);
- ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_WRITE_SINGLE_COIL;
- ucMBFrame[MB_PDU_REQ_WRITE_ADDR_OFF] = usCoilAddr >> 8;
- ucMBFrame[MB_PDU_REQ_WRITE_ADDR_OFF + 1] = usCoilAddr;
- ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF ] = usCoilData >> 8;
- ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF + 1] = usCoilData;
- vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_SIZE );
- ( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
- eErrStatus = eMBMasterWaitRequestFinish( );
- }
- return eErrStatus;
-}
-
-eMBException
-eMBMasterFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen )
-{
- USHORT usRegAddress;
- UCHAR ucBuf[2];
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- if( *usLen == ( MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN ) )
- {
- usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1] );
- usRegAddress++;
-
- if( ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF + 1] == 0x00 ) &&
- ( ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF ) ||
- ( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0x00 ) ) )
- {
- ucBuf[1] = 0;
- if( pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF] == 0xFF )
- {
- ucBuf[0] = 1;
- }
- else
- {
- ucBuf[0] = 0;
- }
- eRegStatus =
- eMBMasterRegCoilsCB( &ucBuf[0], usRegAddress, 1, MB_REG_WRITE );
-
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- else
- {
- /* Can't be a valid write coil register request because the length
- * is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-
-#endif
-
-#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
-
-/**
- * This function will request write multiple coils.
- *
- * @param ucSndAddr salve address
- * @param usCoilAddr coil start address
- * @param usNCoils coil total number
- * @param usCoilData data to be written
- * @param lTimeOut timeout (-1 will waiting forever)
- *
- * @return error code
- *
- * @see eMBMasterReqWriteCoil
- */
-eMBMasterReqErrCode
-eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
- USHORT usCoilAddr, USHORT usNCoils, UCHAR * pucDataBuffer, LONG lTimeOut)
-{
- UCHAR *ucMBFrame;
- USHORT usRegIndex = 0;
- UCHAR ucByteCount;
- eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
-
- if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
- else if ( usNCoils > MB_PDU_REQ_WRITE_MUL_COILCNT_MAX ) eErrStatus = MB_MRE_ILL_ARG;
- else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
- else
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- vMBMasterSetDestAddress(ucSndAddr);
- ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_WRITE_MULTIPLE_COILS;
- ucMBFrame[MB_PDU_REQ_WRITE_MUL_ADDR_OFF] = usCoilAddr >> 8;
- ucMBFrame[MB_PDU_REQ_WRITE_MUL_ADDR_OFF + 1] = usCoilAddr;
- ucMBFrame[MB_PDU_REQ_WRITE_MUL_COILCNT_OFF] = usNCoils >> 8;
- ucMBFrame[MB_PDU_REQ_WRITE_MUL_COILCNT_OFF + 1] = usNCoils ;
- if( ( usNCoils & 0x0007 ) != 0 )
- {
- ucByteCount = ( UCHAR )( usNCoils / 8 + 1 );
- }
- else
- {
- ucByteCount = ( UCHAR )( usNCoils / 8 );
- }
- ucMBFrame[MB_PDU_REQ_WRITE_MUL_BYTECNT_OFF] = ucByteCount;
- ucMBFrame += MB_PDU_REQ_WRITE_MUL_VALUES_OFF;
- while( ucByteCount > usRegIndex)
- {
- *ucMBFrame++ = pucDataBuffer[usRegIndex++];
- }
- vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_MUL_SIZE_MIN + ucByteCount );
- ( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
- eErrStatus = eMBMasterWaitRequestFinish( );
- }
- return eErrStatus;
-}
-
-eMBException
-eMBMasterFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen )
-{
- USHORT usRegAddress;
- USHORT usCoilCnt;
- UCHAR ucByteCount;
- UCHAR ucByteCountVerify;
- UCHAR *ucMBFrame;
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- /* If this request is broadcast, the *usLen is not need check. */
- if( ( *usLen == MB_PDU_FUNC_WRITE_MUL_SIZE ) || xMBMasterRequestIsBroadcast() )
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1] );
- usRegAddress++;
-
- usCoilCnt = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF] << 8 );
- usCoilCnt |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_COILCNT_OFF + 1] );
-
- ucByteCount = ucMBFrame[MB_PDU_REQ_WRITE_MUL_BYTECNT_OFF];
-
- /* Compute the number of expected bytes in the request. */
- if( ( usCoilCnt & 0x0007 ) != 0 )
- {
- ucByteCountVerify = ( UCHAR )( usCoilCnt / 8 + 1 );
- }
- else
- {
- ucByteCountVerify = ( UCHAR )( usCoilCnt / 8 );
- }
-
- if( ( usCoilCnt >= 1 ) && ( ucByteCountVerify == ucByteCount ) )
- {
- eRegStatus =
- eMBMasterRegCoilsCB( &ucMBFrame[MB_PDU_REQ_WRITE_MUL_VALUES_OFF],
- usRegAddress, usCoilCnt, MB_REG_WRITE );
-
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- else
- {
- /* Can't be a valid write coil register request because the length
- * is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-
-#endif
-#endif
diff --git a/components/net/freemodbus/modbus/functions/mbfuncdiag.c b/components/net/freemodbus/modbus/functions/mbfuncdiag.c
deleted file mode 100644
index d75ffc0f72..0000000000
--- a/components/net/freemodbus/modbus/functions/mbfuncdiag.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbfuncdiag.c,v 1.3 2006/12/07 22:10:34 wolti Exp $
- */
diff --git a/components/net/freemodbus/modbus/functions/mbfuncdisc.c b/components/net/freemodbus/modbus/functions/mbfuncdisc.c
deleted file mode 100644
index fb378441b9..0000000000
--- a/components/net/freemodbus/modbus/functions/mbfuncdisc.c
+++ /dev/null
@@ -1,125 +0,0 @@
- /*
- * FreeRTOS Modbus Libary: A Modbus serial implementation for FreeRTOS
- * Copyright (C) 2006 Christian Walter <[email protected]>
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mbframe.h"
-#include "mbproto.h"
-#include "mbconfig.h"
-
-/* ----------------------- Defines ------------------------------------------*/
-#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF )
-#define MB_PDU_FUNC_READ_DISCCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_FUNC_READ_SIZE ( 4 )
-#define MB_PDU_FUNC_READ_DISCCNT_MAX ( 0x07D0 )
-
-/* ----------------------- Static functions ---------------------------------*/
-eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
-
-/* ----------------------- Start implementation -----------------------------*/
-
-#if MB_FUNC_READ_COILS_ENABLED > 0
-
-eMBException
-eMBFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen )
-{
- USHORT usRegAddress;
- USHORT usDiscreteCnt;
- UCHAR ucNBytes;
- UCHAR *pucFrameCur;
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
- {
- usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
- usRegAddress++;
-
- usDiscreteCnt = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF] << 8 );
- usDiscreteCnt |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF + 1] );
-
- /* Check if the number of registers to read is valid. If not
- * return Modbus illegal data value exception.
- */
- if( ( usDiscreteCnt >= 1 ) &&
- ( usDiscreteCnt < MB_PDU_FUNC_READ_DISCCNT_MAX ) )
- {
- /* Set the current PDU data pointer to the beginning. */
- pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
- *usLen = MB_PDU_FUNC_OFF;
-
- /* First byte contains the function code. */
- *pucFrameCur++ = MB_FUNC_READ_DISCRETE_INPUTS;
- *usLen += 1;
-
- /* Test if the quantity of coils is a multiple of 8. If not last
- * byte is only partially field with unused coils set to zero. */
- if( ( usDiscreteCnt & 0x0007 ) != 0 )
- {
- ucNBytes = ( UCHAR ) ( usDiscreteCnt / 8 + 1 );
- }
- else
- {
- ucNBytes = ( UCHAR ) ( usDiscreteCnt / 8 );
- }
- *pucFrameCur++ = ucNBytes;
- *usLen += 1;
-
- eRegStatus =
- eMBRegDiscreteCB( pucFrameCur, usRegAddress, usDiscreteCnt );
-
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- else
- {
- /* The response contains the function code, the starting address
- * and the quantity of registers. We reuse the old values in the
- * buffer because they are still valid. */
- *usLen += ucNBytes;;
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- else
- {
- /* Can't be a valid read coil register request because the length
- * is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-
-#endif
diff --git a/components/net/freemodbus/modbus/functions/mbfuncdisc_m.c b/components/net/freemodbus/modbus/functions/mbfuncdisc_m.c
deleted file mode 100644
index 6c8d6c4741..0000000000
--- a/components/net/freemodbus/modbus/functions/mbfuncdisc_m.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (C) 2013 Armink <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbfuncdisc_m.c,v 1.60 2013/10/15 8:48:20 Armink Add Master Functions Exp $
- */
-
-
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mb_m.h"
-#include "mbframe.h"
-#include "mbproto.h"
-#include "mbconfig.h"
-
-/* ----------------------- Defines ------------------------------------------*/
-#define MB_PDU_REQ_READ_ADDR_OFF ( MB_PDU_DATA_OFF + 0 )
-#define MB_PDU_REQ_READ_DISCCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_REQ_READ_SIZE ( 4 )
-#define MB_PDU_FUNC_READ_DISCCNT_OFF ( MB_PDU_DATA_OFF + 0 )
-#define MB_PDU_FUNC_READ_VALUES_OFF ( MB_PDU_DATA_OFF + 1 )
-#define MB_PDU_FUNC_READ_SIZE_MIN ( 1 )
-
-/* ----------------------- Static functions ---------------------------------*/
-eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
-
-/* ----------------------- Start implementation -----------------------------*/
-#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
-#if MB_FUNC_READ_DISCRETE_INPUTS_ENABLED > 0
-
-/**
- * This function will request read discrete inputs.
- *
- * @param ucSndAddr salve address
- * @param usDiscreteAddr discrete start address
- * @param usNDiscreteIn discrete total number
- * @param lTimeOut timeout (-1 will waiting forever)
- *
- * @return error code
- */
-eMBMasterReqErrCode
-eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT usNDiscreteIn, LONG lTimeOut )
-{
- UCHAR *ucMBFrame;
- eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
-
- if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
- else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
- else
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- vMBMasterSetDestAddress(ucSndAddr);
- ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_READ_DISCRETE_INPUTS;
- ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] = usDiscreteAddr >> 8;
- ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF + 1] = usDiscreteAddr;
- ucMBFrame[MB_PDU_REQ_READ_DISCCNT_OFF ] = usNDiscreteIn >> 8;
- ucMBFrame[MB_PDU_REQ_READ_DISCCNT_OFF + 1] = usNDiscreteIn;
- vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
- ( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
- eErrStatus = eMBMasterWaitRequestFinish( );
- }
- return eErrStatus;
-}
-
-eMBException
-eMBMasterFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen )
-{
- USHORT usRegAddress;
- USHORT usDiscreteCnt;
- UCHAR ucNBytes;
- UCHAR *ucMBFrame;
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- /* If this request is broadcast, and it's read mode. This request don't need execute. */
- if ( xMBMasterRequestIsBroadcast() )
- {
- eStatus = MB_EX_NONE;
- }
- else if( *usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE_MIN )
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF + 1] );
- usRegAddress++;
-
- usDiscreteCnt = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_DISCCNT_OFF] << 8 );
- usDiscreteCnt |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_DISCCNT_OFF + 1] );
-
- /* Test if the quantity of coils is a multiple of 8. If not last
- * byte is only partially field with unused coils set to zero. */
- if( ( usDiscreteCnt & 0x0007 ) != 0 )
- {
- ucNBytes = ( UCHAR )( usDiscreteCnt / 8 + 1 );
- }
- else
- {
- ucNBytes = ( UCHAR )( usDiscreteCnt / 8 );
- }
-
- /* Check if the number of registers to read is valid. If not
- * return Modbus illegal data value exception.
- */
- if ((usDiscreteCnt >= 1) && ucNBytes == pucFrame[MB_PDU_FUNC_READ_DISCCNT_OFF])
- {
- /* Make callback to fill the buffer. */
- eRegStatus = eMBMasterRegDiscreteCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usDiscreteCnt );
-
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- else
- {
- /* Can't be a valid read coil register request because the length
- * is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-
-#endif
-#endif
diff --git a/components/net/freemodbus/modbus/functions/mbfuncholding.c b/components/net/freemodbus/modbus/functions/mbfuncholding.c
deleted file mode 100644
index 7921302f96..0000000000
--- a/components/net/freemodbus/modbus/functions/mbfuncholding.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbfuncholding.c,v 1.12 2007/02/18 23:48:22 wolti Exp $
- */
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mbframe.h"
-#include "mbproto.h"
-#include "mbconfig.h"
-
-/* ----------------------- Defines ------------------------------------------*/
-#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF + 0)
-#define MB_PDU_FUNC_READ_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_FUNC_READ_SIZE ( 4 )
-#define MB_PDU_FUNC_READ_REGCNT_MAX ( 0x007D )
-
-#define MB_PDU_FUNC_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF + 0)
-#define MB_PDU_FUNC_WRITE_VALUE_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_FUNC_WRITE_SIZE ( 4 )
-
-#define MB_PDU_FUNC_WRITE_MUL_ADDR_OFF ( MB_PDU_DATA_OFF + 0 )
-#define MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF ( MB_PDU_DATA_OFF + 4 )
-#define MB_PDU_FUNC_WRITE_MUL_VALUES_OFF ( MB_PDU_DATA_OFF + 5 )
-#define MB_PDU_FUNC_WRITE_MUL_SIZE_MIN ( 5 )
-#define MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX ( 0x0078 )
-
-#define MB_PDU_FUNC_READWRITE_READ_ADDR_OFF ( MB_PDU_DATA_OFF + 0 )
-#define MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF + 4 )
-#define MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF ( MB_PDU_DATA_OFF + 6 )
-#define MB_PDU_FUNC_READWRITE_BYTECNT_OFF ( MB_PDU_DATA_OFF + 8 )
-#define MB_PDU_FUNC_READWRITE_WRITE_VALUES_OFF ( MB_PDU_DATA_OFF + 9 )
-#define MB_PDU_FUNC_READWRITE_SIZE_MIN ( 9 )
-
-/* ----------------------- Static functions ---------------------------------*/
-eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
-
-/* ----------------------- Start implementation -----------------------------*/
-
-#if MB_FUNC_WRITE_HOLDING_ENABLED > 0
-
-eMBException
-eMBFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
-{
- USHORT usRegAddress;
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- if( *usLen == ( MB_PDU_FUNC_WRITE_SIZE + MB_PDU_SIZE_MIN ) )
- {
- usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1] );
- usRegAddress++;
-
- /* Make callback to update the value. */
- eRegStatus = eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF],
- usRegAddress, 1, MB_REG_WRITE );
-
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- }
- else
- {
- /* Can't be a valid request because the length is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-#endif
-
-#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
-eMBException
-eMBFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
-{
- USHORT usRegAddress;
- USHORT usRegCount;
- UCHAR ucRegByteCount;
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- if( *usLen >= ( MB_PDU_FUNC_WRITE_MUL_SIZE_MIN + MB_PDU_SIZE_MIN ) )
- {
- usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_ADDR_OFF + 1] );
- usRegAddress++;
-
- usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF] << 8 );
- usRegCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF + 1] );
-
- ucRegByteCount = pucFrame[MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF];
-
- if( ( usRegCount >= 1 ) &&
- ( usRegCount <= MB_PDU_FUNC_WRITE_MUL_REGCNT_MAX ) &&
- ( ucRegByteCount == ( UCHAR ) ( 2 * usRegCount ) ) )
- {
- /* Make callback to update the register values. */
- eRegStatus =
- eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_WRITE_MUL_VALUES_OFF],
- usRegAddress, usRegCount, MB_REG_WRITE );
-
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- else
- {
- /* The response contains the function code, the starting
- * address and the quantity of registers. We reuse the
- * old values in the buffer because they are still valid.
- */
- *usLen = MB_PDU_FUNC_WRITE_MUL_BYTECNT_OFF;
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- else
- {
- /* Can't be a valid request because the length is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-#endif
-
-#if MB_FUNC_READ_HOLDING_ENABLED > 0
-
-eMBException
-eMBFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
-{
- USHORT usRegAddress;
- USHORT usRegCount;
- UCHAR *pucFrameCur;
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
- {
- usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
- usRegAddress++;
-
- usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] << 8 );
- usRegCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );
-
- /* Check if the number of registers to read is valid. If not
- * return Modbus illegal data value exception.
- */
- if( ( usRegCount >= 1 ) && ( usRegCount <= MB_PDU_FUNC_READ_REGCNT_MAX ) )
- {
- /* Set the current PDU data pointer to the beginning. */
- pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
- *usLen = MB_PDU_FUNC_OFF;
-
- /* First byte contains the function code. */
- *pucFrameCur++ = MB_FUNC_READ_HOLDING_REGISTER;
- *usLen += 1;
-
- /* Second byte in the response contain the number of bytes. */
- *pucFrameCur++ = ( UCHAR ) ( usRegCount * 2 );
- *usLen += 1;
-
- /* Make callback to fill the buffer. */
- eRegStatus = eMBRegHoldingCB( pucFrameCur, usRegAddress, usRegCount, MB_REG_READ );
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- else
- {
- *usLen += usRegCount * 2;
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- else
- {
- /* Can't be a valid request because the length is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-
-#endif
-
-#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
-
-eMBException
-eMBFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
-{
- USHORT usRegReadAddress;
- USHORT usRegReadCount;
- USHORT usRegWriteAddress;
- USHORT usRegWriteCount;
- UCHAR ucRegWriteByteCount;
- UCHAR *pucFrameCur;
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- if( *usLen >= ( MB_PDU_FUNC_READWRITE_SIZE_MIN + MB_PDU_SIZE_MIN ) )
- {
- usRegReadAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_READ_ADDR_OFF] << 8U );
- usRegReadAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_READ_ADDR_OFF + 1] );
- usRegReadAddress++;
-
- usRegReadCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF] << 8U );
- usRegReadCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_READ_REGCNT_OFF + 1] );
-
- usRegWriteAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF] << 8U );
- usRegWriteAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_ADDR_OFF + 1] );
- usRegWriteAddress++;
-
- usRegWriteCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF] << 8U );
- usRegWriteCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READWRITE_WRITE_REGCNT_OFF + 1] );
-
- ucRegWriteByteCount = pucFrame[MB_PDU_FUNC_READWRITE_BYTECNT_OFF];
-
- if( ( usRegReadCount >= 1 ) && ( usRegReadCount <= 0x7D ) &&
- ( usRegWriteCount >= 1 ) && ( usRegWriteCount <= 0x79 ) &&
- ( ( 2 * usRegWriteCount ) == ucRegWriteByteCount ) )
- {
- /* Make callback to update the register values. */
- eRegStatus = eMBRegHoldingCB( &pucFrame[MB_PDU_FUNC_READWRITE_WRITE_VALUES_OFF],
- usRegWriteAddress, usRegWriteCount, MB_REG_WRITE );
-
- if( eRegStatus == MB_ENOERR )
- {
- /* Set the current PDU data pointer to the beginning. */
- pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
- *usLen = MB_PDU_FUNC_OFF;
-
- /* First byte contains the function code. */
- *pucFrameCur++ = MB_FUNC_READWRITE_MULTIPLE_REGISTERS;
- *usLen += 1;
-
- /* Second byte in the response contain the number of bytes. */
- *pucFrameCur++ = ( UCHAR ) ( usRegReadCount * 2 );
- *usLen += 1;
-
- /* Make the read callback. */
- eRegStatus =
- eMBRegHoldingCB( pucFrameCur, usRegReadAddress, usRegReadCount, MB_REG_READ );
- if( eRegStatus == MB_ENOERR )
- {
- *usLen += 2 * usRegReadCount;
- }
- }
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- return eStatus;
-}
-
-#endif
diff --git a/components/net/freemodbus/modbus/functions/mbfuncholding_m.c b/components/net/freemodbus/modbus/functions/mbfuncholding_m.c
deleted file mode 100644
index e1fe69e383..0000000000
--- a/components/net/freemodbus/modbus/functions/mbfuncholding_m.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (C) 2013 Armink <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbfuncholding_m.c,v 1.60 2013/09/02 14:13:40 Armink Add Master Functions Exp $
- */
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mb_m.h"
-#include "mbframe.h"
-#include "mbproto.h"
-#include "mbconfig.h"
-
-/* ----------------------- Defines ------------------------------------------*/
-#define MB_PDU_REQ_READ_ADDR_OFF ( MB_PDU_DATA_OFF + 0 )
-#define MB_PDU_REQ_READ_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_REQ_READ_SIZE ( 4 )
-#define MB_PDU_FUNC_READ_REGCNT_MAX ( 0x007D )
-#define MB_PDU_FUNC_READ_BYTECNT_OFF ( MB_PDU_DATA_OFF + 0 )
-#define MB_PDU_FUNC_READ_VALUES_OFF ( MB_PDU_DATA_OFF + 1 )
-#define MB_PDU_FUNC_READ_SIZE_MIN ( 1 )
-
-#define MB_PDU_REQ_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF + 0)
-#define MB_PDU_REQ_WRITE_VALUE_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_REQ_WRITE_SIZE ( 4 )
-#define MB_PDU_FUNC_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF + 0)
-#define MB_PDU_FUNC_WRITE_VALUE_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_FUNC_WRITE_SIZE ( 4 )
-
-#define MB_PDU_REQ_WRITE_MUL_ADDR_OFF ( MB_PDU_DATA_OFF + 0 )
-#define MB_PDU_REQ_WRITE_MUL_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_REQ_WRITE_MUL_BYTECNT_OFF ( MB_PDU_DATA_OFF + 4 )
-#define MB_PDU_REQ_WRITE_MUL_VALUES_OFF ( MB_PDU_DATA_OFF + 5 )
-#define MB_PDU_REQ_WRITE_MUL_SIZE_MIN ( 5 )
-#define MB_PDU_REQ_WRITE_MUL_REGCNT_MAX ( 0x0078 )
-#define MB_PDU_FUNC_WRITE_MUL_ADDR_OFF ( MB_PDU_DATA_OFF + 0 )
-#define MB_PDU_FUNC_WRITE_MUL_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_FUNC_WRITE_MUL_SIZE ( 4 )
-
-#define MB_PDU_REQ_READWRITE_READ_ADDR_OFF ( MB_PDU_DATA_OFF + 0 )
-#define MB_PDU_REQ_READWRITE_READ_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_REQ_READWRITE_WRITE_ADDR_OFF ( MB_PDU_DATA_OFF + 4 )
-#define MB_PDU_REQ_READWRITE_WRITE_REGCNT_OFF ( MB_PDU_DATA_OFF + 6 )
-#define MB_PDU_REQ_READWRITE_WRITE_BYTECNT_OFF ( MB_PDU_DATA_OFF + 8 )
-#define MB_PDU_REQ_READWRITE_WRITE_VALUES_OFF ( MB_PDU_DATA_OFF + 9 )
-#define MB_PDU_REQ_READWRITE_SIZE_MIN ( 9 )
-#define MB_PDU_FUNC_READWRITE_READ_BYTECNT_OFF ( MB_PDU_DATA_OFF + 0 )
-#define MB_PDU_FUNC_READWRITE_READ_VALUES_OFF ( MB_PDU_DATA_OFF + 1 )
-#define MB_PDU_FUNC_READWRITE_SIZE_MIN ( 1 )
-
-/* ----------------------- Static functions ---------------------------------*/
-eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
-
-/* ----------------------- Start implementation -----------------------------*/
-#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
-#if MB_FUNC_WRITE_HOLDING_ENABLED > 0
-
-/**
- * This function will request write holding register.
- *
- * @param ucSndAddr salve address
- * @param usRegAddr register start address
- * @param usRegData register data to be written
- * @param lTimeOut timeout (-1 will waiting forever)
- *
- * @return error code
- */
-eMBMasterReqErrCode
-eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRegData, LONG lTimeOut )
-{
- UCHAR *ucMBFrame;
- eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
-
- if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
- else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
- else
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- vMBMasterSetDestAddress(ucSndAddr);
- ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_WRITE_REGISTER;
- ucMBFrame[MB_PDU_REQ_WRITE_ADDR_OFF] = usRegAddr >> 8;
- ucMBFrame[MB_PDU_REQ_WRITE_ADDR_OFF + 1] = usRegAddr;
- ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF] = usRegData >> 8;
- ucMBFrame[MB_PDU_REQ_WRITE_VALUE_OFF + 1] = usRegData ;
- vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_SIZE );
- ( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
- eErrStatus = eMBMasterWaitRequestFinish( );
- }
- return eErrStatus;
-}
-
-eMBException
-eMBMasterFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
-{
- USHORT usRegAddress;
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- if( *usLen == ( MB_PDU_SIZE_MIN + MB_PDU_FUNC_WRITE_SIZE ) )
- {
- usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_WRITE_ADDR_OFF + 1] );
- usRegAddress++;
-
- /* Make callback to update the value. */
- eRegStatus = eMBMasterRegHoldingCB( &pucFrame[MB_PDU_FUNC_WRITE_VALUE_OFF],
- usRegAddress, 1, MB_REG_WRITE );
-
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- }
- else
- {
- /* Can't be a valid request because the length is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-#endif
-
-#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
-
-/**
- * This function will request write multiple holding register.
- *
- * @param ucSndAddr salve address
- * @param usRegAddr register start address
- * @param usNRegs register total number
- * @param pusDataBuffer data to be written
- * @param lTimeOut timeout (-1 will waiting forever)
- *
- * @return error code
- */
-eMBMasterReqErrCode
-eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr,
- USHORT usRegAddr, USHORT usNRegs, USHORT * pusDataBuffer, LONG lTimeOut )
-{
- UCHAR *ucMBFrame;
- USHORT usRegIndex = 0;
- eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
-
- if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
- else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
- else
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- vMBMasterSetDestAddress(ucSndAddr);
- ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_WRITE_MULTIPLE_REGISTERS;
- ucMBFrame[MB_PDU_REQ_WRITE_MUL_ADDR_OFF] = usRegAddr >> 8;
- ucMBFrame[MB_PDU_REQ_WRITE_MUL_ADDR_OFF + 1] = usRegAddr;
- ucMBFrame[MB_PDU_REQ_WRITE_MUL_REGCNT_OFF] = usNRegs >> 8;
- ucMBFrame[MB_PDU_REQ_WRITE_MUL_REGCNT_OFF + 1] = usNRegs ;
- ucMBFrame[MB_PDU_REQ_WRITE_MUL_BYTECNT_OFF] = usNRegs * 2;
- ucMBFrame += MB_PDU_REQ_WRITE_MUL_VALUES_OFF;
- while( usNRegs > usRegIndex)
- {
- *ucMBFrame++ = pusDataBuffer[usRegIndex] >> 8;
- *ucMBFrame++ = pusDataBuffer[usRegIndex++] ;
- }
- vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_WRITE_MUL_SIZE_MIN + 2*usNRegs );
- ( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
- eErrStatus = eMBMasterWaitRequestFinish( );
- }
- return eErrStatus;
-}
-
-eMBException
-eMBMasterFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
-{
- UCHAR *ucMBFrame;
- USHORT usRegAddress;
- USHORT usRegCount;
- UCHAR ucRegByteCount;
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- /* If this request is broadcast, the *usLen is not need check. */
- if( ( *usLen == MB_PDU_SIZE_MIN + MB_PDU_FUNC_WRITE_MUL_SIZE ) || xMBMasterRequestIsBroadcast() )
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_WRITE_MUL_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( ucMBFrame[MB_PDU_REQ_WRITE_MUL_ADDR_OFF + 1] );
- usRegAddress++;
-
- usRegCount = ( USHORT )( ucMBFrame[MB_PDU_REQ_WRITE_MUL_REGCNT_OFF] << 8 );
- usRegCount |= ( USHORT )( ucMBFrame[MB_PDU_REQ_WRITE_MUL_REGCNT_OFF + 1] );
-
- ucRegByteCount = ucMBFrame[MB_PDU_REQ_WRITE_MUL_BYTECNT_OFF];
-
- if( ucRegByteCount == 2 * usRegCount )
- {
- /* Make callback to update the register values. */
- eRegStatus =
- eMBMasterRegHoldingCB( &ucMBFrame[MB_PDU_REQ_WRITE_MUL_VALUES_OFF],
- usRegAddress, usRegCount, MB_REG_WRITE );
-
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- else
- {
- /* Can't be a valid request because the length is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-#endif
-
-#if MB_FUNC_READ_HOLDING_ENABLED > 0
-
-/**
- * This function will request read holding register.
- *
- * @param ucSndAddr salve address
- * @param usRegAddr register start address
- * @param usNRegs register total number
- * @param lTimeOut timeout (-1 will waiting forever)
- *
- * @return error code
- */
-eMBMasterReqErrCode
-eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut )
-{
- UCHAR *ucMBFrame;
- eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
-
- if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
- else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
- else
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- vMBMasterSetDestAddress(ucSndAddr);
- ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_READ_HOLDING_REGISTER;
- ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] = usRegAddr >> 8;
- ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF + 1] = usRegAddr;
- ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] = usNRegs >> 8;
- ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] = usNRegs;
- vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
- ( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
- eErrStatus = eMBMasterWaitRequestFinish( );
- }
- return eErrStatus;
-}
-
-eMBException
-eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
-{
- UCHAR *ucMBFrame;
- USHORT usRegAddress;
- USHORT usRegCount;
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- /* If this request is broadcast, and it's read mode. This request don't need execute. */
- if ( xMBMasterRequestIsBroadcast() )
- {
- eStatus = MB_EX_NONE;
- }
- else if( *usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE_MIN )
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF + 1] );
- usRegAddress++;
-
- usRegCount = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] << 8 );
- usRegCount |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] );
-
- /* Check if the number of registers to read is valid. If not
- * return Modbus illegal data value exception.
- */
- if( ( usRegCount >= 1 ) && ( 2 * usRegCount == pucFrame[MB_PDU_FUNC_READ_BYTECNT_OFF] ) )
- {
- /* Make callback to fill the buffer. */
- eRegStatus = eMBMasterRegHoldingCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usRegCount, MB_REG_READ );
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- else
- {
- /* Can't be a valid request because the length is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-
-#endif
-
-#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
-
-/**
- * This function will request read and write holding register.
- *
- * @param ucSndAddr salve address
- * @param usReadRegAddr read register start address
- * @param usNReadRegs read register total number
- * @param pusDataBuffer data to be written
- * @param usWriteRegAddr write register start address
- * @param usNWriteRegs write register total number
- * @param lTimeOut timeout (-1 will waiting forever)
- *
- * @return error code
- */
-eMBMasterReqErrCode
-eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
- USHORT usReadRegAddr, USHORT usNReadRegs, USHORT * pusDataBuffer,
- USHORT usWriteRegAddr, USHORT usNWriteRegs, LONG lTimeOut )
-{
- UCHAR *ucMBFrame;
- USHORT usRegIndex = 0;
- eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
-
- if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
- else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
- else
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- vMBMasterSetDestAddress(ucSndAddr);
- ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_READWRITE_MULTIPLE_REGISTERS;
- ucMBFrame[MB_PDU_REQ_READWRITE_READ_ADDR_OFF] = usReadRegAddr >> 8;
- ucMBFrame[MB_PDU_REQ_READWRITE_READ_ADDR_OFF + 1] = usReadRegAddr;
- ucMBFrame[MB_PDU_REQ_READWRITE_READ_REGCNT_OFF] = usNReadRegs >> 8;
- ucMBFrame[MB_PDU_REQ_READWRITE_READ_REGCNT_OFF + 1] = usNReadRegs ;
- ucMBFrame[MB_PDU_REQ_READWRITE_WRITE_ADDR_OFF] = usWriteRegAddr >> 8;
- ucMBFrame[MB_PDU_REQ_READWRITE_WRITE_ADDR_OFF + 1] = usWriteRegAddr;
- ucMBFrame[MB_PDU_REQ_READWRITE_WRITE_REGCNT_OFF] = usNWriteRegs >> 8;
- ucMBFrame[MB_PDU_REQ_READWRITE_WRITE_REGCNT_OFF + 1] = usNWriteRegs ;
- ucMBFrame[MB_PDU_REQ_READWRITE_WRITE_BYTECNT_OFF] = usNWriteRegs * 2;
- ucMBFrame += MB_PDU_REQ_READWRITE_WRITE_VALUES_OFF;
- while( usNWriteRegs > usRegIndex)
- {
- *ucMBFrame++ = pusDataBuffer[usRegIndex] >> 8;
- *ucMBFrame++ = pusDataBuffer[usRegIndex++] ;
- }
- vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READWRITE_SIZE_MIN + 2*usNWriteRegs );
- ( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
- eErrStatus = eMBMasterWaitRequestFinish( );
- }
- return eErrStatus;
-}
-
-eMBException
-eMBMasterFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
-{
- USHORT usRegReadAddress;
- USHORT usRegReadCount;
- USHORT usRegWriteAddress;
- USHORT usRegWriteCount;
- UCHAR *ucMBFrame;
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- /* If this request is broadcast, and it's read mode. This request don't need execute. */
- if ( xMBMasterRequestIsBroadcast() )
- {
- eStatus = MB_EX_NONE;
- }
- else if( *usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READWRITE_SIZE_MIN )
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- usRegReadAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READWRITE_READ_ADDR_OFF] << 8U );
- usRegReadAddress |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READWRITE_READ_ADDR_OFF + 1] );
- usRegReadAddress++;
-
- usRegReadCount = ( USHORT )( ucMBFrame[MB_PDU_REQ_READWRITE_READ_REGCNT_OFF] << 8U );
- usRegReadCount |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READWRITE_READ_REGCNT_OFF + 1] );
-
- usRegWriteAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READWRITE_WRITE_ADDR_OFF] << 8U );
- usRegWriteAddress |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READWRITE_WRITE_ADDR_OFF + 1] );
- usRegWriteAddress++;
-
- usRegWriteCount = ( USHORT )( ucMBFrame[MB_PDU_REQ_READWRITE_WRITE_REGCNT_OFF] << 8U );
- usRegWriteCount |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READWRITE_WRITE_REGCNT_OFF + 1] );
-
- if( ( 2 * usRegReadCount ) == pucFrame[MB_PDU_FUNC_READWRITE_READ_BYTECNT_OFF] )
- {
- /* Make callback to update the register values. */
- eRegStatus = eMBMasterRegHoldingCB( &ucMBFrame[MB_PDU_REQ_READWRITE_WRITE_VALUES_OFF],
- usRegWriteAddress, usRegWriteCount, MB_REG_WRITE );
-
- if( eRegStatus == MB_ENOERR )
- {
- /* Make the read callback. */
- eRegStatus = eMBMasterRegHoldingCB(&pucFrame[MB_PDU_FUNC_READWRITE_READ_VALUES_OFF],
- usRegReadAddress, usRegReadCount, MB_REG_READ);
- }
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- return eStatus;
-}
-
-#endif
-#endif
-
diff --git a/components/net/freemodbus/modbus/functions/mbfuncinput.c b/components/net/freemodbus/modbus/functions/mbfuncinput.c
deleted file mode 100644
index cceedbafea..0000000000
--- a/components/net/freemodbus/modbus/functions/mbfuncinput.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbfuncinput.c,v 1.10 2007/09/12 10:15:56 wolti Exp $
- */
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mbframe.h"
-#include "mbproto.h"
-#include "mbconfig.h"
-
-/* ----------------------- Defines ------------------------------------------*/
-#define MB_PDU_FUNC_READ_ADDR_OFF ( MB_PDU_DATA_OFF )
-#define MB_PDU_FUNC_READ_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_FUNC_READ_SIZE ( 4 )
-#define MB_PDU_FUNC_READ_REGCNT_MAX ( 0x007D )
-
-#define MB_PDU_FUNC_READ_RSP_BYTECNT_OFF ( MB_PDU_DATA_OFF )
-
-/* ----------------------- Static functions ---------------------------------*/
-eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
-
-/* ----------------------- Start implementation -----------------------------*/
-#if MB_FUNC_READ_INPUT_ENABLED > 0
-
-eMBException
-eMBFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen )
-{
- USHORT usRegAddress;
- USHORT usRegCount;
- UCHAR *pucFrameCur;
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- if( *usLen == ( MB_PDU_FUNC_READ_SIZE + MB_PDU_SIZE_MIN ) )
- {
- usRegAddress = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_ADDR_OFF + 1] );
- usRegAddress++;
-
- usRegCount = ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF] << 8 );
- usRegCount |= ( USHORT )( pucFrame[MB_PDU_FUNC_READ_REGCNT_OFF + 1] );
-
- /* Check if the number of registers to read is valid. If not
- * return Modbus illegal data value exception.
- */
- if( ( usRegCount >= 1 )
- && ( usRegCount < MB_PDU_FUNC_READ_REGCNT_MAX ) )
- {
- /* Set the current PDU data pointer to the beginning. */
- pucFrameCur = &pucFrame[MB_PDU_FUNC_OFF];
- *usLen = MB_PDU_FUNC_OFF;
-
- /* First byte contains the function code. */
- *pucFrameCur++ = MB_FUNC_READ_INPUT_REGISTER;
- *usLen += 1;
-
- /* Second byte in the response contain the number of bytes. */
- *pucFrameCur++ = ( UCHAR )( usRegCount * 2 );
- *usLen += 1;
-
- eRegStatus =
- eMBRegInputCB( pucFrameCur, usRegAddress, usRegCount );
-
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- else
- {
- *usLen += usRegCount * 2;
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- else
- {
- /* Can't be a valid read input register request because the length
- * is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-
-#endif
diff --git a/components/net/freemodbus/modbus/functions/mbfuncinput_m.c b/components/net/freemodbus/modbus/functions/mbfuncinput_m.c
deleted file mode 100644
index 2127efef67..0000000000
--- a/components/net/freemodbus/modbus/functions/mbfuncinput_m.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (C) 2013 Armink <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbfuncinput_m.c,v 1.60 2013/10/12 14:23:40 Armink Add Master Functions Exp $
- */
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mb_m.h"
-#include "mbframe.h"
-#include "mbproto.h"
-#include "mbconfig.h"
-
-/* ----------------------- Defines ------------------------------------------*/
-#define MB_PDU_REQ_READ_ADDR_OFF ( MB_PDU_DATA_OFF + 0 )
-#define MB_PDU_REQ_READ_REGCNT_OFF ( MB_PDU_DATA_OFF + 2 )
-#define MB_PDU_REQ_READ_SIZE ( 4 )
-#define MB_PDU_FUNC_READ_BYTECNT_OFF ( MB_PDU_DATA_OFF + 0 )
-#define MB_PDU_FUNC_READ_VALUES_OFF ( MB_PDU_DATA_OFF + 1 )
-#define MB_PDU_FUNC_READ_SIZE_MIN ( 1 )
-
-#define MB_PDU_FUNC_READ_RSP_BYTECNT_OFF ( MB_PDU_DATA_OFF )
-
-/* ----------------------- Static functions ---------------------------------*/
-eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
-
-/* ----------------------- Start implementation -----------------------------*/
-#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
-#if MB_FUNC_READ_INPUT_ENABLED > 0
-
-/**
- * This function will request read input register.
- *
- * @param ucSndAddr salve address
- * @param usRegAddr register start address
- * @param usNRegs register total number
- * @param lTimeOut timeout (-1 will waiting forever)
- *
- * @return error code
- */
-eMBMasterReqErrCode
-eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut )
-{
- UCHAR *ucMBFrame;
- eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
-
- if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG;
- else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY;
- else
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- vMBMasterSetDestAddress(ucSndAddr);
- ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_READ_INPUT_REGISTER;
- ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] = usRegAddr >> 8;
- ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF + 1] = usRegAddr;
- ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] = usNRegs >> 8;
- ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] = usNRegs;
- vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE );
- ( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT );
- eErrStatus = eMBMasterWaitRequestFinish( );
- }
- return eErrStatus;
-}
-
-eMBException
-eMBMasterFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen )
-{
- UCHAR *ucMBFrame;
- USHORT usRegAddress;
- USHORT usRegCount;
-
- eMBException eStatus = MB_EX_NONE;
- eMBErrorCode eRegStatus;
-
- /* If this request is broadcast, and it's read mode. This request don't need execute. */
- if ( xMBMasterRequestIsBroadcast() )
- {
- eStatus = MB_EX_NONE;
- }
- else if( *usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE_MIN )
- {
- vMBMasterGetPDUSndBuf(&ucMBFrame);
- usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 );
- usRegAddress |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF + 1] );
- usRegAddress++;
-
- usRegCount = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] << 8 );
- usRegCount |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] );
-
- /* Check if the number of registers to read is valid. If not
- * return Modbus illegal data value exception.
- */
- if( ( usRegCount >= 1 ) && ( 2 * usRegCount == pucFrame[MB_PDU_FUNC_READ_BYTECNT_OFF] ) )
- {
- /* Make callback to fill the buffer. */
- eRegStatus = eMBMasterRegInputCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usRegCount );
- /* If an error occured convert it into a Modbus exception. */
- if( eRegStatus != MB_ENOERR )
- {
- eStatus = prveMBError2Exception( eRegStatus );
- }
- }
- else
- {
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- }
- else
- {
- /* Can't be a valid request because the length is incorrect. */
- eStatus = MB_EX_ILLEGAL_DATA_VALUE;
- }
- return eStatus;
-}
-
-#endif
-#endif
diff --git a/components/net/freemodbus/modbus/functions/mbfuncother.c b/components/net/freemodbus/modbus/functions/mbfuncother.c
deleted file mode 100644
index fcee972bf8..0000000000
--- a/components/net/freemodbus/modbus/functions/mbfuncother.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbfuncother.c,v 1.8 2006/12/07 22:10:34 wolti Exp $
- */
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mbframe.h"
-#include "mbproto.h"
-#include "mbconfig.h"
-
-#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED > 0
-
-/* ----------------------- Static variables ---------------------------------*/
-static UCHAR ucMBSlaveID[MB_FUNC_OTHER_REP_SLAVEID_BUF];
-static USHORT usMBSlaveIDLen;
-
-/* ----------------------- Start implementation -----------------------------*/
-
-eMBErrorCode
-eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning,
- UCHAR const *pucAdditional, USHORT usAdditionalLen )
-{
- eMBErrorCode eStatus = MB_ENOERR;
-
- /* the first byte and second byte in the buffer is reserved for
- * the parameter ucSlaveID and the running flag. The rest of
- * the buffer is available for additional data. */
- if( usAdditionalLen + 2 < MB_FUNC_OTHER_REP_SLAVEID_BUF )
- {
- usMBSlaveIDLen = 0;
- ucMBSlaveID[usMBSlaveIDLen++] = ucSlaveID;
- ucMBSlaveID[usMBSlaveIDLen++] = ( UCHAR )( xIsRunning ? 0xFF : 0x00 );
- if( usAdditionalLen > 0 )
- {
- memcpy( &ucMBSlaveID[usMBSlaveIDLen], pucAdditional,
- ( size_t )usAdditionalLen );
- usMBSlaveIDLen += usAdditionalLen;
- }
- }
- else
- {
- eStatus = MB_ENORES;
- }
- return eStatus;
-}
-
-eMBException
-eMBFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen )
-{
- memcpy( &pucFrame[MB_PDU_DATA_OFF], &ucMBSlaveID[0], ( size_t )usMBSlaveIDLen );
- *usLen = ( USHORT )( MB_PDU_DATA_OFF + usMBSlaveIDLen );
- return MB_EX_NONE;
-}
-
-#endif
diff --git a/components/net/freemodbus/modbus/functions/mbutils.c b/components/net/freemodbus/modbus/functions/mbutils.c
deleted file mode 100644
index 2afe3b84b7..0000000000
--- a/components/net/freemodbus/modbus/functions/mbutils.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbutils.c,v 1.6 2007/02/18 23:49:07 wolti Exp $
- */
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mbproto.h"
-
-/* ----------------------- Defines ------------------------------------------*/
-#define BITS_UCHAR 8U
-
-/* ----------------------- Start implementation -----------------------------*/
-void
-xMBUtilSetBits( UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits,
- UCHAR ucValue )
-{
- USHORT usWordBuf;
- USHORT usMask;
- USHORT usByteOffset;
- USHORT usNPreBits;
- USHORT usValue = ucValue;
-
- RT_ASSERT( ucNBits <= 8 );
- RT_ASSERT( ( size_t )BITS_UCHAR == sizeof( UCHAR ) * 8 );
-
- /* Calculate byte offset for first byte containing the bit values starting
- * at usBitOffset. */
- usByteOffset = ( USHORT )( ( usBitOffset ) / BITS_UCHAR );
-
- /* How many bits precede our bits to set. */
- usNPreBits = ( USHORT )( usBitOffset - usByteOffset * BITS_UCHAR );
-
- /* Move bit field into position over bits to set */
- usValue <<= usNPreBits;
-
- /* Prepare a mask for setting the new bits. */
- usMask = ( USHORT )( ( 1 << ( USHORT ) ucNBits ) - 1 );
- usMask <<= usBitOffset - usByteOffset * BITS_UCHAR;
-
- /* copy bits into temporary storage. */
- usWordBuf = ucByteBuf[usByteOffset];
- usWordBuf |= ucByteBuf[usByteOffset + 1] << BITS_UCHAR;
-
- /* Zero out bit field bits and then or value bits into them. */
- usWordBuf = ( USHORT )( ( usWordBuf & ( ~usMask ) ) | usValue );
-
- /* move bits back into storage */
- ucByteBuf[usByteOffset] = ( UCHAR )( usWordBuf & 0xFF );
- ucByteBuf[usByteOffset + 1] = ( UCHAR )( usWordBuf >> BITS_UCHAR );
-}
-
-UCHAR
-xMBUtilGetBits( UCHAR * ucByteBuf, USHORT usBitOffset, UCHAR ucNBits )
-{
- USHORT usWordBuf;
- USHORT usMask;
- USHORT usByteOffset;
- USHORT usNPreBits;
-
- /* Calculate byte offset for first byte containing the bit values starting
- * at usBitOffset. */
- usByteOffset = ( USHORT )( ( usBitOffset ) / BITS_UCHAR );
-
- /* How many bits precede our bits to set. */
- usNPreBits = ( USHORT )( usBitOffset - usByteOffset * BITS_UCHAR );
-
- /* Prepare a mask for setting the new bits. */
- usMask = ( USHORT )( ( 1 << ( USHORT ) ucNBits ) - 1 );
-
- /* copy bits into temporary storage. */
- usWordBuf = ucByteBuf[usByteOffset];
- usWordBuf |= ucByteBuf[usByteOffset + 1] << BITS_UCHAR;
-
- /* throw away unneeded bits. */
- usWordBuf >>= usNPreBits;
-
- /* mask away bits above the requested bitfield. */
- usWordBuf &= usMask;
-
- return ( UCHAR ) usWordBuf;
-}
-
-eMBException
-prveMBError2Exception( eMBErrorCode eErrorCode )
-{
- eMBException eStatus;
-
- switch ( eErrorCode )
- {
- case MB_ENOERR:
- eStatus = MB_EX_NONE;
- break;
-
- case MB_ENOREG:
- eStatus = MB_EX_ILLEGAL_DATA_ADDRESS;
- break;
-
- case MB_ETIMEDOUT:
- eStatus = MB_EX_SLAVE_BUSY;
- break;
-
- default:
- eStatus = MB_EX_SLAVE_DEVICE_FAILURE;
- break;
- }
-
- return eStatus;
-}
diff --git a/components/net/freemodbus/modbus/include/mb.h b/components/net/freemodbus/modbus/include/mb.h
deleted file mode 100644
index 8d6be7b422..0000000000
--- a/components/net/freemodbus/modbus/include/mb.h
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mb.h,v 1.17 2006/12/07 22:10:34 wolti Exp $
- */
-
-#ifndef _MB_H
-#define _MB_H
-
-#include "port.h"
-
-#ifdef __cplusplus
-PR_BEGIN_EXTERN_C
-#endif
-
-#include "mbport.h"
-#include "mbproto.h"
-
-/*! \defgroup modbus Modbus
- * \code #include "mb.h" \endcode
- *
- * This module defines the interface for the application. It contains
- * the basic functions and types required to use the Modbus protocol stack.
- * A typical application will want to call eMBInit() first. If the device
- * is ready to answer network requests it must then call eMBEnable() to activate
- * the protocol stack. In the main loop the function eMBPoll() must be called
- * periodically. The time interval between pooling depends on the configured
- * Modbus timeout. If an RTOS is available a separate task should be created
- * and the task should always call the function eMBPoll().
- *
- * \code
- * // Initialize protocol stack in RTU mode for a slave with address 10 = 0x0A
- * eMBInit( MB_RTU, 0x0A, 38400, MB_PAR_EVEN );
- * // Enable the Modbus Protocol Stack.
- * eMBEnable( );
- * for( ;; )
- * {
- * // Call the main polling loop of the Modbus protocol stack.
- * eMBPoll( );
- * ...
- * }
- * \endcode
- */
-
-/* ----------------------- Defines ------------------------------------------*/
-
-/*! \ingroup modbus
- * \brief Use the default Modbus TCP port (502)
- */
-#define MB_TCP_PORT_USE_DEFAULT 0
-
-/* ----------------------- Type definitions ---------------------------------*/
-
-/*! \ingroup modbus
- * \brief Modbus serial transmission modes (RTU/ASCII).
- *
- * Modbus serial supports two transmission modes. Either ASCII or RTU. RTU
- * is faster but has more hardware requirements and requires a network with
- * a low jitter. ASCII is slower and more reliable on slower links (E.g. modems)
- */
- typedef enum
-{
- MB_RTU, /*!< RTU transmission mode. */
- MB_ASCII, /*!< ASCII transmission mode. */
- MB_TCP /*!< TCP mode. */
-} eMBMode;
-
-/*! \ingroup modbus
- * \brief If register should be written or read.
- *
- * This value is passed to the callback functions which support either
- * reading or writing register values. Writing means that the application
- * registers should be updated and reading means that the modbus protocol
- * stack needs to know the current register values.
- *
- * \see eMBRegHoldingCB( ), eMBRegCoilsCB( ), eMBRegDiscreteCB( ) and
- * eMBRegInputCB( ).
- */
-typedef enum
-{
- MB_REG_READ, /*!< Read register values and pass to protocol stack. */
- MB_REG_WRITE /*!< Update register values. */
-} eMBRegisterMode;
-
-/*! \ingroup modbus
- * \brief Errorcodes used by all function in the protocol stack.
- */
-typedef enum
-{
- MB_ENOERR, /*!< no error. */
- MB_ENOREG, /*!< illegal register address. */
- MB_EINVAL, /*!< illegal argument. */
- MB_EPORTERR, /*!< porting layer error. */
- MB_ENORES, /*!< insufficient resources. */
- MB_EIO, /*!< I/O error. */
- MB_EILLSTATE, /*!< protocol stack in illegal state. */
- MB_ETIMEDOUT /*!< timeout error occurred. */
-} eMBErrorCode;
-
-
-/* ----------------------- Function prototypes ------------------------------*/
-/*! \ingroup modbus
- * \brief Initialize the Modbus protocol stack.
- *
- * This functions initializes the ASCII or RTU module and calls the
- * init functions of the porting layer to prepare the hardware. Please
- * note that the receiver is still disabled and no Modbus frames are
- * processed until eMBEnable( ) has been called.
- *
- * \param eMode If ASCII or RTU mode should be used.
- * \param ucSlaveAddress The slave address. Only frames sent to this
- * address or to the broadcast address are processed.
- * \param ucPort The port to use. E.g. 1 for COM1 on windows. This value
- * is platform dependent and some ports simply choose to ignore it.
- * \param ulBaudRate The baudrate. E.g. 19200. Supported baudrates depend
- * on the porting layer.
- * \param eParity Parity used for serial transmission.
- *
- * \return If no error occurs the function returns eMBErrorCode::MB_ENOERR.
- * The protocol is then in the disabled state and ready for activation
- * by calling eMBEnable( ). Otherwise one of the following error codes
- * is returned:
- * - eMBErrorCode::MB_EINVAL If the slave address was not valid. Valid
- * slave addresses are in the range 1 - 247.
- * - eMBErrorCode::MB_EPORTERR IF the porting layer returned an error.
- */
-eMBErrorCode eMBInit( eMBMode eMode, UCHAR ucSlaveAddress,
- UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity );
-
-/*! \ingroup modbus
- * \brief Initialize the Modbus protocol stack for Modbus TCP.
- *
- * This function initializes the Modbus TCP Module. Please note that
- * frame processing is still disabled until eMBEnable( ) is called.
- *
- * \param usTCPPort The TCP port to listen on.
- * \return If the protocol stack has been initialized correctly the function
- * returns eMBErrorCode::MB_ENOERR. Otherwise one of the following error
- * codes is returned:
- * - eMBErrorCode::MB_EINVAL If the slave address was not valid. Valid
- * slave addresses are in the range 1 - 247.
- * - eMBErrorCode::MB_EPORTERR IF the porting layer returned an error.
- */
-eMBErrorCode eMBTCPInit( USHORT usTCPPort );
-
-/*! \ingroup modbus
- * \brief Release resources used by the protocol stack.
- *
- * This function disables the Modbus protocol stack and release all
- * hardware resources. It must only be called when the protocol stack
- * is disabled.
- *
- * \note Note all ports implement this function. A port which wants to
- * get an callback must define the macro MB_PORT_HAS_CLOSE to 1.
- *
- * \return If the resources where released it return eMBErrorCode::MB_ENOERR.
- * If the protocol stack is not in the disabled state it returns
- * eMBErrorCode::MB_EILLSTATE.
- */
-eMBErrorCode eMBClose( void );
-
-/*! \ingroup modbus
- * \brief Enable the Modbus protocol stack.
- *
- * This function enables processing of Modbus frames. Enabling the protocol
- * stack is only possible if it is in the disabled state.
- *
- * \return If the protocol stack is now in the state enabled it returns
- * eMBErrorCode::MB_ENOERR. If it was not in the disabled state it
- * return eMBErrorCode::MB_EILLSTATE.
- */
-eMBErrorCode eMBEnable( void );
-
-/*! \ingroup modbus
- * \brief Disable the Modbus protocol stack.
- *
- * This function disables processing of Modbus frames.
- *
- * \return If the protocol stack has been disabled it returns
- * eMBErrorCode::MB_ENOERR. If it was not in the enabled state it returns
- * eMBErrorCode::MB_EILLSTATE.
- */
-eMBErrorCode eMBDisable( void );
-
-/*! \ingroup modbus
- * \brief The main pooling loop of the Modbus protocol stack.
- *
- * This function must be called periodically. The timer interval required
- * is given by the application dependent Modbus slave timeout. Internally the
- * function calls xMBPortEventGet() and waits for an event from the receiver or
- * transmitter state machines.
- *
- * \return If the protocol stack is not in the enabled state the function
- * returns eMBErrorCode::MB_EILLSTATE. Otherwise it returns
- * eMBErrorCode::MB_ENOERR.
- */
-eMBErrorCode eMBPoll( void );
-
-/*! \ingroup modbus
- * \brief Configure the slave id of the device.
- *
- * This function should be called when the Modbus function <em>Report Slave ID</em>
- * is enabled ( By defining MB_FUNC_OTHER_REP_SLAVEID_ENABLED in mbconfig.h ).
- *
- * \param ucSlaveID Values is returned in the <em>Slave ID</em> byte of the
- * <em>Report Slave ID</em> response.
- * \param xIsRunning If TRUE the <em>Run Indicator Status</em> byte is set to 0xFF.
- * otherwise the <em>Run Indicator Status</em> is 0x00.
- * \param pucAdditional Values which should be returned in the <em>Additional</em>
- * bytes of the <em> Report Slave ID</em> response.
- * \param usAdditionalLen Length of the buffer <code>pucAdditonal</code>.
- *
- * \return If the static buffer defined by MB_FUNC_OTHER_REP_SLAVEID_BUF in
- * mbconfig.h is to small it returns eMBErrorCode::MB_ENORES. Otherwise
- * it returns eMBErrorCode::MB_ENOERR.
- */
-eMBErrorCode eMBSetSlaveID( UCHAR ucSlaveID, BOOL xIsRunning,
- UCHAR const *pucAdditional,
- USHORT usAdditionalLen );
-
-/*! \ingroup modbus
- * \brief Registers a callback handler for a given function code.
- *
- * This function registers a new callback handler for a given function code.
- * The callback handler supplied is responsible for interpreting the Modbus PDU and
- * the creation of an appropriate response. In case of an error it should return
- * one of the possible Modbus exceptions which results in a Modbus exception frame
- * sent by the protocol stack.
- *
- * \param ucFunctionCode The Modbus function code for which this handler should
- * be registers. Valid function codes are in the range 1 to 127.
- * \param pxHandler The function handler which should be called in case
- * such a frame is received. If \c NULL a previously registered function handler
- * for this function code is removed.
- *
- * \return eMBErrorCode::MB_ENOERR if the handler has been installed. If no
- * more resources are available it returns eMBErrorCode::MB_ENORES. In this
- * case the values in mbconfig.h should be adjusted. If the argument was not
- * valid it returns eMBErrorCode::MB_EINVAL.
- */
-eMBErrorCode eMBRegisterCB( UCHAR ucFunctionCode,
- pxMBFunctionHandler pxHandler );
-
-/* ----------------------- Callback -----------------------------------------*/
-
-/*! \defgroup modbus_registers Modbus Registers
- * \code #include "mb.h" \endcode
- * The protocol stack does not internally allocate any memory for the
- * registers. This makes the protocol stack very small and also usable on
- * low end targets. In addition the values don't have to be in the memory
- * and could for example be stored in a flash.<br>
- * Whenever the protocol stack requires a value it calls one of the callback
- * function with the register address and the number of registers to read
- * as an argument. The application should then read the actual register values
- * (for example the ADC voltage) and should store the result in the supplied
- * buffer.<br>
- * If the protocol stack wants to update a register value because a write
- * register function was received a buffer with the new register values is
- * passed to the callback function. The function should then use these values
- * to update the application register values.
- */
-
-/*! \ingroup modbus_registers
- * \brief Callback function used if the value of a <em>Input Register</em>
- * is required by the protocol stack. The starting register address is given
- * by \c usAddress and the last register is given by <tt>usAddress +
- * usNRegs - 1</tt>.
- *
- * \param pucRegBuffer A buffer where the callback function should write
- * the current value of the modbus registers to.
- * \param usAddress The starting address of the register. Input registers
- * are in the range 1 - 65535.
- * \param usNRegs Number of registers the callback function must supply.
- *
- * \return The function must return one of the following error codes:
- * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
- * Modbus response is sent.
- * - eMBErrorCode::MB_ENOREG If the application can not supply values
- * for registers within this range. In this case a
- * <b>ILLEGAL DATA ADDRESS</b> exception frame is sent as a response.
- * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is
- * currently not available and the application dependent response
- * timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b>
- * exception is sent as a response.
- * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case
- * a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response.
- */
-eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress,
- USHORT usNRegs );
-
-/*! \ingroup modbus_registers
- * \brief Callback function used if a <em>Holding Register</em> value is
- * read or written by the protocol stack. The starting register address
- * is given by \c usAddress and the last register is given by
- * <tt>usAddress + usNRegs - 1</tt>.
- *
- * \param pucRegBuffer If the application registers values should be updated the
- * buffer points to the new registers values. If the protocol stack needs
- * to now the current values the callback function should write them into
- * this buffer.
- * \param usAddress The starting address of the register.
- * \param usNRegs Number of registers to read or write.
- * \param eMode If eMBRegisterMode::MB_REG_WRITE the application register
- * values should be updated from the values in the buffer. For example
- * this would be the case when the Modbus master has issued an
- * <b>WRITE SINGLE REGISTER</b> command.
- * If the value eMBRegisterMode::MB_REG_READ the application should copy
- * the current values into the buffer \c pucRegBuffer.
- *
- * \return The function must return one of the following error codes:
- * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
- * Modbus response is sent.
- * - eMBErrorCode::MB_ENOREG If the application can not supply values
- * for registers within this range. In this case a
- * <b>ILLEGAL DATA ADDRESS</b> exception frame is sent as a response.
- * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is
- * currently not available and the application dependent response
- * timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b>
- * exception is sent as a response.
- * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case
- * a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response.
- */
-eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress,
- USHORT usNRegs, eMBRegisterMode eMode );
-
-/*! \ingroup modbus_registers
- * \brief Callback function used if a <em>Coil Register</em> value is
- * read or written by the protocol stack. If you are going to use
- * this function you might use the functions xMBUtilSetBits( ) and
- * xMBUtilGetBits( ) for working with bitfields.
- *
- * \param pucRegBuffer The bits are packed in bytes where the first coil
- * starting at address \c usAddress is stored in the LSB of the
- * first byte in the buffer <code>pucRegBuffer</code>.
- * If the buffer should be written by the callback function unused
- * coil values (I.e. if not a multiple of eight coils is used) should be set
- * to zero.
- * \param usAddress The first coil number.
- * \param usNCoils Number of coil values requested.
- * \param eMode If eMBRegisterMode::MB_REG_WRITE the application values should
- * be updated from the values supplied in the buffer \c pucRegBuffer.
- * If eMBRegisterMode::MB_REG_READ the application should store the current
- * values in the buffer \c pucRegBuffer.
- *
- * \return The function must return one of the following error codes:
- * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
- * Modbus response is sent.
- * - eMBErrorCode::MB_ENOREG If the application does not map an coils
- * within the requested address range. In this case a
- * <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
- * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is
- * currently not available and the application dependent response
- * timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b>
- * exception is sent as a response.
- * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case
- * a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response.
- */
-eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress,
- USHORT usNCoils, eMBRegisterMode eMode );
-
-/*! \ingroup modbus_registers
- * \brief Callback function used if a <em>Input Discrete Register</em> value is
- * read by the protocol stack.
- *
- * If you are going to use his function you might use the functions
- * xMBUtilSetBits( ) and xMBUtilGetBits( ) for working with bitfields.
- *
- * \param pucRegBuffer The buffer should be updated with the current
- * coil values. The first discrete input starting at \c usAddress must be
- * stored at the LSB of the first byte in the buffer. If the requested number
- * is not a multiple of eight the remaining bits should be set to zero.
- * \param usAddress The starting address of the first discrete input.
- * \param usNDiscrete Number of discrete input values.
- * \return The function must return one of the following error codes:
- * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
- * Modbus response is sent.
- * - eMBErrorCode::MB_ENOREG If no such discrete inputs exists.
- * In this case a <b>ILLEGAL DATA ADDRESS</b> exception frame is sent
- * as a response.
- * - eMBErrorCode::MB_ETIMEDOUT If the requested register block is
- * currently not available and the application dependent response
- * timeout would be violated. In this case a <b>SLAVE DEVICE BUSY</b>
- * exception is sent as a response.
- * - eMBErrorCode::MB_EIO If an unrecoverable error occurred. In this case
- * a <b>SLAVE DEVICE FAILURE</b> exception is sent as a response.
- */
-eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress,
- USHORT usNDiscrete );
-
-#ifdef __cplusplus
-PR_END_EXTERN_C
-#endif
-#endif
diff --git a/components/net/freemodbus/modbus/include/mb_m.h b/components/net/freemodbus/modbus/include/mb_m.h
deleted file mode 100644
index f6b25e2cf3..0000000000
--- a/components/net/freemodbus/modbus/include/mb_m.h
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (C) 2013 Armink <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mb_m.h,v 1.60 2013/09/03 10:20:05 Armink Add Master Functions $
- */
-
-#ifndef _MB_M_H
-#define _MB_M_H
-
-#ifdef __cplusplus
-PR_BEGIN_EXTERN_C
-#endif
-
-/*! \defgroup modbus Modbus
- * \code #include "mb_m.h" \endcode
- *
- * This module defines the interface for the application. It contains
- * the basic functions and types required to use the Modbus Master protocol stack.
- * A typical application will want to call eMBMasterInit() first. If the device
- * is ready to answer network requests it must then call eMBEnable() to activate
- * the protocol stack. In the main loop the function eMBMasterPoll() must be called
- * periodically. The time interval between pooling depends on the configured
- * Modbus timeout. If an RTOS is available a separate task should be created
- * and the task should always call the function eMBMasterPoll().
- *
- * \code
- * // Initialize protocol stack in RTU mode for a Master
- * eMBMasterInit( MB_RTU, 38400, MB_PAR_EVEN );
- * // Enable the Modbus Protocol Stack.
- * eMBMasterEnable( );
- * for( ;; )
- * {
- * // Call the main polling loop of the Modbus Master protocol stack.
- * eMBMasterPoll( );
- * ...
- * }
- * \endcode
- */
-
-/* ----------------------- Defines ------------------------------------------*/
-
-/*! \ingroup modbus
- * \brief Use the default Modbus Master TCP port (502)
- */
-#define MB_MASTER_TCP_PORT_USE_DEFAULT 0
-
-/* ----------------------- Type definitions ---------------------------------*/
-/*! \ingroup modbus
- * \brief Errorcodes used by all function in the Master request.
- */
-typedef enum
-{
- MB_MRE_NO_ERR, /*!< no error. */
- MB_MRE_NO_REG, /*!< illegal register address. */
- MB_MRE_ILL_ARG, /*!< illegal argument. */
- MB_MRE_REV_DATA, /*!< receive data error. */
- MB_MRE_TIMEDOUT, /*!< timeout error occurred. */
- MB_MRE_MASTER_BUSY, /*!< master is busy now. */
- MB_MRE_EXE_FUN /*!< execute function error. */
-} eMBMasterReqErrCode;
-/*! \ingroup modbus
- * \brief TimerMode is Master 3 kind of Timer modes.
- */
-typedef enum
-{
- MB_TMODE_T35, /*!< Master receive frame T3.5 timeout. */
- MB_TMODE_RESPOND_TIMEOUT, /*!< Master wait respond for slave. */
- MB_TMODE_CONVERT_DELAY /*!< Master sent broadcast ,then delay sometime.*/
-}eMBMasterTimerMode;
-
-/* ----------------------- Function prototypes ------------------------------*/
-/*! \ingroup modbus
- * \brief Initialize the Modbus Master protocol stack.
- *
- * This functions initializes the ASCII or RTU module and calls the
- * init functions of the porting layer to prepare the hardware. Please
- * note that the receiver is still disabled and no Modbus frames are
- * processed until eMBMasterEnable( ) has been called.
- *
- * \param eMode If ASCII or RTU mode should be used.
- * \param ucPort The port to use. E.g. 1 for COM1 on windows. This value
- * is platform dependent and some ports simply choose to ignore it.
- * \param ulBaudRate The baudrate. E.g. 19200. Supported baudrates depend
- * on the porting layer.
- * \param eParity Parity used for serial transmission.
- *
- * \return If no error occurs the function returns eMBErrorCode::MB_ENOERR.
- * The protocol is then in the disabled state and ready for activation
- * by calling eMBMasterEnable( ). Otherwise one of the following error codes
- * is returned:
- * - eMBErrorCode::MB_EPORTERR IF the porting layer returned an error.
- */
-eMBErrorCode eMBMasterInit( eMBMode eMode, UCHAR ucPort,
- ULONG ulBaudRate, eMBParity eParity );
-
-/*! \ingroup modbus
- * \brief Initialize the Modbus Master protocol stack for Modbus TCP.
- *
- * This function initializes the Modbus TCP Module. Please note that
- * frame processing is still disabled until eMBEnable( ) is called.
- *
- * \param usTCPPort The TCP port to listen on.
- * \return If the protocol stack has been initialized correctly the function
- * returns eMBErrorCode::MB_ENOERR. Otherwise one of the following error
- * codes is returned:
- * - eMBErrorCode::MB_EINVAL If the slave address was not valid. Valid
- * slave addresses are in the range 1 - 247.
- * - eMBErrorCode::MB_EPORTERR IF the porting layer returned an error.
- */
-eMBErrorCode eMBMasterTCPInit( USHORT usTCPPort );
-
-/*! \ingroup modbus
- * \brief Release resources used by the protocol stack.
- *
- * This function disables the Modbus Master protocol stack and release all
- * hardware resources. It must only be called when the protocol stack
- * is disabled.
- *
- * \note Note all ports implement this function. A port which wants to
- * get an callback must define the macro MB_PORT_HAS_CLOSE to 1.
- *
- * \return If the resources where released it return eMBErrorCode::MB_ENOERR.
- * If the protocol stack is not in the disabled state it returns
- * eMBErrorCode::MB_EILLSTATE.
- */
-eMBErrorCode eMBMasterClose( void );
-
-/*! \ingroup modbus
- * \brief Enable the Modbus Master protocol stack.
- *
- * This function enables processing of Modbus Master frames. Enabling the protocol
- * stack is only possible if it is in the disabled state.
- *
- * \return If the protocol stack is now in the state enabled it returns
- * eMBErrorCode::MB_ENOERR. If it was not in the disabled state it
- * return eMBErrorCode::MB_EILLSTATE.
- */
-eMBErrorCode eMBMasterEnable( void );
-
-/*! \ingroup modbus
- * \brief Disable the Modbus Master protocol stack.
- *
- * This function disables processing of Modbus frames.
- *
- * \return If the protocol stack has been disabled it returns
- * eMBErrorCode::MB_ENOERR. If it was not in the enabled state it returns
- * eMBErrorCode::MB_EILLSTATE.
- */
-eMBErrorCode eMBMasterDisable( void );
-
-/*! \ingroup modbus
- * \brief The main pooling loop of the Modbus Master protocol stack.
- *
- * This function must be called periodically. The timer interval required
- * is given by the application dependent Modbus slave timeout. Internally the
- * function calls xMBMasterPortEventGet() and waits for an event from the receiver or
- * transmitter state machines.
- *
- * \return If the protocol stack is not in the enabled state the function
- * returns eMBErrorCode::MB_EILLSTATE. Otherwise it returns
- * eMBErrorCode::MB_ENOERR.
- */
-eMBErrorCode eMBMasterPoll( void );
-
-/*! \ingroup modbus
- * \brief Registers a callback handler for a given function code.
- *
- * This function registers a new callback handler for a given function code.
- * The callback handler supplied is responsible for interpreting the Modbus PDU and
- * the creation of an appropriate response. In case of an error it should return
- * one of the possible Modbus exceptions which results in a Modbus exception frame
- * sent by the protocol stack.
- *
- * \param ucFunctionCode The Modbus function code for which this handler should
- * be registers. Valid function codes are in the range 1 to 127.
- * \param pxHandler The function handler which should be called in case
- * such a frame is received. If \c NULL a previously registered function handler
- * for this function code is removed.
- *
- * \return eMBErrorCode::MB_ENOERR if the handler has been installed. If no
- * more resources are available it returns eMBErrorCode::MB_ENORES. In this
- * case the values in mbconfig.h should be adjusted. If the argument was not
- * valid it returns eMBErrorCode::MB_EINVAL.
- */
-eMBErrorCode eMBMasterRegisterCB( UCHAR ucFunctionCode,
- pxMBFunctionHandler pxHandler );
-
-/* ----------------------- Callback -----------------------------------------*/
-
-/*! \defgroup modbus_master registers Modbus Registers
- * \code #include "mb_m.h" \endcode
- * The protocol stack does not internally allocate any memory for the
- * registers. This makes the protocol stack very small and also usable on
- * low end targets. In addition the values don't have to be in the memory
- * and could for example be stored in a flash.<br>
- * Whenever the protocol stack requires a value it calls one of the callback
- * function with the register address and the number of registers to read
- * as an argument. The application should then read the actual register values
- * (for example the ADC voltage) and should store the result in the supplied
- * buffer.<br>
- * If the protocol stack wants to update a register value because a write
- * register function was received a buffer with the new register values is
- * passed to the callback function. The function should then use these values
- * to update the application register values.
- */
-
-/*! \ingroup modbus_registers
- * \brief Callback function used if the value of a <em>Input Register</em>
- * is required by the protocol stack. The starting register address is given
- * by \c usAddress and the last register is given by <tt>usAddress +
- * usNRegs - 1</tt>.
- *
- * \param pucRegBuffer A buffer where the callback function should write
- * the current value of the modbus registers to.
- * \param usAddress The starting address of the register. Input registers
- * are in the range 1 - 65535.
- * \param usNRegs Number of registers the callback function must supply.
- *
- * \return The function must return one of the following error codes:
- * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
- * Modbus response is sent.
- * - eMBErrorCode::MB_ENOREG If the application does not map an coils
- * within the requested address range. In this case a
- * <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
- */
-eMBErrorCode eMBMasterRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress,
- USHORT usNRegs );
-
-/*! \ingroup modbus_registers
- * \brief Callback function used if a <em>Holding Register</em> value is
- * read or written by the protocol stack. The starting register address
- * is given by \c usAddress and the last register is given by
- * <tt>usAddress + usNRegs - 1</tt>.
- *
- * \param pucRegBuffer If the application registers values should be updated the
- * buffer points to the new registers values. If the protocol stack needs
- * to now the current values the callback function should write them into
- * this buffer.
- * \param usAddress The starting address of the register.
- * \param usNRegs Number of registers to read or write.
- * \param eMode If eMBRegisterMode::MB_REG_WRITE the application register
- * values should be updated from the values in the buffer. For example
- * this would be the case when the Modbus master has issued an
- * <b>WRITE SINGLE REGISTER</b> command.
- * If the value eMBRegisterMode::MB_REG_READ the application should copy
- * the current values into the buffer \c pucRegBuffer.
- *
- * \return The function must return one of the following error codes:
- * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
- * Modbus response is sent.
- * - eMBErrorCode::MB_ENOREG If the application does not map an coils
- * within the requested address range. In this case a
- * <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
- */
-eMBErrorCode eMBMasterRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress,
- USHORT usNRegs, eMBRegisterMode eMode );
-
-/*! \ingroup modbus_registers
- * \brief Callback function used if a <em>Coil Register</em> value is
- * read or written by the protocol stack. If you are going to use
- * this function you might use the functions xMBUtilSetBits( ) and
- * xMBUtilGetBits( ) for working with bitfields.
- *
- * \param pucRegBuffer The bits are packed in bytes where the first coil
- * starting at address \c usAddress is stored in the LSB of the
- * first byte in the buffer <code>pucRegBuffer</code>.
- * If the buffer should be written by the callback function unused
- * coil values (I.e. if not a multiple of eight coils is used) should be set
- * to zero.
- * \param usAddress The first coil number.
- * \param usNCoils Number of coil values requested.
- * \param eMode If eMBRegisterMode::MB_REG_WRITE the application values should
- * be updated from the values supplied in the buffer \c pucRegBuffer.
- * If eMBRegisterMode::MB_REG_READ the application should store the current
- * values in the buffer \c pucRegBuffer.
- *
- * \return The function must return one of the following error codes:
- * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
- * Modbus response is sent.
- * - eMBErrorCode::MB_ENOREG If the application does not map an coils
- * within the requested address range. In this case a
- * <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
- */
-eMBErrorCode eMBMasterRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress,
- USHORT usNCoils, eMBRegisterMode eMode );
-
-/*! \ingroup modbus_registers
- * \brief Callback function used if a <em>Input Discrete Register</em> value is
- * read by the protocol stack.
- *
- * If you are going to use his function you might use the functions
- * xMBUtilSetBits( ) and xMBUtilGetBits( ) for working with bitfields.
- *
- * \param pucRegBuffer The buffer should be updated with the current
- * coil values. The first discrete input starting at \c usAddress must be
- * stored at the LSB of the first byte in the buffer. If the requested number
- * is not a multiple of eight the remaining bits should be set to zero.
- * \param usAddress The starting address of the first discrete input.
- * \param usNDiscrete Number of discrete input values.
- * \return The function must return one of the following error codes:
- * - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
- * Modbus response is sent.
- * - eMBErrorCode::MB_ENOREG If the application does not map an coils
- * within the requested address range. In this case a
- * <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
- */
-eMBErrorCode eMBMasterRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress,
- USHORT usNDiscrete );
-
-/*! \ingroup modbus
- *\brief These Modbus functions are called for user when Modbus run in Master Mode.
- */
-eMBMasterReqErrCode
-eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut );
-eMBMasterReqErrCode
-eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRegData, LONG lTimeOut );
-eMBMasterReqErrCode
-eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr,
- USHORT usNRegs, USHORT * pusDataBuffer, LONG lTimeOut );
-eMBMasterReqErrCode
-eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut );
-eMBMasterReqErrCode
-eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
- USHORT usReadRegAddr, USHORT usNReadRegs, USHORT * pusDataBuffer,
- USHORT usWriteRegAddr, USHORT usNWriteRegs, LONG lTimeOut );
-eMBMasterReqErrCode
-eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils, LONG lTimeOut );
-eMBMasterReqErrCode
-eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData, LONG lTimeOut );
-eMBMasterReqErrCode
-eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
- USHORT usCoilAddr, USHORT usNCoils, UCHAR * pucDataBuffer, LONG lTimeOut );
-eMBMasterReqErrCode
-eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT usNDiscreteIn, LONG lTimeOut );
-
-eMBException
-eMBMasterFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen );
-eMBException
-eMBMasterFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen );
-eMBException
-eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen );
-eMBException
-eMBMasterFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen );
-eMBException
-eMBMasterFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen );
-eMBException
-eMBMasterFuncReadCoils( UCHAR * pucFrame, USHORT * usLen );
-eMBException
-eMBMasterFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen );
-eMBException
-eMBMasterFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen );
-eMBException
-eMBMasterFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen );
-eMBException
-eMBMasterFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen );
-
-/*�� \ingroup modbus
- *\brief These functions are interface for Modbus Master
- */
-void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame );
-UCHAR ucMBMasterGetDestAddress( void );
-void vMBMasterSetDestAddress( UCHAR Address );
-BOOL xMBMasterGetCBRunInMasterMode( void );
-void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode );
-USHORT usMBMasterGetPDUSndLength( void );
-void vMBMasterSetPDUSndLength( USHORT SendPDULength );
-void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode );
-BOOL xMBMasterRequestIsBroadcast( void );
-eMBMasterErrorEventType eMBMasterGetErrorType( void );
-void vMBMasterSetErrorType( eMBMasterErrorEventType errorType );
-eMBMasterReqErrCode eMBMasterWaitRequestFinish( void );
-
-/* ----------------------- Callback -----------------------------------------*/
-
-#ifdef __cplusplus
-PR_END_EXTERN_C
-#endif
-#endif
diff --git a/components/net/freemodbus/modbus/include/mbconfig.h b/components/net/freemodbus/modbus/include/mbconfig.h
deleted file mode 100644
index 89030b7abd..0000000000
--- a/components/net/freemodbus/modbus/include/mbconfig.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbconfig.h,v 1.14 2006/12/07 22:10:34 wolti Exp $
- * $Id: mbconfig.h,v 1.60 2013/08/13 21:19:55 Armink Add Master Functions $
- */
-
-#ifndef _MB_CONFIG_H
-#define _MB_CONFIG_H
-
-#ifdef __cplusplus
-PR_BEGIN_EXTERN_C
-#endif
-/* ----------------------- Defines ------------------------------------------*/
-/*! \defgroup modbus_cfg Modbus Configuration
- *
- * Most modules in the protocol stack are completly optional and can be
- * excluded. This is specially important if target resources are very small
- * and program memory space should be saved.<br>
- *
- * All of these settings are available in the file <code>mbconfig.h</code>
- */
-/*! \addtogroup modbus_cfg
- * @{
- */
-/*! \brief If Modbus Master ASCII support is enabled. */
-#define MB_MASTER_ASCII_ENABLED ( 0 )
-/*! \brief If Modbus Master RTU support is enabled. */
-#define MB_MASTER_RTU_ENABLED ( 1 )
-/*! \brief If Modbus Master TCP support is enabled. */
-#define MB_MASTER_TCP_ENABLED ( 0 )
-/*! \brief If Modbus Slave ASCII support is enabled. */
-#define MB_SLAVE_ASCII_ENABLED ( 0 )
-/*! \brief If Modbus Slave RTU support is enabled. */
-#define MB_SLAVE_RTU_ENABLED ( 1 )
-/*! \brief If Modbus Slave TCP support is enabled. */
-#define MB_SLAVE_TCP_ENABLED ( 0 )
-/*! \brief The character timeout value for Modbus ASCII.
- *
- * The character timeout value is not fixed for Modbus ASCII and is therefore
- * a configuration option. It should be set to the maximum expected delay
- * time of the network.
- */
-#define MB_ASCII_TIMEOUT_SEC ( 1 )
-/*! \brief Maximum number of Modbus functions codes the protocol stack
- * should support.
- *
- * The maximum number of supported Modbus functions must be greater than
- * the sum of all enabled functions in this file and custom function
- * handlers. If set to small adding more functions will fail.
- */
-#define MB_FUNC_HANDLERS_MAX ( 16 )
-/*! \brief Number of bytes which should be allocated for the <em>Report Slave ID
- * </em>command.
- *
- * This number limits the maximum size of the additional segment in the
- * report slave id function. See eMBSetSlaveID( ) for more information on
- * how to set this value. It is only used if MB_FUNC_OTHER_REP_SLAVEID_ENABLED
- * is set to <code>1</code>.
- */
-#define MB_FUNC_OTHER_REP_SLAVEID_BUF ( 32 )
-/*! \brief If the <em>Report Slave ID</em> function should be enabled. */
-#define MB_FUNC_OTHER_REP_SLAVEID_ENABLED ( 1 )
-/*! \brief If the <em>Read Input Registers</em> function should be enabled. */
-#define MB_FUNC_READ_INPUT_ENABLED ( 1 )
-/*! \brief If the <em>Read Holding Registers</em> function should be enabled. */
-#define MB_FUNC_READ_HOLDING_ENABLED ( 1 )
-/*! \brief If the <em>Write Single Register</em> function should be enabled. */
-#define MB_FUNC_WRITE_HOLDING_ENABLED ( 1 )
-/*! \brief If the <em>Write Multiple registers</em> function should be enabled. */
-#define MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED ( 1 )
-/*! \brief If the <em>Read Coils</em> function should be enabled. */
-#define MB_FUNC_READ_COILS_ENABLED ( 1 )
-/*! \brief If the <em>Write Coils</em> function should be enabled. */
-#define MB_FUNC_WRITE_COIL_ENABLED ( 1 )
-/*! \brief If the <em>Write Multiple Coils</em> function should be enabled. */
-#define MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED ( 1 )
-/*! \brief If the <em>Read Discrete Inputs</em> function should be enabled. */
-#define MB_FUNC_READ_DISCRETE_INPUTS_ENABLED ( 1 )
-/*! \brief If the <em>Read/Write Multiple Registers</em> function should be enabled. */
-#define MB_FUNC_READWRITE_HOLDING_ENABLED ( 1 )
-/*! @} */
-#ifdef __cplusplus
- PR_END_EXTERN_C
-#endif
-
-#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
-/*! \brief If master send a broadcast frame,the master will wait time of convert to delay,
- * then master can send other frame */
-#define MB_MASTER_DELAY_MS_CONVERT (200 )
-/*! \brief If master send a frame which is not broadcast,the master will wait sometime for slave.
- * And if slave is not respond in this time,the master will process this timeout error.
- * Then master can send other frame */
-#define MB_MASTER_TIMEOUT_MS_RESPOND (100 )
-/*! \brief The total slaves in Modbus Master system. Default 16.
- * \note : The slave ID must be continuous from 1.*/
-#define MB_MASTER_TOTAL_SLAVE_NUM ( 16 )
-#endif
-
-#endif
diff --git a/components/net/freemodbus/modbus/include/mbframe.h b/components/net/freemodbus/modbus/include/mbframe.h
deleted file mode 100644
index 99d59c613e..0000000000
--- a/components/net/freemodbus/modbus/include/mbframe.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbframe.h,v 1.9 2006/12/07 22:10:34 wolti Exp $
- */
-
-#ifndef _MB_FRAME_H
-#define _MB_FRAME_H
-
-#ifdef __cplusplus
-PR_BEGIN_EXTERN_C
-#endif
-
-/*!
- * Constants which defines the format of a modbus frame. The example is
- * shown for a Modbus RTU/ASCII frame. Note that the Modbus PDU is not
- * dependent on the underlying transport.
- *
- * <code>
- * <------------------------ MODBUS SERIAL LINE PDU (1) ------------------->
- * <----------- MODBUS PDU (1') ---------------->
- * +-----------+---------------+----------------------------+-------------+
- * | Address | Function Code | Data | CRC/LRC |
- * +-----------+---------------+----------------------------+-------------+
- * | | | |
- * (2) (3/2') (3') (4)
- *
- * (1) ... MB_SER_PDU_SIZE_MAX = 256
- * (2) ... MB_SER_PDU_ADDR_OFF = 0
- * (3) ... MB_SER_PDU_PDU_OFF = 1
- * (4) ... MB_SER_PDU_SIZE_CRC = 2
- *
- * (1') ... MB_PDU_SIZE_MAX = 253
- * (2') ... MB_PDU_FUNC_OFF = 0
- * (3') ... MB_PDU_DATA_OFF = 1
- * </code>
- */
-
-/* ----------------------- Defines ------------------------------------------*/
-#define MB_PDU_SIZE_MAX 253 /*!< Maximum size of a PDU. */
-#define MB_PDU_SIZE_MIN 1 /*!< Function Code */
-#define MB_PDU_FUNC_OFF 0 /*!< Offset of function code in PDU. */
-#define MB_PDU_DATA_OFF 1 /*!< Offset for response data in PDU. */
-
-/* ----------------------- Prototypes 0-------------------------------------*/
-typedef void ( *pvMBFrameStart ) ( void );
-
-typedef void ( *pvMBFrameStop ) ( void );
-
-typedef eMBErrorCode( *peMBFrameReceive ) ( UCHAR * pucRcvAddress,
- UCHAR ** pucFrame,
- USHORT * pusLength );
-
-typedef eMBErrorCode( *peMBFrameSend ) ( UCHAR slaveAddress,
- const UCHAR * pucFrame,
- USHORT usLength );
-
-typedef void( *pvMBFrameClose ) ( void );
-
-#ifdef __cplusplus
-PR_END_EXTERN_C
-#endif
-#endif
diff --git a/components/net/freemodbus/modbus/include/mbfunc.h b/components/net/freemodbus/modbus/include/mbfunc.h
deleted file mode 100644
index 3f9c2725a1..0000000000
--- a/components/net/freemodbus/modbus/include/mbfunc.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbfunc.h,v 1.12 2006/12/07 22:10:34 wolti Exp $
- */
-
-#ifndef _MB_FUNC_H
-#define _MB_FUNC_H
-
-#ifdef __cplusplus
-PR_BEGIN_EXTERN_C
-#endif
-#if MB_FUNC_OTHER_REP_SLAVEID_BUF > 0
-eMBException eMBFuncReportSlaveID( UCHAR * pucFrame, USHORT * usLen );
-#endif
-
-#if MB_FUNC_READ_INPUT_ENABLED > 0
-eMBException eMBFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen );
-#endif
-
-#if MB_FUNC_READ_HOLDING_ENABLED > 0
-eMBException eMBFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen );
-#endif
-
-#if MB_FUNC_WRITE_HOLDING_ENABLED > 0
-eMBException eMBFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen );
-#endif
-
-#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
-eMBException eMBFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen );
-#endif
-
-#if MB_FUNC_READ_COILS_ENABLED > 0
-eMBException eMBFuncReadCoils( UCHAR * pucFrame, USHORT * usLen );
-#endif
-
-#if MB_FUNC_WRITE_COIL_ENABLED > 0
-eMBException eMBFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen );
-#endif
-
-#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
-eMBException eMBFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen );
-#endif
-
-#if MB_FUNC_READ_DISCRETE_INPUTS_ENABLED > 0
-eMBException eMBFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen );
-#endif
-
-#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
-eMBException eMBFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen );
-#endif
-
-#ifdef __cplusplus
-PR_END_EXTERN_C
-#endif
-#endif
diff --git a/components/net/freemodbus/modbus/include/mbport.h b/components/net/freemodbus/modbus/include/mbport.h
deleted file mode 100644
index 11794a2929..0000000000
--- a/components/net/freemodbus/modbus/include/mbport.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbport.h,v 1.17 2006/12/07 22:10:34 wolti Exp $
- * mbport.h,v 1.60 2013/08/17 11:42:56 Armink Add Master Functions $
- */
-
-#ifndef _MB_PORT_H
-#define _MB_PORT_H
-
-#ifdef __cplusplus
-PR_BEGIN_EXTERN_C
-#endif
-
-/* ----------------------- Defines ------------------------------------------*/
-
-/* ----------------------- Type definitions ---------------------------------*/
-
-typedef enum
-{
- EV_READY = 1<<0, /*!< Startup finished. */
- EV_FRAME_RECEIVED = 1<<1, /*!< Frame received. */
- EV_EXECUTE = 1<<2, /*!< Execute function. */
- EV_FRAME_SENT = 1<<3 /*!< Frame sent. */
-} eMBEventType;
-
-typedef enum
-{
- EV_MASTER_READY = 1<<0, /*!< Startup finished. */
- EV_MASTER_FRAME_RECEIVED = 1<<1, /*!< Frame received. */
- EV_MASTER_EXECUTE = 1<<2, /*!< Execute function. */
- EV_MASTER_FRAME_SENT = 1<<3, /*!< Frame sent. */
- EV_MASTER_ERROR_PROCESS = 1<<4, /*!< Frame error process. */
- EV_MASTER_PROCESS_SUCESS = 1<<5, /*!< Request process success. */
- EV_MASTER_ERROR_RESPOND_TIMEOUT = 1<<6, /*!< Request respond timeout. */
- EV_MASTER_ERROR_RECEIVE_DATA = 1<<7, /*!< Request receive data error. */
- EV_MASTER_ERROR_EXECUTE_FUNCTION = 1<<8, /*!< Request execute function error. */
-} eMBMasterEventType;
-
-typedef enum
-{
- EV_ERROR_RESPOND_TIMEOUT, /*!< Slave respond timeout. */
- EV_ERROR_RECEIVE_DATA, /*!< Receive frame data erroe. */
- EV_ERROR_EXECUTE_FUNCTION, /*!< Execute function error. */
-} eMBMasterErrorEventType;
-
-/*! \ingroup modbus
- * \brief Parity used for characters in serial mode.
- *
- * The parity which should be applied to the characters sent over the serial
- * link. Please note that this values are actually passed to the porting
- * layer and therefore not all parity modes might be available.
- */
-typedef enum
-{
- MB_PAR_NONE, /*!< No parity. */
- MB_PAR_ODD, /*!< Odd parity. */
- MB_PAR_EVEN /*!< Even parity. */
-} eMBParity;
-
-/* ----------------------- Supporting functions -----------------------------*/
-BOOL xMBPortEventInit( void );
-
-BOOL xMBPortEventPost( eMBEventType eEvent );
-
-BOOL xMBPortEventGet( /*@out@ */ eMBEventType * eEvent );
-
-BOOL xMBMasterPortEventInit( void );
-
-BOOL xMBMasterPortEventPost( eMBMasterEventType eEvent );
-
-BOOL xMBMasterPortEventGet( /*@out@ */ eMBMasterEventType * eEvent );
-
-void vMBMasterOsResInit( void );
-
-BOOL xMBMasterRunResTake( int32_t time );
-
-void vMBMasterRunResRelease( void );
-
-/* ----------------------- Serial port functions ----------------------------*/
-
-BOOL xMBPortSerialInit( UCHAR ucPort, ULONG ulBaudRate,
- UCHAR ucDataBits, eMBParity eParity );
-
-void vMBPortClose( void );
-
-void xMBPortSerialClose( void );
-
-void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable );
-
-INLINE BOOL xMBPortSerialGetByte( CHAR * pucByte );
-
-INLINE BOOL xMBPortSerialPutByte( CHAR ucByte );
-
-BOOL xMBMasterPortSerialInit( UCHAR ucPort, ULONG ulBaudRate,
- UCHAR ucDataBits, eMBParity eParity );
-
-void vMBMasterPortClose( void );
-
-void xMBMasterPortSerialClose( void );
-
-void vMBMasterPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable );
-
-INLINE BOOL xMBMasterPortSerialGetByte( CHAR * pucByte );
-
-INLINE BOOL xMBMasterPortSerialPutByte( CHAR ucByte );
-
-/* ----------------------- Timers functions ---------------------------------*/
-BOOL xMBPortTimersInit( USHORT usTimeOut50us );
-
-void xMBPortTimersClose( void );
-
-INLINE void vMBPortTimersEnable( void );
-
-INLINE void vMBPortTimersDisable( void );
-
-BOOL xMBMasterPortTimersInit( USHORT usTimeOut50us );
-
-void xMBMasterPortTimersClose( void );
-
-INLINE void vMBMasterPortTimersT35Enable( void );
-
-INLINE void vMBMasterPortTimersConvertDelayEnable( void );
-
-INLINE void vMBMasterPortTimersRespondTimeoutEnable( void );
-
-INLINE void vMBMasterPortTimersDisable( void );
-
-/* ----------------- Callback for the master error process ------------------*/
-void vMBMasterErrorCBRespondTimeout( UCHAR ucDestAddress, const UCHAR* pucPDUData,
- USHORT ucPDULength );
-
-void vMBMasterErrorCBReceiveData( UCHAR ucDestAddress, const UCHAR* pucPDUData,
- USHORT ucPDULength );
-
-void vMBMasterErrorCBExecuteFunction( UCHAR ucDestAddress, const UCHAR* pucPDUData,
- USHORT ucPDULength );
-
-void vMBMasterCBRequestScuuess( void );
-
-/* ----------------------- Callback for the protocol stack ------------------*/
-
-/*!
- * \brief Callback function for the porting layer when a new byte is
- * available.
- *
- * Depending upon the mode this callback function is used by the RTU or
- * ASCII transmission layers. In any case a call to xMBPortSerialGetByte()
- * must immediately return a new character.
- *
- * \return <code>TRUE</code> if a event was posted to the queue because
- * a new byte was received. The port implementation should wake up the
- * tasks which are currently blocked on the eventqueue.
- */
-extern BOOL( *pxMBFrameCBByteReceived ) ( void );
-
-extern BOOL( *pxMBFrameCBTransmitterEmpty ) ( void );
-
-extern BOOL( *pxMBPortCBTimerExpired ) ( void );
-
-extern BOOL( *pxMBMasterFrameCBByteReceived ) ( void );
-
-extern BOOL( *pxMBMasterFrameCBTransmitterEmpty ) ( void );
-
-extern BOOL( *pxMBMasterPortCBTimerExpired ) ( void );
-
-/* ----------------------- TCP port functions -------------------------------*/
-BOOL xMBTCPPortInit( USHORT usTCPPort );
-
-void vMBTCPPortClose( void );
-
-void vMBTCPPortDisable( void );
-
-BOOL xMBTCPPortGetRequest( UCHAR **ppucMBTCPFrame, USHORT * usTCPLength );
-
-BOOL xMBTCPPortSendResponse( const UCHAR *pucMBTCPFrame, USHORT usTCPLength );
-
-#ifdef __cplusplus
-PR_END_EXTERN_C
-#endif
-#endif
diff --git a/components/net/freemodbus/modbus/include/mbproto.h b/components/net/freemodbus/modbus/include/mbproto.h
deleted file mode 100644
index 786aaf4030..0000000000
--- a/components/net/freemodbus/modbus/include/mbproto.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbproto.h,v 1.14 2006/12/07 22:10:34 wolti Exp $
- */
-
-#ifndef _MB_PROTO_H
-#define _MB_PROTO_H
-
-#ifdef __cplusplus
-PR_BEGIN_EXTERN_C
-#endif
-/* ----------------------- Defines ------------------------------------------*/
-#define MB_ADDRESS_BROADCAST ( 0 ) /*! Modbus broadcast address. */
-#define MB_ADDRESS_MIN ( 1 ) /*! Smallest possible slave address. */
-#define MB_ADDRESS_MAX ( 247 ) /*! Biggest possible slave address. */
-#define MB_FUNC_NONE ( 0 )
-#define MB_FUNC_READ_COILS ( 1 )
-#define MB_FUNC_READ_DISCRETE_INPUTS ( 2 )
-#define MB_FUNC_WRITE_SINGLE_COIL ( 5 )
-#define MB_FUNC_WRITE_MULTIPLE_COILS ( 15 )
-#define MB_FUNC_READ_HOLDING_REGISTER ( 3 )
-#define MB_FUNC_READ_INPUT_REGISTER ( 4 )
-#define MB_FUNC_WRITE_REGISTER ( 6 )
-#define MB_FUNC_WRITE_MULTIPLE_REGISTERS ( 16 )
-#define MB_FUNC_READWRITE_MULTIPLE_REGISTERS ( 23 )
-#define MB_FUNC_DIAG_READ_EXCEPTION ( 7 )
-#define MB_FUNC_DIAG_DIAGNOSTIC ( 8 )
-#define MB_FUNC_DIAG_GET_COM_EVENT_CNT ( 11 )
-#define MB_FUNC_DIAG_GET_COM_EVENT_LOG ( 12 )
-#define MB_FUNC_OTHER_REPORT_SLAVEID ( 17 )
-#define MB_FUNC_ERROR ( 128 )
-/* ----------------------- Type definitions ---------------------------------*/
- typedef enum
-{
- MB_EX_NONE = 0x00,
- MB_EX_ILLEGAL_FUNCTION = 0x01,
- MB_EX_ILLEGAL_DATA_ADDRESS = 0x02,
- MB_EX_ILLEGAL_DATA_VALUE = 0x03,
- MB_EX_SLAVE_DEVICE_FAILURE = 0x04,
- MB_EX_ACKNOWLEDGE = 0x05,
- MB_EX_SLAVE_BUSY = 0x06,
- MB_EX_MEMORY_PARITY_ERROR = 0x08,
- MB_EX_GATEWAY_PATH_FAILED = 0x0A,
- MB_EX_GATEWAY_TGT_FAILED = 0x0B
-} eMBException;
-
-typedef eMBException( *pxMBFunctionHandler ) ( UCHAR * pucFrame, USHORT * pusLength );
-
-typedef struct
-{
- UCHAR ucFunctionCode;
- pxMBFunctionHandler pxHandler;
-} xMBFunctionHandler;
-
-#ifdef __cplusplus
-PR_END_EXTERN_C
-#endif
-#endif
diff --git a/components/net/freemodbus/modbus/include/mbutils.h b/components/net/freemodbus/modbus/include/mbutils.h
deleted file mode 100644
index 61495751d4..0000000000
--- a/components/net/freemodbus/modbus/include/mbutils.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbutils.h,v 1.5 2006/12/07 22:10:34 wolti Exp $
- */
-
-#ifndef _MB_UTILS_H
-#define _MB_UTILS_H
-
-#ifdef __cplusplus
-PR_BEGIN_EXTERN_C
-#endif
-/*! \defgroup modbus_utils Utilities
- *
- * This module contains some utility functions which can be used by
- * the application. It includes some special functions for working with
- * bitfields backed by a character array buffer.
- *
- */
-/*! \addtogroup modbus_utils
- * @{
- */
-/*! \brief Function to set bits in a byte buffer.
- *
- * This function allows the efficient use of an array to implement bitfields.
- * The array used for storing the bits must always be a multiple of two
- * bytes. Up to eight bits can be set or cleared in one operation.
- *
- * \param ucByteBuf A buffer where the bit values are stored. Must be a
- * multiple of 2 bytes. No length checking is performed and if
- * usBitOffset / 8 is greater than the size of the buffer memory contents
- * is overwritten.
- * \param usBitOffset The starting address of the bits to set. The first
- * bit has the offset 0.
- * \param ucNBits Number of bits to modify. The value must always be smaller
- * than 8.
- * \param ucValues Thew new values for the bits. The value for the first bit
- * starting at <code>usBitOffset</code> is the LSB of the value
- * <code>ucValues</code>
- *
- * \code
- * ucBits[2] = {0, 0};
- *
- * // Set bit 4 to 1 (read: set 1 bit starting at bit offset 4 to value 1)
- * xMBUtilSetBits( ucBits, 4, 1, 1 );
- *
- * // Set bit 7 to 1 and bit 8 to 0.
- * xMBUtilSetBits( ucBits, 7, 2, 0x01 );
- *
- * // Set bits 8 - 11 to 0x05 and bits 12 - 15 to 0x0A;
- * xMBUtilSetBits( ucBits, 8, 8, 0x5A);
- * \endcode
- */
-void xMBUtilSetBits( UCHAR * ucByteBuf, USHORT usBitOffset,
- UCHAR ucNBits, UCHAR ucValues );
-
-/*! \brief Function to read bits in a byte buffer.
- *
- * This function is used to extract up bit values from an array. Up to eight
- * bit values can be extracted in one step.
- *
- * \param ucByteBuf A buffer where the bit values are stored.
- * \param usBitOffset The starting address of the bits to set. The first
- * bit has the offset 0.
- * \param ucNBits Number of bits to modify. The value must always be smaller
- * than 8.
- *
- * \code
- * UCHAR ucBits[2] = {0, 0};
- * UCHAR ucResult;
- *
- * // Extract the bits 3 - 10.
- * ucResult = xMBUtilGetBits( ucBits, 3, 8 );
- * \endcode
- */
-UCHAR xMBUtilGetBits( UCHAR * ucByteBuf, USHORT usBitOffset,
- UCHAR ucNBits );
-
-/*! @} */
-
-#ifdef __cplusplus
-PR_END_EXTERN_C
-#endif
-#endif
diff --git a/components/net/freemodbus/modbus/mb.c b/components/net/freemodbus/modbus/mb.c
deleted file mode 100644
index 96d693c910..0000000000
--- a/components/net/freemodbus/modbus/mb.c
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mb.c,v 1.27 2007/02/18 23:45:41 wolti Exp $
- */
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-
-#include "mb.h"
-#include "mbconfig.h"
-#include "mbframe.h"
-#include "mbproto.h"
-#include "mbfunc.h"
-
-#include "mbport.h"
-#if MB_SLAVE_RTU_ENABLED == 1
-#include "mbrtu.h"
-#endif
-#if MB_SLAVE_ASCII_ENABLED == 1
-#include "mbascii.h"
-#endif
-#if MB_SLAVE_TCP_ENABLED == 1
-#include "mbtcp.h"
-#endif
-
-#ifndef MB_PORT_HAS_CLOSE
-#define MB_PORT_HAS_CLOSE 0
-#endif
-
-/* ----------------------- Static variables ---------------------------------*/
-
-static UCHAR ucMBAddress;
-static eMBMode eMBCurrentMode;
-
-static enum
-{
- STATE_ENABLED,
- STATE_DISABLED,
- STATE_NOT_INITIALIZED
-} eMBState = STATE_NOT_INITIALIZED;
-
-/* Functions pointer which are initialized in eMBInit( ). Depending on the
- * mode (RTU or ASCII) the are set to the correct implementations.
- * Using for Modbus Slave
- */
-static peMBFrameSend peMBFrameSendCur;
-static pvMBFrameStart pvMBFrameStartCur;
-static pvMBFrameStop pvMBFrameStopCur;
-static peMBFrameReceive peMBFrameReceiveCur;
-static pvMBFrameClose pvMBFrameCloseCur;
-
-/* Callback functions required by the porting layer. They are called when
- * an external event has happend which includes a timeout or the reception
- * or transmission of a character.
- * Using for Modbus Slave
- */
-BOOL( *pxMBFrameCBByteReceived ) ( void );
-BOOL( *pxMBFrameCBTransmitterEmpty ) ( void );
-BOOL( *pxMBPortCBTimerExpired ) ( void );
-
-BOOL( *pxMBFrameCBReceiveFSMCur ) ( void );
-BOOL( *pxMBFrameCBTransmitFSMCur ) ( void );
-
-/* An array of Modbus functions handlers which associates Modbus function
- * codes with implementing functions.
- */
-static xMBFunctionHandler xFuncHandlers[MB_FUNC_HANDLERS_MAX] = {
-#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED > 0
- {MB_FUNC_OTHER_REPORT_SLAVEID, eMBFuncReportSlaveID},
-#endif
-#if MB_FUNC_READ_INPUT_ENABLED > 0
- {MB_FUNC_READ_INPUT_REGISTER, eMBFuncReadInputRegister},
-#endif
-#if MB_FUNC_READ_HOLDING_ENABLED > 0
- {MB_FUNC_READ_HOLDING_REGISTER, eMBFuncReadHoldingRegister},
-#endif
-#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
- {MB_FUNC_WRITE_MULTIPLE_REGISTERS, eMBFuncWriteMultipleHoldingRegister},
-#endif
-#if MB_FUNC_WRITE_HOLDING_ENABLED > 0
- {MB_FUNC_WRITE_REGISTER, eMBFuncWriteHoldingRegister},
-#endif
-#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
- {MB_FUNC_READWRITE_MULTIPLE_REGISTERS, eMBFuncReadWriteMultipleHoldingRegister},
-#endif
-#if MB_FUNC_READ_COILS_ENABLED > 0
- {MB_FUNC_READ_COILS, eMBFuncReadCoils},
-#endif
-#if MB_FUNC_WRITE_COIL_ENABLED > 0
- {MB_FUNC_WRITE_SINGLE_COIL, eMBFuncWriteCoil},
-#endif
-#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
- {MB_FUNC_WRITE_MULTIPLE_COILS, eMBFuncWriteMultipleCoils},
-#endif
-#if MB_FUNC_READ_DISCRETE_INPUTS_ENABLED > 0
- {MB_FUNC_READ_DISCRETE_INPUTS, eMBFuncReadDiscreteInputs},
-#endif
-};
-
-/* ----------------------- Start implementation -----------------------------*/
-eMBErrorCode
-eMBInit( eMBMode eMode, UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
-{
- eMBErrorCode eStatus = MB_ENOERR;
-
- /* check preconditions */
- if( ( ucSlaveAddress == MB_ADDRESS_BROADCAST ) ||
- ( ucSlaveAddress < MB_ADDRESS_MIN ) || ( ucSlaveAddress > MB_ADDRESS_MAX ) )
- {
- eStatus = MB_EINVAL;
- }
- else
- {
- ucMBAddress = ucSlaveAddress;
-
- switch ( eMode )
- {
-#if MB_SLAVE_RTU_ENABLED > 0
- case MB_RTU:
- pvMBFrameStartCur = eMBRTUStart;
- pvMBFrameStopCur = eMBRTUStop;
- peMBFrameSendCur = eMBRTUSend;
- peMBFrameReceiveCur = eMBRTUReceive;
- pvMBFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBPortClose : NULL;
- pxMBFrameCBByteReceived = xMBRTUReceiveFSM;
- pxMBFrameCBTransmitterEmpty = xMBRTUTransmitFSM;
- pxMBPortCBTimerExpired = xMBRTUTimerT35Expired;
-
- eStatus = eMBRTUInit( ucMBAddress, ucPort, ulBaudRate, eParity );
- break;
-#endif
-#if MB_SLAVE_ASCII_ENABLED > 0
- case MB_ASCII:
- pvMBFrameStartCur = eMBASCIIStart;
- pvMBFrameStopCur = eMBASCIIStop;
- peMBFrameSendCur = eMBASCIISend;
- peMBFrameReceiveCur = eMBASCIIReceive;
- pvMBFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBPortClose : NULL;
- pxMBFrameCBByteReceived = xMBASCIIReceiveFSM;
- pxMBFrameCBTransmitterEmpty = xMBASCIITransmitFSM;
- pxMBPortCBTimerExpired = xMBASCIITimerT1SExpired;
-
- eStatus = eMBASCIIInit( ucMBAddress, ucPort, ulBaudRate, eParity );
- break;
-#endif
- default:
- eStatus = MB_EINVAL;
- break;
- }
-
- if( eStatus == MB_ENOERR )
- {
- if( !xMBPortEventInit( ) )
- {
- /* port dependent event module initalization failed. */
- eStatus = MB_EPORTERR;
- }
- else
- {
- eMBCurrentMode = eMode;
- eMBState = STATE_DISABLED;
- }
- }
- }
- return eStatus;
-}
-
-#if MB_SLAVE_TCP_ENABLED > 0
-eMBErrorCode
-eMBTCPInit( USHORT ucTCPPort )
-{
- eMBErrorCode eStatus = MB_ENOERR;
-
- if( ( eStatus = eMBTCPDoInit( ucTCPPort ) ) != MB_ENOERR )
- {
- eMBState = STATE_DISABLED;
- }
- else if( !xMBPortEventInit( ) )
- {
- /* Port dependent event module initalization failed. */
- eStatus = MB_EPORTERR;
- }
- else
- {
- pvMBFrameStartCur = eMBTCPStart;
- pvMBFrameStopCur = eMBTCPStop;
- peMBFrameReceiveCur = eMBTCPReceive;
- peMBFrameSendCur = eMBTCPSend;
- pvMBFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBTCPPortClose : NULL;
- ucMBAddress = MB_TCP_PSEUDO_ADDRESS;
- eMBCurrentMode = MB_TCP;
- eMBState = STATE_DISABLED;
- }
- return eStatus;
-}
-#endif
-
-eMBErrorCode
-eMBRegisterCB( UCHAR ucFunctionCode, pxMBFunctionHandler pxHandler )
-{
- int i;
- eMBErrorCode eStatus;
-
- if( ( 0 < ucFunctionCode ) && ( ucFunctionCode <= 127 ) )
- {
- ENTER_CRITICAL_SECTION( );
- if( pxHandler != NULL )
- {
- for( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
- {
- if( ( xFuncHandlers[i].pxHandler == NULL ) ||
- ( xFuncHandlers[i].pxHandler == pxHandler ) )
- {
- xFuncHandlers[i].ucFunctionCode = ucFunctionCode;
- xFuncHandlers[i].pxHandler = pxHandler;
- break;
- }
- }
- eStatus = ( i != MB_FUNC_HANDLERS_MAX ) ? MB_ENOERR : MB_ENORES;
- }
- else
- {
- for( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
- {
- if( xFuncHandlers[i].ucFunctionCode == ucFunctionCode )
- {
- xFuncHandlers[i].ucFunctionCode = 0;
- xFuncHandlers[i].pxHandler = NULL;
- break;
- }
- }
- /* Remove can't fail. */
- eStatus = MB_ENOERR;
- }
- EXIT_CRITICAL_SECTION( );
- }
- else
- {
- eStatus = MB_EINVAL;
- }
- return eStatus;
-}
-
-
-eMBErrorCode
-eMBClose( void )
-{
- eMBErrorCode eStatus = MB_ENOERR;
-
- if( eMBState == STATE_DISABLED )
- {
- if( pvMBFrameCloseCur != NULL )
- {
- pvMBFrameCloseCur( );
- }
- }
- else
- {
- eStatus = MB_EILLSTATE;
- }
- return eStatus;
-}
-
-
-eMBErrorCode
-eMBEnable( void )
-{
- eMBErrorCode eStatus = MB_ENOERR;
-
- if( eMBState == STATE_DISABLED )
- {
- /* Activate the protocol stack. */
- pvMBFrameStartCur( );
- eMBState = STATE_ENABLED;
- }
- else
- {
- eStatus = MB_EILLSTATE;
- }
- return eStatus;
-}
-
-eMBErrorCode
-eMBDisable( void )
-{
- eMBErrorCode eStatus;
-
- if( eMBState == STATE_ENABLED )
- {
- pvMBFrameStopCur( );
- eMBState = STATE_DISABLED;
- eStatus = MB_ENOERR;
- }
- else if( eMBState == STATE_DISABLED )
- {
- eStatus = MB_ENOERR;
- }
- else
- {
- eStatus = MB_EILLSTATE;
- }
- return eStatus;
-}
-
-eMBErrorCode eMBPoll( void )
-{
- static UCHAR *ucMBFrame;
- static UCHAR ucRcvAddress;
- static UCHAR ucFunctionCode;
- static USHORT usLength;
- static eMBException eException;
-
- int i;
- eMBErrorCode eStatus = MB_ENOERR;
- eMBEventType eEvent;
-
- /* Check if the protocol stack is ready. */
- if( eMBState != STATE_ENABLED )
- {
- return MB_EILLSTATE;
- }
-
- /* Check if there is a event available. If not return control to caller.
- * Otherwise we will handle the event. */
- if( xMBPortEventGet( &eEvent ) == TRUE )
- {
- switch ( eEvent )
- {
- case EV_READY:
- break;
-
- case EV_FRAME_RECEIVED:
- eStatus = peMBFrameReceiveCur( &ucRcvAddress, &ucMBFrame, &usLength );
- if( eStatus == MB_ENOERR )
- {
- /* Check if the frame is for us. If not ignore the frame. */
- if( ( ucRcvAddress == ucMBAddress ) || ( ucRcvAddress == MB_ADDRESS_BROADCAST ) )
- {
- ( void )xMBPortEventPost( EV_EXECUTE );
- }
- }
- break;
-
- case EV_EXECUTE:
- ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
- eException = MB_EX_ILLEGAL_FUNCTION;
- for( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
- {
- /* No more function handlers registered. Abort. */
- if( xFuncHandlers[i].ucFunctionCode == 0 )
- {
- break;
- }
- else if( xFuncHandlers[i].ucFunctionCode == ucFunctionCode )
- {
- eException = xFuncHandlers[i].pxHandler( ucMBFrame, &usLength );
- break;
- }
- }
-
- /* If the request was not sent to the broadcast address we
- * return a reply. */
- if( ucRcvAddress != MB_ADDRESS_BROADCAST )
- {
- if( eException != MB_EX_NONE )
- {
- /* An exception occured. Build an error frame. */
- usLength = 0;
- ucMBFrame[usLength++] = ( UCHAR )( ucFunctionCode | MB_FUNC_ERROR );
- ucMBFrame[usLength++] = eException;
- }
- eStatus = peMBFrameSendCur( ucMBAddress, ucMBFrame, usLength );
- }
- break;
-
- case EV_FRAME_SENT:
- break;
- }
- }
- return MB_ENOERR;
-}
diff --git a/components/net/freemodbus/modbus/mb_m.c b/components/net/freemodbus/modbus/mb_m.c
deleted file mode 100644
index 4e7c4b2b74..0000000000
--- a/components/net/freemodbus/modbus/mb_m.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (C) 2013 Armink <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbrtu_m.c,v 1.60 2013/08/20 11:18:10 Armink Add Master Functions $
- */
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-
-#include "mb.h"
-#include "mb_m.h"
-#include "mbconfig.h"
-#include "mbframe.h"
-#include "mbproto.h"
-#include "mbfunc.h"
-
-#include "mbport.h"
-#if MB_MASTER_RTU_ENABLED == 1
-#include "mbrtu.h"
-#endif
-#if MB_MASTER_ASCII_ENABLED == 1
-#include "mbascii.h"
-#endif
-#if MB_MASTER_TCP_ENABLED == 1
-#include "mbtcp.h"
-#endif
-
-#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
-
-#ifndef MB_PORT_HAS_CLOSE
-#define MB_PORT_HAS_CLOSE 0
-#endif
-
-/* ----------------------- Static variables ---------------------------------*/
-
-static UCHAR ucMBMasterDestAddress;
-static BOOL xMBRunInMasterMode = FALSE;
-static eMBMasterErrorEventType eMBMasterCurErrorType;
-
-static enum
-{
- STATE_ENABLED,
- STATE_DISABLED,
- STATE_NOT_INITIALIZED
-} eMBState = STATE_NOT_INITIALIZED;
-
-/* Functions pointer which are initialized in eMBInit( ). Depending on the
- * mode (RTU or ASCII) the are set to the correct implementations.
- * Using for Modbus Master,Add by Armink 20130813
- */
-static peMBFrameSend peMBMasterFrameSendCur;
-static pvMBFrameStart pvMBMasterFrameStartCur;
-static pvMBFrameStop pvMBMasterFrameStopCur;
-static peMBFrameReceive peMBMasterFrameReceiveCur;
-static pvMBFrameClose pvMBMasterFrameCloseCur;
-
-/* Callback functions required by the porting layer. They are called when
- * an external event has happend which includes a timeout or the reception
- * or transmission of a character.
- * Using for Modbus Master,Add by Armink 20130813
- */
-BOOL( *pxMBMasterFrameCBByteReceived ) ( void );
-BOOL( *pxMBMasterFrameCBTransmitterEmpty ) ( void );
-BOOL( *pxMBMasterPortCBTimerExpired ) ( void );
-
-BOOL( *pxMBMasterFrameCBReceiveFSMCur ) ( void );
-BOOL( *pxMBMasterFrameCBTransmitFSMCur ) ( void );
-
-/* An array of Modbus functions handlers which associates Modbus function
- * codes with implementing functions.
- */
-static xMBFunctionHandler xMasterFuncHandlers[MB_FUNC_HANDLERS_MAX] = {
-#if MB_FUNC_OTHER_REP_SLAVEID_ENABLED > 0
- //TODO Add Master function define
- {MB_FUNC_OTHER_REPORT_SLAVEID, eMBFuncReportSlaveID},
-#endif
-#if MB_FUNC_READ_INPUT_ENABLED > 0
- {MB_FUNC_READ_INPUT_REGISTER, eMBMasterFuncReadInputRegister},
-#endif
-#if MB_FUNC_READ_HOLDING_ENABLED > 0
- {MB_FUNC_READ_HOLDING_REGISTER, eMBMasterFuncReadHoldingRegister},
-#endif
-#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
- {MB_FUNC_WRITE_MULTIPLE_REGISTERS, eMBMasterFuncWriteMultipleHoldingRegister},
-#endif
-#if MB_FUNC_WRITE_HOLDING_ENABLED > 0
- {MB_FUNC_WRITE_REGISTER, eMBMasterFuncWriteHoldingRegister},
-#endif
-#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
- {MB_FUNC_READWRITE_MULTIPLE_REGISTERS, eMBMasterFuncReadWriteMultipleHoldingRegister},
-#endif
-#if MB_FUNC_READ_COILS_ENABLED > 0
- {MB_FUNC_READ_COILS, eMBMasterFuncReadCoils},
-#endif
-#if MB_FUNC_WRITE_COIL_ENABLED > 0
- {MB_FUNC_WRITE_SINGLE_COIL, eMBMasterFuncWriteCoil},
-#endif
-#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
- {MB_FUNC_WRITE_MULTIPLE_COILS, eMBMasterFuncWriteMultipleCoils},
-#endif
-#if MB_FUNC_READ_DISCRETE_INPUTS_ENABLED > 0
- {MB_FUNC_READ_DISCRETE_INPUTS, eMBMasterFuncReadDiscreteInputs},
-#endif
-};
-
-/* ----------------------- Start implementation -----------------------------*/
-eMBErrorCode
-eMBMasterInit( eMBMode eMode, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
-{
- eMBErrorCode eStatus = MB_ENOERR;
-
- switch (eMode)
- {
-#if MB_MASTER_RTU_ENABLED > 0
- case MB_RTU:
- pvMBMasterFrameStartCur = eMBMasterRTUStart;
- pvMBMasterFrameStopCur = eMBMasterRTUStop;
- peMBMasterFrameSendCur = eMBMasterRTUSend;
- peMBMasterFrameReceiveCur = eMBMasterRTUReceive;
- pvMBMasterFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBMasterPortClose : NULL;
- pxMBMasterFrameCBByteReceived = xMBMasterRTUReceiveFSM;
- pxMBMasterFrameCBTransmitterEmpty = xMBMasterRTUTransmitFSM;
- pxMBMasterPortCBTimerExpired = xMBMasterRTUTimerExpired;
-
- eStatus = eMBMasterRTUInit(ucPort, ulBaudRate, eParity);
- break;
-#endif
-#if MB_MASTER_ASCII_ENABLED > 0
- case MB_ASCII:
- pvMBMasterFrameStartCur = eMBMasterASCIIStart;
- pvMBMasterFrameStopCur = eMBMasterASCIIStop;
- peMBMasterFrameSendCur = eMBMasterASCIISend;
- peMBMasterFrameReceiveCur = eMBMasterASCIIReceive;
- pvMBMasterFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBMasterPortClose : NULL;
- pxMBMasterFrameCBByteReceived = xMBMasterASCIIReceiveFSM;
- pxMBMasterFrameCBTransmitterEmpty = xMBMasterASCIITransmitFSM;
- pxMBMasterPortCBTimerExpired = xMBMasterASCIITimerT1SExpired;
-
- eStatus = eMBMasterASCIIInit(ucPort, ulBaudRate, eParity );
- break;
-#endif
- default:
- eStatus = MB_EINVAL;
- break;
- }
-
- if (eStatus == MB_ENOERR)
- {
- if (!xMBMasterPortEventInit())
- {
- /* port dependent event module initalization failed. */
- eStatus = MB_EPORTERR;
- }
- else
- {
- eMBState = STATE_DISABLED;
- }
- /* initialize the OS resource for modbus master. */
- vMBMasterOsResInit();
- }
- return eStatus;
-}
-
-eMBErrorCode
-eMBMasterClose( void )
-{
- eMBErrorCode eStatus = MB_ENOERR;
-
- if( eMBState == STATE_DISABLED )
- {
- if( pvMBMasterFrameCloseCur != NULL )
- {
- pvMBMasterFrameCloseCur( );
- }
- }
- else
- {
- eStatus = MB_EILLSTATE;
- }
- return eStatus;
-}
-
-eMBErrorCode
-eMBMasterEnable( void )
-{
- eMBErrorCode eStatus = MB_ENOERR;
-
- if( eMBState == STATE_DISABLED )
- {
- /* Activate the protocol stack. */
- pvMBMasterFrameStartCur( );
- eMBState = STATE_ENABLED;
- }
- else
- {
- eStatus = MB_EILLSTATE;
- }
- return eStatus;
-}
-
-eMBErrorCode
-eMBMasterDisable( void )
-{
- eMBErrorCode eStatus;
-
- if( eMBState == STATE_ENABLED )
- {
- pvMBMasterFrameStopCur( );
- eMBState = STATE_DISABLED;
- eStatus = MB_ENOERR;
- }
- else if( eMBState == STATE_DISABLED )
- {
- eStatus = MB_ENOERR;
- }
- else
- {
- eStatus = MB_EILLSTATE;
- }
- return eStatus;
-}
-
-eMBErrorCode
-eMBMasterPoll( void )
-{
- static UCHAR *ucMBFrame;
- static UCHAR ucRcvAddress;
- static UCHAR ucFunctionCode;
- static USHORT usLength;
- static eMBException eException;
-
- int i , j;
- eMBErrorCode eStatus = MB_ENOERR;
- eMBMasterEventType eEvent;
- eMBMasterErrorEventType errorType;
-
- /* Check if the protocol stack is ready. */
- if( eMBState != STATE_ENABLED )
- {
- return MB_EILLSTATE;
- }
-
- /* Check if there is a event available. If not return control to caller.
- * Otherwise we will handle the event. */
- if( xMBMasterPortEventGet( &eEvent ) == TRUE )
- {
- switch ( eEvent )
- {
- case EV_MASTER_READY:
- break;
-
- case EV_MASTER_FRAME_RECEIVED:
- eStatus = peMBMasterFrameReceiveCur( &ucRcvAddress, &ucMBFrame, &usLength );
- /* Check if the frame is for us. If not ,send an error process event. */
- if ( ( eStatus == MB_ENOERR ) && ( ucRcvAddress == ucMBMasterGetDestAddress() ) )
- {
- ( void ) xMBMasterPortEventPost( EV_MASTER_EXECUTE );
- }
- else
- {
- vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
- ( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
- }
- break;
-
- case EV_MASTER_EXECUTE:
- ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
- eException = MB_EX_ILLEGAL_FUNCTION;
- /* If receive frame has exception .The receive function code highest bit is 1.*/
- if(ucFunctionCode >> 7) {
- eException = (eMBException)ucMBFrame[MB_PDU_DATA_OFF];
- }
- else
- {
- for (i = 0; i < MB_FUNC_HANDLERS_MAX; i++)
- {
- /* No more function handlers registered. Abort. */
- if (xMasterFuncHandlers[i].ucFunctionCode == 0) {
- break;
- }
- else if (xMasterFuncHandlers[i].ucFunctionCode == ucFunctionCode) {
- vMBMasterSetCBRunInMasterMode(TRUE);
- /* If master request is broadcast,
- * the master need execute function for all slave.
- */
- if ( xMBMasterRequestIsBroadcast() ) {
- usLength = usMBMasterGetPDUSndLength();
- for(j = 1; j <= MB_MASTER_TOTAL_SLAVE_NUM; j++){
- vMBMasterSetDestAddress(j);
- eException = xMasterFuncHandlers[i].pxHandler(ucMBFrame, &usLength);
- }
- }
- else {
- eException = xMasterFuncHandlers[i].pxHandler(ucMBFrame, &usLength);
- }
- vMBMasterSetCBRunInMasterMode(FALSE);
- break;
- }
- }
- }
- /* If master has exception ,Master will send error process.Otherwise the Master is idle.*/
- if (eException != MB_EX_NONE) {
- vMBMasterSetErrorType(EV_ERROR_EXECUTE_FUNCTION);
- ( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
- }
- else {
- vMBMasterCBRequestScuuess( );
- vMBMasterRunResRelease( );
- }
- break;
-
- case EV_MASTER_FRAME_SENT:
- /* Master is busy now. */
- vMBMasterGetPDUSndBuf( &ucMBFrame );
- eStatus = peMBMasterFrameSendCur( ucMBMasterGetDestAddress(), ucMBFrame, usMBMasterGetPDUSndLength() );
- break;
-
- case EV_MASTER_ERROR_PROCESS:
- /* Execute specified error process callback function. */
- errorType = eMBMasterGetErrorType();
- vMBMasterGetPDUSndBuf( &ucMBFrame );
- switch (errorType) {
- case EV_ERROR_RESPOND_TIMEOUT:
- vMBMasterErrorCBRespondTimeout(ucMBMasterGetDestAddress(),
- ucMBFrame, usMBMasterGetPDUSndLength());
- break;
- case EV_ERROR_RECEIVE_DATA:
- vMBMasterErrorCBReceiveData(ucMBMasterGetDestAddress(),
- ucMBFrame, usMBMasterGetPDUSndLength());
- break;
- case EV_ERROR_EXECUTE_FUNCTION:
- vMBMasterErrorCBExecuteFunction(ucMBMasterGetDestAddress(),
- ucMBFrame, usMBMasterGetPDUSndLength());
- break;
- }
- vMBMasterRunResRelease();
- break;
- }
- }
- return MB_ENOERR;
-}
-
-/* Get whether the Modbus Master is run in master mode.*/
-BOOL xMBMasterGetCBRunInMasterMode( void )
-{
- return xMBRunInMasterMode;
-}
-/* Set whether the Modbus Master is run in master mode.*/
-void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode )
-{
- xMBRunInMasterMode = IsMasterMode;
-}
-/* Get Modbus Master send destination address. */
-UCHAR ucMBMasterGetDestAddress( void )
-{
- return ucMBMasterDestAddress;
-}
-/* Set Modbus Master send destination address. */
-void vMBMasterSetDestAddress( UCHAR Address )
-{
- ucMBMasterDestAddress = Address;
-}
-/* Get Modbus Master current error event type. */
-eMBMasterErrorEventType eMBMasterGetErrorType( void )
-{
- return eMBMasterCurErrorType;
-}
-/* Set Modbus Master current error event type. */
-void vMBMasterSetErrorType( eMBMasterErrorEventType errorType )
-{
- eMBMasterCurErrorType = errorType;
-}
-
-
-
-#endif
diff --git a/components/net/freemodbus/modbus/rtu/mbcrc.c b/components/net/freemodbus/modbus/rtu/mbcrc.c
deleted file mode 100644
index 29b9ea765a..0000000000
--- a/components/net/freemodbus/modbus/rtu/mbcrc.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbcrc.c,v 1.7 2007/02/18 23:50:27 wolti Exp $
- */
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-static const UCHAR aucCRCHi[] = {
- 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
- 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
- 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
- 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
- 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
- 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
- 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
- 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
- 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
- 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
- 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
- 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
- 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
- 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
- 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
- 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
- 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
- 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
- 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
- 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
- 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
- 0x00, 0xC1, 0x81, 0x40
-};
-
-static const UCHAR aucCRCLo[] = {
- 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
- 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
- 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
- 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
- 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
- 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
- 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
- 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
- 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
- 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
- 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
- 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
- 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
- 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
- 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
- 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
- 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
- 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
- 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
- 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
- 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
- 0x41, 0x81, 0x80, 0x40
-};
-
-USHORT
-usMBCRC16( UCHAR * pucFrame, USHORT usLen )
-{
- UCHAR ucCRCHi = 0xFF;
- UCHAR ucCRCLo = 0xFF;
- int iIndex;
-
- while( usLen-- )
- {
- iIndex = ucCRCLo ^ *( pucFrame++ );
- ucCRCLo = ( UCHAR )( ucCRCHi ^ aucCRCHi[iIndex] );
- ucCRCHi = aucCRCLo[iIndex];
- }
- return ( USHORT )( ucCRCHi << 8 | ucCRCLo );
-}
diff --git a/components/net/freemodbus/modbus/rtu/mbcrc.h b/components/net/freemodbus/modbus/rtu/mbcrc.h
deleted file mode 100644
index db227763f1..0000000000
--- a/components/net/freemodbus/modbus/rtu/mbcrc.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbcrc.h,v 1.5 2006/12/07 22:10:34 wolti Exp $
- */
-
-#ifndef _MB_CRC_H
-#define _MB_CRC_H
-
-USHORT usMBCRC16( UCHAR * pucFrame, USHORT usLen );
-
-#endif
diff --git a/components/net/freemodbus/modbus/rtu/mbrtu.c b/components/net/freemodbus/modbus/rtu/mbrtu.c
deleted file mode 100644
index 40c29348ce..0000000000
--- a/components/net/freemodbus/modbus/rtu/mbrtu.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbrtu.c,v 1.18 2007/09/12 10:15:56 wolti Exp $
- */
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mbrtu.h"
-#include "mbframe.h"
-
-#include "mbcrc.h"
-#include "mbport.h"
-
-/* ----------------------- Defines ------------------------------------------*/
-#define MB_SER_PDU_SIZE_MIN 4 /*!< Minimum size of a Modbus RTU frame. */
-#define MB_SER_PDU_SIZE_MAX 256 /*!< Maximum size of a Modbus RTU frame. */
-#define MB_SER_PDU_SIZE_CRC 2 /*!< Size of CRC field in PDU. */
-#define MB_SER_PDU_ADDR_OFF 0 /*!< Offset of slave address in Ser-PDU. */
-#define MB_SER_PDU_PDU_OFF 1 /*!< Offset of Modbus-PDU in Ser-PDU. */
-
-/* ----------------------- Type definitions ---------------------------------*/
-typedef enum
-{
- STATE_RX_INIT, /*!< Receiver is in initial state. */
- STATE_RX_IDLE, /*!< Receiver is in idle state. */
- STATE_RX_RCV, /*!< Frame is beeing received. */
- STATE_RX_ERROR /*!< If the frame is invalid. */
-} eMBRcvState;
-
-typedef enum
-{
- STATE_TX_IDLE, /*!< Transmitter is in idle state. */
- STATE_TX_XMIT /*!< Transmitter is in transfer state. */
-} eMBSndState;
-
-/* ----------------------- Static variables ---------------------------------*/
-static volatile eMBSndState eSndState;
-static volatile eMBRcvState eRcvState;
-
-volatile UCHAR ucRTUBuf[MB_SER_PDU_SIZE_MAX];
-
-static volatile UCHAR *pucSndBufferCur;
-static volatile USHORT usSndBufferCount;
-
-static volatile USHORT usRcvBufferPos;
-
-/* ----------------------- Start implementation -----------------------------*/
-eMBErrorCode
-eMBRTUInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
-{
- eMBErrorCode eStatus = MB_ENOERR;
- ULONG usTimerT35_50us;
-
- ( void )ucSlaveAddress;
- ENTER_CRITICAL_SECTION( );
-
- /* Modbus RTU uses 8 Databits. */
- if( xMBPortSerialInit( ucPort, ulBaudRate, 8, eParity ) != TRUE )
- {
- eStatus = MB_EPORTERR;
- }
- else
- {
- /* If baudrate > 19200 then we should use the fixed timer values
- * t35 = 1750us. Otherwise t35 must be 3.5 times the character time.
- */
- if( ulBaudRate > 19200 )
- {
- usTimerT35_50us = 35; /* 1800us. */
- }
- else
- {
- /* The timer reload value for a character is given by:
- *
- * ChTimeValue = Ticks_per_1s / ( Baudrate / 11 )
- * = 11 * Ticks_per_1s / Baudrate
- * = 220000 / Baudrate
- * The reload for t3.5 is 1.5 times this value and similary
- * for t3.5.
- */
- usTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate );
- }
- if( xMBPortTimersInit( ( USHORT ) usTimerT35_50us ) != TRUE )
- {
- eStatus = MB_EPORTERR;
- }
- }
- EXIT_CRITICAL_SECTION( );
-
- return eStatus;
-}
-
-void
-eMBRTUStart( void )
-{
- ENTER_CRITICAL_SECTION( );
- /* Initially the receiver is in the state STATE_RX_INIT. we start
- * the timer and if no character is received within t3.5 we change
- * to STATE_RX_IDLE. This makes sure that we delay startup of the
- * modbus protocol stack until the bus is free.
- */
- eRcvState = STATE_RX_INIT;
- vMBPortSerialEnable( TRUE, FALSE );
- vMBPortTimersEnable( );
-
- EXIT_CRITICAL_SECTION( );
-}
-
-void
-eMBRTUStop( void )
-{
- ENTER_CRITICAL_SECTION( );
- vMBPortSerialEnable( FALSE, FALSE );
- vMBPortTimersDisable( );
- EXIT_CRITICAL_SECTION( );
-}
-
-eMBErrorCode
-eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
-{
- eMBErrorCode eStatus = MB_ENOERR;
-
- ENTER_CRITICAL_SECTION( );
- RT_ASSERT( usRcvBufferPos <= MB_SER_PDU_SIZE_MAX );
-
- /* Length and CRC check */
- if( ( usRcvBufferPos >= MB_SER_PDU_SIZE_MIN )
- && ( usMBCRC16( ( UCHAR * ) ucRTUBuf, usRcvBufferPos ) == 0 ) )
- {
- /* Save the address field. All frames are passed to the upper layed
- * and the decision if a frame is used is done there.
- */
- *pucRcvAddress = ucRTUBuf[MB_SER_PDU_ADDR_OFF];
-
- /* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
- * size of address field and CRC checksum.
- */
- *pusLength = ( USHORT )( usRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC );
-
- /* Return the start of the Modbus PDU to the caller. */
- *pucFrame = ( UCHAR * ) & ucRTUBuf[MB_SER_PDU_PDU_OFF];
- }
- else
- {
- eStatus = MB_EIO;
- }
-
- EXIT_CRITICAL_SECTION( );
- return eStatus;
-}
-
-eMBErrorCode
-eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
-{
- eMBErrorCode eStatus = MB_ENOERR;
- USHORT usCRC16;
-
- ENTER_CRITICAL_SECTION( );
-
- /* Check if the receiver is still in idle state. If not we where to
- * slow with processing the received frame and the master sent another
- * frame on the network. We have to abort sending the frame.
- */
- if( eRcvState == STATE_RX_IDLE )
- {
- /* First byte before the Modbus-PDU is the slave address. */
- pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
- usSndBufferCount = 1;
-
- /* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */
- pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress;
- usSndBufferCount += usLength;
-
- /* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
- usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount );
- ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
- ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );
-
- /* Activate the transmitter. */
- eSndState = STATE_TX_XMIT;
- vMBPortSerialEnable( FALSE, TRUE );
- }
- else
- {
- eStatus = MB_EIO;
- }
- EXIT_CRITICAL_SECTION( );
- return eStatus;
-}
-
-BOOL
-xMBRTUReceiveFSM( void )
-{
- BOOL xTaskNeedSwitch = FALSE;
- UCHAR ucByte;
-
- RT_ASSERT( eSndState == STATE_TX_IDLE );
-
- /* Always read the character. */
- ( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte );
-
- switch ( eRcvState )
- {
- /* If we have received a character in the init state we have to
- * wait until the frame is finished.
- */
- case STATE_RX_INIT:
- vMBPortTimersEnable( );
- break;
-
- /* In the error state we wait until all characters in the
- * damaged frame are transmitted.
- */
- case STATE_RX_ERROR:
- vMBPortTimersEnable( );
- break;
-
- /* In the idle state we wait for a new character. If a character
- * is received the t1.5 and t3.5 timers are started and the
- * receiver is in the state STATE_RX_RECEIVCE.
- */
- case STATE_RX_IDLE:
- usRcvBufferPos = 0;
- ucRTUBuf[usRcvBufferPos++] = ucByte;
- eRcvState = STATE_RX_RCV;
-
- /* Enable t3.5 timers. */
- vMBPortTimersEnable( );
- break;
-
- /* We are currently receiving a frame. Reset the timer after
- * every character received. If more than the maximum possible
- * number of bytes in a modbus frame is received the frame is
- * ignored.
- */
- case STATE_RX_RCV:
- if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX )
- {
- ucRTUBuf[usRcvBufferPos++] = ucByte;
- }
- else
- {
- eRcvState = STATE_RX_ERROR;
- }
- vMBPortTimersEnable();
- break;
- }
- return xTaskNeedSwitch;
-}
-
-BOOL
-xMBRTUTransmitFSM( void )
-{
- BOOL xNeedPoll = FALSE;
-
- RT_ASSERT( eRcvState == STATE_RX_IDLE );
-
- switch ( eSndState )
- {
- /* We should not get a transmitter event if the transmitter is in
- * idle state. */
- case STATE_TX_IDLE:
- /* enable receiver/disable transmitter. */
- vMBPortSerialEnable( TRUE, FALSE );
- break;
-
- case STATE_TX_XMIT:
- /* check if we are finished. */
- if( usSndBufferCount != 0 )
- {
- xMBPortSerialPutByte( ( CHAR )*pucSndBufferCur );
- pucSndBufferCur++; /* next byte in sendbuffer. */
- usSndBufferCount--;
- }
- else
- {
- xNeedPoll = xMBPortEventPost( EV_FRAME_SENT );
- /* Disable transmitter. This prevents another transmit buffer
- * empty interrupt. */
- vMBPortSerialEnable( TRUE, FALSE );
- eSndState = STATE_TX_IDLE;
- }
- break;
- }
-
- return xNeedPoll;
-}
-
-BOOL
-xMBRTUTimerT35Expired( void )
-{
- BOOL xNeedPoll = FALSE;
-
- switch ( eRcvState )
- {
- /* Timer t35 expired. Startup phase is finished. */
- case STATE_RX_INIT:
- xNeedPoll = xMBPortEventPost( EV_READY );
- break;
-
- /* A frame was received and t35 expired. Notify the listener that
- * a new frame was received. */
- case STATE_RX_RCV:
- xNeedPoll = xMBPortEventPost( EV_FRAME_RECEIVED );
- break;
-
- /* An error occured while receiving the frame. */
- case STATE_RX_ERROR:
- break;
-
- /* Function called in an illegal state. */
- default:
- RT_ASSERT( ( eRcvState == STATE_RX_INIT ) ||
- ( eRcvState == STATE_RX_RCV ) || ( eRcvState == STATE_RX_ERROR ) );
- break;
- }
-
- vMBPortTimersDisable( );
- eRcvState = STATE_RX_IDLE;
-
- return xNeedPoll;
-}
diff --git a/components/net/freemodbus/modbus/rtu/mbrtu.h b/components/net/freemodbus/modbus/rtu/mbrtu.h
deleted file mode 100644
index 98c43de4aa..0000000000
--- a/components/net/freemodbus/modbus/rtu/mbrtu.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbrtu.h,v 1.9 2006/12/07 22:10:34 wolti Exp $
- * File: $Id: mbrtu.h,v 1.60 2013/08/17 13:11:42 Armink Add Master Functions $
- */
-#include "mbconfig.h"
-
-#ifndef _MB_RTU_H
-#define _MB_RTU_H
-
-#ifdef __cplusplus
-PR_BEGIN_EXTERN_C
-#endif
-eMBErrorCode eMBRTUInit( UCHAR slaveAddress, UCHAR ucPort, ULONG ulBaudRate,
- eMBParity eParity );
-void eMBRTUStart( void );
-void eMBRTUStop( void );
-eMBErrorCode eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength );
-eMBErrorCode eMBRTUSend( UCHAR slaveAddress, const UCHAR * pucFrame, USHORT usLength );
-BOOL xMBRTUReceiveFSM( void );
-BOOL xMBRTUTransmitFSM( void );
-BOOL xMBRTUTimerT15Expired( void );
-BOOL xMBRTUTimerT35Expired( void );
-
-#if MB_MASTER_RTU_ENABLED > 0
-eMBErrorCode eMBMasterRTUInit( UCHAR ucPort, ULONG ulBaudRate,eMBParity eParity );
-void eMBMasterRTUStart( void );
-void eMBMasterRTUStop( void );
-eMBErrorCode eMBMasterRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength );
-eMBErrorCode eMBMasterRTUSend( UCHAR slaveAddress, const UCHAR * pucFrame, USHORT usLength );
-BOOL xMBMasterRTUReceiveFSM( void );
-BOOL xMBMasterRTUTransmitFSM( void );
-BOOL xMBMasterRTUTimerExpired( void );
-#endif
-
-#ifdef __cplusplus
-PR_END_EXTERN_C
-#endif
-#endif
diff --git a/components/net/freemodbus/modbus/rtu/mbrtu_m.c b/components/net/freemodbus/modbus/rtu/mbrtu_m.c
deleted file mode 100644
index 0c024e2b09..0000000000
--- a/components/net/freemodbus/modbus/rtu/mbrtu_m.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2013 China Beijing Armink <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbrtu_m.c,v 1.60 2013/08/17 11:42:56 Armink Add Master Functions $
- */
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mb_m.h"
-#include "mbrtu.h"
-#include "mbframe.h"
-
-#include "mbcrc.h"
-#include "mbport.h"
-
-#if MB_MASTER_RTU_ENABLED > 0
-/* ----------------------- Defines ------------------------------------------*/
-#define MB_SER_PDU_SIZE_MIN 4 /*!< Minimum size of a Modbus RTU frame. */
-#define MB_SER_PDU_SIZE_MAX 256 /*!< Maximum size of a Modbus RTU frame. */
-#define MB_SER_PDU_SIZE_CRC 2 /*!< Size of CRC field in PDU. */
-#define MB_SER_PDU_ADDR_OFF 0 /*!< Offset of slave address in Ser-PDU. */
-#define MB_SER_PDU_PDU_OFF 1 /*!< Offset of Modbus-PDU in Ser-PDU. */
-
-/* ----------------------- Type definitions ---------------------------------*/
-typedef enum
-{
- STATE_M_RX_INIT, /*!< Receiver is in initial state. */
- STATE_M_RX_IDLE, /*!< Receiver is in idle state. */
- STATE_M_RX_RCV, /*!< Frame is beeing received. */
- STATE_M_RX_ERROR, /*!< If the frame is invalid. */
-} eMBMasterRcvState;
-
-typedef enum
-{
- STATE_M_TX_IDLE, /*!< Transmitter is in idle state. */
- STATE_M_TX_XMIT, /*!< Transmitter is in transfer state. */
- STATE_M_TX_XFWR, /*!< Transmitter is in transfer finish and wait receive state. */
-} eMBMasterSndState;
-
-/* ----------------------- Static variables ---------------------------------*/
-static volatile eMBMasterSndState eSndState;
-static volatile eMBMasterRcvState eRcvState;
-
-static volatile UCHAR ucMasterRTUSndBuf[MB_PDU_SIZE_MAX];
-static volatile UCHAR ucMasterRTURcvBuf[MB_SER_PDU_SIZE_MAX];
-static volatile USHORT usMasterSendPDULength;
-
-static volatile UCHAR *pucMasterSndBufferCur;
-static volatile USHORT usMasterSndBufferCount;
-
-static volatile USHORT usMasterRcvBufferPos;
-static volatile BOOL xFrameIsBroadcast = FALSE;
-
-static volatile eMBMasterTimerMode eMasterCurTimerMode;
-
-/* ----------------------- Start implementation -----------------------------*/
-eMBErrorCode
-eMBMasterRTUInit(UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
-{
- eMBErrorCode eStatus = MB_ENOERR;
- ULONG usTimerT35_50us;
-
- ENTER_CRITICAL_SECTION( );
-
- /* Modbus RTU uses 8 Databits. */
- if( xMBMasterPortSerialInit( ucPort, ulBaudRate, 8, eParity ) != TRUE )
- {
- eStatus = MB_EPORTERR;
- }
- else
- {
- /* If baudrate > 19200 then we should use the fixed timer values
- * t35 = 1750us. Otherwise t35 must be 3.5 times the character time.
- */
- if( ulBaudRate > 19200 )
- {
- usTimerT35_50us = 35; /* 1800us. */
- }
- else
- {
- /* The timer reload value for a character is given by:
- *
- * ChTimeValue = Ticks_per_1s / ( Baudrate / 11 )
- * = 11 * Ticks_per_1s / Baudrate
- * = 220000 / Baudrate
- * The reload for t3.5 is 1.5 times this value and similary
- * for t3.5.
- */
- usTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate );
- }
- if( xMBMasterPortTimersInit( ( USHORT ) usTimerT35_50us ) != TRUE )
- {
- eStatus = MB_EPORTERR;
- }
- }
- EXIT_CRITICAL_SECTION( );
-
- return eStatus;
-}
-
-void
-eMBMasterRTUStart( void )
-{
- ENTER_CRITICAL_SECTION( );
- /* Initially the receiver is in the state STATE_M_RX_INIT. we start
- * the timer and if no character is received within t3.5 we change
- * to STATE_M_RX_IDLE. This makes sure that we delay startup of the
- * modbus protocol stack until the bus is free.
- */
- eRcvState = STATE_M_RX_INIT;
- vMBMasterPortSerialEnable( TRUE, FALSE );
- vMBMasterPortTimersT35Enable( );
-
- EXIT_CRITICAL_SECTION( );
-}
-
-void
-eMBMasterRTUStop( void )
-{
- ENTER_CRITICAL_SECTION( );
- vMBMasterPortSerialEnable( FALSE, FALSE );
- vMBMasterPortTimersDisable( );
- EXIT_CRITICAL_SECTION( );
-}
-
-eMBErrorCode
-eMBMasterRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
-{
- eMBErrorCode eStatus = MB_ENOERR;
-
- ENTER_CRITICAL_SECTION( );
- RT_ASSERT( usMasterRcvBufferPos < MB_SER_PDU_SIZE_MAX );
-
- /* Length and CRC check */
- if( ( usMasterRcvBufferPos >= MB_SER_PDU_SIZE_MIN )
- && ( usMBCRC16( ( UCHAR * ) ucMasterRTURcvBuf, usMasterRcvBufferPos ) == 0 ) )
- {
- /* Save the address field. All frames are passed to the upper layed
- * and the decision if a frame is used is done there.
- */
- *pucRcvAddress = ucMasterRTURcvBuf[MB_SER_PDU_ADDR_OFF];
-
- /* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
- * size of address field and CRC checksum.
- */
- *pusLength = ( USHORT )( usMasterRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC );
-
- /* Return the start of the Modbus PDU to the caller. */
- *pucFrame = ( UCHAR * ) & ucMasterRTURcvBuf[MB_SER_PDU_PDU_OFF];
- }
- else
- {
- eStatus = MB_EIO;
- }
-
- EXIT_CRITICAL_SECTION( );
- return eStatus;
-}
-
-eMBErrorCode
-eMBMasterRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
-{
- eMBErrorCode eStatus = MB_ENOERR;
- USHORT usCRC16;
-
- if ( ucSlaveAddress > MB_MASTER_TOTAL_SLAVE_NUM ) return MB_EINVAL;
-
- ENTER_CRITICAL_SECTION( );
-
- /* Check if the receiver is still in idle state. If not we where to
- * slow with processing the received frame and the master sent another
- * frame on the network. We have to abort sending the frame.
- */
- if( eRcvState == STATE_M_RX_IDLE )
- {
- /* First byte before the Modbus-PDU is the slave address. */
- pucMasterSndBufferCur = ( UCHAR * ) pucFrame - 1;
- usMasterSndBufferCount = 1;
-
- /* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */
- pucMasterSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress;
- usMasterSndBufferCount += usLength;
-
- /* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
- usCRC16 = usMBCRC16( ( UCHAR * ) pucMasterSndBufferCur, usMasterSndBufferCount );
- ucMasterRTUSndBuf[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
- ucMasterRTUSndBuf[usMasterSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );
-
- /* Activate the transmitter. */
- eSndState = STATE_M_TX_XMIT;
- vMBMasterPortSerialEnable( FALSE, TRUE );
- }
- else
- {
- eStatus = MB_EIO;
- }
- EXIT_CRITICAL_SECTION( );
- return eStatus;
-}
-
-BOOL
-xMBMasterRTUReceiveFSM( void )
-{
- BOOL xTaskNeedSwitch = FALSE;
- UCHAR ucByte;
-
- RT_ASSERT(( eSndState == STATE_M_TX_IDLE ) || ( eSndState == STATE_M_TX_XFWR ));
-
- /* Always read the character. */
- ( void )xMBMasterPortSerialGetByte( ( CHAR * ) & ucByte );
-
- switch ( eRcvState )
- {
- /* If we have received a character in the init state we have to
- * wait until the frame is finished.
- */
- case STATE_M_RX_INIT:
- vMBMasterPortTimersT35Enable( );
- break;
-
- /* In the error state we wait until all characters in the
- * damaged frame are transmitted.
- */
- case STATE_M_RX_ERROR:
- vMBMasterPortTimersT35Enable( );
- break;
-
- /* In the idle state we wait for a new character. If a character
- * is received the t1.5 and t3.5 timers are started and the
- * receiver is in the state STATE_RX_RECEIVCE and disable early
- * the timer of respond timeout .
- */
- case STATE_M_RX_IDLE:
- /* In time of respond timeout,the receiver receive a frame.
- * Disable timer of respond timeout and change the transmiter state to idle.
- */
- vMBMasterPortTimersDisable( );
- eSndState = STATE_M_TX_IDLE;
-
- usMasterRcvBufferPos = 0;
- ucMasterRTURcvBuf[usMasterRcvBufferPos++] = ucByte;
- eRcvState = STATE_M_RX_RCV;
-
- /* Enable t3.5 timers. */
- vMBMasterPortTimersT35Enable( );
- break;
-
- /* We are currently receiving a frame. Reset the timer after
- * every character received. If more than the maximum possible
- * number of bytes in a modbus frame is received the frame is
- * ignored.
- */
- case STATE_M_RX_RCV:
- if( usMasterRcvBufferPos < MB_SER_PDU_SIZE_MAX )
- {
- ucMasterRTURcvBuf[usMasterRcvBufferPos++] = ucByte;
- }
- else
- {
- eRcvState = STATE_M_RX_ERROR;
- }
- vMBMasterPortTimersT35Enable();
- break;
- }
- return xTaskNeedSwitch;
-}
-
-BOOL
-xMBMasterRTUTransmitFSM( void )
-{
- BOOL xNeedPoll = FALSE;
-
- RT_ASSERT( eRcvState == STATE_M_RX_IDLE );
-
- switch ( eSndState )
- {
- /* We should not get a transmitter event if the transmitter is in
- * idle state. */
- case STATE_M_TX_IDLE:
- /* enable receiver/disable transmitter. */
- vMBMasterPortSerialEnable( TRUE, FALSE );
- break;
-
- case STATE_M_TX_XMIT:
- /* check if we are finished. */
- if( usMasterSndBufferCount != 0 )
- {
- xMBMasterPortSerialPutByte( ( CHAR )*pucMasterSndBufferCur );
- pucMasterSndBufferCur++; /* next byte in sendbuffer. */
- usMasterSndBufferCount--;
- }
- else
- {
- xFrameIsBroadcast = ( ucMasterRTUSndBuf[MB_SER_PDU_ADDR_OFF] == MB_ADDRESS_BROADCAST ) ? TRUE : FALSE;
- /* Disable transmitter. This prevents another transmit buffer
- * empty interrupt. */
- vMBMasterPortSerialEnable( TRUE, FALSE );
- eSndState = STATE_M_TX_XFWR;
- /* If the frame is broadcast ,master will enable timer of convert delay,
- * else master will enable timer of respond timeout. */
- if ( xFrameIsBroadcast == TRUE )
- {
- vMBMasterPortTimersConvertDelayEnable( );
- }
- else
- {
- vMBMasterPortTimersRespondTimeoutEnable( );
- }
- }
- break;
- }
-
- return xNeedPoll;
-}
-
-BOOL
-xMBMasterRTUTimerExpired(void)
-{
- BOOL xNeedPoll = FALSE;
-
- switch (eRcvState)
- {
- /* Timer t35 expired. Startup phase is finished. */
- case STATE_M_RX_INIT:
- xNeedPoll = xMBMasterPortEventPost(EV_MASTER_READY);
- break;
-
- /* A frame was received and t35 expired. Notify the listener that
- * a new frame was received. */
- case STATE_M_RX_RCV:
- xNeedPoll = xMBMasterPortEventPost(EV_MASTER_FRAME_RECEIVED);
- break;
-
- /* An error occured while receiving the frame. */
- case STATE_M_RX_ERROR:
- vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
- xNeedPoll = xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
- break;
-
- /* Function called in an illegal state. */
- default:
- RT_ASSERT(
- ( eRcvState == STATE_M_RX_INIT ) || ( eRcvState == STATE_M_RX_RCV ) ||
- ( eRcvState == STATE_M_RX_ERROR ) || ( eRcvState == STATE_M_RX_IDLE ));
- break;
- }
- eRcvState = STATE_M_RX_IDLE;
-
- switch (eSndState)
- {
- /* A frame was send finish and convert delay or respond timeout expired.
- * If the frame is broadcast,The master will idle,and if the frame is not
- * broadcast.Notify the listener process error.*/
- case STATE_M_TX_XFWR:
- if ( xFrameIsBroadcast == FALSE ) {
- vMBMasterSetErrorType(EV_ERROR_RESPOND_TIMEOUT);
- xNeedPoll = xMBMasterPortEventPost(EV_MASTER_ERROR_PROCESS);
- }
- break;
- /* Function called in an illegal state. */
- default:
- RT_ASSERT(
- ( eSndState == STATE_M_TX_XFWR ) || ( eSndState == STATE_M_TX_IDLE ));
- break;
- }
- eSndState = STATE_M_TX_IDLE;
-
- vMBMasterPortTimersDisable( );
- /* If timer mode is convert delay, the master event then turns EV_MASTER_EXECUTE status. */
- if (eMasterCurTimerMode == MB_TMODE_CONVERT_DELAY) {
- xNeedPoll = xMBMasterPortEventPost( EV_MASTER_EXECUTE );
- }
-
- return xNeedPoll;
-}
-
-/* Get Modbus Master send RTU's buffer address pointer.*/
-void vMBMasterGetRTUSndBuf( UCHAR ** pucFrame )
-{
- *pucFrame = ( UCHAR * ) ucMasterRTUSndBuf;
-}
-
-/* Get Modbus Master send PDU's buffer address pointer.*/
-void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame )
-{
- *pucFrame = ( UCHAR * ) &ucMasterRTUSndBuf[MB_SER_PDU_PDU_OFF];
-}
-
-/* Set Modbus Master send PDU's buffer length.*/
-void vMBMasterSetPDUSndLength( USHORT SendPDULength )
-{
- usMasterSendPDULength = SendPDULength;
-}
-
-/* Get Modbus Master send PDU's buffer length.*/
-USHORT usMBMasterGetPDUSndLength( void )
-{
- return usMasterSendPDULength;
-}
-
-/* Set Modbus Master current timer mode.*/
-void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode )
-{
- eMasterCurTimerMode = eMBTimerMode;
-}
-
-/* The master request is broadcast? */
-BOOL xMBMasterRequestIsBroadcast( void ){
- return xFrameIsBroadcast;
-}
-#endif
-
diff --git a/components/net/freemodbus/modbus/tcp/mbtcp.c b/components/net/freemodbus/modbus/tcp/mbtcp.c
deleted file mode 100644
index 3eb3b7071f..0000000000
--- a/components/net/freemodbus/modbus/tcp/mbtcp.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbtcp.c,v 1.3 2006/12/07 22:10:34 wolti Exp $
- */
-
-/* ----------------------- System includes ----------------------------------*/
-#include "stdlib.h"
-#include "string.h"
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mbconfig.h"
-#include "mbtcp.h"
-#include "mbframe.h"
-#include "mbport.h"
-
-#if MB_SLAVE_TCP_ENABLED > 0
-
-/* ----------------------- Defines ------------------------------------------*/
-
-/* ----------------------- MBAP Header --------------------------------------*/
-/*
- *
- * <------------------------ MODBUS TCP/IP ADU(1) ------------------------->
- * <----------- MODBUS PDU (1') ---------------->
- * +-----------+---------------+------------------------------------------+
- * | TID | PID | Length | UID |Code | Data |
- * +-----------+---------------+------------------------------------------+
- * | | | | |
- * (2) (3) (4) (5) (6)
- *
- * (2) ... MB_TCP_TID = 0 (Transaction Identifier - 2 Byte)
- * (3) ... MB_TCP_PID = 2 (Protocol Identifier - 2 Byte)
- * (4) ... MB_TCP_LEN = 4 (Number of bytes - 2 Byte)
- * (5) ... MB_TCP_UID = 6 (Unit Identifier - 1 Byte)
- * (6) ... MB_TCP_FUNC = 7 (Modbus Function Code)
- *
- * (1) ... Modbus TCP/IP Application Data Unit
- * (1') ... Modbus Protocol Data Unit
- */
-
-#define MB_TCP_TID 0
-#define MB_TCP_PID 2
-#define MB_TCP_LEN 4
-#define MB_TCP_UID 6
-#define MB_TCP_FUNC 7
-
-#define MB_TCP_PROTOCOL_ID 0 /* 0 = Modbus Protocol */
-
-
-/* ----------------------- Start implementation -----------------------------*/
-eMBErrorCode
-eMBTCPDoInit( USHORT ucTCPPort )
-{
- eMBErrorCode eStatus = MB_ENOERR;
-
- if( xMBTCPPortInit( ucTCPPort ) == FALSE )
- {
- eStatus = MB_EPORTERR;
- }
- return eStatus;
-}
-
-void
-eMBTCPStart( void )
-{
-}
-
-void
-eMBTCPStop( void )
-{
- /* Make sure that no more clients are connected. */
- vMBTCPPortDisable( );
-}
-
-eMBErrorCode
-eMBTCPReceive( UCHAR * pucRcvAddress, UCHAR ** ppucFrame, USHORT * pusLength )
-{
- eMBErrorCode eStatus = MB_EIO;
- UCHAR *pucMBTCPFrame;
- USHORT usLength;
- USHORT usPID;
-
- if( xMBTCPPortGetRequest( &pucMBTCPFrame, &usLength ) != FALSE )
- {
- usPID = pucMBTCPFrame[MB_TCP_PID] << 8U;
- usPID |= pucMBTCPFrame[MB_TCP_PID + 1];
-
- if( usPID == MB_TCP_PROTOCOL_ID )
- {
- *ppucFrame = &pucMBTCPFrame[MB_TCP_FUNC];
- *pusLength = usLength - MB_TCP_FUNC;
- eStatus = MB_ENOERR;
-
- /* Modbus TCP does not use any addresses. Fake the source address such
- * that the processing part deals with this frame.
- */
- *pucRcvAddress = MB_TCP_PSEUDO_ADDRESS;
- }
- }
- else
- {
- eStatus = MB_EIO;
- }
- return eStatus;
-}
-
-eMBErrorCode
-eMBTCPSend( UCHAR _unused, const UCHAR * pucFrame, USHORT usLength )
-{
- eMBErrorCode eStatus = MB_ENOERR;
- UCHAR *pucMBTCPFrame = ( UCHAR * ) pucFrame - MB_TCP_FUNC;
- USHORT usTCPLength = usLength + MB_TCP_FUNC;
-
- /* The MBAP header is already initialized because the caller calls this
- * function with the buffer returned by the previous call. Therefore we
- * only have to update the length in the header. Note that the length
- * header includes the size of the Modbus PDU and the UID Byte. Therefore
- * the length is usLength plus one.
- */
- pucMBTCPFrame[MB_TCP_LEN] = ( usLength + 1 ) >> 8U;
- pucMBTCPFrame[MB_TCP_LEN + 1] = ( usLength + 1 ) & 0xFF;
- if( xMBTCPPortSendResponse( pucMBTCPFrame, usTCPLength ) == FALSE )
- {
- eStatus = MB_EIO;
- }
- return eStatus;
-}
-
-#endif
diff --git a/components/net/freemodbus/modbus/tcp/mbtcp.h b/components/net/freemodbus/modbus/tcp/mbtcp.h
deleted file mode 100644
index 905d113c5a..0000000000
--- a/components/net/freemodbus/modbus/tcp/mbtcp.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
- * Copyright (c) 2006 Christian Walter <[email protected]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * File: $Id: mbtcp.h,v 1.2 2006/12/07 22:10:34 wolti Exp $
- */
-
-#ifndef _MB_TCP_H
-#define _MB_TCP_H
-
-#ifdef __cplusplus
-PR_BEGIN_EXTERN_C
-#endif
-
-/* ----------------------- Defines ------------------------------------------*/
-#define MB_TCP_PSEUDO_ADDRESS 255
-
-/* ----------------------- Function prototypes ------------------------------*/
- eMBErrorCode eMBTCPDoInit( USHORT ucTCPPort );
-void eMBTCPStart( void );
-void eMBTCPStop( void );
-eMBErrorCode eMBTCPReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame,
- USHORT * pusLength );
-eMBErrorCode eMBTCPSend( UCHAR _unused, const UCHAR * pucFrame,
- USHORT usLength );
-
-#ifdef __cplusplus
-PR_END_EXTERN_C
-#endif
-#endif
diff --git a/components/net/freemodbus/port/port.c b/components/net/freemodbus/port/port.c
deleted file mode 100644
index d01c5c9d6a..0000000000
--- a/components/net/freemodbus/port/port.c
+++ /dev/null
@@ -1,38 +0,0 @@
- /*
- * FreeModbus Libary: RT-Thread Port
- * Copyright (C) 2013 Armink <[email protected]>
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * File: $Id: port.c,v 1.60 2015/02/01 9:18:05 Armink $
- */
-
-/* ----------------------- System includes --------------------------------*/
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "port.h"
-/* ----------------------- Variables ----------------------------------------*/
-static rt_base_t level;
-/* ----------------------- Start implementation -----------------------------*/
-void EnterCriticalSection(void)
-{
- level = rt_hw_interrupt_disable();
-}
-
-void ExitCriticalSection(void)
-{
- rt_hw_interrupt_enable(level);
-}
-
diff --git a/components/net/freemodbus/port/port.h b/components/net/freemodbus/port/port.h
deleted file mode 100644
index 97b648a8bb..0000000000
--- a/components/net/freemodbus/port/port.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * FreeModbus Libary: BARE Port
- * Copyright (C) 2013 Armink <[email protected]>
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * File: $Id: port.h ,v 1.60 2013/08/13 15:07:05 Armink add Master Functions $
- */
-
-#ifndef _PORT_H
-#define _PORT_H
-
-#include "mbconfig.h"
-#include <rthw.h>
-#include <rtthread.h>
-
-#include <assert.h>
-#include <inttypes.h>
-
-#define INLINE
-#define PR_BEGIN_EXTERN_C extern "C" {
-#define PR_END_EXTERN_C }
-
-#define ENTER_CRITICAL_SECTION() EnterCriticalSection()
-#define EXIT_CRITICAL_SECTION() ExitCriticalSection()
-
-typedef uint8_t BOOL;
-
-typedef unsigned char UCHAR;
-typedef char CHAR;
-
-typedef uint16_t USHORT;
-typedef int16_t SHORT;
-
-typedef uint32_t ULONG;
-typedef int32_t LONG;
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-void EnterCriticalSection(void);
-void ExitCriticalSection(void);
-
-#endif
diff --git a/components/net/freemodbus/port/portevent.c b/components/net/freemodbus/port/portevent.c
deleted file mode 100644
index 1a881166be..0000000000
--- a/components/net/freemodbus/port/portevent.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * FreeModbus Libary: RT-Thread Port
- * Copyright (C) 2013 Armink <[email protected]>
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * File: $Id: portevent.c,v 1.60 2013/08/13 15:07:05 Armink $
- */
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mbport.h"
-
-/* ----------------------- Variables ----------------------------------------*/
-static struct rt_event xSlaveOsEvent;
-/* ----------------------- Start implementation -----------------------------*/
-BOOL
-xMBPortEventInit( void )
-{
- rt_event_init(&xSlaveOsEvent,"slave event",RT_IPC_FLAG_PRIO);
- return TRUE;
-}
-
-BOOL
-xMBPortEventPost( eMBEventType eEvent )
-{
- rt_event_send(&xSlaveOsEvent, eEvent);
- return TRUE;
-}
-
-BOOL
-xMBPortEventGet( eMBEventType * eEvent )
-{
- rt_uint32_t recvedEvent;
- /* waiting forever OS event */
- rt_event_recv(&xSlaveOsEvent,
- EV_READY | EV_FRAME_RECEIVED | EV_EXECUTE | EV_FRAME_SENT,
- RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER,
- &recvedEvent);
- switch (recvedEvent)
- {
- case EV_READY:
- *eEvent = EV_READY;
- break;
- case EV_FRAME_RECEIVED:
- *eEvent = EV_FRAME_RECEIVED;
- break;
- case EV_EXECUTE:
- *eEvent = EV_EXECUTE;
- break;
- case EV_FRAME_SENT:
- *eEvent = EV_FRAME_SENT;
- break;
- }
- return TRUE;
-}
diff --git a/components/net/freemodbus/port/portevent_m.c b/components/net/freemodbus/port/portevent_m.c
deleted file mode 100644
index 031a3b84ef..0000000000
--- a/components/net/freemodbus/port/portevent_m.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * FreeModbus Libary: RT-Thread Port
- * Copyright (C) 2013 Armink <[email protected]>
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * File: $Id: portevent_m.c v 1.60 2013/08/13 15:07:05 Armink add Master Functions$
- */
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mb_m.h"
-#include "mbport.h"
-#include "port.h"
-
-#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
-/* ----------------------- Defines ------------------------------------------*/
-/* ----------------------- Variables ----------------------------------------*/
-static struct rt_semaphore xMasterRunRes;
-static struct rt_event xMasterOsEvent;
-/* ----------------------- Start implementation -----------------------------*/
-BOOL
-xMBMasterPortEventInit( void )
-{
- rt_event_init(&xMasterOsEvent,"master event",RT_IPC_FLAG_PRIO);
- return TRUE;
-}
-
-BOOL
-xMBMasterPortEventPost( eMBMasterEventType eEvent )
-{
- rt_event_send(&xMasterOsEvent, eEvent);
- return TRUE;
-}
-
-BOOL
-xMBMasterPortEventGet( eMBMasterEventType * eEvent )
-{
- rt_uint32_t recvedEvent;
- /* waiting forever OS event */
- rt_event_recv(&xMasterOsEvent,
- EV_MASTER_READY | EV_MASTER_FRAME_RECEIVED | EV_MASTER_EXECUTE |
- EV_MASTER_FRAME_SENT | EV_MASTER_ERROR_PROCESS,
- RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER,
- &recvedEvent);
- /* the enum type couldn't convert to int type */
- switch (recvedEvent)
- {
- case EV_MASTER_READY:
- *eEvent = EV_MASTER_READY;
- break;
- case EV_MASTER_FRAME_RECEIVED:
- *eEvent = EV_MASTER_FRAME_RECEIVED;
- break;
- case EV_MASTER_EXECUTE:
- *eEvent = EV_MASTER_EXECUTE;
- break;
- case EV_MASTER_FRAME_SENT:
- *eEvent = EV_MASTER_FRAME_SENT;
- break;
- case EV_MASTER_ERROR_PROCESS:
- *eEvent = EV_MASTER_ERROR_PROCESS;
- break;
- }
- return TRUE;
-}
-/**
- * This function is initialize the OS resource for modbus master.
- * Note:The resource is define by OS.If you not use OS this function can be empty.
- *
- */
-void vMBMasterOsResInit( void )
-{
- rt_sem_init(&xMasterRunRes, "master res", 0x01 , RT_IPC_FLAG_PRIO);
-}
-
-/**
- * This function is take Mobus Master running resource.
- * Note:The resource is define by Operating System.If you not use OS this function can be just return TRUE.
- *
- * @param lTimeOut the waiting time.
- *
- * @return resource taked result
- */
-BOOL xMBMasterRunResTake( LONG lTimeOut )
-{
- /*If waiting time is -1 .It will wait forever */
- return rt_sem_take(&xMasterRunRes, lTimeOut) ? FALSE : TRUE ;
-}
-
-/**
- * This function is release Mobus Master running resource.
- * Note:The resource is define by Operating System.If you not use OS this function can be empty.
- *
- */
-void vMBMasterRunResRelease( void )
-{
- /* release resource */
- rt_sem_release(&xMasterRunRes);
-}
-
-/**
- * This is modbus master respond timeout error process callback function.
- * @note There functions will block modbus master poll while execute OS waiting.
- * So,for real-time of system.Do not execute too much waiting process.
- *
- * @param ucDestAddress destination salve address
- * @param pucPDUData PDU buffer data
- * @param ucPDULength PDU buffer length
- *
- */
-void vMBMasterErrorCBRespondTimeout(UCHAR ucDestAddress, const UCHAR* pucPDUData,
- USHORT ucPDULength) {
- /**
- * @note This code is use OS's event mechanism for modbus master protocol stack.
- * If you don't use OS, you can change it.
- */
- rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_RESPOND_TIMEOUT);
-
- /* You can add your code under here. */
-
-}
-
-/**
- * This is modbus master receive data error process callback function.
- * @note There functions will block modbus master poll while execute OS waiting.
- * So,for real-time of system.Do not execute too much waiting process.
- *
- * @param ucDestAddress destination salve address
- * @param pucPDUData PDU buffer data
- * @param ucPDULength PDU buffer length
- *
- */
-void vMBMasterErrorCBReceiveData(UCHAR ucDestAddress, const UCHAR* pucPDUData,
- USHORT ucPDULength) {
- /**
- * @note This code is use OS's event mechanism for modbus master protocol stack.
- * If you don't use OS, you can change it.
- */
- rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_RECEIVE_DATA);
-
- /* You can add your code under here. */
-
-}
-
-/**
- * This is modbus master execute function error process callback function.
- * @note There functions will block modbus master poll while execute OS waiting.
- * So,for real-time of system.Do not execute too much waiting process.
- *
- * @param ucDestAddress destination salve address
- * @param pucPDUData PDU buffer data
- * @param ucPDULength PDU buffer length
- *
- */
-void vMBMasterErrorCBExecuteFunction(UCHAR ucDestAddress, const UCHAR* pucPDUData,
- USHORT ucPDULength) {
- /**
- * @note This code is use OS's event mechanism for modbus master protocol stack.
- * If you don't use OS, you can change it.
- */
- rt_event_send(&xMasterOsEvent, EV_MASTER_ERROR_EXECUTE_FUNCTION);
-
- /* You can add your code under here. */
-
-}
-
-/**
- * This is modbus master request process success callback function.
- * @note There functions will block modbus master poll while execute OS waiting.
- * So,for real-time of system.Do not execute too much waiting process.
- *
- */
-void vMBMasterCBRequestScuuess( void ) {
- /**
- * @note This code is use OS's event mechanism for modbus master protocol stack.
- * If you don't use OS, you can change it.
- */
- rt_event_send(&xMasterOsEvent, EV_MASTER_PROCESS_SUCESS);
-
- /* You can add your code under here. */
-
-}
-
-/**
- * This function is wait for modbus master request finish and return result.
- * Waiting result include request process success, request respond timeout,
- * receive data error and execute function error.You can use the above callback function.
- * @note If you are use OS, you can use OS's event mechanism. Otherwise you have to run
- * much user custom delay for waiting.
- *
- * @return request error code
- */
-eMBMasterReqErrCode eMBMasterWaitRequestFinish( void ) {
- eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR;
- rt_uint32_t recvedEvent;
- /* waiting for OS event */
- rt_event_recv(&xMasterOsEvent,
- EV_MASTER_PROCESS_SUCESS | EV_MASTER_ERROR_RESPOND_TIMEOUT
- | EV_MASTER_ERROR_RECEIVE_DATA
- | EV_MASTER_ERROR_EXECUTE_FUNCTION,
- RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER,
- &recvedEvent);
- switch (recvedEvent)
- {
- case EV_MASTER_PROCESS_SUCESS:
- break;
- case EV_MASTER_ERROR_RESPOND_TIMEOUT:
- {
- eErrStatus = MB_MRE_TIMEDOUT;
- break;
- }
- case EV_MASTER_ERROR_RECEIVE_DATA:
- {
- eErrStatus = MB_MRE_REV_DATA;
- break;
- }
- case EV_MASTER_ERROR_EXECUTE_FUNCTION:
- {
- eErrStatus = MB_MRE_EXE_FUN;
- break;
- }
- }
- return eErrStatus;
-}
-
-#endif
diff --git a/components/net/freemodbus/port/portserial.c b/components/net/freemodbus/port/portserial.c
deleted file mode 100644
index cbd846d7ff..0000000000
--- a/components/net/freemodbus/port/portserial.c
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * FreeModbus Libary: RT-Thread Port
- * Copyright (C) 2013 Armink <[email protected]>
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * File: $Id: portserial.c,v 1.60 2013/08/13 15:07:05 Armink $
- */
-
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mbport.h"
-#include "rtdevice.h"
-#include "board.h"
-
-/* ----------------------- Static variables ---------------------------------*/
-ALIGN(RT_ALIGN_SIZE)
-/* software simulation serial transmit IRQ handler thread stack */
-static rt_uint8_t serial_soft_trans_irq_stack[512];
-/* software simulation serial transmit IRQ handler thread */
-static struct rt_thread thread_serial_soft_trans_irq;
-/* serial event */
-static struct rt_event event_serial;
-/* modbus slave serial device */
-static rt_serial_t *serial;
-
-/* ----------------------- Defines ------------------------------------------*/
-/* serial transmit event */
-#define EVENT_SERIAL_TRANS_START (1<<0)
-
-/* ----------------------- static functions ---------------------------------*/
-static void prvvUARTTxReadyISR(void);
-static void prvvUARTRxISR(void);
-static rt_err_t serial_rx_ind(rt_device_t dev, rt_size_t size);
-static void serial_soft_trans_irq(void* parameter);
-
-/* ----------------------- Start implementation -----------------------------*/
-BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
- eMBParity eParity)
-{
- rt_device_t dev = RT_NULL;
- char uart_name[20];
- /**
- * set 485 mode receive and transmit control IO
- * @note MODBUS_SLAVE_RT_CONTROL_PIN_INDEX need be defined by user
- */
-#if defined(RT_MODBUS_SLAVE_USE_CONTROL_PIN)
- rt_pin_mode(MODBUS_SLAVE_RT_CONTROL_PIN_INDEX, PIN_MODE_OUTPUT);
-#endif
- /* set serial name */
- rt_snprintf(uart_name,sizeof(uart_name), "uart%d", ucPORT);
-
- dev = rt_device_find(uart_name);
- if(dev == RT_NULL)
- {
- /* can not find uart */
- return FALSE;
- }
- else
- {
- serial = (struct rt_serial_device*)dev;
- }
-
- /* set serial configure parameter */
- serial->config.baud_rate = ulBaudRate;
- serial->config.stop_bits = STOP_BITS_1;
- switch(eParity){
- case MB_PAR_NONE: {
- serial->config.data_bits = DATA_BITS_8;
- serial->config.parity = PARITY_NONE;
- break;
- }
- case MB_PAR_ODD: {
- serial->config.data_bits = DATA_BITS_9;
- serial->config.parity = PARITY_ODD;
- break;
- }
- case MB_PAR_EVEN: {
- serial->config.data_bits = DATA_BITS_9;
- serial->config.parity = PARITY_EVEN;
- break;
- }
- }
- /* set serial configure */
- serial->ops->configure(serial, &(serial->config));
-
- /* open serial device */
- if (!rt_device_open(&serial->parent, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX)) {
- rt_device_set_rx_indicate(&serial->parent, serial_rx_ind);
- } else {
- return FALSE;
- }
-
- /* software initialize */
- rt_event_init(&event_serial, "slave event", RT_IPC_FLAG_PRIO);
- rt_thread_init(&thread_serial_soft_trans_irq,
- "slave trans",
- serial_soft_trans_irq,
- RT_NULL,
- serial_soft_trans_irq_stack,
- sizeof(serial_soft_trans_irq_stack),
- 10, 5);
- rt_thread_startup(&thread_serial_soft_trans_irq);
-
- return TRUE;
-}
-
-void vMBPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable)
-{
- rt_uint32_t recved_event;
- if (xRxEnable)
- {
- /* enable RX interrupt */
- serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX);
- /* switch 485 to receive mode */
-#if defined(RT_MODBUS_SLAVE_USE_CONTROL_PIN)
- rt_pin_write(MODBUS_SLAVE_RT_CONTROL_PIN_INDEX, PIN_LOW);
-#endif
- }
- else
- {
- /* switch 485 to transmit mode */
-#if defined(RT_MODBUS_SLAVE_USE_CONTROL_PIN)
- rt_pin_write(MODBUS_SLAVE_RT_CONTROL_PIN_INDEX, PIN_HIGH);
-#endif
- /* disable RX interrupt */
- serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *)RT_DEVICE_FLAG_INT_RX);
- }
- if (xTxEnable)
- {
- /* start serial transmit */
- rt_event_send(&event_serial, EVENT_SERIAL_TRANS_START);
- }
- else
- {
- /* stop serial transmit */
- rt_event_recv(&event_serial, EVENT_SERIAL_TRANS_START,
- RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 0,
- &recved_event);
- }
-}
-
-void vMBPortClose(void)
-{
- serial->parent.close(&(serial->parent));
-}
-
-BOOL xMBPortSerialPutByte(CHAR ucByte)
-{
- serial->parent.write(&(serial->parent), 0, &ucByte, 1);
- return TRUE;
-}
-
-BOOL xMBPortSerialGetByte(CHAR * pucByte)
-{
- serial->parent.read(&(serial->parent), 0, pucByte, 1);
- return TRUE;
-}
-
-/*
- * Create an interrupt handler for the transmit buffer empty interrupt
- * (or an equivalent) for your target processor. This function should then
- * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
- * a new character can be sent. The protocol stack will then call
- * xMBPortSerialPutByte( ) to send the character.
- */
-void prvvUARTTxReadyISR(void)
-{
- pxMBFrameCBTransmitterEmpty();
-}
-
-/*
- * Create an interrupt handler for the receive interrupt for your target
- * processor. This function should then call pxMBFrameCBByteReceived( ). The
- * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
- * character.
- */
-void prvvUARTRxISR(void)
-{
- pxMBFrameCBByteReceived();
-}
-
-/**
- * Software simulation serial transmit IRQ handler.
- *
- * @param parameter parameter
- */
-static void serial_soft_trans_irq(void* parameter) {
- rt_uint32_t recved_event;
- while (1)
- {
- /* waiting for serial transmit start */
- rt_event_recv(&event_serial, EVENT_SERIAL_TRANS_START, RT_EVENT_FLAG_OR,
- RT_WAITING_FOREVER, &recved_event);
- /* execute modbus callback */
- prvvUARTTxReadyISR();
- }
-}
-
-/**
- * This function is serial receive callback function
- *
- * @param dev the device of serial
- * @param size the data size that receive
- *
- * @return return RT_EOK
- */
-static rt_err_t serial_rx_ind(rt_device_t dev, rt_size_t size) {
- prvvUARTRxISR();
- return RT_EOK;
-}
diff --git a/components/net/freemodbus/port/portserial_m.c b/components/net/freemodbus/port/portserial_m.c
deleted file mode 100644
index 47a70dd905..0000000000
--- a/components/net/freemodbus/port/portserial_m.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * FreeModbus Libary: RT-Thread Port
- * Copyright (C) 2013 Armink <[email protected]>
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * File: $Id: portserial_m.c,v 1.60 2013/08/13 15:07:05 Armink add Master Functions $
- */
-
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mbport.h"
-#include "rtdevice.h"
-#include "board.h"
-
-#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
-/* ----------------------- Static variables ---------------------------------*/
-ALIGN(RT_ALIGN_SIZE)
-/* software simulation serial transmit IRQ handler thread stack */
-static rt_uint8_t serial_soft_trans_irq_stack[512];
-/* software simulation serial transmit IRQ handler thread */
-static struct rt_thread thread_serial_soft_trans_irq;
-/* serial event */
-static struct rt_event event_serial;
-/* modbus master serial device */
-static rt_serial_t *serial;
-
-/* ----------------------- Defines ------------------------------------------*/
-/* serial transmit event */
-#define EVENT_SERIAL_TRANS_START (1<<0)
-
-/* ----------------------- static functions ---------------------------------*/
-static void prvvUARTTxReadyISR(void);
-static void prvvUARTRxISR(void);
-static rt_err_t serial_rx_ind(rt_device_t dev, rt_size_t size);
-static void serial_soft_trans_irq(void* parameter);
-
-/* ----------------------- Start implementation -----------------------------*/
-BOOL xMBMasterPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
- eMBParity eParity)
-{
- rt_device_t dev = RT_NULL;
- char uart_name[20];
-
- /**
- * set 485 mode receive and transmit control IO
- * @note MODBUS_MASTER_RT_CONTROL_PIN_INDEX need be defined by user
- */
-#if defined(RT_MODBUS_MASTER_USE_CONTROL_PIN)
- rt_pin_mode(MODBUS_MASTER_RT_CONTROL_PIN_INDEX, PIN_MODE_OUTPUT);
-#endif
- /* set serial name */
- rt_snprintf(uart_name,sizeof(uart_name), "uart%d", ucPORT);
-
- dev = rt_device_find(uart_name);
- if(dev == RT_NULL)
- {
- /* can not find uart */
- return FALSE;
- }
- else
- {
- serial = (struct rt_serial_device*)dev;
- }
-
- /* set serial configure parameter */
- serial->config.baud_rate = ulBaudRate;
- serial->config.stop_bits = STOP_BITS_1;
- switch(eParity){
- case MB_PAR_NONE: {
- serial->config.data_bits = DATA_BITS_8;
- serial->config.parity = PARITY_NONE;
- break;
- }
- case MB_PAR_ODD: {
- serial->config.data_bits = DATA_BITS_9;
- serial->config.parity = PARITY_ODD;
- break;
- }
- case MB_PAR_EVEN: {
- serial->config.data_bits = DATA_BITS_9;
- serial->config.parity = PARITY_EVEN;
- break;
- }
- }
- /* set serial configure */
- serial->ops->configure(serial, &(serial->config));
-
- /* open serial device */
- if (!rt_device_open(&serial->parent, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX)) {
- rt_device_set_rx_indicate(&serial->parent, serial_rx_ind);
- } else {
- return FALSE;
- }
-
- /* software initialize */
- rt_event_init(&event_serial, "master event", RT_IPC_FLAG_PRIO);
- rt_thread_init(&thread_serial_soft_trans_irq,
- "master trans",
- serial_soft_trans_irq,
- RT_NULL,
- serial_soft_trans_irq_stack,
- sizeof(serial_soft_trans_irq_stack),
- 10, 5);
- rt_thread_startup(&thread_serial_soft_trans_irq);
-
- return TRUE;
-}
-
-void vMBMasterPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable)
-{
- rt_uint32_t recved_event;
- if (xRxEnable)
- {
- /* enable RX interrupt */
- serial->ops->control(serial, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX);
- /* switch 485 to receive mode */
-#if defined(RT_MODBUS_MASTER_USE_CONTROL_PIN)
- rt_pin_write(MODBUS_MASTER_RT_CONTROL_PIN_INDEX, PIN_LOW);
-#endif
- }
- else
- {
- /* switch 485 to transmit mode */
-#if defined(RT_MODBUS_MASTER_USE_CONTROL_PIN)
- rt_pin_write(MODBUS_MASTER_RT_CONTROL_PIN_INDEX, PIN_HIGH);
-#endif
- /* disable RX interrupt */
- serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *)RT_DEVICE_FLAG_INT_RX);
- }
- if (xTxEnable)
- {
- /* start serial transmit */
- rt_event_send(&event_serial, EVENT_SERIAL_TRANS_START);
- }
- else
- {
- /* stop serial transmit */
- rt_event_recv(&event_serial, EVENT_SERIAL_TRANS_START,
- RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, 0,
- &recved_event);
- }
-}
-
-void vMBMasterPortClose(void)
-{
- serial->parent.close(&(serial->parent));
-}
-
-BOOL xMBMasterPortSerialPutByte(CHAR ucByte)
-{
- serial->parent.write(&(serial->parent), 0, &ucByte, 1);
- return TRUE;
-}
-
-BOOL xMBMasterPortSerialGetByte(CHAR * pucByte)
-{
- serial->parent.read(&(serial->parent), 0, pucByte, 1);
- return TRUE;
-}
-
-/*
- * Create an interrupt handler for the transmit buffer empty interrupt
- * (or an equivalent) for your target processor. This function should then
- * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
- * a new character can be sent. The protocol stack will then call
- * xMBPortSerialPutByte( ) to send the character.
- */
-void prvvUARTTxReadyISR(void)
-{
- pxMBMasterFrameCBTransmitterEmpty();
-}
-
-/*
- * Create an interrupt handler for the receive interrupt for your target
- * processor. This function should then call pxMBFrameCBByteReceived( ). The
- * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
- * character.
- */
-void prvvUARTRxISR(void)
-{
- pxMBMasterFrameCBByteReceived();
-}
-
-/**
- * Software simulation serial transmit IRQ handler.
- *
- * @param parameter parameter
- */
-static void serial_soft_trans_irq(void* parameter) {
- rt_uint32_t recved_event;
- while (1)
- {
- /* waiting for serial transmit start */
- rt_event_recv(&event_serial, EVENT_SERIAL_TRANS_START, RT_EVENT_FLAG_OR,
- RT_WAITING_FOREVER, &recved_event);
- /* execute modbus callback */
- prvvUARTTxReadyISR();
- }
-}
-
-/**
- * This function is serial receive callback function
- *
- * @param dev the device of serial
- * @param size the data size that receive
- *
- * @return return RT_EOK
- */
-static rt_err_t serial_rx_ind(rt_device_t dev, rt_size_t size) {
- prvvUARTRxISR();
- return RT_EOK;
-}
-
-#endif
diff --git a/components/net/freemodbus/port/porttimer.c b/components/net/freemodbus/port/porttimer.c
deleted file mode 100644
index 8c51ad06d5..0000000000
--- a/components/net/freemodbus/port/porttimer.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * FreeModbus Libary: RT-Thread Port
- * Copyright (C) 2013 Armink <[email protected]>
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * File: $Id: porttimer.c,v 1.60 2013/08/13 15:07:05 Armink $
- */
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mbport.h"
-
-/* ----------------------- static functions ---------------------------------*/
-static struct rt_timer timer;
-static void prvvTIMERExpiredISR(void);
-static void timer_timeout_ind(void* parameter);
-
-/* ----------------------- Start implementation -----------------------------*/
-BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
-{
- rt_timer_init(&timer, "slave timer",
- timer_timeout_ind, /* bind timeout callback function */
- RT_NULL,
- (50 * usTim1Timerout50us) / (1000 * 1000 / RT_TICK_PER_SECOND) + 1,
- RT_TIMER_FLAG_ONE_SHOT); /* one shot */
- return TRUE;
-}
-
-void vMBPortTimersEnable()
-{
- rt_timer_start(&timer);
-}
-
-void vMBPortTimersDisable()
-{
- rt_timer_stop(&timer);
-}
-
-void prvvTIMERExpiredISR(void)
-{
- (void) pxMBPortCBTimerExpired();
-}
-
-static void timer_timeout_ind(void* parameter)
-{
- prvvTIMERExpiredISR();
-}
diff --git a/components/net/freemodbus/port/porttimer_m.c b/components/net/freemodbus/port/porttimer_m.c
deleted file mode 100644
index ebf80004d8..0000000000
--- a/components/net/freemodbus/port/porttimer_m.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * FreeModbus Libary: RT-Thread Port
- * Copyright (C) 2013 Armink <[email protected]>
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * File: $Id: porttimer_m.c,v 1.60 2013/08/13 15:07:05 Armink add Master Functions$
- */
-
-/* ----------------------- Platform includes --------------------------------*/
-#include "port.h"
-
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mb_m.h"
-#include "mbport.h"
-
-#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
-/* ----------------------- Variables ----------------------------------------*/
-static USHORT usT35TimeOut50us;
-static struct rt_timer timer;
-static void prvvTIMERExpiredISR(void);
-static void timer_timeout_ind(void* parameter);
-
-/* ----------------------- static functions ---------------------------------*/
-static void prvvTIMERExpiredISR(void);
-
-/* ----------------------- Start implementation -----------------------------*/
-BOOL xMBMasterPortTimersInit(USHORT usTimeOut50us)
-{
- /* backup T35 ticks */
- usT35TimeOut50us = usTimeOut50us;
-
- rt_timer_init(&timer, "master timer",
- timer_timeout_ind, /* bind timeout callback function */
- RT_NULL,
- (50 * usT35TimeOut50us) / (1000 * 1000 / RT_TICK_PER_SECOND) + 1,
- RT_TIMER_FLAG_ONE_SHOT); /* one shot */
-
- return TRUE;
-}
-
-void vMBMasterPortTimersT35Enable()
-{
- rt_tick_t timer_tick = (50 * usT35TimeOut50us)
- / (1000 * 1000 / RT_TICK_PER_SECOND);
-
- /* Set current timer mode, don't change it.*/
- vMBMasterSetCurTimerMode(MB_TMODE_T35);
-
- rt_timer_control(&timer, RT_TIMER_CTRL_SET_TIME, &timer_tick);
-
- rt_timer_start(&timer);
-}
-
-void vMBMasterPortTimersConvertDelayEnable()
-{
- rt_tick_t timer_tick = MB_MASTER_DELAY_MS_CONVERT * RT_TICK_PER_SECOND / 1000;
-
- /* Set current timer mode, don't change it.*/
- vMBMasterSetCurTimerMode(MB_TMODE_CONVERT_DELAY);
-
- rt_timer_control(&timer, RT_TIMER_CTRL_SET_TIME, &timer_tick);
-
- rt_timer_start(&timer);
-}
-
-void vMBMasterPortTimersRespondTimeoutEnable()
-{
- rt_tick_t timer_tick = MB_MASTER_TIMEOUT_MS_RESPOND * RT_TICK_PER_SECOND / 1000;
-
- /* Set current timer mode, don't change it.*/
- vMBMasterSetCurTimerMode(MB_TMODE_RESPOND_TIMEOUT);
-
- rt_timer_control(&timer, RT_TIMER_CTRL_SET_TIME, &timer_tick);
-
- rt_timer_start(&timer);
-}
-
-void vMBMasterPortTimersDisable()
-{
- rt_timer_stop(&timer);
-}
-
-void prvvTIMERExpiredISR(void)
-{
- (void) pxMBMasterPortCBTimerExpired();
-}
-
-static void timer_timeout_ind(void* parameter)
-{
- prvvTIMERExpiredISR();
-}
-
-#endif
diff --git a/components/net/freemodbus/port/user_mb_app.c b/components/net/freemodbus/port/user_mb_app.c
deleted file mode 100644
index 8da7376336..0000000000
--- a/components/net/freemodbus/port/user_mb_app.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * FreeModbus Libary: user callback functions and buffer define in slave mode
- * Copyright (C) 2013 Armink <[email protected]>
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * File: $Id: user_mb_app.c,v 1.60 2013/11/23 11:49:05 Armink $
- */
-#include "user_mb_app.h"
-
-/*------------------------Slave mode use these variables----------------------*/
-//Slave mode:DiscreteInputs variables
-USHORT usSDiscInStart = S_DISCRETE_INPUT_START;
-#if S_DISCRETE_INPUT_NDISCRETES%8
-UCHAR ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8+1];
-#else
-UCHAR ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8] ;
-#endif
-//Slave mode:Coils variables
-USHORT usSCoilStart = S_COIL_START;
-#if S_COIL_NCOILS%8
-UCHAR ucSCoilBuf[S_COIL_NCOILS/8+1] ;
-#else
-UCHAR ucSCoilBuf[S_COIL_NCOILS/8] ;
-#endif
-//Slave mode:InputRegister variables
-USHORT usSRegInStart = S_REG_INPUT_START;
-USHORT usSRegInBuf[S_REG_INPUT_NREGS] ;
-//Slave mode:HoldingRegister variables
-USHORT usSRegHoldStart = S_REG_HOLDING_START;
-USHORT usSRegHoldBuf[S_REG_HOLDING_NREGS] ;
-
-/**
- * Modbus slave input register callback function.
- *
- * @param pucRegBuffer input register buffer
- * @param usAddress input register address
- * @param usNRegs input register number
- *
- * @return result
- */
-eMBErrorCode eMBRegInputCB(UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
-{
- eMBErrorCode eStatus = MB_ENOERR;
- USHORT iRegIndex;
- USHORT * pusRegInputBuf;
- USHORT REG_INPUT_START;
- USHORT REG_INPUT_NREGS;
- USHORT usRegInStart;
-
- pusRegInputBuf = usSRegInBuf;
- REG_INPUT_START = S_REG_INPUT_START;
- REG_INPUT_NREGS = S_REG_INPUT_NREGS;
- usRegInStart = usSRegInStart;
-
- /* it already plus one in modbus function method. */
- usAddress--;
-
- if ((usAddress >= REG_INPUT_START)
- && (usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS))
- {
- iRegIndex = usAddress - usRegInStart;
- while (usNRegs > 0)
- {
- *pucRegBuffer++ = (UCHAR) (pusRegInputBuf[iRegIndex] >> 8);
- *pucRegBuffer++ = (UCHAR) (pusRegInputBuf[iRegIndex] & 0xFF);
- iRegIndex++;
- usNRegs--;
- }
- }
- else
- {
- eStatus = MB_ENOREG;
- }
-
- return eStatus;
-}
-
-/**
- * Modbus slave holding register callback function.
- *
- * @param pucRegBuffer holding register buffer
- * @param usAddress holding register address
- * @param usNRegs holding register number
- * @param eMode read or write
- *
- * @return result
- */
-eMBErrorCode eMBRegHoldingCB(UCHAR * pucRegBuffer, USHORT usAddress,
- USHORT usNRegs, eMBRegisterMode eMode)
-{
- eMBErrorCode eStatus = MB_ENOERR;
- USHORT iRegIndex;
- USHORT * pusRegHoldingBuf;
- USHORT REG_HOLDING_START;
- USHORT REG_HOLDING_NREGS;
- USHORT usRegHoldStart;
-
- pusRegHoldingBuf = usSRegHoldBuf;
- REG_HOLDING_START = S_REG_HOLDING_START;
- REG_HOLDING_NREGS = S_REG_HOLDING_NREGS;
- usRegHoldStart = usSRegHoldStart;
-
- /* it already plus one in modbus function method. */
- usAddress--;
-
- if ((usAddress >= REG_HOLDING_START)
- && (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS))
- {
- iRegIndex = usAddress - usRegHoldStart;
- switch (eMode)
- {
- /* read current register values from the protocol stack. */
- case MB_REG_READ:
- while (usNRegs > 0)
- {
- *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] >> 8);
- *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] & 0xFF);
- iRegIndex++;
- usNRegs--;
- }
- break;
-
- /* write current register values with new values from the protocol stack. */
- case MB_REG_WRITE:
- while (usNRegs > 0)
- {
- pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
- pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
- iRegIndex++;
- usNRegs--;
- }
- break;
- }
- }
- else
- {
- eStatus = MB_ENOREG;
- }
- return eStatus;
-}
-
-/**
- * Modbus slave coils callback function.
- *
- * @param pucRegBuffer coils buffer
- * @param usAddress coils address
- * @param usNCoils coils number
- * @param eMode read or write
- *
- * @return result
- */
-eMBErrorCode eMBRegCoilsCB(UCHAR * pucRegBuffer, USHORT usAddress,
- USHORT usNCoils, eMBRegisterMode eMode)
-{
- eMBErrorCode eStatus = MB_ENOERR;
- USHORT iRegIndex , iRegBitIndex , iNReg;
- UCHAR * pucCoilBuf;
- USHORT COIL_START;
- USHORT COIL_NCOILS;
- USHORT usCoilStart;
- iNReg = usNCoils / 8 + 1;
-
- pucCoilBuf = ucSCoilBuf;
- COIL_START = S_COIL_START;
- COIL_NCOILS = S_COIL_NCOILS;
- usCoilStart = usSCoilStart;
-
- /* it already plus one in modbus function method. */
- usAddress--;
-
- if( ( usAddress >= COIL_START ) &&
- ( usAddress + usNCoils <= COIL_START + COIL_NCOILS ) )
- {
- iRegIndex = (USHORT) (usAddress - usCoilStart) / 8;
- iRegBitIndex = (USHORT) (usAddress - usCoilStart) % 8;
- switch ( eMode )
- {
- /* read current coil values from the protocol stack. */
- case MB_REG_READ:
- while (iNReg > 0)
- {
- *pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++],
- iRegBitIndex, 8);
- iNReg--;
- }
- pucRegBuffer--;
- /* last coils */
- usNCoils = usNCoils % 8;
- /* filling zero to high bit */
- *pucRegBuffer = *pucRegBuffer << (8 - usNCoils);
- *pucRegBuffer = *pucRegBuffer >> (8 - usNCoils);
- break;
-
- /* write current coil values with new values from the protocol stack. */
- case MB_REG_WRITE:
- while (iNReg > 1)
- {
- xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, 8,
- *pucRegBuffer++);
- iNReg--;
- }
- /* last coils */
- usNCoils = usNCoils % 8;
- /* xMBUtilSetBits has bug when ucNBits is zero */
- if (usNCoils != 0)
- {
- xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils,
- *pucRegBuffer++);
- }
- break;
- }
- }
- else
- {
- eStatus = MB_ENOREG;
- }
- return eStatus;
-}
-
-/**
- * Modbus slave discrete callback function.
- *
- * @param pucRegBuffer discrete buffer
- * @param usAddress discrete address
- * @param usNDiscrete discrete number
- *
- * @return result
- */
-eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
-{
- eMBErrorCode eStatus = MB_ENOERR;
- USHORT iRegIndex , iRegBitIndex , iNReg;
- UCHAR * pucDiscreteInputBuf;
- USHORT DISCRETE_INPUT_START;
- USHORT DISCRETE_INPUT_NDISCRETES;
- USHORT usDiscreteInputStart;
- iNReg = usNDiscrete / 8 + 1;
-
- pucDiscreteInputBuf = ucSDiscInBuf;
- DISCRETE_INPUT_START = S_DISCRETE_INPUT_START;
- DISCRETE_INPUT_NDISCRETES = S_DISCRETE_INPUT_NDISCRETES;
- usDiscreteInputStart = usSDiscInStart;
-
- /* it already plus one in modbus function method. */
- usAddress--;
-
- if ((usAddress >= DISCRETE_INPUT_START)
- && (usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES))
- {
- iRegIndex = (USHORT) (usAddress - usDiscreteInputStart) / 8;
- iRegBitIndex = (USHORT) (usAddress - usDiscreteInputStart) % 8;
-
- while (iNReg > 0)
- {
- *pucRegBuffer++ = xMBUtilGetBits(&pucDiscreteInputBuf[iRegIndex++],
- iRegBitIndex, 8);
- iNReg--;
- }
- pucRegBuffer--;
- /* last discrete */
- usNDiscrete = usNDiscrete % 8;
- /* filling zero to high bit */
- *pucRegBuffer = *pucRegBuffer << (8 - usNDiscrete);
- *pucRegBuffer = *pucRegBuffer >> (8 - usNDiscrete);
- }
- else
- {
- eStatus = MB_ENOREG;
- }
-
- return eStatus;
-}
-
diff --git a/components/net/freemodbus/port/user_mb_app.h b/components/net/freemodbus/port/user_mb_app.h
deleted file mode 100644
index 864c3860bf..0000000000
--- a/components/net/freemodbus/port/user_mb_app.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef USER_APP
-#define USER_APP
-/* ----------------------- Modbus includes ----------------------------------*/
-#include "mb.h"
-#include "mb_m.h"
-#include "mbconfig.h"
-#include "mbframe.h"
-#include "mbutils.h"
-
-/* -----------------------Slave Defines -------------------------------------*/
-#define S_DISCRETE_INPUT_START 0
-#define S_DISCRETE_INPUT_NDISCRETES 16
-#define S_COIL_START 0
-#define S_COIL_NCOILS 64
-#define S_REG_INPUT_START 0
-#define S_REG_INPUT_NREGS 100
-#define S_REG_HOLDING_START 0
-#define S_REG_HOLDING_NREGS 100
-/* salve mode: holding register's all address */
-#define S_HD_RESERVE 0
-/* salve mode: input register's all address */
-#define S_IN_RESERVE 0
-/* salve mode: coil's all address */
-#define S_CO_RESERVE 0
-/* salve mode: discrete's all address */
-#define S_DI_RESERVE 0
-
-/* -----------------------Master Defines -------------------------------------*/
-#define M_DISCRETE_INPUT_START 0
-#define M_DISCRETE_INPUT_NDISCRETES 16
-#define M_COIL_START 0
-#define M_COIL_NCOILS 64
-#define M_REG_INPUT_START 0
-#define M_REG_INPUT_NREGS 100
-#define M_REG_HOLDING_START 0
-#define M_REG_HOLDING_NREGS 100
-/* master mode: holding register's all address */
-#define M_HD_RESERVE 0
-/* master mode: input register's all address */
-#define M_IN_RESERVE 0
-/* master mode: coil's all address */
-#define M_CO_RESERVE 0
-/* master mode: discrete's all address */
-#define M_DI_RESERVE 0
-
-#endif
diff --git a/components/net/freemodbus/port/user_mb_app_m.c b/components/net/freemodbus/port/user_mb_app_m.c
deleted file mode 100644
index 12fabf21ac..0000000000
--- a/components/net/freemodbus/port/user_mb_app_m.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * FreeModbus Libary: user callback functions and buffer define in master mode
- * Copyright (C) 2013 Armink <[email protected]>
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * File: $Id: user_mb_app_m.c,v 1.60 2013/11/23 11:49:05 Armink $
- */
-#include "user_mb_app.h"
-
-/*-----------------------Master mode use these variables----------------------*/
-#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
-//Master mode:DiscreteInputs variables
-USHORT usMDiscInStart = M_DISCRETE_INPUT_START;
-#if M_DISCRETE_INPUT_NDISCRETES%8
-UCHAR ucMDiscInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_DISCRETE_INPUT_NDISCRETES/8+1];
-#else
-UCHAR ucMDiscInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_DISCRETE_INPUT_NDISCRETES/8];
-#endif
-//Master mode:Coils variables
-USHORT usMCoilStart = M_COIL_START;
-#if M_COIL_NCOILS%8
-UCHAR ucMCoilBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_COIL_NCOILS/8+1];
-#else
-UCHAR ucMCoilBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_COIL_NCOILS/8];
-#endif
-//Master mode:InputRegister variables
-USHORT usMRegInStart = M_REG_INPUT_START;
-USHORT usMRegInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_INPUT_NREGS];
-//Master mode:HoldingRegister variables
-USHORT usMRegHoldStart = M_REG_HOLDING_START;
-USHORT usMRegHoldBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_HOLDING_NREGS];
-
-/**
- * Modbus master input register callback function.
- *
- * @param pucRegBuffer input register buffer
- * @param usAddress input register address
- * @param usNRegs input register number
- *
- * @return result
- */
-eMBErrorCode eMBMasterRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
-{
- eMBErrorCode eStatus = MB_ENOERR;
- USHORT iRegIndex;
- USHORT * pusRegInputBuf;
- USHORT REG_INPUT_START;
- USHORT REG_INPUT_NREGS;
- USHORT usRegInStart;
-
- pusRegInputBuf = usMRegInBuf[ucMBMasterGetDestAddress() - 1];
- REG_INPUT_START = M_REG_INPUT_START;
- REG_INPUT_NREGS = M_REG_INPUT_NREGS;
- usRegInStart = usMRegInStart;
-
- /* it already plus one in modbus function method. */
- usAddress--;
-
- if ((usAddress >= REG_INPUT_START)
- && (usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS))
- {
- iRegIndex = usAddress - usRegInStart;
- while (usNRegs > 0)
- {
- pusRegInputBuf[iRegIndex] = *pucRegBuffer++ << 8;
- pusRegInputBuf[iRegIndex] |= *pucRegBuffer++;
- iRegIndex++;
- usNRegs--;
- }
- }
- else
- {
- eStatus = MB_ENOREG;
- }
-
- return eStatus;
-}
-
-/**
- * Modbus master holding register callback function.
- *
- * @param pucRegBuffer holding register buffer
- * @param usAddress holding register address
- * @param usNRegs holding register number
- * @param eMode read or write
- *
- * @return result
- */
-eMBErrorCode eMBMasterRegHoldingCB(UCHAR * pucRegBuffer, USHORT usAddress,
- USHORT usNRegs, eMBRegisterMode eMode)
-{
- eMBErrorCode eStatus = MB_ENOERR;
- USHORT iRegIndex;
- USHORT * pusRegHoldingBuf;
- USHORT REG_HOLDING_START;
- USHORT REG_HOLDING_NREGS;
- USHORT usRegHoldStart;
-
- pusRegHoldingBuf = usMRegHoldBuf[ucMBMasterGetDestAddress() - 1];
- REG_HOLDING_START = M_REG_HOLDING_START;
- REG_HOLDING_NREGS = M_REG_HOLDING_NREGS;
- usRegHoldStart = usMRegHoldStart;
- /* if mode is read, the master will write the received date to buffer. */
- eMode = MB_REG_WRITE;
-
- /* it already plus one in modbus function method. */
- usAddress--;
-
- if ((usAddress >= REG_HOLDING_START)
- && (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS))
- {
- iRegIndex = usAddress - usRegHoldStart;
- switch (eMode)
- {
- /* read current register values from the protocol stack. */
- case MB_REG_READ:
- while (usNRegs > 0)
- {
- *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] >> 8);
- *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] & 0xFF);
- iRegIndex++;
- usNRegs--;
- }
- break;
- /* write current register values with new values from the protocol stack. */
- case MB_REG_WRITE:
- while (usNRegs > 0)
- {
- pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
- pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
- iRegIndex++;
- usNRegs--;
- }
- break;
- }
- }
- else
- {
- eStatus = MB_ENOREG;
- }
- return eStatus;
-}
-
-/**
- * Modbus master coils callback function.
- *
- * @param pucRegBuffer coils buffer
- * @param usAddress coils address
- * @param usNCoils coils number
- * @param eMode read or write
- *
- * @return result
- */
-eMBErrorCode eMBMasterRegCoilsCB(UCHAR * pucRegBuffer, USHORT usAddress,
- USHORT usNCoils, eMBRegisterMode eMode)
-{
- eMBErrorCode eStatus = MB_ENOERR;
- USHORT iRegIndex , iRegBitIndex , iNReg;
- UCHAR * pucCoilBuf;
- USHORT COIL_START;
- USHORT COIL_NCOILS;
- USHORT usCoilStart;
- iNReg = usNCoils / 8 + 1;
-
- pucCoilBuf = ucMCoilBuf[ucMBMasterGetDestAddress() - 1];
- COIL_START = M_COIL_START;
- COIL_NCOILS = M_COIL_NCOILS;
- usCoilStart = usMCoilStart;
-
- /* if mode is read,the master will write the received date to buffer. */
- eMode = MB_REG_WRITE;
-
- /* it already plus one in modbus function method. */
- usAddress--;
-
- if ((usAddress >= COIL_START)
- && (usAddress + usNCoils <= COIL_START + COIL_NCOILS))
- {
- iRegIndex = (USHORT) (usAddress - usCoilStart) / 8;
- iRegBitIndex = (USHORT) (usAddress - usCoilStart) % 8;
- switch (eMode)
- {
- /* read current coil values from the protocol stack. */
- case MB_REG_READ:
- while (iNReg > 0)
- {
- *pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++],
- iRegBitIndex, 8);
- iNReg--;
- }
- pucRegBuffer--;
- /* last coils */
- usNCoils = usNCoils % 8;
- /* filling zero to high bit */
- *pucRegBuffer = *pucRegBuffer << (8 - usNCoils);
- *pucRegBuffer = *pucRegBuffer >> (8 - usNCoils);
- break;
-
- /* write current coil values with new values from the protocol stack. */
- case MB_REG_WRITE:
- while (iNReg > 1)
- {
- xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, 8,
- *pucRegBuffer++);
- iNReg--;
- }
- /* last coils */
- usNCoils = usNCoils % 8;
- /* xMBUtilSetBits has bug when ucNBits is zero */
- if (usNCoils != 0)
- {
- xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils,
- *pucRegBuffer++);
- }
- break;
- }
- }
- else
- {
- eStatus = MB_ENOREG;
- }
- return eStatus;
-}
-
-/**
- * Modbus master discrete callback function.
- *
- * @param pucRegBuffer discrete buffer
- * @param usAddress discrete address
- * @param usNDiscrete discrete number
- *
- * @return result
- */
-eMBErrorCode eMBMasterRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
-{
- eMBErrorCode eStatus = MB_ENOERR;
- USHORT iRegIndex , iRegBitIndex , iNReg;
- UCHAR * pucDiscreteInputBuf;
- USHORT DISCRETE_INPUT_START;
- USHORT DISCRETE_INPUT_NDISCRETES;
- USHORT usDiscreteInputStart;
- iNReg = usNDiscrete / 8 + 1;
-
- pucDiscreteInputBuf = ucMDiscInBuf[ucMBMasterGetDestAddress() - 1];
- DISCRETE_INPUT_START = M_DISCRETE_INPUT_START;
- DISCRETE_INPUT_NDISCRETES = M_DISCRETE_INPUT_NDISCRETES;
- usDiscreteInputStart = usMDiscInStart;
-
- /* it already plus one in modbus function method. */
- usAddress--;
-
- if ((usAddress >= DISCRETE_INPUT_START)
- && (usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES))
- {
- iRegIndex = (USHORT) (usAddress - usDiscreteInputStart) / 8;
- iRegBitIndex = (USHORT) (usAddress - usDiscreteInputStart) % 8;
-
- /* write current discrete values with new values from the protocol stack. */
- while (iNReg > 1)
- {
- xMBUtilSetBits(&pucDiscreteInputBuf[iRegIndex++], iRegBitIndex, 8,
- *pucRegBuffer++);
- iNReg--;
- }
- /* last discrete */
- usNDiscrete = usNDiscrete % 8;
- /* xMBUtilSetBits has bug when ucNBits is zero */
- if (usNDiscrete != 0)
- {
- xMBUtilSetBits(&pucDiscreteInputBuf[iRegIndex++], iRegBitIndex,
- usNDiscrete, *pucRegBuffer++);
- }
- }
- else
- {
- eStatus = MB_ENOREG;
- }
-
- return eStatus;
-}
-#endif
diff --git a/components/net/lwip-1.4.1/src/arch/sys_arch.c b/components/net/lwip-1.4.1/src/arch/sys_arch.c
index dc20ee97a1..c31bd59c1d 100644
--- a/components/net/lwip-1.4.1/src/arch/sys_arch.c
+++ b/components/net/lwip-1.4.1/src/arch/sys_arch.c
@@ -198,7 +198,7 @@ int lwip_system_init(void)
return 0;
}
-INIT_COMPONENT_EXPORT(lwip_system_init);
+INIT_PREV_EXPORT(lwip_system_init);
void sys_init(void)
{
@@ -497,8 +497,7 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
t = timeout / (1000/RT_TICK_PER_SECOND);
}
- ret = rt_mb_recv(*mbox, (rt_uint32_t *)msg, t);
-
+ ret = rt_mb_recv(*mbox, (rt_ubase_t *)msg, t);
if(ret == -RT_ETIMEOUT)
{
return SYS_ARCH_TIMEOUT;
@@ -530,8 +529,7 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
{
int ret;
- ret = rt_mb_recv(*mbox, (rt_uint32_t *)msg, 0);
-
+ ret = rt_mb_recv(*mbox, (rt_ubase_t *)msg, 0);
if(ret == -RT_ETIMEOUT)
{
return SYS_ARCH_TIMEOUT;
diff --git a/components/net/lwip-1.4.1/src/core/dns.c b/components/net/lwip-1.4.1/src/core/dns.c
index 18c73d0a8c..2e1356ca97 100644
--- a/components/net/lwip-1.4.1/src/core/dns.c
+++ b/components/net/lwip-1.4.1/src/core/dns.c
@@ -279,13 +279,14 @@ dns_setserver(u8_t numdns, ip_addr_t *dnsserver)
dns_servers[numdns] = (*dnsserver);
#ifdef RT_USING_NETDEV
- extern struct netif *netif_default;
+ extern struct netif *netif_list;
extern struct netdev *netdev_get_by_name(const char *name);
extern void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
+ struct netif *netif = NULL;
/* set network interface device DNS server address */
- if (netif_default) {
- netdev_low_level_set_dns_server(netdev_get_by_name(netif_default->name), numdns, dnsserver);
+ for (netif = netif_list; netif != NULL; netif = netif->next) {
+ netdev_low_level_set_dns_server(netdev_get_by_name(netif->name), numdns, dnsserver);
}
#endif /* RT_USING_NETDEV */
}
diff --git a/components/net/lwip-1.4.1/src/netif/ethernetif.c b/components/net/lwip-1.4.1/src/netif/ethernetif.c
index 10bcaa0c95..9d8fa650a4 100644
--- a/components/net/lwip-1.4.1/src/netif/ethernetif.c
+++ b/components/net/lwip-1.4.1/src/netif/ethernetif.c
@@ -146,8 +146,8 @@ static int lwip_netdev_set_addr_info(struct netdev *netif, ip_addr_t *ip_addr, i
#ifdef RT_LWIP_DNS
static int lwip_netdev_set_dns_server(struct netdev *netif, uint8_t dns_num, ip_addr_t *dns_server)
{
- extern void set_dns(uint8_t dns_num, char* dns_server);
- set_dns(dns_num, ipaddr_ntoa(dns_server));
+ extern void dns_setserver(uint8_t dns_num, ip_addr_t *dns_server);
+ dns_setserver(dns_num, dns_server);
return ERR_OK;
}
#endif /* RT_LWIP_DNS */
@@ -160,6 +160,7 @@ static int lwip_netdev_set_dhcp(struct netdev *netif, rt_bool_t is_enabled)
}
#endif /* RT_LWIP_DHCP */
+#ifdef RT_USING_FINSH
#ifdef RT_LWIP_USING_PING
extern int lwip_ping_recv(int s, int *ttl);
extern err_t lwip_ping_send(int s, ip_addr_t *addr, int size);
@@ -250,6 +251,13 @@ void lwip_netdev_netstat(struct netdev *netif)
#endif
}
#endif /* RT_LWIP_TCP || RT_LWIP_UDP */
+#endif /* RT_USING_FINSH */
+
+static int lwip_netdev_set_default(struct netdev *netif)
+{
+ netif_set_default((struct netif *)netif->user_data);
+ return ERR_OK;
+}
const struct netdev_ops lwip_netdev_ops =
{
@@ -269,6 +277,7 @@ const struct netdev_ops lwip_netdev_ops =
NULL,
#endif /* RT_LWIP_DHCP */
+#ifdef RT_USING_FINSH
#ifdef RT_LWIP_USING_PING
lwip_netdev_ping,
#else
@@ -278,6 +287,9 @@ const struct netdev_ops lwip_netdev_ops =
#if defined (RT_LWIP_TCP) || defined (RT_LWIP_UDP)
lwip_netdev_netstat,
#endif /* RT_LWIP_TCP || RT_LWIP_UDP */
+#endif /* RT_USING_FINSH */
+
+ lwip_netdev_set_default,
};
static int netdev_add(struct netif *lwip_netif)
@@ -295,12 +307,6 @@ static int netdev_add(struct netif *lwip_netif)
return -ERR_IF;
}
- netdev->flags = lwip_netif->flags;
- netdev->mtu = lwip_netif->mtu;
- netdev->ops = &lwip_netdev_ops;
- netdev->hwaddr_len = lwip_netif->hwaddr_len;
- rt_memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len);
-
#ifdef SAL_USING_LWIP
extern int sal_lwip_netdev_set_pf_info(struct netdev *netdev);
/* set the lwIP network interface device protocol family information */
@@ -309,7 +315,17 @@ static int netdev_add(struct netif *lwip_netif)
rt_strncpy(name, lwip_netif->name, LWIP_NETIF_NAME_LEN);
result = netdev_register(netdev, name, (void *)lwip_netif);
-
+
+ /* Update netdev info after registered */
+ netdev->flags = lwip_netif->flags;
+ netdev->mtu = lwip_netif->mtu;
+ netdev->ops = &lwip_netdev_ops;
+ netdev->hwaddr_len = lwip_netif->hwaddr_len;
+ rt_memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len);
+ netdev->ip_addr = lwip_netif->ip_addr;
+ netdev->gw = lwip_netif->gw;
+ netdev->netmask = lwip_netif->netmask;
+
#ifdef RT_LWIP_DHCP
netdev_low_level_set_dhcp_status(netdev, RT_TRUE);
#endif
@@ -678,8 +694,6 @@ int eth_system_device_init(void)
}
INIT_PREV_EXPORT(eth_system_device_init);
-#ifdef RT_USING_FINSH
-#include <finsh.h>
void set_if(char* netif_name, char* ip_addr, char* gw_addr, char* nm_addr)
{
struct ip_addr *ip;
@@ -725,6 +739,9 @@ void set_if(char* netif_name, char* ip_addr, char* gw_addr, char* nm_addr)
netif_set_netmask(netif, ip);
}
}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
FINSH_FUNCTION_EXPORT(set_if, set network interface address);
#if LWIP_DNS
diff --git a/components/net/lwip-2.0.2/src/arch/sys_arch.c b/components/net/lwip-2.0.2/src/arch/sys_arch.c
index 7a92170886..b2abaeab54 100644
--- a/components/net/lwip-2.0.2/src/arch/sys_arch.c
+++ b/components/net/lwip-2.0.2/src/arch/sys_arch.c
@@ -508,7 +508,7 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
t = timeout / (1000/RT_TICK_PER_SECOND);
}
- ret = rt_mb_recv(*mbox, (rt_uint32_t *)msg, t);
+ ret = rt_mb_recv(*mbox, (rt_ubase_t *)msg, t);
if(ret == -RT_ETIMEOUT)
return SYS_ARCH_TIMEOUT;
@@ -539,7 +539,7 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
{
int ret;
- ret = rt_mb_recv(*mbox, (rt_uint32_t *)msg, 0);
+ ret = rt_mb_recv(*mbox, (rt_ubase_t *)msg, 0);
if(ret == -RT_ETIMEOUT)
return SYS_ARCH_TIMEOUT;
diff --git a/components/net/lwip-2.0.2/src/core/dns.c b/components/net/lwip-2.0.2/src/core/dns.c
index c793b320a4..cd4de06229 100644
--- a/components/net/lwip-2.0.2/src/core/dns.c
+++ b/components/net/lwip-2.0.2/src/core/dns.c
@@ -370,13 +370,14 @@ dns_setserver(u8_t numdns, const ip_addr_t *dnsserver)
dns_servers[numdns] = (*dnsserver);
#ifdef RT_USING_NETDEV
- extern struct netif *netif_default;
+ extern struct netif *netif_list;
extern struct netdev *netdev_get_by_name(const char *name);
extern void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
+ struct netif *netif = NULL;
/* set network interface device DNS server address */
- if (netif_default) {
- netdev_low_level_set_dns_server(netdev_get_by_name(netif_default->name), numdns, dnsserver);
+ for (netif = netif_list; netif != NULL; netif = netif->next) {
+ netdev_low_level_set_dns_server(netdev_get_by_name(netif->name), numdns, dnsserver);
}
#endif /* RT_USING_NETDEV */
} else {
diff --git a/components/net/lwip-2.0.2/src/core/netif.c b/components/net/lwip-2.0.2/src/core/netif.c
index 01e83676da..ee57bb9a9d 100644
--- a/components/net/lwip-2.0.2/src/core/netif.c
+++ b/components/net/lwip-2.0.2/src/core/netif.c
@@ -544,7 +544,7 @@ netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr)
#ifdef RT_USING_NETDEV
/* rt-thread sal network interface device set IP address operations */
- netdev_low_level_set_ipaddr(netdev_get_by_name(netif->name), (ip_addr_t *)ipaddr);
+ netdev_low_level_set_ipaddr(netdev_get_by_name(netif->name), &netif->ip_addr);
#endif /* RT_USING_NETDEV */
}
@@ -579,7 +579,7 @@ netif_set_gw(struct netif *netif, const ip4_addr_t *gw)
#ifdef RT_USING_NETDEV
/* rt_thread network interface device set gateway address */
- netdev_low_level_set_gw(netdev_get_by_name(netif->name), (ip_addr_t *)gw);
+ netdev_low_level_set_gw(netdev_get_by_name(netif->name), &netif->gw);
#endif /* RT_USING_NETDEV */
}
@@ -610,7 +610,7 @@ netif_set_netmask(struct netif *netif, const ip4_addr_t *netmask)
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set netmask address */
- netdev_low_level_set_netmask(netdev_get_by_name(netif->name), (ip_addr_t *)netmask);
+ netdev_low_level_set_netmask(netdev_get_by_name(netif->name), &netif->netmask);
#endif /* RT_USING_NETDEV */
}
#endif /* LWIP_IPV4 */
@@ -1241,6 +1241,11 @@ netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit)
}
}
+#ifdef RT_USING_NETDEV
+ /* rt-thread network interface device set ipv6 address */
+ ip_addr_copy(netdev_get_by_name(netif->name)->ip6_addr[0], netif->ip6_addr[0]);
+#endif /* RT_USING_NETDEV */
+
/* Set address state. */
#if LWIP_IPV6_DUP_DETECT_ATTEMPTS
/* Will perform duplicate address detection (DAD). */
@@ -1279,6 +1284,10 @@ netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chos
for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (ip6_addr_isinvalid(netif_ip6_addr_state(netif, i))) {
ip_addr_copy_from_ip6(netif->ip6_addr[i], *ip6addr);
+#ifdef RT_USING_NETDEV
+ /* rt-thread network interface device set ipv6 address */
+ ip_addr_copy(netdev_get_by_name(netif->name)->ip6_addr[i], netif->ip6_addr[i]);
+#endif /* RT_USING_NETDEV */
netif_ip6_addr_set_state(netif, i, IP6_ADDR_TENTATIVE);
if (chosen_idx != NULL) {
*chosen_idx = i;
diff --git a/components/net/lwip-2.0.2/src/include/netif/ethernetif.h b/components/net/lwip-2.0.2/src/include/netif/ethernetif.h
index 1c969e6e25..244bafdd1b 100644
--- a/components/net/lwip-2.0.2/src/include/netif/ethernetif.h
+++ b/components/net/lwip-2.0.2/src/include/netif/ethernetif.h
@@ -41,6 +41,7 @@ extern "C" {
rt_err_t eth_device_init(struct eth_device * dev, const char *name);
rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_uint16_t flag);
rt_err_t eth_device_linkchange(struct eth_device* dev, rt_bool_t up);
+ void eth_device_deinit(struct eth_device *dev);
int eth_system_device_init(void);
diff --git a/components/net/lwip-2.0.2/src/netif/ethernetif.c b/components/net/lwip-2.0.2/src/netif/ethernetif.c
index f19ec094fa..a7bed3065f 100644
--- a/components/net/lwip-2.0.2/src/netif/ethernetif.c
+++ b/components/net/lwip-2.0.2/src/netif/ethernetif.c
@@ -128,23 +128,23 @@ static int lwip_netdev_set_addr_info(struct netdev *netif, ip_addr_t *ip_addr, i
{
if (ip_addr && netmask && gw)
{
- netif_set_addr((struct netif *)netif->user_data, ip_addr, netmask, gw);
+ netif_set_addr((struct netif *)netif->user_data, ip_2_ip4(ip_addr), ip_2_ip4(netmask), ip_2_ip4(gw));
}
else
{
if (ip_addr)
{
- netif_set_ipaddr((struct netif *)netif->user_data, ip_addr);
+ netif_set_ipaddr((struct netif *)netif->user_data, ip_2_ip4(ip_addr));
}
if (netmask)
{
- netif_set_netmask((struct netif *)netif->user_data, netmask);
+ netif_set_netmask((struct netif *)netif->user_data, ip_2_ip4(netmask));
}
if (gw)
{
- netif_set_gw((struct netif *)netif->user_data, gw);
+ netif_set_gw((struct netif *)netif->user_data, ip_2_ip4(gw));
}
}
@@ -154,8 +154,8 @@ static int lwip_netdev_set_addr_info(struct netdev *netif, ip_addr_t *ip_addr, i
#ifdef RT_LWIP_DNS
static int lwip_netdev_set_dns_server(struct netdev *netif, uint8_t dns_num, ip_addr_t *dns_server)
{
- extern void set_dns(uint8_t dns_num, char* dns_server);
- set_dns(dns_num, ipaddr_ntoa(dns_server));
+ extern void dns_setserver(uint8_t dns_num, const ip_addr_t *dns_server);
+ dns_setserver(dns_num, dns_server);
return ERR_OK;
}
#endif /* RT_LWIP_DNS */
@@ -168,6 +168,7 @@ static int lwip_netdev_set_dhcp(struct netdev *netif, rt_bool_t is_enabled)
}
#endif /* RT_LWIP_DHCP */
+#ifdef RT_USING_FINSH
#ifdef RT_LWIP_USING_PING
extern int lwip_ping_recv(int s, int *ttl);
extern err_t lwip_ping_send(int s, ip_addr_t *addr, int size);
@@ -258,6 +259,13 @@ void lwip_netdev_netstat(struct netdev *netif)
#endif
}
#endif /* RT_LWIP_TCP || RT_LWIP_UDP */
+#endif /* RT_USING_FINSH */
+
+static int lwip_netdev_set_default(struct netdev *netif)
+{
+ netif_set_default((struct netif *)netif->user_data);
+ return ERR_OK;
+}
const struct netdev_ops lwip_netdev_ops =
{
@@ -277,6 +285,7 @@ const struct netdev_ops lwip_netdev_ops =
NULL,
#endif /* RT_LWIP_DHCP */
+#ifdef RT_USING_FINSH
#ifdef RT_LWIP_USING_PING
lwip_netdev_ping,
#else
@@ -286,6 +295,9 @@ const struct netdev_ops lwip_netdev_ops =
#if defined (RT_LWIP_TCP) || defined (RT_LWIP_UDP)
lwip_netdev_netstat,
#endif /* RT_LWIP_TCP || RT_LWIP_UDP */
+#endif /* RT_USING_FINSH */
+
+ lwip_netdev_set_default,
};
static int netdev_add(struct netif *lwip_netif)
@@ -303,12 +315,6 @@ static int netdev_add(struct netif *lwip_netif)
return -ERR_IF;
}
- netdev->flags = lwip_netif->flags;
- netdev->mtu = lwip_netif->mtu;
- netdev->ops = &lwip_netdev_ops;
- netdev->hwaddr_len = lwip_netif->hwaddr_len;
- rt_memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len);
-
#ifdef SAL_USING_LWIP
extern int sal_lwip_netdev_set_pf_info(struct netdev *netdev);
/* set the lwIP network interface device protocol family information */
@@ -317,7 +323,17 @@ static int netdev_add(struct netif *lwip_netif)
rt_strncpy(name, lwip_netif->name, LWIP_NETIF_NAME_LEN);
result = netdev_register(netdev, name, (void *)lwip_netif);
-
+
+ /* Update netdev info after registered */
+ netdev->flags = lwip_netif->flags;
+ netdev->mtu = lwip_netif->mtu;
+ netdev->ops = &lwip_netdev_ops;
+ netdev->hwaddr_len = lwip_netif->hwaddr_len;
+ rt_memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len);
+ netdev->ip_addr = lwip_netif->ip_addr;
+ netdev->gw = lwip_netif->gw;
+ netdev->netmask = lwip_netif->netmask;
+
#ifdef RT_LWIP_DHCP
netdev_low_level_set_dhcp_status(netdev, RT_TRUE);
#endif
@@ -325,6 +341,19 @@ static int netdev_add(struct netif *lwip_netif)
return result;
}
+static void netdev_del(struct netif *lwip_netif)
+{
+ char name[LWIP_NETIF_NAME_LEN + 1];
+ struct netdev *netdev;
+
+ RT_ASSERT(lwip_netif);
+
+ rt_strncpy(name, lwip_netif->name, LWIP_NETIF_NAME_LEN);
+ netdev = netdev_get_by_name(name);
+ netdev_unregister(netdev);
+ rt_free(netdev);
+}
+
/* synchronize lwIP network interface device and network interface device flags */
static int netdev_flags_sync(struct netif *lwip_netif)
{
@@ -530,6 +559,25 @@ rt_err_t eth_device_init(struct eth_device * dev, const char *name)
return eth_device_init_with_flag(dev, name, flags);
}
+void eth_device_deinit(struct eth_device *dev)
+{
+ struct netif* netif = dev->netif;
+
+#if LWIP_DHCP
+ dhcp_stop(netif);
+ dhcp_cleanup(netif);
+#endif
+ netif_set_down(netif);
+ netif_remove(netif);
+#ifdef RT_USING_NETDEV
+ netdev_del(netif);
+#endif
+ rt_device_close(&(dev->parent));
+ rt_device_unregister(&(dev->parent));
+ rt_sem_detach(&(dev->tx_ack));
+ rt_free(netif);
+}
+
#ifndef LWIP_NO_RX_THREAD
rt_err_t eth_device_ready(struct eth_device* dev)
{
@@ -707,8 +755,6 @@ int eth_system_device_init_private(void)
return (int)result;
}
-#ifdef RT_USING_FINSH
-#include <finsh.h>
void set_if(char* netif_name, char* ip_addr, char* gw_addr, char* nm_addr)
{
ip4_addr_t *ip;
@@ -754,6 +800,9 @@ void set_if(char* netif_name, char* ip_addr, char* gw_addr, char* nm_addr)
netif_set_netmask(netif, ip);
}
}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
FINSH_FUNCTION_EXPORT(set_if, set network interface address);
#if LWIP_DNS
diff --git a/components/net/lwip-2.1.0/src/arch/sys_arch.c b/components/net/lwip-2.1.0/src/arch/sys_arch.c
index 17ebdfbacf..dc08715ecc 100644
--- a/components/net/lwip-2.1.0/src/arch/sys_arch.c
+++ b/components/net/lwip-2.1.0/src/arch/sys_arch.c
@@ -522,7 +522,7 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
t = timeout / (1000/RT_TICK_PER_SECOND);
}
- ret = rt_mb_recv(*mbox, (rt_uint32_t *)msg, t);
+ ret = rt_mb_recv(*mbox, (rt_ubase_t *)msg, t);
if(ret == -RT_ETIMEOUT)
return SYS_ARCH_TIMEOUT;
@@ -553,7 +553,7 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
{
int ret;
- ret = rt_mb_recv(*mbox, (rt_uint32_t *)msg, 0);
+ ret = rt_mb_recv(*mbox, (rt_ubase_t *)msg, 0);
if(ret == -RT_ETIMEOUT)
return SYS_ARCH_TIMEOUT;
diff --git a/components/net/lwip-2.1.0/src/core/dns.c b/components/net/lwip-2.1.0/src/core/dns.c
index 5129b7f3bc..c688cb2205 100644
--- a/components/net/lwip-2.1.0/src/core/dns.c
+++ b/components/net/lwip-2.1.0/src/core/dns.c
@@ -367,13 +367,14 @@ dns_setserver(u8_t numdns, const ip_addr_t *dnsserver)
dns_servers[numdns] = (*dnsserver);
#ifdef RT_USING_NETDEV
- extern struct netif *netif_default;
+ extern struct netif *netif_list;
extern struct netdev *netdev_get_by_name(const char *name);
extern void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
+ struct netif *netif = NULL;
/* set network interface device DNS server address */
- if (netif_default) {
- netdev_low_level_set_dns_server(netdev_get_by_name(netif_default->name), numdns, dnsserver);
+ for (netif = netif_list; netif != NULL; netif = netif->next) {
+ netdev_low_level_set_dns_server(netdev_get_by_name(netif->name), numdns, dnsserver);
}
#endif /* RT_USING_NETDEV */
} else {
diff --git a/components/net/lwip-2.1.0/src/core/netif.c b/components/net/lwip-2.1.0/src/core/netif.c
index 5b31c627e9..b2b4adf85b 100644
--- a/components/net/lwip-2.1.0/src/core/netif.c
+++ b/components/net/lwip-2.1.0/src/core/netif.c
@@ -491,7 +491,7 @@ netif_do_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr, ip_addr_t *ol
#ifdef RT_USING_NETDEV
/* rt-thread sal network interface device set IP address operations */
- netdev_low_level_set_ipaddr(netdev_get_by_name(netif->name), (ip_addr_t *)ipaddr);
+ netdev_low_level_set_ipaddr(netdev_get_by_name(netif->name), &netif->ip_addr);
#endif /* RT_USING_NETDEV */
return 1; /* address changed */
@@ -557,7 +557,7 @@ netif_do_set_netmask(struct netif *netif, const ip4_addr_t *netmask, ip_addr_t *
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set netmask address */
- netdev_low_level_set_netmask(netdev_get_by_name(netif->name), (ip_addr_t *)netmask);
+ netdev_low_level_set_netmask(netdev_get_by_name(netif->name), &netif->netmask);
#endif /* RT_USING_NETDEV */
return 1; /* netmask changed */
@@ -625,7 +625,7 @@ netif_do_set_gw(struct netif *netif, const ip4_addr_t *gw, ip_addr_t *old_gw)
#ifdef RT_USING_NETDEV
/* rt_thread network interface device set gateway address */
- netdev_low_level_set_gw(netdev_get_by_name(netif->name), (ip_addr_t *)gw);
+ netdev_low_level_set_gw(netdev_get_by_name(netif->name), &netif->gw);
#endif /* RT_USING_NETDEV */
return 1; /* gateway changed */
@@ -1586,6 +1586,11 @@ netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit)
* zone field, so this should not create any compatibility problems. */
ip6_addr_assign_zone(ip_2_ip6(&netif->ip6_addr[0]), IP6_UNICAST, netif);
+#ifdef RT_USING_NETDEV
+ /* rt-thread network interface device set ipv6 address */
+ ip_addr_copy(netdev_get_by_name(netif->name)->ip6_addr[0], netif->ip6_addr[0]);
+#endif /* RT_USING_NETDEV */
+
/* Set address state. */
#if LWIP_IPV6_DUP_DETECT_ATTEMPTS
/* Will perform duplicate address detection (DAD). */
@@ -1629,6 +1634,10 @@ netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chos
for (i = ip6_addr_islinklocal(ip6addr) ? 0 : 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (ip6_addr_isinvalid(netif_ip6_addr_state(netif, i))) {
ip_addr_copy_from_ip6(netif->ip6_addr[i], *ip6addr);
+#ifdef RT_USING_NETDEV
+ /* rt-thread network interface device set ipv6 address */
+ ip_addr_copy(netdev_get_by_name(netif->name)->ip6_addr[i], netif->ip6_addr[i]);
+#endif /* RT_USING_NETDEV */
ip6_addr_assign_zone(ip_2_ip6(&netif->ip6_addr[i]), IP6_UNICAST, netif);
netif_ip6_addr_set_state(netif, i, IP6_ADDR_TENTATIVE);
if (chosen_idx != NULL) {
diff --git a/components/net/lwip-2.1.0/src/include/netif/ethernetif.h b/components/net/lwip-2.1.0/src/include/netif/ethernetif.h
index 1c969e6e25..244bafdd1b 100644
--- a/components/net/lwip-2.1.0/src/include/netif/ethernetif.h
+++ b/components/net/lwip-2.1.0/src/include/netif/ethernetif.h
@@ -41,6 +41,7 @@ extern "C" {
rt_err_t eth_device_init(struct eth_device * dev, const char *name);
rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_uint16_t flag);
rt_err_t eth_device_linkchange(struct eth_device* dev, rt_bool_t up);
+ void eth_device_deinit(struct eth_device *dev);
int eth_system_device_init(void);
diff --git a/components/net/lwip-2.1.0/src/netif/ethernetif.c b/components/net/lwip-2.1.0/src/netif/ethernetif.c
index db28a4a55b..66ea1d2376 100644
--- a/components/net/lwip-2.1.0/src/netif/ethernetif.c
+++ b/components/net/lwip-2.1.0/src/netif/ethernetif.c
@@ -129,23 +129,23 @@ static int lwip_netdev_set_addr_info(struct netdev *netif, ip_addr_t *ip_addr, i
{
if (ip_addr && netmask && gw)
{
- netif_set_addr((struct netif *)netif->user_data, ip_addr, netmask, gw);
+ netif_set_addr((struct netif *)netif->user_data, ip_2_ip4(ip_addr), ip_2_ip4(netmask), ip_2_ip4(gw));
}
else
{
if (ip_addr)
{
- netif_set_ipaddr((struct netif *)netif->user_data, ip_addr);
+ netif_set_ipaddr((struct netif *)netif->user_data, ip_2_ip4(ip_addr));
}
if (netmask)
{
- netif_set_netmask((struct netif *)netif->user_data, netmask);
+ netif_set_netmask((struct netif *)netif->user_data, ip_2_ip4(netmask));
}
if (gw)
{
- netif_set_gw((struct netif *)netif->user_data, gw);
+ netif_set_gw((struct netif *)netif->user_data, ip_2_ip4(gw));
}
}
@@ -155,8 +155,8 @@ static int lwip_netdev_set_addr_info(struct netdev *netif, ip_addr_t *ip_addr, i
#ifdef RT_LWIP_DNS
static int lwip_netdev_set_dns_server(struct netdev *netif, uint8_t dns_num, ip_addr_t *dns_server)
{
- extern void set_dns(uint8_t dns_num, char* dns_server);
- set_dns(dns_num, ipaddr_ntoa(dns_server));
+ extern void dns_setserver(uint8_t dns_num, const ip_addr_t *dns_server);
+ dns_setserver(dns_num, dns_server);
return ERR_OK;
}
#endif /* RT_LWIP_DNS */
@@ -169,6 +169,7 @@ static int lwip_netdev_set_dhcp(struct netdev *netif, rt_bool_t is_enabled)
}
#endif /* RT_LWIP_DHCP */
+#ifdef RT_USING_FINSH
#ifdef RT_LWIP_USING_PING
extern int lwip_ping_recv(int s, int *ttl);
extern err_t lwip_ping_send(int s, ip_addr_t *addr, int size);
@@ -259,6 +260,13 @@ void lwip_netdev_netstat(struct netdev *netif)
#endif
}
#endif /* RT_LWIP_TCP || RT_LWIP_UDP */
+#endif /* RT_USING_FINSH */
+
+static int lwip_netdev_set_default(struct netdev *netif)
+{
+ netif_set_default((struct netif *)netif->user_data);
+ return ERR_OK;
+}
const struct netdev_ops lwip_netdev_ops =
{
@@ -278,6 +286,7 @@ const struct netdev_ops lwip_netdev_ops =
NULL,
#endif /* RT_LWIP_DHCP */
+#ifdef RT_USING_FINSH
#ifdef RT_LWIP_USING_PING
lwip_netdev_ping,
#else
@@ -287,6 +296,9 @@ const struct netdev_ops lwip_netdev_ops =
#if defined (RT_LWIP_TCP) || defined (RT_LWIP_UDP)
lwip_netdev_netstat,
#endif /* RT_LWIP_TCP || RT_LWIP_UDP */
+#endif /* RT_USING_FINSH */
+
+ lwip_netdev_set_default,
};
static int netdev_add(struct netif *lwip_netif)
@@ -303,11 +315,6 @@ static int netdev_add(struct netif *lwip_netif)
{
return -ERR_IF;
}
-
- netdev->flags = lwip_netif->flags;
- netdev->ops = &lwip_netdev_ops;
- netdev->hwaddr_len = lwip_netif->hwaddr_len;
- rt_memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len);
#ifdef SAL_USING_LWIP
extern int sal_lwip_netdev_set_pf_info(struct netdev *netdev);
@@ -317,6 +324,16 @@ static int netdev_add(struct netif *lwip_netif)
rt_strncpy(name, lwip_netif->name, LWIP_NETIF_NAME_LEN);
result = netdev_register(netdev, name, (void *)lwip_netif);
+
+ /* Update netdev info after registered */
+ netdev->flags = lwip_netif->flags;
+ netdev->mtu = lwip_netif->mtu;
+ netdev->ops = &lwip_netdev_ops;
+ netdev->hwaddr_len = lwip_netif->hwaddr_len;
+ rt_memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len);
+ netdev->ip_addr = lwip_netif->ip_addr;
+ netdev->gw = lwip_netif->gw;
+ netdev->netmask = lwip_netif->netmask;
#ifdef RT_LWIP_DHCP
netdev_low_level_set_dhcp_status(netdev, RT_TRUE);
@@ -325,6 +342,19 @@ static int netdev_add(struct netif *lwip_netif)
return result;
}
+static void netdev_del(struct netif *lwip_netif)
+{
+ char name[LWIP_NETIF_NAME_LEN + 1];
+ struct netdev *netdev;
+
+ RT_ASSERT(lwip_netif);
+
+ rt_strncpy(name, lwip_netif->name, LWIP_NETIF_NAME_LEN);
+ netdev = netdev_get_by_name(name);
+ netdev_unregister(netdev);
+ rt_free(netdev);
+}
+
/* synchronize lwIP network interface device and network interface device flags */
static int netdev_flags_sync(struct netif *lwip_netif)
{
@@ -534,6 +564,25 @@ rt_err_t eth_device_init(struct eth_device * dev, const char *name)
return eth_device_init_with_flag(dev, name, flags);
}
+void eth_device_deinit(struct eth_device *dev)
+{
+ struct netif* netif = dev->netif;
+
+#if LWIP_DHCP
+ dhcp_stop(netif);
+ dhcp_cleanup(netif);
+#endif
+ netif_set_down(netif);
+ netif_remove(netif);
+#ifdef RT_USING_NETDEV
+ netdev_del(netif);
+#endif
+ rt_device_close(&(dev->parent));
+ rt_device_unregister(&(dev->parent));
+ rt_sem_detach(&(dev->tx_ack));
+ rt_free(netif);
+}
+
#ifndef LWIP_NO_RX_THREAD
rt_err_t eth_device_ready(struct eth_device* dev)
{
@@ -711,8 +760,6 @@ int eth_system_device_init_private(void)
return (int)result;
}
-#ifdef RT_USING_FINSH
-#include <finsh.h>
void set_if(char* netif_name, char* ip_addr, char* gw_addr, char* nm_addr)
{
ip4_addr_t *ip;
@@ -758,6 +805,9 @@ void set_if(char* netif_name, char* ip_addr, char* gw_addr, char* nm_addr)
netif_set_netmask(netif, ip);
}
}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
FINSH_FUNCTION_EXPORT(set_if, set network interface address);
#if LWIP_DNS
diff --git a/components/net/lwip-2.1.0/src/netif/lowpan6.c b/components/net/lwip-2.1.0/src/netif/lowpan6.c
index 5769522d5e..6397b0cb5d 100644
--- a/components/net/lwip-2.1.0/src/netif/lowpan6.c
+++ b/components/net/lwip-2.1.0/src/netif/lowpan6.c
@@ -50,7 +50,7 @@
#include "netif/lowpan6.h"
-#if LWIP_IPV6
+#if LWIP_IPV6 && LWIP_6LOWPAN
#include "lwip/ip.h"
#include "lwip/pbuf.h"
diff --git a/components/net/lwip_dhcpd/SConscript b/components/net/lwip_dhcpd/SConscript
index f7513cb0e3..16c673036a 100644
--- a/components/net/lwip_dhcpd/SConscript
+++ b/components/net/lwip_dhcpd/SConscript
@@ -2,7 +2,7 @@ from building import *
cwd = GetCurrentDir()
-if GetDepend('RT_USING_LWIP202'):
+if GetDepend('RT_USING_LWIP202') or GetDepend('RT_USING_LWIP210') :
src = ['dhcp_server_raw.c']
else:
src = ['dhcp_server.c']
diff --git a/components/net/lwip_dhcpd/dhcp_server.c b/components/net/lwip_dhcpd/dhcp_server.c
index c548ecfa98..93b4ad16f0 100644
--- a/components/net/lwip_dhcpd/dhcp_server.c
+++ b/components/net/lwip_dhcpd/dhcp_server.c
@@ -279,6 +279,7 @@ static void dhcpd_thread_entry(void *parameter)
{
/* bind failed. */
DEBUG_PRINTF("bind server address failed, errno=%d\n", errno);
+ closesocket(sock);
rt_free(recv_data);
return;
}
@@ -290,7 +291,13 @@ static void dhcpd_thread_entry(void *parameter)
{
bytes_read = recvfrom(sock, recv_data, BUFSZ - 1, 0,
(struct sockaddr *)&client_addr, &addr_len);
- if (bytes_read < DHCP_MSG_LEN)
+ if (bytes_read <= 0)
+ {
+ closesocket(sock);
+ rt_free(recv_data);
+ return;
+ }
+ else if (bytes_read < DHCP_MSG_LEN)
{
DEBUG_PRINTF("packet too short, wait for next!\n");
continue;
@@ -546,4 +553,3 @@ void dhcpd_start(const char *netif_name)
rt_thread_startup(thread);
}
}
-
diff --git a/components/net/lwip_dhcpd/dhcp_server.h b/components/net/lwip_dhcpd/dhcp_server.h
index a8056540ec..ea68d6b8ec 100644
--- a/components/net/lwip_dhcpd/dhcp_server.h
+++ b/components/net/lwip_dhcpd/dhcp_server.h
@@ -44,6 +44,7 @@ extern "C" {
#endif
void dhcpd_start(const char *netif_name);
+void dhcpd_stop(const char *netif_name);
#ifdef __cplusplus
}
diff --git a/components/net/lwip_dhcpd/dhcp_server_raw.c b/components/net/lwip_dhcpd/dhcp_server_raw.c
index 6b359eea4e..6c786301be 100644
--- a/components/net/lwip_dhcpd/dhcp_server_raw.c
+++ b/components/net/lwip_dhcpd/dhcp_server_raw.c
@@ -97,6 +97,10 @@
#define LWIP_NETIF_LOCK(...)
#define LWIP_NETIF_UNLOCK(...)
+#ifndef DHCP_SERVER_PORT
+#define DHCP_SERVER_PORT 67
+#endif
+
/**
* The dhcp client node struct.
*/
@@ -662,6 +666,7 @@ dhcp_server_start(struct netif *netif, ip4_addr_t *start, ip4_addr_t *end)
return ERR_OK;
}
+extern void set_if(const char *netif_name, const char *ip_addr, const char *gw_addr, const char *nm_addr);
void dhcpd_start(const char *netif_name)
{
@@ -697,8 +702,6 @@ void dhcpd_start(const char *netif_name)
if (1)
{
- extern void set_if(const char *netif_name, const char *ip_addr, const char *gw_addr, const char *nm_addr);
-
dhcp_stop(netif);
set_if(netif_name, DHCPD_SERVER_IP, "0.0.0.0", "255.255.255.0");
@@ -746,4 +749,83 @@ _exit:
return;
}
+void dhcpd_stop(const char *netif_name)
+{
+ struct dhcp_server *dhcp_server, *server_node;
+ struct netif *netif = netif_list;
+ struct dhcp_client_node *node, *next;
+
+ DEBUG_PRINTF("%s: %s\r\n", __FUNCTION__, netif_name);
+
+ LWIP_NETIF_LOCK();
+ if (strlen(netif_name) > sizeof(netif->name))
+ {
+ DEBUG_PRINTF("network interface name too long!\r\n");
+ goto _exit;
+ }
+ while (netif != RT_NULL)
+ {
+ if (strncmp(netif_name, netif->name, sizeof(netif->name)) == 0)
+ break;
+
+ netif = netif->next;
+ if (netif == RT_NULL)
+ {
+ DEBUG_PRINTF("network interface: %s not found!\r\n", netif_name);
+ break;
+ }
+ }
+
+ if (netif == RT_NULL)
+ {
+ goto _exit;
+ }
+
+ /* If this netif alreday use the dhcp server. */
+ for (dhcp_server = lw_dhcp_server; dhcp_server != NULL; dhcp_server = dhcp_server->next)
+ {
+ if (dhcp_server->netif == netif)
+ {
+ break;
+ }
+ }
+ if (dhcp_server == RT_NULL)
+ {
+ goto _exit;
+ }
+
+ /* remove dhcp server */
+ if (dhcp_server == lw_dhcp_server)
+ {
+ lw_dhcp_server = lw_dhcp_server->next;
+ }
+ else
+ {
+ server_node = lw_dhcp_server;
+ while (server_node->next && server_node->next != dhcp_server)
+ {
+ server_node = server_node->next;
+ }
+ if (server_node->next != RT_NULL)
+ {
+ server_node->next = server_node->next->next;
+ }
+ }
+
+ udp_disconnect(dhcp_server->pcb);
+ udp_remove(dhcp_server->pcb);
+
+ /* remove all client node */
+ for (node = dhcp_server->node_list; node != NULL; node = next)
+ {
+ next = node->next;
+ mem_free(node);
+ }
+
+ mem_free(dhcp_server);
+ set_if(netif_name, "0.0.0.0", "0.0.0.0", "0.0.0.0");
+
+_exit:
+ LWIP_NETIF_UNLOCK();
+}
diff --git a/components/net/netdev/include/netdev.h b/components/net/netdev/include/netdev.h
index 0be2a2bda3..e11a8929b0 100644
--- a/components/net/netdev/include/netdev.h
+++ b/components/net/netdev/include/netdev.h
@@ -27,6 +27,13 @@ extern "C" {
#define NETDEV_DNS_SERVERS_NUM 2U
#endif
+#if NETDEV_IPV6
+/* the maximum of dns server number supported */
+#ifndef NETDEV_IPV6_NUM_ADDRESSES
+#define NETDEV_IPV6_NUM_ADDRESSES 3U
+#endif
+#endif /* NETDEV_IPV6 */
+
/* whether the network interface device is 'up' (set by the network interface driver or application) */
#define NETDEV_FLAG_UP 0x01U
/* if set, the network interface device has broadcast capability, only supported in the 'lwIP' stack */
@@ -78,6 +85,9 @@ struct netdev
ip_addr_t ip_addr; /* IP address */
ip_addr_t netmask; /* subnet mask */
ip_addr_t gw; /* gateway */
+#if NETDEV_IPV6
+ ip_addr_t ip6_addr[NETDEV_IPV6_NUM_ADDRESSES]; /* array of IPv6 addresses */
+#endif /* NETDEV_IPV6 */
ip_addr_t dns_servers[NETDEV_DNS_SERVERS_NUM]; /* DNS server */
uint8_t hwaddr_len; /* hardware address length */
uint8_t hwaddr[NETDEV_HWADDR_MAX_LEN]; /* hardware address */
@@ -122,10 +132,14 @@ struct netdev_ops
int (*set_dns_server)(struct netdev *netdev, uint8_t dns_num, ip_addr_t *dns_server);
int (*set_dhcp)(struct netdev *netdev, rt_bool_t is_enabled);
+#ifdef RT_USING_FINSH
/* set network interface device common network interface device operations */
int (*ping)(struct netdev *netdev, const char *host, size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp);
void (*netstat)(struct netdev *netdev);
+#endif
+ /* set default network interface device in current network stack*/
+ int (*set_default)(struct netdev *netdev);
};
/* The network interface device registered and unregistered*/
@@ -163,6 +177,7 @@ int netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_
/* Set network interface device callback, it can be called when the status or address changed */
void netdev_set_status_callback(struct netdev *netdev, netdev_callback_fn status_callback);
+void netdev_set_addr_callback(struct netdev *netdev, netdev_callback_fn addr_callback);
/* Set network interface device status and address, this function can only be called in the network interface device driver */
void netdev_low_level_set_ipaddr(struct netdev *netdev, const ip_addr_t *ipaddr);
diff --git a/components/net/netdev/include/netdev_ipaddr.h b/components/net/netdev/include/netdev_ipaddr.h
index c2e13cd118..65970ec5b7 100644
--- a/components/net/netdev/include/netdev_ipaddr.h
+++ b/components/net/netdev/include/netdev_ipaddr.h
@@ -12,21 +12,53 @@
#define __NETDEV_IPADDR_H__
#include <stdint.h>
+#include <rtconfig.h>
#ifdef __cplusplus
extern "C" {
#endif
-/* Only supports the IPV4 protocol */
-#ifndef NETDEV_IPV4
-#define NETDEV_IPV4 1
-#endif
+/*
+ * Definitions of bits in internet address integers.
+ * On subnets, the decomposition of addresses to host and net parts
+ * is done according to subnet mask, not the masks here.
+ */
+#define IN_CLASSA(i) (((long)(i) & 0x80000000) == 0)
+#define IN_CLASSA_NET 0xff000000
+#define IN_CLASSA_NSHIFT 24
+#define IN_CLASSA_HOST 0x00ffffff
+#define IN_CLASSA_MAX 128
-#ifndef NETDEV_IPV6
-#define NETDEV_IPV6 0
-#endif
+#define IN_CLASSB(i) (((long)(i) & 0xc0000000) == 0x80000000)
+#define IN_CLASSB_NET 0xffff0000
+#define IN_CLASSB_NSHIFT 16
+#define IN_CLASSB_HOST 0x0000ffff
+#define IN_CLASSB_MAX 65536
+
+#define IN_CLASSC(i) (((long)(i) & 0xe0000000) == 0xc0000000)
+#define IN_CLASSC_NET 0xffffff00
+#define IN_CLASSC_NSHIFT 8
+#define IN_CLASSC_HOST 0x000000ff
+
+#define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000)
+#define IN_MULTICAST(i) IN_CLASSD(i)
-#ifdef NETDEV_IPV4
+#define IN_EXPERIMENTAL(i) (((long)(i) & 0xe0000000) == 0xe0000000)
+#define IN_BADCLASS(i) (((long)(i) & 0xf0000000) == 0xf0000000)
+
+#define IN_LOOPBACKNET 127 /* official! */
+
+/* IP address types for use in ip_addr_t.type member */
+enum netdev_ip_addr_type {
+ /** IPv4 */
+ IPADDR_TYPE_V4 = 0U,
+ /** IPv6 */
+ IPADDR_TYPE_V6 = 6U,
+ /** IPv4+IPv6 ("dual-stack") */
+ IPADDR_TYPE_ANY = 46U
+};
+
+#if NETDEV_IPV4
/** IPv4 only: set the IP address given as an u32_t */
#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32))
/** IPv4 only: get the IP address as an u32_t */
@@ -68,7 +100,42 @@ typedef struct ip4_addr
uint32_t addr;
} ip4_addr_t;
-typedef ip4_addr_t ip_addr_t;
+/** 255.255.255.255 */
+#define IPADDR_NONE ((uint32_t)0xffffffffUL)
+/** 127.0.0.1 */
+#define IPADDR_LOOPBACK ((uint32_t)0x7f000001UL)
+/** 0.0.0.0 */
+#define IPADDR_ANY ((uint32_t)0x00000000UL)
+/** 255.255.255.255 */
+#define IPADDR_BROADCAST ((uint32_t)0xffffffffUL)
+
+/** 255.255.255.255 */
+#define INADDR_NONE IPADDR_NONE
+/** 127.0.0.1 */
+#define INADDR_LOOPBACK IPADDR_LOOPBACK
+/** 0.0.0.0 */
+#define INADDR_ANY IPADDR_ANY
+/** 255.255.255.255 */
+#define INADDR_BROADCAST IPADDR_BROADCAST
+
+#define IPADDR_BROADCAST_STRING "255.255.255.255"
+
+/** Copy IP address - faster than ip4_addr_set: no NULL check */
+#define ip4_addr_copy(dest, src) ((dest).addr = (src).addr)
+#define ip4_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)
+/** Safely copy one IP address to another (src may be NULL) */
+#define ip4_addr_set(dest, src) ((dest)->addr = ((src) == NULL ? 0 : (src)->addr))
+/** Set complete address to zero */
+#define ip4_addr_set_zero(ipaddr) ((ipaddr)->addr = 0)
+/** Set address to IPADDR_ANY (no need for htonl()) */
+#define ip4_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY)
+#define ip4_addr_isany_val(ipaddr) ((ipaddr).addr == IPADDR_ANY)
+#define ip4_addr_isany(ipaddr) ((ipaddr) == NULL || ip4_addr_isany_val(*(ipaddr)))
+
+in_addr_t netdev_ipaddr_addr(const char *cp);
+int netdev_ip4addr_aton(const char *cp, ip4_addr_t *addr);
+char *netdev_ip4addr_ntoa(const ip4_addr_t *addr);
+char *netdev_ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen);
#endif /* NETIF_IPV4 */
#if NETDEV_IPV6
@@ -85,23 +152,55 @@ struct in6_addr
typedef struct ip6_addr
{
uint32_t addr[4];
+#ifdef NETDEV_IPV6_SCOPES
+ uint8_t zone;
+#endif /* NETDEV_IPV6_SCOPES */
} ip6_addr_t;
-typedef ip6_addr ip_addr_t
+/** This macro can be used to initialize a variable of type struct in6_addr
+ to the IPv6 wildcard address. */
+#define IN6ADDR_ANY_INIT {{{0,0,0,0}}}
+/** This macro can be used to initialize a variable of type struct in6_addr
+ to the IPv6 loopback address. */
+#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}}
+
+/** This variable is initialized by the system to contain the wildcard IPv6 address.
+ */
+extern const struct in6_addr in6addr_any;
+
+#define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
+ ((addr1)->addr[1] == (addr2)->addr[1]) && \
+ ((addr1)->addr[2] == (addr2)->addr[2]) && \
+ ((addr1)->addr[3] == (addr2)->addr[3]))
+/** Copy IPv6 address - faster than ip6_addr_set: no NULL check */
+#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \
+ (dest).addr[1] = (src).addr[1]; \
+ (dest).addr[2] = (src).addr[2]; \
+ (dest).addr[3] = (src).addr[3];}while(0)
+/** Safely copy one IPv6 address to another (src may be NULL) */
+#define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \
+ (dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \
+ (dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \
+ (dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3];}while(0)
+/** Set complete address to zero */
+#define ip6_addr_set_zero(ip6addr) do{(ip6addr)->addr[0] = 0; \
+ (ip6addr)->addr[1] = 0; \
+ (ip6addr)->addr[2] = 0; \
+ (ip6addr)->addr[3] = 0;}while(0)
+/** Set address to ipv6 'any' (no need for lwip_htonl()) */
+#define ip6_addr_set_any(ip6addr) ip6_addr_set_zero(ip6addr)
+#define ip6_addr_isany_val(ip6addr) (((ip6addr).addr[0] == 0) && \
+ ((ip6addr).addr[1] == 0) && \
+ ((ip6addr).addr[2] == 0) && \
+ ((ip6addr).addr[3] == 0))
+#define ip6_addr_isany(ip6addr) (((ip6addr) == NULL) || ip6_addr_isany_val(*(ip6addr)))
+
+int netdev_ip6addr_aton(const char *cp, ip6_addr_t *addr);
+char *netdev_ip6addr_ntoa(const ip6_addr_t *addr);
+char *netdev_ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen);
#endif /* NETIF_IPV6 */
#if NETDEV_IPV4 && NETDEV_IPV6
-/* IP address types for use in ip_addr_t.type member */
-enum netdev_ip_addr_type
-{
- /** IPv4 */
- IPADDR_TYPE_V4 = 0U,
- /** IPv6 */
- IPADDR_TYPE_V6 = 6U,
- /** IPv4+IPv6 ("dual-stack") */
- IPADDR_TYPE_ANY = 46U
-};
-
/* A union struct for both IP version's addresses */
typedef struct _ip_addr
{
@@ -113,54 +212,102 @@ typedef struct _ip_addr
/** @ref netdev_ip_addr_type */
uint8_t type;
} ip_addr_t;
-#endif /* NETIF_IPV4 && NETIF_IPV6 */
-/** 255.255.255.255 */
-#define IPADDR_NONE ((uint32_t)0xffffffffUL)
-/** 127.0.0.1 */
-#define IPADDR_LOOPBACK ((uint32_t)0x7f000001UL)
-/** 0.0.0.0 */
-#define IPADDR_ANY ((uint32_t)0x00000000UL)
-/** 255.255.255.255 */
-#define IPADDR_BROADCAST ((uint32_t)0xffffffffUL)
+#define IP_SET_TYPE_VAL(ipaddr, iptype) do { (ipaddr).type = (iptype); }while(0)
+#define IP_SET_TYPE(ipaddr, iptype) do { if((ipaddr) != NULL) { IP_SET_TYPE_VAL(*(ipaddr), iptype); }}while(0)
+#define IP_GET_TYPE(ipaddr) ((ipaddr)->type)
-/** 255.255.255.255 */
-#define INADDR_NONE IPADDR_NONE
-/** 127.0.0.1 */
-#define INADDR_LOOPBACK IPADDR_LOOPBACK
-/** 0.0.0.0 */
-#define INADDR_ANY IPADDR_ANY
-/** 255.255.255.255 */
-#define INADDR_BROADCAST IPADDR_BROADCAST
+#define IP_IS_V4_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V4)
+#define IP_IS_V6_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V6)
+#define IP_IS_V4(ipaddr) (((ipaddr) == NULL) || IP_IS_V4_VAL(*(ipaddr)))
+#define IP_IS_V6(ipaddr) (((ipaddr) != NULL) && IP_IS_V6_VAL(*(ipaddr)))
-#define IPADDR_BROADCAST_STRING "255.255.255.255"
+/** Convert generic ip address to specific protocol version */
+#define ip_2_ip6(ipaddr) (&((ipaddr)->u_addr.ip6))
+/** Convert generic ip address to specific protocol version */
+#define ip_2_ip4(ipaddr) (&((ipaddr)->u_addr.ip4))
-#ifdef NETDEV_IPV4
+#define ip_addr_copy(dest, src) do{ IP_SET_TYPE_VAL(dest, IP_GET_TYPE(&src)); if(IP_IS_V6_VAL(src)){ \
+ ip6_addr_copy(*ip_2_ip6(&(dest)), *ip_2_ip6(&(src))); }else{ \
+ ip4_addr_copy(*ip_2_ip4(&(dest)), *ip_2_ip4(&(src))); }}while(0)
+#define ip_addr_cmp(addr1, addr2) ((IP_GET_TYPE(addr1) != IP_GET_TYPE(addr2)) ? 0 : (IP_IS_V6_VAL(*(addr1)) ? \
+ ip6_addr_cmp(ip_2_ip6(addr1), ip_2_ip6(addr2)) : \
+ ip4_addr_cmp(ip_2_ip4(addr1), ip_2_ip4(addr2))))
+#define ip_addr_set(dest, src) do{ IP_SET_TYPE(dest, IP_GET_TYPE(src)); if(IP_IS_V6(src)){ \
+ ip6_addr_set(ip_2_ip6(dest), ip_2_ip6(src)); }else{ \
+ ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); }}while(0)
+#define ip_addr_set_zero(ipaddr) do{ ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, 0); }while(0)
+#define ip_addr_set_any(is_ipv6, ipaddr) do{ if(is_ipv6){ \
+ ip6_addr_set_any(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }else{ \
+ ip4_addr_set_any(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }}while(0)
-/** Copy IP address - faster than ip4_addr_set: no NULL check */
-#define ip4_addr_copy(dest, src) ((dest).addr = (src).addr)
-#define ip4_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)
-/** Set complete address to zero */
-#define ip4_addr_set_zero(ipaddr) ((ipaddr)->addr = 0)
-#define ip4_addr_isany_val(ipaddr) ((ipaddr).addr == IPADDR_ANY)
-#define ip4_addr_isany(ipaddr) ((ipaddr) == NULL || ip4_addr_isany_val(*(ipaddr)))
+#define ip_addr_isany_val(ipaddr) ((IP_IS_V6_VAL(ipaddr)) ? \
+ ip6_addr_isany_val(*ip_2_ip6(&(ipaddr))) : \
+ ip4_addr_isany_val(*ip_2_ip4(&(ipaddr))))
+#define ip_addr_isany(ipaddr) ((IP_IS_V6(ipaddr)) ? \
+ ip6_addr_isany(ip_2_ip6(ipaddr)) : \
+ ip4_addr_isany(ip_2_ip4(ipaddr)))
+
+/* directly map this to the lwip internal functions */
+#define inet_addr(cp) netdev_ipaddr_addr(cp)
+#define inet_aton(cp, addr) ((IP_IS_V6_VAL(*addr)) ? \
+ netdev_ip6addr_aton(cp, ip_2_ip6(addr)) : \
+ netdev_ip4addr_aton(cp, ip_2_ip4(addr)))
+#define inet_ntoa(addr) ((IP_IS_V6_VAL(addr)) ? \
+ netdev_ip6addr_ntoa(ip_2_ip6(&addr)) : \
+ netdev_ip4addr_ntoa(ip_2_ip4(&addr)))
+#define inet_ntoa_r(addr, buf, buflen) ((IP_IS_V6_VAL(addr)) ? \
+ netdev_ip6addr_ntoa_r(ip_2_ip6(&addr), buf, buflen) : \
+ netdev_ip4addr_ntoa_r(ip_2_ip4(&addr), buf, buflen))
+#elif NETDEV_IPV4 /* NETDEV_IPV4 */
+
+typedef ip4_addr_t ip_addr_t;
+
+#define IP_SET_TYPE_VAL(ipaddr, iptype)
+#define IP_SET_TYPE(ipaddr, iptype)
+#define IP_GET_TYPE(ipaddr) IPADDR_TYPE_V4
#define ip_addr_copy(dest, src) ip4_addr_copy(dest, src)
#define ip_addr_cmp(addr1, addr2) ip4_addr_cmp(addr1, addr2)
+#define ip_addr_set(dest, src) ip4_addr_set(dest, src)
#define ip_addr_set_zero(ipaddr) ip4_addr_set_zero(ipaddr)
+#define ip_addr_set_any(is_ipv6, ipaddr) ip4_addr_set_any(ipaddr)
+#define ip_addr_isany_val(ipaddr) ip4_addr_isany_val(ipaddr)
#define ip_addr_isany(ipaddr) ip4_addr_isany(ipaddr)
-in_addr_t netdev_ipaddr_addr(const char *cp);
-int netdev_ip4addr_aton(const char *cp, ip4_addr_t *addr);
-char *netdev_ip4addr_ntoa(const ip4_addr_t *addr);
-char *netdev_ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen);
-
+/* directly map this to the lwip internal functions */
#define inet_addr(cp) netdev_ipaddr_addr(cp)
#define inet_aton(cp, addr) netdev_ip4addr_aton(cp,(ip4_addr_t*)addr)
#define inet_ntoa(addr) netdev_ip4addr_ntoa((const ip4_addr_t*)&(addr))
#define inet_ntoa_r(addr, buf, buflen) netdev_ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen)
+#else /* NETDEV_IPV6 */
+
+typedef ip6_addr_t ip_addr_t;
+
+#define IP_SET_TYPE_VAL(ipaddr, iptype)
+#define IP_SET_TYPE(ipaddr, iptype)
+#define IP_GET_TYPE(ipaddr) IPADDR_TYPE_V6
+
+#define ip_addr_copy(dest, src) ip6_addr_copy(dest, src)
+#define ip_addr_cmp(addr1, addr2) ip6_addr_cmp(addr1, addr2)
+#define ip_addr_set(dest, src) ip6_addr_set(dest, src)
+#define ip_addr_set_zero(ipaddr) ip6_addr_set_zero(ipaddr)
+#define ip_addr_set_any(is_ipv6, ipaddr) ip6_addr_set_any(ipaddr)
+#define ip_addr_isany_val(ipaddr) ip6_addr_isany_val(ipaddr)
+#define ip_addr_isany(ipaddr) ip6_addr_isany(ipaddr)
+
+/* directly map this to the lwip internal functions */
+#define inet_aton(cp, addr) netdev_ip6addr_aton(cp, (ip6_addr_t*)addr)
+#define inet_ntoa(addr) netdev_ip6addr_ntoa((const ip6_addr_t*)&(addr))
+#define inet_ntoa_r(addr, buf, buflen) netdev_ip6addr_ntoa_r((const ip6_addr_t*)&(addr), buf, buflen)
+#endif /* NTDEV_IPV4 && NTDEV_IPV6 */
+
+
+const char *netdev_inet_ntop(int af, const void *src, char *dst, int32_t size);
+int netdev_inet_pton(int af, const char *src, void *dst);
-#endif /* NETDEV_IPV4 */
+#define inet_ntop(af, src, dst, size) netdev_inet_ntop(af, src, dst, size)
+#define inet_pton(af, src, dst) netdev_inet_pton(af, src, dst)
#ifdef __cplusplus
}
diff --git a/components/net/netdev/src/netdev.c b/components/net/netdev/src/netdev.c
index 5f49a46f17..68e5364a9e 100644
--- a/components/net/netdev/src/netdev.c
+++ b/components/net/netdev/src/netdev.c
@@ -34,11 +34,11 @@ struct netdev *netdev_default;
/**
* This function will register network interface device and
* add it to network interface device list.
- *
+ *
* @param netdev the network interface device object
* @param name the network interface device name
* @param user_data user-specific data
- *
+ *
* @return 0: registered successfully
* -1: registered failed
*/
@@ -58,9 +58,21 @@ int netdev_register(struct netdev *netdev, const char *name, void *user_data)
ip_addr_set_zero(&(netdev->ip_addr));
ip_addr_set_zero(&(netdev->netmask));
ip_addr_set_zero(&(netdev->gw));
+
+ IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4);
+ IP_SET_TYPE_VAL(netdev->netmask, IPADDR_TYPE_V4);
+ IP_SET_TYPE_VAL(netdev->gw, IPADDR_TYPE_V4);
+#if NETDEV_IPV6
+ for (index = 0; index < NETDEV_IPV6_NUM_ADDRESSES; index++)
+ {
+ ip_addr_set_zero(&(netdev->ip6_addr[index]));
+ IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V6);
+ }
+#endif /* NETDEV_IPV6 */
for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
{
ip_addr_set_zero(&(netdev->dns_servers[index]));
+ IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4);
}
netdev->status_callback = RT_NULL;
netdev->addr_callback = RT_NULL;
@@ -87,15 +99,15 @@ int netdev_register(struct netdev *netdev, const char *name, void *user_data)
rt_hw_interrupt_enable(level);
- return RT_EOK;
+ return RT_EOK;
}
/**
* This function will unregister network interface device and
* delete it from network interface device list.
- *
+ *
* @param netdev the network interface device object
- *
+ *
* @return 0: unregistered successfully
* -1: unregistered failed
*/
@@ -106,7 +118,7 @@ int netdev_unregister(struct netdev *netdev)
struct netdev *cur_netdev = RT_NULL;
RT_ASSERT(netdev);
-
+
if (netdev_list == RT_NULL)
{
return -RT_ERROR;
@@ -117,29 +129,46 @@ int netdev_unregister(struct netdev *netdev)
for (node = &(netdev_list->list); node; node = rt_slist_next(node))
{
cur_netdev = rt_slist_entry(node, struct netdev, list);
- if (cur_netdev && (rt_memcpy(cur_netdev, netdev, sizeof(struct netdev)) == 0))
+ if (cur_netdev == netdev)
{
- rt_slist_remove(&(netdev_list->list), &(cur_netdev->list));
- rt_hw_interrupt_enable(level);
-
- return RT_EOK;
+ /* find this network interface device in network interface device list */
+ if (netdev_list == netdev && rt_slist_next(&netdev_list->list) == RT_NULL)
+ {
+ netdev_list = RT_NULL;
+ }
+ else
+ {
+ rt_slist_remove(&(netdev_list->list), &(cur_netdev->list));
+ }
+ if (netdev_default == netdev)
+ {
+ netdev_default = netdev_list;
+ }
+ break;
}
}
-
rt_hw_interrupt_enable(level);
- /* not find this network interface device in network interface device list */
+ if (cur_netdev == netdev)
+ {
+#ifdef RT_USING_SAL
+ extern int sal_netdev_cleanup(struct netdev *netdev);
+ sal_netdev_cleanup(netdev);
+#endif
+ rt_memset(netdev, 0, sizeof(*netdev));
+ }
+
return -RT_ERROR;
}
/**
* This function will get the first network interface device
* with the flags in network interface device list.
- *
+ *
* @param flags the network interface device flags
- *
+ *
* @return != NULL: network interface device object
- * NULL: get failed
+ * NULL: get failed
*/
struct netdev *netdev_get_first_by_flags(uint16_t flags)
{
@@ -172,11 +201,11 @@ struct netdev *netdev_get_first_by_flags(uint16_t flags)
/**
* This function will get the first network interface device
* in network interface device list by IP address.
- *
+ *
* @param addr the network interface device IP address
- *
+ *
* @return != NULL: network interface device object
- * NULL: get failed
+ * NULL: get failed
*/
struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr)
{
@@ -209,11 +238,11 @@ struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr)
/**
* This function will get network interface device
* in network interface device list by netdev name.
- *
+ *
* @param name the network interface device name
- *
+ *
* @return != NULL: network interface device object
- * NULL: get failed
+ * NULL: get failed
*/
struct netdev *netdev_get_by_name(const char *name)
{
@@ -247,11 +276,11 @@ struct netdev *netdev_get_by_name(const char *name)
/**
* This function will get the first network interface device
* in network interface device list by protocol family type.
- *
+ *
* @param family the network interface device protocol family type
- *
+ *
* @return != NULL: network interface device object
- * NULL: get failed
+ * NULL: get failed
*/
struct netdev *netdev_get_by_family(int family)
{
@@ -296,15 +325,15 @@ struct netdev *netdev_get_by_family(int family)
/**
* This function will get the family type from network interface device
- *
+ *
* @param netdev network interface device object
- *
+ *
* @return the network interface device family type
*/
int netdev_family_get(struct netdev *netdev)
{
- RT_ASSERT(netdev);
-
+ RT_ASSERT(netdev);
+
return ((struct sal_proto_family *)netdev->sal_user_data)->family;
}
@@ -312,7 +341,7 @@ int netdev_family_get(struct netdev *netdev)
/**
* This function will set default network interface device.
- *
+ *
* @param netdev the network interface device to change
*/
void netdev_set_default(struct netdev *netdev)
@@ -320,15 +349,21 @@ void netdev_set_default(struct netdev *netdev)
if (netdev)
{
netdev_default = netdev;
- LOG_D("Setting default network interface device name(%s) successfully.", netdev->name);
+
+ if (netdev->ops->set_default)
+ {
+ /* set default network interface device in the current network stack */
+ netdev->ops->set_default(netdev);
+ }
+ LOG_D("Setting default network interface device name(%s) successfully.", netdev->name);
}
}
/**
* This function will enable network interface device .
- *
+ *
* @param netdev the network interface device to change
- *
+ *
* @return 0: set status successfully
* -1: set status failed
*/
@@ -341,7 +376,7 @@ int netdev_set_up(struct netdev *netdev)
LOG_E("The network interface device(%s) not support to set status.", netdev->name);
return -RT_ERROR;
}
-
+
/* network interface device status flags check */
if (netdev_is_up(netdev))
{
@@ -353,9 +388,9 @@ int netdev_set_up(struct netdev *netdev)
}
/**
* This function will disable network interface device.
- *
+ *
* @param netdev the network interface device to change
- *
+ *
* @return 0: set status successfully
* -1: set sttaus failed
*/
@@ -368,7 +403,7 @@ int netdev_set_down(struct netdev *netdev)
LOG_E("The network interface device(%s) not support to set status.", netdev->name);
return -RT_ERROR;
}
-
+
/* network interface device status flags check */
if (!netdev_is_up(netdev))
{
@@ -381,10 +416,10 @@ int netdev_set_down(struct netdev *netdev)
/**
* This function will control network interface device DHCP capability enable or disable.
- *
+ *
* @param netdev the network interface device device to change
* @param is_enable the new DHCP status
- *
+ *
* @return 0: set DHCP status successfully
* -1: set DHCP status failed
*/
@@ -403,17 +438,17 @@ int netdev_dhcp_enabled(struct netdev *netdev, rt_bool_t is_enabled)
{
return RT_EOK;
}
-
+
/* execute network interface device DHCP capability control operations */
return netdev->ops->set_dhcp(netdev, is_enabled);
}
/**
* This function will set network interface device IP address.
- *
+ *
* @param netdev the network interface device to change
* @param ipaddr the new IP address
- *
+ *
* @return 0: set IP address successfully
* -1: set IP address failed
*/
@@ -427,7 +462,7 @@ int netdev_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr)
LOG_E("The network interface device(%s) not support to set IP address.", netdev->name);
return -RT_ERROR;
}
-
+
if (netdev_is_dhcp_enabled(netdev))
{
LOG_E("The network interface device(%s) DHCP capability is enable, not support set IP address.", netdev->name);
@@ -440,10 +475,10 @@ int netdev_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr)
/**
* This function will set network interface device netmask address.
- *
+ *
* @param netdev the network interface device to change
* @param netmask the new netmask address
- *
+ *
* @return 0: set netmask address successfully
* -1: set netmask address failed
*/
@@ -457,7 +492,7 @@ int netdev_set_netmask(struct netdev *netdev, const ip_addr_t *netmask)
LOG_E("The network interface device(%s) not support to set netmask address.", netdev->name);
return -RT_ERROR;
}
-
+
if (netdev_is_dhcp_enabled(netdev))
{
LOG_E("The network interface device(%s) DHCP capability is enable, not support set netmask address.", netdev->name);
@@ -470,10 +505,10 @@ int netdev_set_netmask(struct netdev *netdev, const ip_addr_t *netmask)
/**
* This function will set network interface device gateway address.
- *
+ *
* @param netdev the network interface device to change
- * @param gateway the new gateway address
- *
+ * @param gateway the new gateway address
+ *
* @return 0: set gateway address successfully
* -1: set gateway address failed
*/
@@ -487,7 +522,7 @@ int netdev_set_gw(struct netdev *netdev, const ip_addr_t *gw)
LOG_E("The network interface device(%s) not support to set gateway address.", netdev->name);
return -RT_ERROR;
}
-
+
if (netdev_is_dhcp_enabled(netdev))
{
LOG_E("The network interface device(%s) DHCP capability is enable, not support set gateway address.", netdev->name);
@@ -500,10 +535,10 @@ int netdev_set_gw(struct netdev *netdev, const ip_addr_t *gw)
/**
* This function will set network interface device DNS server address.
- *
+ *
* @param netdev the network interface device to change
* @param dns_server the new DNS server address
- *
+ *
* @return 0: set netmask address successfully
* -1: set netmask address failed
*/
@@ -530,7 +565,7 @@ int netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_
/**
* This function will set callback to be called when the network interface device status has been changed.
- *
+ *
* @param netdev the network interface device to change
* @param status_callback the callback be called when the status has been changed.
*/
@@ -544,7 +579,7 @@ void netdev_set_status_callback(struct netdev *netdev, netdev_callback_fn status
/**
* This function will set callback to be called when the network interface device address has been changed.
- *
+ *
* @param netdev the network interface device to change
* @param addr_callback the callback be called when the address has been changed.
*/
@@ -560,7 +595,7 @@ void netdev_set_addr_callback(struct netdev *netdev, netdev_callback_fn addr_cal
/**
* This function will set network interface device IP address.
* @NOTE it can only be called in the network interface device driver.
- *
+ *
* @param netdev the network interface device to change
* @param ipaddr the new IP address
*/
@@ -591,7 +626,7 @@ void netdev_low_level_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr
/**
* This function will set network interface device netmask address.
* @NOTE it can only be called in the network interface device driver.
- *
+ *
* @param netdev the network interface device to change
* @param netmask the new netmask address
*/
@@ -605,7 +640,7 @@ void netdev_low_level_set_netmask(struct netdev *netdev, const ip_addr_t *netmas
#ifdef RT_USING_SAL
/* set network interface device flags to internet up */
- if (netdev_is_up(netdev) && netdev_is_link_up(netdev) &&
+ if (netdev_is_up(netdev) && netdev_is_link_up(netdev) &&
!ip_addr_isany(&(netdev->ip_addr)))
{
sal_check_netdev_internet_up(netdev);
@@ -623,7 +658,7 @@ void netdev_low_level_set_netmask(struct netdev *netdev, const ip_addr_t *netmas
/**
* This function will set network interface device gateway address.
* @NOTE it can only be called in the network interface device driver.
- *
+ *
* @param netdev the network interface device to change
* @param gateway the new gateway address
*/
@@ -637,7 +672,7 @@ void netdev_low_level_set_gw(struct netdev *netdev, const ip_addr_t *gw)
#ifdef RT_USING_SAL
/* set network interface device flags to internet up */
- if (netdev_is_up(netdev) && netdev_is_link_up(netdev) &&
+ if (netdev_is_up(netdev) && netdev_is_link_up(netdev) &&
!ip_addr_isany(&(netdev->ip_addr)))
{
sal_check_netdev_internet_up(netdev);
@@ -655,10 +690,10 @@ void netdev_low_level_set_gw(struct netdev *netdev, const ip_addr_t *gw)
/**
* This function will set network interface device DNS server address.
* @NOTE it can only be called in the network interface device driver.
- *
+ *
* @param netdev the network interface device to change
* @param dns_server the new DNS server address
- *
+ *
*/
void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server)
{
@@ -666,6 +701,10 @@ void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, con
RT_ASSERT(dns_server);
+ if (netdev == RT_NULL)
+ {
+ return;
+ }
/* check DNS servers is exist */
for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
{
@@ -675,7 +714,7 @@ void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, con
}
}
- if (netdev && dns_num < NETDEV_DNS_SERVERS_NUM)
+ if (dns_num < NETDEV_DNS_SERVERS_NUM)
{
ip_addr_copy(netdev->dns_servers[dns_num], *dns_server);
@@ -707,7 +746,7 @@ static void netdev_auto_change_default(struct netdev *netdev)
/**
* This function will set network interface device status.
* @NOTE it can only be called in the network interface device driver.
- *
+ *
* @param netdev the network interface device to change
* @param is_up the new status
*/
@@ -740,14 +779,14 @@ void netdev_low_level_set_status(struct netdev *netdev, rt_bool_t is_up)
/**
* This function will set network interface device active link status.
* @NOTE it can only be called in the network interface device driver.
- *
+ *
* @param netdev the network interface device to change
* @param is_up the new link status
*/
void netdev_low_level_set_link_status(struct netdev *netdev, rt_bool_t is_up)
{
if (netdev && netdev_is_link_up(netdev) != is_up)
- {
+ {
if (is_up)
{
netdev->flags |= NETDEV_FLAG_LINK_UP;
@@ -763,7 +802,7 @@ void netdev_low_level_set_link_status(struct netdev *netdev, rt_bool_t is_up)
else
{
netdev->flags &= ~NETDEV_FLAG_LINK_UP;
-
+
/* set network interface device flags to internet down */
netdev->flags &= ~NETDEV_FLAG_INTERNET_UP;
@@ -784,7 +823,7 @@ void netdev_low_level_set_link_status(struct netdev *netdev, rt_bool_t is_up)
/**
* This function will set network interface device DHCP status.
* @NOTE it can only be called in the network interface device driver.
- *
+ *
* @param netdev the network interface device to change
* @param is_up the new DHCP status
*/
@@ -809,7 +848,7 @@ void netdev_low_level_set_dhcp_status(struct netdev *netdev, rt_bool_t is_enable
}
}
-#ifdef FINSH_USING_MSH
+#ifdef RT_USING_FINSH
#include <finsh.h>
@@ -820,7 +859,6 @@ static void netdev_list_if(void)
#define NETDEV_IFCONFIG_IEMI_MAX_LEN 8
rt_ubase_t index;
- rt_base_t level;
rt_slist_t *node = RT_NULL;
struct netdev *netdev = RT_NULL;
struct netdev *cur_netdev_list = netdev_list;
@@ -831,15 +869,13 @@ static void netdev_list_if(void)
return;
}
- level = rt_hw_interrupt_disable();
-
for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
{
netdev = rt_list_entry(node, struct netdev, list);
- rt_kprintf("network interface device: %s%s\n",
- netdev->name,
- (netdev == netdev_default)?" (Default)":"");
+ rt_kprintf("network interface device: %.*s%s\n",
+ RT_NAME_MAX, netdev->name,
+ (netdev == netdev_default) ? " (Default)" : "");
rt_kprintf("MTU: %d\n", netdev->mtu);
/* 6 - MAC address, 8 - IEMI */
@@ -853,13 +889,13 @@ static void netdev_list_if(void)
}
else if (netdev->hwaddr_len == NETDEV_IFCONFIG_IEMI_MAX_LEN)
{
- rt_kprintf("IEMI: ");
+ rt_kprintf("IMEI: ");
for (index = 0; index < netdev->hwaddr_len; index++)
{
/* two numbers are displayed at one time*/
if (netdev->hwaddr[index] < 10 && index != netdev->hwaddr_len - 1)
rt_kprintf("0");
-
+
rt_kprintf("%d", netdev->hwaddr[index]);
}
}
@@ -881,18 +917,38 @@ static void netdev_list_if(void)
rt_kprintf("gw address: %s\n", inet_ntoa(netdev->gw));
rt_kprintf("net mask : %s\n", inet_ntoa(netdev->netmask));
+#if NETDEV_IPV6
+ {
+ ip_addr_t *addr;
+ int i;
+
+ addr = &netdev->ip6_addr[0];
+
+ if (!ip_addr_isany(addr))
+ {
+ rt_kprintf("ipv6 link-local: %s %s\n", inet_ntoa(*addr),
+ !ip_addr_isany(addr) ? "VALID" : "INVALID");
+
+ for (i = 1; i < NETDEV_IPV6_NUM_ADDRESSES; i++)
+ {
+ addr = &netdev->ip6_addr[i];
+ rt_kprintf("ipv6[%d] address: %s %s\n", i, inet_ntoa(*addr),
+ !ip_addr_isany(addr) ? "VALID" : "INVALID");
+ }
+ }
+ }
+#endif /* NETDEV_IPV6 */
+
for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
{
rt_kprintf("dns server #%d: %s\n", index, inet_ntoa(netdev->dns_servers[index]));
}
-
+
if (rt_slist_next(node))
{
rt_kprintf("\n");
}
}
-
- rt_hw_interrupt_enable(level);
}
static void netdev_set_if(char* netdev_name, char* ip_addr, char* gw_addr, char* nm_addr)
@@ -951,7 +1007,7 @@ FINSH_FUNCTION_EXPORT_ALIAS(netdev_ifconfig, __cmd_ifconfig, list the informatio
#endif /* NETDEV_USING_IFCONFIG */
#ifdef NETDEV_USING_PING
-static int netdev_cmd_ping(char* target_name, rt_uint32_t times, rt_size_t size)
+int netdev_cmd_ping(char* target_name, rt_uint32_t times, rt_size_t size)
{
#define NETDEV_PING_DATA_SIZE 32
/** ping receive timeout - in milliseconds */
@@ -966,7 +1022,7 @@ static int netdev_cmd_ping(char* target_name, rt_uint32_t times, rt_size_t size)
struct netdev *netdev = RT_NULL;
struct netdev_ping_resp ping_resp;
int index, ret = 0;
-
+
if (size == 0)
{
size = NETDEV_PING_DATA_SIZE;
@@ -981,20 +1037,34 @@ static int netdev_cmd_ping(char* target_name, rt_uint32_t times, rt_size_t size)
{
/* using first internet up status network interface device */
netdev = netdev_get_first_by_flags(NETDEV_FLAG_LINK_UP);
- if (netdev == RT_NULL || NETDEV_PING_IS_COMMONICABLE(netdev) == 0)
+ if (netdev == RT_NULL)
+ {
+ rt_kprintf("ping: not found available network interface device.\n");
+ return -RT_ERROR;
+ }
+ else if (netdev->ops == RT_NULL || netdev->ops->ping == RT_NULL)
+ {
+ rt_kprintf("ping: network interface device(%s) not support ping feature.\n", netdev->name);
+ return -RT_ERROR;
+ }
+ else if (!netdev_is_up(netdev) || !netdev_is_link_up(netdev))
{
- rt_kprintf("ping: network interface device get error.\n");
+ rt_kprintf("ping: network interface device(%s) status error.\n", netdev->name);
return -RT_ERROR;
}
}
for (index = 0; index < times; index++)
{
+ int delay_tick = 0;
+ rt_tick_t start_tick = 0;
+
rt_memset(&ping_resp, 0x00, sizeof(struct netdev_ping_resp));
+ start_tick = rt_tick_get();
ret = netdev->ops->ping(netdev, (const char *)target_name, size, NETDEV_PING_RECV_TIMEO, &ping_resp);
if (ret == -RT_ETIMEOUT)
{
- rt_kprintf("ping: from %s icmp_seq=%d timeout\n",
+ rt_kprintf("ping: from %s icmp_seq=%d timeout\n",
(ip_addr_isany(&(ping_resp.ip_addr))) ? target_name : inet_ntoa(ping_resp.ip_addr), index);
}
else if (ret == -RT_ERROR)
@@ -1007,17 +1077,19 @@ static int netdev_cmd_ping(char* target_name, rt_uint32_t times, rt_size_t size)
{
if (ping_resp.ttl == 0)
{
- rt_kprintf("%d bytes from %s icmp_seq=%d time=%d ms\n",
+ rt_kprintf("%d bytes from %s icmp_seq=%d time=%d ms\n",
ping_resp.data_len, inet_ntoa(ping_resp.ip_addr), index, ping_resp.ticks);
}
else
{
- rt_kprintf("%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n",
+ rt_kprintf("%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n",
ping_resp.data_len, inet_ntoa(ping_resp.ip_addr), index, ping_resp.ttl, ping_resp.ticks);
}
}
-
- rt_thread_mdelay(NETDEV_PING_DELAY);
+
+ /* if the response time is more than NETDEV_PING_DELAY, no nead to delay */
+ delay_tick = ((rt_tick_get() - start_tick) > NETDEV_PING_DELAY) || (index == times) ? 0 : NETDEV_PING_DELAY;
+ rt_thread_delay(delay_tick);
}
return RT_EOK;
@@ -1041,33 +1113,28 @@ FINSH_FUNCTION_EXPORT_ALIAS(netdev_ping, __cmd_ping, ping network host);
static void netdev_list_dns(void)
{
- rt_base_t level;
int index = 0;
struct netdev *netdev = RT_NULL;
rt_slist_t *node = RT_NULL;
- level = rt_hw_interrupt_disable();
-
for (node = &(netdev_list->list); node; node = rt_slist_next(node))
{
netdev = rt_list_entry(node, struct netdev, list);
- rt_kprintf("network interface device: %s%s\n",
- netdev->name,
+ rt_kprintf("network interface device: %.*s%s\n",
+ RT_NAME_MAX, netdev->name,
(netdev == netdev_default)?" (Default)":"");
for(index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
{
rt_kprintf("dns server #%d: %s\n", index, inet_ntoa(netdev->dns_servers[index]));
}
-
+
if (rt_slist_next(node))
{
rt_kprintf("\n");
}
}
-
- rt_hw_interrupt_enable(level);
}
static void netdev_set_dns(char *netdev_name, uint8_t dns_num, char *dns_server)
@@ -1083,9 +1150,10 @@ static void netdev_set_dns(char *netdev_name, uint8_t dns_num, char *dns_server)
}
inet_aton(dns_server, &dns_addr);
- netdev_set_dns_server(netdev, dns_num, &dns_addr);
-
- rt_kprintf("set network interface device(%s) dns server #0: %s\n", netdev_name, dns_server);
+ if (netdev_set_dns_server(netdev, dns_num, &dns_addr) == RT_EOK)
+ {
+ rt_kprintf("set network interface device(%s) dns server #%d: %s\n", netdev_name, dns_num, dns_server);
+ }
}
int netdev_dns(int argc, char **argv)
@@ -1115,7 +1183,6 @@ FINSH_FUNCTION_EXPORT_ALIAS(netdev_dns, __cmd_dns, list and set the information
#ifdef NETDEV_USING_NETSTAT
static void netdev_cmd_netstat(void)
{
- rt_base_t level;
rt_slist_t *node = RT_NULL;
struct netdev *netdev = RT_NULL;
struct netdev *cur_netdev_list = netdev_list;
@@ -1126,8 +1193,6 @@ static void netdev_cmd_netstat(void)
return;
}
- level = rt_hw_interrupt_disable();
-
for (node = &(cur_netdev_list->list); node; node = rt_slist_next(node))
{
netdev = rt_list_entry(node, struct netdev, list);
@@ -1138,9 +1203,14 @@ static void netdev_cmd_netstat(void)
}
}
- rt_hw_interrupt_enable(level);
-
- netdev->ops->netstat(netdev);
+ if (netdev->ops->netstat != RT_NULL)
+ {
+ netdev->ops->netstat(netdev);
+ }
+ else
+ {
+ rt_kprintf("netstat: this command is not supported!\n");
+ }
}
int netdev_netstat(int argc, char **argv)
@@ -1149,7 +1219,7 @@ int netdev_netstat(int argc, char **argv)
{
rt_kprintf("Please input: netstat \n");
}
- else
+ else
{
netdev_cmd_netstat();
}
@@ -1159,4 +1229,4 @@ int netdev_netstat(int argc, char **argv)
FINSH_FUNCTION_EXPORT_ALIAS(netdev_netstat, __cmd_netstat, list the information of TCP / IP);
#endif /* NETDEV_USING_NETSTAT */
-#endif /* FINSH_USING_MSH */
+#endif /* RT_USING_FINSH */
diff --git a/components/net/netdev/src/netdev_ipaddr.c b/components/net/netdev/src/netdev_ipaddr.c
index 988bd50eb7..8d83937da9 100644
--- a/components/net/netdev/src/netdev_ipaddr.c
+++ b/components/net/netdev/src/netdev_ipaddr.c
@@ -19,8 +19,10 @@
#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
#define islower(c) in_range(c, 'a', 'z')
#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
+#define xchar(i) ((i) < 10 ? '0' + (i) : 'A' + (i) - 10)
#endif
+#if NETDEV_IPV4
/**
* Check whether "cp" is a valid ascii representation
@@ -255,3 +257,358 @@ in_addr_t netdev_ipaddr_addr(const char *cp)
}
return (IPADDR_NONE);
}
+
+#endif /* NETDEV_IPV4 */
+
+
+#if NETDEV_IPV6
+
+RT_WEAK const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
+
+/**
+ * Check whether "cp" is a valid ascii representation
+ * of an IPv6 address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ *
+ * @param cp IPv6 address in ascii representation (e.g. "FF01::1")
+ * @param addr pointer to which to save the ip address in network order
+ * @return 1 if cp could be converted to addr, 0 on failure
+ */
+int
+netdev_ip6addr_aton(const char *cp, ip6_addr_t *addr)
+{
+ uint32_t addr_index, zero_blocks, current_block_index, current_block_value;
+ const char *s;
+
+ /* Count the number of colons, to count the number of blocks in a "::" sequence
+ zero_blocks may be 1 even if there are no :: sequences */
+ zero_blocks = 8;
+ for (s = cp; *s != 0; s++)
+ {
+ if (*s == ':')
+ {
+ zero_blocks--;
+ }
+ else if (!isxdigit(*s))
+ {
+ break;
+ }
+ }
+
+ /* parse each block */
+ addr_index = 0;
+ current_block_index = 0;
+ current_block_value = 0;
+ for (s = cp; *s != 0; s++)
+ {
+ if (*s == ':')
+ {
+ if (addr)
+ {
+ if (current_block_index & 0x1)
+ {
+ addr->addr[addr_index++] |= current_block_value;
+ }
+ else
+ {
+ addr->addr[addr_index] = current_block_value << 16;
+ }
+ }
+ current_block_index++;
+ current_block_value = 0;
+ if (current_block_index > 7)
+ {
+ /* address too long! */
+ return 0;
+ }
+ if (s[1] == ':')
+ {
+ if (s[2] == ':')
+ {
+ /* invalid format: three successive colons */
+ return 0;
+ }
+ s++;
+ /* "::" found, set zeros */
+ while (zero_blocks > 0)
+ {
+ zero_blocks--;
+ if (current_block_index & 0x1)
+ {
+ addr_index++;
+ }
+ else
+ {
+ if (addr)
+ {
+ addr->addr[addr_index] = 0;
+ }
+ }
+ current_block_index++;
+ if (current_block_index > 7)
+ {
+ /* address too long! */
+ return 0;
+ }
+ }
+ }
+ }
+ else if (isxdigit(*s))
+ {
+ /* add current digit */
+ current_block_value = (current_block_value << 4) +
+ (isdigit(*s) ? (uint32_t)(*s - '0') : (uint32_t)(10 + (islower(*s) ? *s - 'a' : *s - 'A')));
+ }
+ else
+ {
+ /* unexpected digit, space? CRLF? */
+ break;
+ }
+ }
+
+ if (addr)
+ {
+ if (current_block_index & 0x1)
+ {
+ addr->addr[addr_index++] |= current_block_value;
+ }
+ else
+ {
+ addr->addr[addr_index] = current_block_value << 16;
+ }
+ }
+
+ /* convert to network byte order. */
+ if (addr)
+ {
+ for (addr_index = 0; addr_index < 4; addr_index++)
+ {
+ addr->addr[addr_index] = htonl(addr->addr[addr_index]);
+ }
+ }
+
+ if (current_block_index != 7)
+ {
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
+ * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used.
+ *
+ * @param addr ip6 address in network order to convert
+ * @param buf target buffer where the string is stored
+ * @param buflen length of buf
+ * @return either pointer to buf which now holds the ASCII
+ * representation of addr or NULL if buf was too small
+ */
+char *
+netdev_ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen)
+{
+ uint32_t current_block_index, current_block_value, next_block_value;
+ int32_t i;
+ uint8_t zero_flag, empty_block_flag;
+
+ i = 0;
+ empty_block_flag = 0; /* used to indicate a zero chain for "::' */
+
+ for (current_block_index = 0; current_block_index < 8; current_block_index++)
+ {
+ /* get the current 16-bit block */
+ current_block_value = htonl(addr->addr[current_block_index >> 1]);
+ if ((current_block_index & 0x1) == 0)
+ {
+ current_block_value = current_block_value >> 16;
+ }
+ current_block_value &= 0xffff;
+
+ /* Check for empty block. */
+ if (current_block_value == 0)
+ {
+ if (current_block_index == 7 && empty_block_flag == 1)
+ {
+ /* special case, we must render a ':' for the last block. */
+ buf[i++] = ':';
+ if (i >= buflen)
+ {
+ return NULL;
+ }
+ break;
+ }
+ if (empty_block_flag == 0)
+ {
+ /* generate empty block "::", but only if more than one contiguous zero block,
+ * according to current formatting suggestions RFC 5952. */
+ next_block_value = htonl(addr->addr[(current_block_index + 1) >> 1]);
+ if ((current_block_index & 0x1) == 0x01)
+ {
+ next_block_value = next_block_value >> 16;
+ }
+ next_block_value &= 0xffff;
+ if (next_block_value == 0)
+ {
+ empty_block_flag = 1;
+ buf[i++] = ':';
+ if (i >= buflen)
+ {
+ return NULL;
+ }
+ continue; /* move on to next block. */
+ }
+ }
+ else if (empty_block_flag == 1)
+ {
+ /* move on to next block. */
+ continue;
+ }
+ }
+ else if (empty_block_flag == 1)
+ {
+ /* Set this flag value so we don't produce multiple empty blocks. */
+ empty_block_flag = 2;
+ }
+
+ if (current_block_index > 0)
+ {
+ buf[i++] = ':';
+ if (i >= buflen)
+ {
+ return NULL;
+ }
+ }
+
+ if ((current_block_value & 0xf000) == 0)
+ {
+ zero_flag = 1;
+ }
+ else
+ {
+ buf[i++] = xchar(((current_block_value & 0xf000) >> 12));
+ zero_flag = 0;
+ if (i >= buflen)
+ {
+ return NULL;
+ }
+ }
+
+ if (((current_block_value & 0xf00) == 0) && (zero_flag))
+ {
+ /* do nothing */
+ }
+ else
+ {
+ buf[i++] = xchar(((current_block_value & 0xf00) >> 8));
+ zero_flag = 0;
+ if (i >= buflen)
+ {
+ return NULL;
+ }
+ }
+
+ if (((current_block_value & 0xf0) == 0) && (zero_flag))
+ {
+ /* do nothing */
+ }
+ else
+ {
+ buf[i++] = xchar(((current_block_value & 0xf0) >> 4));
+ zero_flag = 0;
+ if (i >= buflen)
+ {
+ return NULL;
+ }
+ }
+
+ buf[i++] = xchar((current_block_value & 0xf));
+ if (i >= buflen)
+ {
+ return NULL;
+ }
+ }
+
+ buf[i] = 0;
+
+ return buf;
+}
+
+/**
+ * Convert numeric IPv6 address into ASCII representation.
+ * returns ptr to static buffer; not reentrant!
+ *
+ * @param addr ip6 address in network order to convert
+ * @return pointer to a global static (!) buffer that holds the ASCII
+ * representation of addr
+ */
+char *
+netdev_ip6addr_ntoa(const ip6_addr_t *addr)
+{
+ static char str[40];
+ return netdev_ip6addr_ntoa_r(addr, str, 40);
+}
+
+#endif /* NETDEV_IPV6 */
+
+const char *
+netdev_inet_ntop(int af, const void *src, char *dst, int32_t size)
+{
+#define AF_INET 2
+#define AF_INET6 10
+
+ const char *ret = NULL;
+ int size_int = (int)size;
+ if (size_int < 0)
+ {
+ return NULL;
+ }
+ switch (af)
+ {
+#if NTEDEV_IPV4
+ case AF_INET:
+ return netdev_ip4addr_ntoa_r((const ip4_addr_t *)src, dst, size_int);
+#endif
+#if NETDEV_IPV6
+ case AF_INET6:
+ return netdev_ip6addr_ntoa_r((const ip6_addr_t *)src, dst, size_int);
+#endif
+ default:
+ break;
+ }
+ return ret;
+}
+
+int
+netdev_inet_pton(int af, const char *src, void *dst)
+{
+#define AF_INET 2
+#define AF_INET6 10
+
+ int err;
+ switch (af)
+ {
+#if NETDEV_IPV4
+ case AF_INET:
+ err = netdev_ip4addr_aton(src, (ip4_addr_t *)dst);
+ break;
+#endif
+#if NETDEV_IPV6
+ case AF_INET6:
+ {
+ /* convert into temporary variable since ip6_addr_t might be larger
+ than in6_addr when scopes are enabled */
+ ip6_addr_t addr;
+ err = netdev_ip6addr_aton(src, &addr);
+ if (err)
+ {
+ rt_memcpy(dst, &addr.addr, sizeof(addr.addr));
+ }
+ break;
+ }
+#endif
+ default:
+ err = -1;
+ break;
+ }
+ return err;
+}
diff --git a/components/net/sal_socket/impl/af_inet_lwip.c b/components/net/sal_socket/impl/af_inet_lwip.c
index 95e7633635..56df735ab9 100644
--- a/components/net/sal_socket/impl/af_inet_lwip.c
+++ b/components/net/sal_socket/impl/af_inet_lwip.c
@@ -25,6 +25,12 @@
#include <netdev.h>
+#if (LWIP_VERSION < 0x2000000) && NETDEV_IPV6
+#error "The lwIP version is not support IPV6, please disable netdev IPV6 configuration "
+#elif (LWIP_VERSION > 0x2000000) && (NETDEV_IPV6 != LWIP_IPV6)
+#error "IPV6 configuration error, Please check and synchronize netdev and lwip IPV6 configuration."
+#endif
+
#if LWIP_VERSION < 0x2000000
#define SELWAIT_T int
#else
@@ -267,6 +273,8 @@ static int inet_poll(struct dfs_fd *file, struct rt_pollreq *req)
if (sock->errevent)
{
mask |= POLLERR;
+ /* clean error event */
+ sock->errevent = 0;
}
rt_hw_interrupt_enable(level);
}
@@ -308,7 +316,11 @@ static const struct sal_netdb_ops lwip_netdb_ops =
static const struct sal_proto_family lwip_inet_family =
{
AF_INET,
+#if LWIP_VERSION > 0x2000000
+ AF_INET6,
+#else
AF_INET,
+#endif
&lwip_socket_ops,
&lwip_netdb_ops,
};
diff --git a/components/net/sal_socket/include/sal_socket.h b/components/net/sal_socket/include/sal_socket.h
index d72f1e4c3c..b620bbe23c 100644
--- a/components/net/sal_socket/include/sal_socket.h
+++ b/components/net/sal_socket/include/sal_socket.h
@@ -157,6 +157,7 @@ struct sockaddr
char sa_data[14];
};
+#if NETDEV_IPV4
/* members are in network byte order */
struct sockaddr_in
{
@@ -167,6 +168,19 @@ struct sockaddr_in
#define SIN_ZERO_LEN 8
char sin_zero[SIN_ZERO_LEN];
};
+#endif /* NETDEV_IPV4 */
+
+#if NETDEV_IPV6
+struct sockaddr_in6
+{
+ uint8_t sin6_len; /* length of this structure */
+ sa_family_t sin6_family; /* AF_INET6 */
+ in_port_t sin6_port; /* Transport layer port # */
+ uint32_t sin6_flowinfo; /* IPv6 flow information */
+ struct in6_addr sin6_addr; /* IPv6 address */
+ uint32_t sin6_scope_id; /* Set of interfaces for scope */
+};
+#endif /* NETDEV_IPV6 */
struct sockaddr_storage
{
@@ -174,9 +188,9 @@ struct sockaddr_storage
sa_family_t ss_family;
char s2_data1[2];
uint32_t s2_data2[3];
-#if SAL_IPV6
- u32_t s2_data3[3];
-#endif /* SAL_IPV6 */
+#if NETDEV_IPV6
+ uint32_t s2_data3[3];
+#endif /* NETDEV_IPV6 */
};
int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen);
diff --git a/components/net/sal_socket/socket/net_sockets.c b/components/net/sal_socket/socket/net_sockets.c
index 12024c8173..a53b2f1f9c 100644
--- a/components/net/sal_socket/socket/net_sockets.c
+++ b/components/net/sal_socket/socket/net_sockets.c
@@ -105,9 +105,7 @@ int shutdown(int s, int how)
rt_set_errno(-ENOTSOCK);
error = -1;
}
-
- /* socket has been closed, delete it from file system fd */
- fd_put(d);
+
fd_put(d);
return error;
diff --git a/components/net/sal_socket/src/sal_socket.c b/components/net/sal_socket/src/sal_socket.c
index 8f3149abd5..e5c55f8bf8 100644
--- a/components/net/sal_socket/src/sal_socket.c
+++ b/components/net/sal_socket/src/sal_socket.c
@@ -94,12 +94,12 @@ do {
* SAL (Socket Abstraction Layer) initialize.
*
* @return result 0: initialize success
- * -1: initialize failed
+ * -1: initialize failed
*/
int sal_init(void)
{
int cn;
-
+
if (init_ok)
{
LOG_D("Socket Abstraction Layer is already initialized.");
@@ -115,7 +115,7 @@ int sal_init(void)
LOG_E("No memory for socket table.\n");
return -1;
}
-
+
/* create sal socket lock */
rt_mutex_init(&sal_core_lock, "sal_lock", RT_IPC_FLAG_FIFO);
@@ -131,7 +131,7 @@ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data)
{
#define SAL_INTERNET_VERSION 0x00
#define SAL_INTERNET_BUFF_LEN 12
-#define SAL_INTERNET_TIMEOUT (2 * RT_TICK_PER_SECOND)
+#define SAL_INTERNET_TIMEOUT (2)
#define SAL_INTERNET_HOST "link.rt-thread.org"
#define SAL_INTERNET_PORT 8101
@@ -148,7 +148,7 @@ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data)
char send_data[SAL_INTERNET_BUFF_LEN], recv_data = 0;
struct rt_delayed_work *delay_work = (struct rt_delayed_work *)work;
- const char month[][SAL_INTERNET_MONTH_LEN] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
+ const char month[][SAL_INTERNET_MONTH_LEN] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
char date[SAL_INTERNET_DATE_LEN];
int moth_num = 0;
@@ -175,7 +175,7 @@ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data)
}
skt_ops = pf->skt_ops;
- if((sockfd = skt_ops->socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ if ((sockfd = skt_ops->socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
result = -RT_ERROR;
goto __exit;
@@ -224,7 +224,7 @@ static void check_netdev_internet_up_work(struct rt_work *work, void *work_data)
send_data[11] = RT_REVISION;
skt_ops->sendto(sockfd, send_data, SAL_INTERNET_BUFF_LEN, 0,
- (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
+ (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
result = skt_ops->recvfrom(sockfd, &recv_data, sizeof(recv_data), 0, (struct sockaddr *)&server_addr, &addr_len);
if (result < 0)
@@ -242,7 +242,7 @@ __exit:
if (result > 0)
{
LOG_D("Set network interface device(%s) internet status up.", netdev->name);
- netdev->flags |= NETDEV_FLAG_INTERNET_UP;
+ netdev->flags |= NETDEV_FLAG_INTERNET_UP;
}
else
{
@@ -277,7 +277,7 @@ int sal_check_netdev_internet_up(struct netdev *netdev)
rt_delayed_work_init(net_work, check_netdev_internet_up_work, (void *)netdev);
rt_work_submit(&(net_work->work), RT_TICK_PER_SECOND);
-
+
return 0;
}
@@ -316,10 +316,7 @@ struct sal_socket *sal_get_socket(int socket)
socket = socket - SAL_SOCKET_OFFSET;
/* check socket structure valid or not */
- if (st->sockets[socket]->magic != SAL_SOCKET_MAGIC)
- {
- return RT_NULL;
- }
+ RT_ASSERT(st->sockets[socket]->magic == SAL_SOCKET_MAGIC);
return st->sockets[socket];
}
@@ -351,6 +348,38 @@ static void sal_unlock(void)
}
/**
+ * This function will clean the netdev.
+ *
+ * @note please don't invoke it on ISR.
+ */
+int sal_netdev_cleanup(struct netdev *netdev)
+{
+ int idx = 0, find_dev;
+
+ do
+ {
+ find_dev = 0;
+ sal_lock();
+ for (idx = 0; idx < socket_table.max_socket; idx++)
+ {
+ if (socket_table.sockets[idx] && socket_table.sockets[idx]->netdev == netdev)
+ {
+ find_dev = 1;
+ break;
+ }
+ }
+ sal_unlock();
+ if (find_dev)
+ {
+ rt_thread_mdelay(100);
+ }
+ }
+ while (find_dev);
+
+ return 0;
+}
+
+/**
* This function will initialize sal socket object and set socket options
*
* @param family protocol family
@@ -397,7 +426,7 @@ static int socket_init(int family, int type, int protocol, struct sal_socket **r
flag = RT_TRUE;
}
}
-
+
if (flag == RT_FALSE)
{
/* get network interface device by protocol family */
@@ -421,8 +450,7 @@ static int socket_alloc(struct sal_socket_table *st, int f_socket)
/* find an empty socket entry */
for (idx = f_socket; idx < (int) st->max_socket; idx++)
{
- if (st->sockets[idx] == RT_NULL ||
- st->sockets[idx]->netdev == RT_NULL)
+ if (st->sockets[idx] == RT_NULL)
{
break;
}
@@ -466,6 +494,15 @@ __result:
return idx;
}
+static void socket_free(struct sal_socket_table *st, int idx)
+{
+ struct sal_socket *sock;
+
+ sock = st->sockets[idx];
+ st->sockets[idx] = RT_NULL;
+ rt_free(sock);
+}
+
static int socket_new(void)
{
struct sal_socket *sock;
@@ -498,18 +535,38 @@ __result:
return idx + SAL_SOCKET_OFFSET;
}
+static void socket_delete(int socket)
+{
+ struct sal_socket *sock;
+ struct sal_socket_table *st = &socket_table;
+ int idx;
+
+ idx = socket - SAL_SOCKET_OFFSET;
+ if (idx < 0 || idx >= (int) st->max_socket)
+ {
+ return;
+ }
+ sal_lock();
+ sock = sal_get_socket(socket);
+ RT_ASSERT(sock != RT_NULL);
+ sock->magic = 0;
+ sock->netdev = RT_NULL;
+ socket_free(st, idx);
+ sal_unlock();
+}
+
int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen)
{
int new_socket;
struct sal_socket *sock;
- struct sal_proto_family *pf;
+ struct sal_proto_family *pf;
/* get the socket object by socket descriptor */
SAL_SOCKET_OBJ_GET(sock, socket);
/* check the network interface socket operations */
SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, accept);
-
+
new_socket = pf->skt_ops->accept((int) sock->user_data, addr, addrlen);
if (new_socket != -1)
{
@@ -519,18 +576,20 @@ int sal_accept(int socket, struct sockaddr *addr, socklen_t *addrlen)
/* allocate a new socket structure and registered socket options */
new_sal_socket = socket_new();
- if (new_sal_socket < 0)
+ new_sock = sal_get_socket(new_sal_socket);
+ if (new_sock == RT_NULL)
{
pf->skt_ops->closesocket(new_socket);
return -1;
}
- new_sock = sal_get_socket(new_sal_socket);
retval = socket_init(sock->domain, sock->type, sock->protocol, &new_sock);
if (retval < 0)
{
pf->skt_ops->closesocket(new_socket);
rt_memset(new_sock, 0x00, sizeof(struct sal_socket));
+ /* socket init failed, delete socket */
+ socket_delete(new_sal_socket);
LOG_E("New socket registered failed, return error %d.", retval);
return -1;
}
@@ -549,20 +608,20 @@ static void sal_sockaddr_to_ipaddr(const struct sockaddr *name, ip_addr_t *local
const struct sockaddr_in *svr_addr = (const struct sockaddr_in *) name;
#if NETDEV_IPV4 && NETDEV_IPV6
- (*local_ipaddr).u_addr.ip4.addr = svr_addr->sin_addr.s_addr;
+ local_ipaddr->u_addr.ip4.addr = svr_addr->sin_addr.s_addr;
+ local_ipaddr->type = IPADDR_TYPE_V4;
#elif NETDEV_IPV4
- (*local_ipaddr).addr = svr_addr->sin_addr.s_addr;
+ local_ipaddr->addr = svr_addr->sin_addr.s_addr;
#elif NETDEV_IPV6
- LOG_E("not support IPV6");
-#endif /* SAL_IPV4 && SAL_IPV6*/
-}
+#error "not only support IPV6"
+#endif /* NETDEV_IPV4 && NETDEV_IPV6*/
+}
int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen)
{
struct sal_socket *sock;
struct sal_proto_family *pf;
- struct netdev *new_netdev;
- ip_addr_t local_addr;
+ ip_addr_t input_ipaddr;
RT_ASSERT(name);
@@ -570,44 +629,43 @@ int sal_bind(int socket, const struct sockaddr *name, socklen_t namelen)
SAL_SOCKET_OBJ_GET(sock, socket);
/* bind network interface by ip address */
- sal_sockaddr_to_ipaddr(name, &local_addr);
+ sal_sockaddr_to_ipaddr(name, &input_ipaddr);
/* check input ipaddr is default netdev ipaddr */
- if (local_addr.addr == INADDR_ANY)
+ if (!ip_addr_isany_val(input_ipaddr))
{
- SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, bind);
- return pf->skt_ops->bind((int) sock->user_data, name, namelen);
- }
-
- new_netdev = netdev_get_by_ipaddr(&local_addr);
- if (new_netdev == RT_NULL)
- {
- LOG_E("Not find network interface device ipaddr(%s).", inet_ntoa(local_addr));
- return -1;
- }
+ struct sal_proto_family *input_pf = RT_NULL, *local_pf = RT_NULL;
+ struct netdev *new_netdev = RT_NULL;
- /* change network interface device parameter in sal socket object */
- if (sock->netdev != new_netdev)
- {
- struct sal_proto_family *old_pf, *new_pf;
- int new_socket = 0;
+ new_netdev = netdev_get_by_ipaddr(&input_ipaddr);
+ if (new_netdev == RT_NULL)
+ {
+ return -1;
+ }
- /* close old netdev socket */
- SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, old_pf, closesocket);
- old_pf->skt_ops->closesocket(socket);
+ /* get input and local ip address proto_family */
+ SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, local_pf, bind);
+ SAL_NETDEV_SOCKETOPS_VALID(new_netdev, input_pf, bind);
- /* open new netdev socket */
- SAL_NETDEV_SOCKETOPS_VALID(new_netdev, new_pf, socket);
- new_socket = new_pf->skt_ops->socket(sock->domain, sock->type, sock->protocol);
- if (new_socket < 0)
+ /* check the network interface protocol family type */
+ if (input_pf->family != local_pf->family)
{
- return -1;
+ int new_socket = -1;
+
+ /* protocol family is different, close old socket and create new socket by input ip address */
+ local_pf->skt_ops->closesocket(socket);
+
+ new_socket = input_pf->skt_ops->socket(input_pf->family, sock->type, sock->protocol);
+ if (new_socket < 0)
+ {
+ return -1;
+ }
+ sock->netdev = new_netdev;
+ sock->user_data = (void *) new_socket;
}
- sock->netdev = new_netdev;
- sock->user_data = (void *) new_socket;
}
- /* check the network interface socket opreation */
+ /* check and get protocol families by the network interface device */
SAL_NETDEV_SOCKETOPS_VALID(sock->netdev, pf, bind);
return pf->skt_ops->bind((int) sock->user_data, name, namelen);
}
@@ -643,9 +701,6 @@ int sal_shutdown(int socket, int how)
error = -1;
}
- /* free socket */
- rt_free(sock);
- socket_table.sockets[socket] = RT_NULL;
return error;
}
@@ -761,7 +816,7 @@ int sal_connect(int socket, const struct sockaddr *name, socklen_t namelen)
{
return -1;
}
-
+
return ret;
}
#endif
@@ -784,7 +839,7 @@ int sal_listen(int socket, int backlog)
}
int sal_recvfrom(int socket, void *mem, size_t len, int flags,
- struct sockaddr *from, socklen_t *fromlen)
+ struct sockaddr *from, socklen_t *fromlen)
{
struct sal_socket *sock;
struct sal_proto_family *pf;
@@ -801,11 +856,11 @@ int sal_recvfrom(int socket, void *mem, size_t len, int flags,
if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, recv))
{
int ret;
-
+
if ((ret = proto_tls->ops->recv(sock->user_data_tls, mem, len)) < 0)
{
return -1;
- }
+ }
return ret;
}
else
@@ -818,7 +873,7 @@ int sal_recvfrom(int socket, void *mem, size_t len, int flags,
}
int sal_sendto(int socket, const void *dataptr, size_t size, int flags,
- const struct sockaddr *to, socklen_t tolen)
+ const struct sockaddr *to, socklen_t tolen)
{
struct sal_socket *sock;
struct sal_proto_family *pf;
@@ -835,11 +890,11 @@ int sal_sendto(int socket, const void *dataptr, size_t size, int flags,
if (SAL_SOCKOPS_PROTO_TLS_VALID(sock, send))
{
int ret;
-
+
if ((ret = proto_tls->ops->send(sock->user_data_tls, dataptr, size)) < 0)
{
return -1;
- }
+ }
return ret;
}
else
@@ -877,6 +932,7 @@ int sal_socket(int domain, int type, int protocol)
if (retval < 0)
{
LOG_E("SAL socket protocol family input failed, return error %d.", retval);
+ socket_delete(socket);
return -1;
}
@@ -892,6 +948,7 @@ int sal_socket(int domain, int type, int protocol)
sock->user_data_tls = proto_tls->ops->socket(socket);
if (sock->user_data_tls == RT_NULL)
{
+ socket_delete(socket);
return -1;
}
}
@@ -934,9 +991,8 @@ int sal_closesocket(int socket)
error = -1;
}
- /* free socket */
- rt_free(sock);
- socket_table.sockets[socket] = RT_NULL;
+ /* delete socket */
+ socket_delete(socket);
return error;
}
@@ -997,7 +1053,7 @@ struct hostent *sal_gethostbyname(const char *name)
}
int sal_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
- size_t buflen, struct hostent **result, int *h_errnop)
+ size_t buflen, struct hostent **result, int *h_errnop)
{
struct netdev *netdev = netdev_default;
struct sal_proto_family *pf;
@@ -1020,9 +1076,9 @@ int sal_gethostbyname_r(const char *name, struct hostent *ret, char *buf,
}
int sal_getaddrinfo(const char *nodename,
- const char *servname,
- const struct addrinfo *hints,
- struct addrinfo **res)
+ const char *servname,
+ const struct addrinfo *hints,
+ struct addrinfo **res)
{
struct netdev *netdev = netdev_default;
struct sal_proto_family *pf;
diff --git a/components/utilities/Kconfig b/components/utilities/Kconfig
index 250239aea6..7fa6b47601 100644
--- a/components/utilities/Kconfig
+++ b/components/utilities/Kconfig
@@ -2,8 +2,15 @@ menu "Utilities"
config RT_USING_RYM
bool "Enable Ymodem"
+ depends on RT_USING_DFS = y
default n
+ if RT_USING_RYM
+ config YMODEM_DISABLE_CRC_TABLE
+ bool "Disable CRC Table"
+ default n
+ endif
+
config RT_USING_ULOG
bool "Enable ulog"
default n
@@ -146,7 +153,6 @@ config RT_USING_ULOG
config ULOG_TIME_USING_TIMESTAMP
bool "Enable timestamp format for time."
default n
- select RT_USING_LIBC
depends on ULOG_OUTPUT_TIME
config ULOG_OUTPUT_LEVEL
diff --git a/components/utilities/ulog/backend/console_be.c b/components/utilities/ulog/backend/console_be.c
index 04b0d91add..95dd547426 100644
--- a/components/utilities/ulog/backend/console_be.c
+++ b/components/utilities/ulog/backend/console_be.c
@@ -22,9 +22,9 @@ static struct ulog_backend console;
void ulog_console_backend_output(struct ulog_backend *backend, rt_uint32_t level, const char *tag, rt_bool_t is_raw,
const char *log, size_t len)
{
+#ifdef RT_USING_DEVICE
rt_device_t dev = rt_console_get_device();
-#ifdef RT_USING_DEVICE
if (dev == RT_NULL)
{
rt_hw_console_output(log);
diff --git a/components/utilities/ulog/ulog.c b/components/utilities/ulog/ulog.c
index 9af5fe5b9d..8a8d142eff 100644
--- a/components/utilities/ulog/ulog.c
+++ b/components/utilities/ulog/ulog.c
@@ -684,7 +684,7 @@ void ulog_hexdump(const char *tag, rt_size_t width, rt_uint8_t *buf, rt_size_t s
log_len = 6 + name_len + 2;
rt_memset(log_buf, ' ', log_len);
}
- fmt_result = rt_snprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE, "%04X-%04X: ", i, i + width);
+ fmt_result = rt_snprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE, "%04X-%04X: ", i, i + width - 1);
/* calculate log length */
if ((fmt_result > -1) && (fmt_result <= ULOG_LINE_BUF_SIZE))
{
diff --git a/components/utilities/utest/utest.c b/components/utilities/utest/utest.c
index f59f97bb64..6500ae2fbe 100644
--- a/components/utilities/utest/utest.c
+++ b/components/utilities/utest/utest.c
@@ -63,20 +63,20 @@ void utest_log_lv_set(rt_uint8_t lv)
int utest_init(void)
{
/* initialize the utest commands table.*/
-#if defined(__CC_ARM) /* ARM C Compiler */
+#if defined(__CC_ARM) || defined(__CLANG_ARM) /* ARM C Compiler */
extern const int UtestTcTab$$Base;
extern const int UtestTcTab$$Limit;
tc_table = (utest_tc_export_t)&UtestTcTab$$Base;
tc_num = (utest_tc_export_t)&UtestTcTab$$Limit - tc_table;
-#elif defined (__ICCARM__) || defined(__ICCRX__) /* for IAR Compiler */
+#elif defined (__ICCARM__) || defined(__ICCRX__) /* for IAR Compiler */
tc_table = (utest_tc_export_t)__section_begin("UtestTcTab");
tc_num = (utest_tc_export_t)__section_end("UtestTcTab") - tc_table;
-#elif defined (__GNUC__) /* for GCC Compiler */
+#elif defined (__GNUC__) /* for GCC Compiler */
extern const int __rt_utest_tc_tab_start;
extern const int __rt_utest_tc_tab_end;
tc_table = (utest_tc_export_t)&__rt_utest_tc_tab_start;
tc_num = (utest_tc_export_t) &__rt_utest_tc_tab_end - tc_table;
-#endif /* defined(__CC_ARM) */
+#endif
LOG_I("utest is initialize success.");
LOG_I("total utest testcase num: (%d)", tc_num);
@@ -215,7 +215,7 @@ static void utest_run(const char *utest_name)
i++;
}
- if (i == tc_num && is_find == RT_FALSE)
+ if (i == tc_num && is_find == RT_FALSE && utest_name != RT_NULL)
{
LOG_I("[==========] [ utest ] Not find (%s)", utest_name);
LOG_I("[==========] [ utest ] finished");
diff --git a/components/utilities/utest/utest.h b/components/utilities/utest/utest.h
index 386d177a77..2c91bfe0e1 100644
--- a/components/utilities/utest/utest.h
+++ b/components/utilities/utest/utest.h
@@ -15,6 +15,10 @@
#include "utest_log.h"
#include "utest_assert.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* utest_error
*
@@ -157,4 +161,8 @@ utest_t utest_handle_get(void);
utest_unit_run(test_unit_func, #test_unit_func); \
if(utest_handle_get()->failed_num != 0) return;
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __UTEST_H__ */
diff --git a/components/utilities/utest/utest_assert.h b/components/utilities/utest/utest_assert.h
index 9c620c689d..d83279272e 100644
--- a/components/utilities/utest/utest_assert.h
+++ b/components/utilities/utest/utest_assert.h
@@ -14,6 +14,10 @@
#include "utest.h"
#include <rtthread.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* No need for the user to use this function directly */
void utest_assert(int value, const char *file, int line, const char *func, const char *msg);
@@ -61,4 +65,8 @@ void utest_assert_buf(const char *a, const char *b, rt_size_t sz, rt_bool_t equa
#define uassert_in_range(value, min, max) __utest_assert(((value >= min) && (value <= max)), "(" #value ") not in range("#min","#max")")
#define uassert_not_in_range(value, min, max) __utest_assert(!((value >= min) && (value <= max)), "(" #value ") in range("#min","#max")")
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __UTEST_ASSERT_H__ */
diff --git a/components/utilities/ymodem/ry_sy.c b/components/utilities/ymodem/ry_sy.c
new file mode 100644
index 0000000000..fa57b8553a
--- /dev/null
+++ b/components/utilities/ymodem/ry_sy.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-12-09 Steven Liu the first version
+ */
+
+#include <rtthread.h>
+#include <ymodem.h>
+#include <dfs_posix.h>
+#include <stdlib.h>
+#include <board.h>
+#include <string.h>
+
+struct custom_ctx
+{
+ struct rym_ctx parent;
+ int fd;
+ int flen;
+ char fpath[DFS_PATH_MAX];
+};
+
+static enum rym_code _rym_recv_begin(
+ struct rym_ctx *ctx,
+ rt_uint8_t *buf,
+ rt_size_t len)
+{
+ struct custom_ctx *cctx = (struct custom_ctx *)ctx;
+
+ cctx->fpath[0] = '/';
+ rt_strncpy(&(cctx->fpath[1]), (const char *)buf, len - 1);
+ cctx->fd = open(cctx->fpath, O_CREAT | O_WRONLY | O_TRUNC, 0);
+ if (cctx->fd < 0)
+ {
+ rt_err_t err = rt_get_errno();
+ rt_kprintf("error creating file: %d\n", err);
+ return RYM_CODE_CAN;
+ }
+ cctx->flen = atoi((const char *)buf + rt_strnlen((const char *)buf, len - 1));
+ if (cctx->flen == 0)
+ cctx->flen = -1;
+
+ return RYM_CODE_ACK;
+}
+
+static enum rym_code _rym_recv_data(
+ struct rym_ctx *ctx,
+ rt_uint8_t *buf,
+ rt_size_t len)
+{
+ struct custom_ctx *cctx = (struct custom_ctx *)ctx;
+
+ RT_ASSERT(cctx->fd >= 0);
+ if (cctx->flen == -1)
+ {
+ write(cctx->fd, buf, len);
+ }
+ else
+ {
+ int wlen = len > cctx->flen ? cctx->flen : len;
+ write(cctx->fd, buf, wlen);
+ cctx->flen -= wlen;
+ }
+
+ return RYM_CODE_ACK;
+}
+
+static enum rym_code _rym_recv_end(
+ struct rym_ctx *ctx,
+ rt_uint8_t *buf,
+ rt_size_t len)
+{
+ struct custom_ctx *cctx = (struct custom_ctx *)ctx;
+
+ RT_ASSERT(cctx->fd >= 0);
+ close(cctx->fd);
+ cctx->fd = -1;
+
+ return RYM_CODE_ACK;
+}
+
+static enum rym_code _rym_send_begin(
+ struct rym_ctx *ctx,
+ rt_uint8_t *buf,
+ rt_size_t len)
+{
+ struct custom_ctx *cctx = (struct custom_ctx *)ctx;
+ struct stat file_buf;
+ char insert_0 = '\0';
+ rt_err_t err;
+
+ cctx->fd = open(cctx->fpath, O_RDONLY);
+ if (cctx->fd < 0)
+ {
+ err = rt_get_errno();
+ rt_kprintf("error open file: %d\n", err);
+ return RYM_ERR_FILE;
+ }
+ rt_memset(buf, 0, len);
+ err = stat(cctx->fpath, &file_buf);
+ if (err != RT_EOK)
+ {
+ rt_kprintf("error open file.\n");
+ return RYM_ERR_FILE;
+ }
+ sprintf((char *)buf, "%s%c%ld", (char *) & (cctx->fpath[1]), insert_0, file_buf.st_size);
+
+ return RYM_CODE_SOH;
+}
+
+static enum rym_code _rym_send_data(
+ struct rym_ctx *ctx,
+ rt_uint8_t *buf,
+ rt_size_t len)
+{
+ struct custom_ctx *cctx = (struct custom_ctx *)ctx;
+ rt_size_t read_size;
+ int retry_read;
+
+ read_size = 0;
+ for (retry_read = 0; retry_read < 10; retry_read++)
+ {
+ read_size += read(cctx->fd, buf + read_size, len - read_size);
+ if (read_size == len)
+ break;
+ }
+
+ if (read_size < len)
+ {
+ rt_memset(buf + read_size, 0x1A, len - read_size);
+ /* stage = RYM_STAGE_FINISHING */
+ ctx->stage = 4;
+ }
+
+ return RYM_CODE_SOH;
+}
+
+static enum rym_code _rym_send_end(
+ struct rym_ctx *ctx,
+ rt_uint8_t *buf,
+ rt_size_t len)
+{
+ rt_memset(buf, 0, len);
+
+ return RYM_CODE_SOH;
+}
+
+static rt_err_t rym_download_file(rt_device_t idev)
+{
+ rt_err_t res;
+ struct custom_ctx *ctx = rt_calloc(1, sizeof(*ctx));
+
+ if (!ctx)
+ {
+ rt_kprintf("rt_malloc failed\n");
+ return RT_ENOMEM;
+ }
+ ctx->fd = -1;
+ RT_ASSERT(idev);
+ res = rym_recv_on_device(&ctx->parent, idev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+ _rym_recv_begin, _rym_recv_data, _rym_recv_end, 1000);
+ rt_free(ctx);
+
+ return res;
+}
+
+static rt_err_t rym_upload_file(rt_device_t idev, const char *file_path)
+{
+ rt_err_t res = 0;
+
+ struct custom_ctx *ctx = rt_calloc(1, sizeof(*ctx));
+ if (!ctx)
+ {
+ rt_kprintf("rt_malloc failed\n");
+ return RT_ENOMEM;
+ }
+ ctx->fd = -1;
+ rt_strncpy(ctx->fpath, file_path, DFS_PATH_MAX);
+ RT_ASSERT(idev);
+ res = rym_send_on_device(&ctx->parent, idev,
+ RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+ _rym_send_begin, _rym_send_data, _rym_send_end, 1000);
+ rt_free(ctx);
+
+ return res;
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+
+static rt_err_t ry(uint8_t argc, char **argv)
+{
+ rt_err_t res;
+ rt_device_t dev;
+
+ if (argc > 1)
+ dev = rt_device_find(argv[1]);
+ else
+ dev = rt_console_get_device();
+ if (!dev)
+ {
+ rt_kprintf("could not find device.\n");
+ return -RT_ERROR;
+ }
+ res = rym_download_file(dev);
+
+ return res;
+}
+MSH_CMD_EXPORT(ry, YMODEM Receive e.g: ry [uart0] default by console.);
+
+static rt_err_t sy(uint8_t argc, char **argv)
+{
+ rt_err_t res;
+ /* temporarily support 1 file*/
+ const char *file_path;
+ rt_device_t dev;
+
+ if (argc > 2)
+ dev = rt_device_find(argv[2]);
+ else
+ dev = rt_console_get_device();
+ if (!dev)
+ {
+ rt_kprintf("could not find device.\n");
+ return -RT_ERROR;
+ }
+ file_path = argv[1];
+ res = rym_upload_file(dev, file_path);
+
+ return res;
+}
+MSH_CMD_EXPORT(sy, YMODEM Send e.g: sy file_path [uart0] default by console.);
+
+#endif /* RT_USING_FINSH */
diff --git a/components/utilities/ymodem/ymodem.c b/components/utilities/ymodem/ymodem.c
index 716c702328..0214845303 100644
--- a/components/utilities/ymodem/ymodem.c
+++ b/components/utilities/ymodem/ymodem.c
@@ -7,12 +7,15 @@
* Change Logs:
* Date Author Notes
* 2013-04-14 Grissiom initial implementation
+ * 2019-12-09 Steven Liu add YMODEM send protocol
*/
#include <rthw.h>
#include "ymodem.h"
-static const rt_uint16_t ccitt_table[256] = {
+#ifndef YMODEM_DISABLE_CRC_TABLE
+static const rt_uint16_t ccitt_table[256] =
+{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
@@ -46,7 +49,7 @@ static const rt_uint16_t ccitt_table[256] = {
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
-rt_uint16_t CRC16(unsigned char *q, int len)
+static rt_uint16_t CRC16(unsigned char *q, int len)
{
rt_uint16_t crc = 0;
@@ -54,6 +57,30 @@ rt_uint16_t CRC16(unsigned char *q, int len)
crc = (crc << 8) ^ ccitt_table[((crc >> 8) ^ *q++) & 0xff];
return crc;
}
+#else
+static rt_uint16_t CRC16(unsigned char *q, int len)
+{
+ rt_uint16_t crc;
+ char i;
+
+ crc = 0;
+ while (--len >= 0)
+ {
+ crc = crc ^ (int) * q++ << 8;
+ i = 8;
+ do
+ {
+ if (crc & 0x8000)
+ crc = crc << 1 ^ 0x1021;
+ else
+ crc = crc << 1;
+ }
+ while (--i);
+ }
+
+ return (crc);
+}
+#endif
// we could only use global varible because we could not use
// rt_device_t->user_data(it is used by the serial driver)...
@@ -69,15 +96,16 @@ static rt_err_t _rym_rx_ind(rt_device_t dev, rt_size_t size)
#define _RYM_STX_PKG_SZ (1+2+1024+2)
static enum rym_code _rym_read_code(
- struct rym_ctx *ctx,
- rt_tick_t timeout)
+ struct rym_ctx *ctx,
+ rt_tick_t timeout)
{
/* Fast path */
if (rt_device_read(ctx->dev, 0, ctx->buf, 1) == 1)
return (enum rym_code)(*ctx->buf);
/* Slow path */
- do {
+ do
+ {
rt_size_t rsz;
/* No data yet, wait for one */
@@ -88,13 +116,14 @@ static enum rym_code _rym_read_code(
rsz = rt_device_read(ctx->dev, 0, ctx->buf, 1);
if (rsz == 1)
return (enum rym_code)(*ctx->buf);
- } while (1);
+ }
+ while (1);
}
/* the caller should at least alloc _RYM_STX_PKG_SZ buffer */
static rt_size_t _rym_read_data(
- struct rym_ctx *ctx,
- rt_size_t len)
+ struct rym_ctx *ctx,
+ rt_size_t len)
{
/* we should already have had the code */
rt_uint8_t *buf = ctx->buf + 1;
@@ -103,23 +132,61 @@ static rt_size_t _rym_read_data(
do
{
readlen += rt_device_read(ctx->dev,
- 0, buf+readlen, len-readlen);
+ 0, buf + readlen, len - readlen);
if (readlen >= len)
return readlen;
- } while (rt_sem_take(&ctx->sem, RYM_WAIT_CHR_TICK) == RT_EOK);
+ }
+ while (rt_sem_take(&ctx->sem, RYM_WAIT_CHR_TICK) == RT_EOK);
return readlen;
}
+static rt_err_t _rym_send_packet(
+ struct rym_ctx *ctx,
+ enum rym_code code,
+ rt_uint8_t index)
+{
+ rt_uint16_t send_crc;
+ rt_uint8_t index_inv = ~index;
+ rt_size_t writelen = 0;
+
+ send_crc = CRC16(ctx->buf + 3, _RYM_SOH_PKG_SZ - 5);
+ ctx->buf[0] = code;
+ ctx->buf[1] = index;
+ ctx->buf[2] = index_inv;
+ ctx->buf[131] = (rt_uint8_t)(send_crc >> 8);
+ ctx->buf[132] = (rt_uint8_t)send_crc & 0xff;
+
+ do
+ {
+ writelen += rt_device_write(ctx->dev, 0, ctx->buf + writelen,
+ _RYM_SOH_PKG_SZ - writelen);
+ }
+ while (writelen < _RYM_SOH_PKG_SZ);
+
+ return RT_EOK;
+}
+
static rt_size_t _rym_putchar(struct rym_ctx *ctx, rt_uint8_t code)
{
rt_device_write(ctx->dev, 0, &code, sizeof(code));
return 1;
}
+static rt_size_t _rym_getchar(struct rym_ctx *ctx)
+{
+ rt_uint8_t getc_ack;
+
+ while (rt_device_read(ctx->dev, 0, &getc_ack, 1) != 1)
+ {
+ rt_sem_take(&ctx->sem, RT_WAITING_FOREVER);
+ }
+ return getc_ack;
+}
+
static rt_err_t _rym_do_handshake(
- struct rym_ctx *ctx,
- int tm_sec)
+ struct rym_ctx *ctx,
+ int tm_sec)
{
enum rym_code code;
rt_size_t i;
@@ -133,13 +200,13 @@ static rt_err_t _rym_do_handshake(
{
_rym_putchar(ctx, RYM_CODE_C);
code = _rym_read_code(ctx,
- RYM_CHD_INTV_TICK);
+ RYM_CHD_INTV_TICK);
if (code == RYM_CODE_SOH)
{
data_sz = _RYM_SOH_PKG_SZ;
break;
}
- else if(code == RYM_CODE_STX)
+ else if (code == RYM_CODE_STX)
{
data_sz = _RYM_STX_PKG_SZ;
break;
@@ -154,7 +221,7 @@ static rt_err_t _rym_do_handshake(
i = 0;
/* automatic exit after receiving specified length data, timeout: 100ms */
tick = rt_tick_get();
- while (rt_tick_get() <= (tick + rt_tick_from_millisecond(100)) && i < (data_sz-1))
+ while (rt_tick_get() <= (tick + rt_tick_from_millisecond(100)) && i < (data_sz - 1))
{
i += _rym_read_data(ctx, data_sz - 1);
rt_thread_mdelay(5);
@@ -167,24 +234,79 @@ static rt_err_t _rym_do_handshake(
if (ctx->buf[1] != 0 || ctx->buf[2] != 0xFF)
return -RYM_ERR_SEQ;
- recv_crc = (rt_uint16_t)(*(ctx->buf+data_sz-2) << 8) | *(ctx->buf+data_sz-1);
- cal_crc = CRC16(ctx->buf+3, data_sz-5);
+ recv_crc = (rt_uint16_t)(*(ctx->buf + data_sz - 2) << 8) | *(ctx->buf + data_sz - 1);
+ cal_crc = CRC16(ctx->buf + 3, data_sz - 5);
if (recv_crc != cal_crc)
return -RYM_ERR_CRC;
/* congratulations, check passed. */
- if (ctx->on_begin && ctx->on_begin(ctx, ctx->buf+3, data_sz-5) != RYM_CODE_ACK)
+ if (ctx->on_begin && ctx->on_begin(ctx, ctx->buf + 3, data_sz - 5) != RYM_CODE_ACK)
return -RYM_ERR_CAN;
return RT_EOK;
}
+static rt_err_t _rym_do_send_handshake(
+ struct rym_ctx *ctx,
+ int tm_sec)
+{
+ enum rym_code code;
+ rt_size_t i;
+ rt_size_t data_sz;
+ rt_uint8_t index = 0;
+ rt_uint8_t getc_ack;
+
+ ctx->stage = RYM_STAGE_ESTABLISHING;
+ data_sz = _RYM_SOH_PKG_SZ;
+
+ /* receive C every second */
+ for (i = 0; i < tm_sec; i++)
+ {
+ code = _rym_read_code(ctx,
+ RYM_CHD_INTV_TICK);
+ if (code == RYM_CODE_C)
+ {
+ break;
+ }
+ }
+ if (i == tm_sec)
+ {
+ return -RYM_ERR_TMO;
+ }
+
+ /* congratulations, check passed. */
+ if (ctx->on_begin && ctx->on_begin(ctx, ctx->buf + 3, data_sz - 5) != RYM_CODE_SOH)
+ return -RYM_ERR_CODE;
+
+ code = RYM_CODE_SOH;
+ _rym_send_packet(ctx, code, index);
+
+ rt_device_set_rx_indicate(ctx->dev, _rym_rx_ind);
+ getc_ack = _rym_getchar(ctx);
+
+ if (getc_ack != RYM_CODE_ACK)
+ {
+ return -RYM_ERR_ACK;
+ }
+
+ getc_ack = _rym_getchar(ctx);
+
+ if (getc_ack != RYM_CODE_C)
+ {
+ return -RYM_ERR_ACK;
+ }
+
+ ctx->stage = RYM_STAGE_ESTABLISHED;
+
+ return RT_EOK;
+}
+
static rt_err_t _rym_trans_data(
- struct rym_ctx *ctx,
- rt_size_t data_sz,
- enum rym_code *code)
+ struct rym_ctx *ctx,
+ rt_size_t data_sz,
+ enum rym_code *code)
{
- const rt_size_t tsz = 2+data_sz+2;
+ const rt_size_t tsz = 2 + data_sz + 2;
rt_uint16_t recv_crc;
/* seq + data + crc */
@@ -210,13 +332,13 @@ static rt_err_t _rym_trans_data(
ctx->stage = RYM_STAGE_TRANSMITTING;
/* sanity check */
- recv_crc = (rt_uint16_t)(*(ctx->buf+tsz-1) << 8) | *(ctx->buf+tsz);
- if (recv_crc != CRC16(ctx->buf+3, data_sz))
+ recv_crc = (rt_uint16_t)(*(ctx->buf + tsz - 1) << 8) | *(ctx->buf + tsz);
+ if (recv_crc != CRC16(ctx->buf + 3, data_sz))
return -RYM_ERR_CRC;
/* congratulations, check passed. */
if (ctx->on_data)
- *code = ctx->on_data(ctx, ctx->buf+3, data_sz);
+ *code = ctx->on_data(ctx, ctx->buf + 3, data_sz);
else
*code = RYM_CODE_ACK;
return RT_EOK;
@@ -235,7 +357,7 @@ static rt_err_t _rym_do_trans(struct rym_ctx *ctx)
rt_size_t data_sz, i;
code = _rym_read_code(ctx,
- RYM_WAIT_PKG_TICK);
+ RYM_WAIT_PKG_TICK);
switch (code)
{
case RYM_CODE_SOH:
@@ -257,7 +379,8 @@ static rt_err_t _rym_do_trans(struct rym_ctx *ctx)
{
case RYM_CODE_CAN:
/* the spec require multiple CAN */
- for (i = 0; i < RYM_END_SESSION_SEND_CAN_NUM; i++) {
+ for (i = 0; i < RYM_END_SESSION_SEND_CAN_NUM; i++)
+ {
_rym_putchar(ctx, RYM_CODE_CAN);
}
return -RYM_ERR_CAN;
@@ -271,6 +394,41 @@ static rt_err_t _rym_do_trans(struct rym_ctx *ctx)
}
}
+static rt_err_t _rym_do_send_trans(struct rym_ctx *ctx)
+{
+ ctx->stage = RYM_STAGE_TRANSMITTING;
+ enum rym_code code;
+ rt_size_t data_sz;
+ rt_uint32_t index = 1;
+ rt_uint8_t getc_ack;
+
+ data_sz = _RYM_SOH_PKG_SZ;
+
+ while (1)
+ {
+ if (ctx->on_data && ctx->on_data(ctx, ctx->buf + 3, data_sz - 5) != RYM_CODE_SOH)
+ return -RYM_ERR_CODE;
+
+ code = RYM_CODE_SOH;
+
+ _rym_send_packet(ctx, code, index);
+ index++;
+ rt_device_set_rx_indicate(ctx->dev, _rym_rx_ind);
+
+ getc_ack = _rym_getchar(ctx);
+
+ if (getc_ack != RYM_CODE_ACK)
+ {
+ return -RYM_ERR_ACK;
+ }
+
+ if (ctx->stage == RYM_STAGE_FINISHING)
+ break;
+ }
+
+ return RT_EOK;
+}
+
static rt_err_t _rym_do_fin(struct rym_ctx *ctx)
{
enum rym_code code;
@@ -282,7 +440,7 @@ static rt_err_t _rym_do_fin(struct rym_ctx *ctx)
/* we already got one EOT in the caller. invoke the callback if there is
* one. */
if (ctx->on_end)
- ctx->on_end(ctx, ctx->buf+3, 128);
+ ctx->on_end(ctx, ctx->buf + 3, 128);
_rym_putchar(ctx, RYM_CODE_NAK);
code = _rym_read_code(ctx, RYM_WAIT_PKG_TICK);
@@ -297,15 +455,15 @@ static rt_err_t _rym_do_fin(struct rym_ctx *ctx)
{
data_sz = _RYM_SOH_PKG_SZ;
}
- else if(code == RYM_CODE_STX)
+ else if (code == RYM_CODE_STX)
{
data_sz = _RYM_STX_PKG_SZ;
}
else
return -RYM_ERR_CODE;
- i = _rym_read_data(ctx, _RYM_SOH_PKG_SZ-1);
- if (i != (_RYM_SOH_PKG_SZ-1))
+ i = _rym_read_data(ctx, _RYM_SOH_PKG_SZ - 1);
+ if (i != (_RYM_SOH_PKG_SZ - 1))
return -RYM_ERR_DSZ;
/* sanity check
@@ -313,14 +471,14 @@ static rt_err_t _rym_do_fin(struct rym_ctx *ctx)
if (ctx->buf[1] != 0 || ctx->buf[2] != 0xFF)
return -RYM_ERR_SEQ;
- recv_crc = (rt_uint16_t)(*(ctx->buf+_RYM_SOH_PKG_SZ-2) << 8) | *(ctx->buf+_RYM_SOH_PKG_SZ-1);
- if (recv_crc != CRC16(ctx->buf+3, _RYM_SOH_PKG_SZ-5))
+ recv_crc = (rt_uint16_t)(*(ctx->buf + _RYM_SOH_PKG_SZ - 2) << 8) | *(ctx->buf + _RYM_SOH_PKG_SZ - 1);
+ if (recv_crc != CRC16(ctx->buf + 3, _RYM_SOH_PKG_SZ - 5))
return -RYM_ERR_CRC;
/*next file transmission*/
if (ctx->buf[3] != 0)
{
- if (ctx->on_begin && ctx->on_begin(ctx, ctx->buf+3, data_sz-5) != RYM_CODE_ACK)
+ if (ctx->on_begin && ctx->on_begin(ctx, ctx->buf + 3, data_sz - 5) != RYM_CODE_ACK)
return -RYM_ERR_CAN;
return RT_EOK;
}
@@ -334,9 +492,54 @@ static rt_err_t _rym_do_fin(struct rym_ctx *ctx)
return RT_EOK;
}
+static rt_err_t _rym_do_send_fin(struct rym_ctx *ctx)
+{
+ enum rym_code code;
+ rt_size_t data_sz;
+ rt_uint8_t index = 0;
+ rt_uint8_t getc_ack;
+
+ data_sz = _RYM_SOH_PKG_SZ;
+ rt_device_set_rx_indicate(ctx->dev, _rym_rx_ind);
+
+ _rym_putchar(ctx, RYM_CODE_EOT);
+ getc_ack = _rym_getchar(ctx);
+
+ if (getc_ack != RYM_CODE_NAK)
+ {
+ return -RYM_ERR_ACK;
+ }
+
+ _rym_putchar(ctx, RYM_CODE_EOT);
+ getc_ack = _rym_getchar(ctx);
+
+ if (getc_ack != RYM_CODE_ACK)
+ {
+ return -RYM_ERR_ACK;
+ }
+
+ getc_ack = _rym_getchar(ctx);
+
+ if (getc_ack != RYM_CODE_C)
+ {
+ return -RYM_ERR_ACK;
+ }
+
+ if (ctx->on_end && ctx->on_end(ctx, ctx->buf + 3, data_sz - 5) != RYM_CODE_SOH)
+ return -RYM_ERR_CODE;
+
+ code = RYM_CODE_SOH;
+
+ _rym_send_packet(ctx, code, index);
+
+ ctx->stage = RYM_STAGE_FINISHED;
+
+ return RT_EOK;
+}
+
static rt_err_t _rym_do_recv(
- struct rym_ctx *ctx,
- int handshake_timeout)
+ struct rym_ctx *ctx,
+ int handshake_timeout)
{
rt_err_t err;
@@ -348,30 +551,78 @@ static rt_err_t _rym_do_recv(
err = _rym_do_handshake(ctx, handshake_timeout);
if (err != RT_EOK)
+ {
+ rt_free(ctx->buf);
return err;
+ }
while (1)
{
err = _rym_do_trans(ctx);
if (err != RT_EOK)
+ {
+ rt_free(ctx->buf);
return err;
+ }
err = _rym_do_fin(ctx);
if (err != RT_EOK)
+ {
+ rt_free(ctx->buf);
return err;
+ }
+
if (ctx->stage == RYM_STAGE_FINISHED)
break;
}
+ rt_free(ctx->buf);
+ return err;
+}
+
+static rt_err_t _rym_do_send(
+ struct rym_ctx *ctx,
+ int handshake_timeout)
+{
+ rt_err_t err;
+
+ ctx->stage = RYM_STAGE_NONE;
+
+ ctx->buf = rt_malloc(_RYM_STX_PKG_SZ);
+ if (ctx->buf == RT_NULL)
+ return -RT_ENOMEM;
+
+ err = _rym_do_send_handshake(ctx, handshake_timeout);
+ if (err != RT_EOK)
+ {
+ rt_free(ctx->buf);
+ return err;
+ }
+
+ err = _rym_do_send_trans(ctx);
+ if (err != RT_EOK)
+ {
+ rt_free(ctx->buf);
+ return err;
+ }
+
+ err = _rym_do_send_fin(ctx);
+ if (err != RT_EOK)
+ {
+ rt_free(ctx->buf);
+ return err;
+ }
+
+ rt_free(ctx->buf);
return err;
}
rt_err_t rym_recv_on_device(
- struct rym_ctx *ctx,
- rt_device_t dev,
- rt_uint16_t oflag,
- rym_callback on_begin,
- rym_callback on_data,
- rym_callback on_end,
- int handshake_timeout)
+ struct rym_ctx *ctx,
+ rt_device_t dev,
+ rt_uint16_t oflag,
+ rym_callback on_begin,
+ rym_callback on_data,
+ rym_callback on_end,
+ int handshake_timeout)
{
rt_err_t res;
rt_err_t (*odev_rx_ind)(rt_device_t dev, rt_size_t size);
@@ -393,9 +644,9 @@ rt_err_t rym_recv_on_device(
int_lvl = rt_hw_interrupt_disable();
rt_device_set_rx_indicate(dev, _rym_rx_ind);
- odev_flag = dev->flag;
+ odev_flag = dev->open_flag;
/* make sure the device don't change the content. */
- dev->flag &= ~RT_DEVICE_FLAG_STREAM;
+ dev->open_flag &= ~RT_DEVICE_FLAG_STREAM;
rt_hw_interrupt_enable(int_lvl);
res = rt_device_open(dev, oflag);
@@ -412,12 +663,68 @@ __exit:
int_lvl = rt_hw_interrupt_disable();
rt_sem_detach(&ctx->sem);
- dev->flag = odev_flag;
+ dev->open_flag = odev_flag;
+ rt_device_set_rx_indicate(dev, odev_rx_ind);
+ rt_hw_interrupt_enable(int_lvl);
+
+ _rym_the_ctx = RT_NULL;
+
+ return res;
+}
+
+rt_err_t rym_send_on_device(
+ struct rym_ctx *ctx,
+ rt_device_t dev,
+ rt_uint16_t oflag,
+ rym_callback on_begin,
+ rym_callback on_data,
+ rym_callback on_end,
+ int handshake_timeout)
+{
+ rt_err_t res = 0;
+ rt_err_t (*odev_rx_ind)(rt_device_t dev, rt_size_t size);
+ rt_uint16_t odev_flag;
+ int int_lvl;
+
+ RT_ASSERT(_rym_the_ctx == 0);
+ _rym_the_ctx = ctx;
+
+ ctx->on_begin = on_begin;
+ ctx->on_data = on_data;
+ ctx->on_end = on_end;
+ ctx->dev = dev;
+ rt_sem_init(&ctx->sem, "rymsem", 0, RT_IPC_FLAG_FIFO);
+
+ odev_rx_ind = dev->rx_indicate;
+ /* no data should be received before the device has been fully setted up.
+ */
+ int_lvl = rt_hw_interrupt_disable();
+ rt_device_set_rx_indicate(dev, _rym_rx_ind);
+
+ odev_flag = dev->open_flag;
+ /* make sure the device don't change the content. */
+ dev->open_flag &= ~RT_DEVICE_FLAG_STREAM;
+ rt_hw_interrupt_enable(int_lvl);
+
+ res = rt_device_open(dev, oflag);
+ if (res != RT_EOK)
+ goto __exit;
+
+ res = _rym_do_send(ctx, handshake_timeout);
+
+ rt_device_close(dev);
+
+__exit:
+
+ int_lvl = rt_hw_interrupt_disable();
+ rt_sem_detach(&ctx->sem);
+
+ dev->open_flag = odev_flag;
rt_device_set_rx_indicate(dev, odev_rx_ind);
rt_hw_interrupt_enable(int_lvl);
- rt_free(ctx->buf);
_rym_the_ctx = RT_NULL;
return res;
}
+
diff --git a/components/utilities/ymodem/ymodem.h b/components/utilities/ymodem/ymodem.h
index 45e8f2272e..8419290e13 100644
--- a/components/utilities/ymodem/ymodem.h
+++ b/components/utilities/ymodem/ymodem.h
@@ -7,16 +7,19 @@
* Change Logs:
* Date Author Notes
* 2013-04-14 Grissiom initial implementation
+ * 2019-12-09 Steven Liu add YMODEM send protocol
*/
#ifndef __YMODEM_H__
#define __YMODEM_H__
#include "rtthread.h"
+#include <string.h>
/* The word "RYM" is stand for "Real-YModem". */
-enum rym_code {
+enum rym_code
+{
RYM_CODE_NONE = 0x00,
RYM_CODE_SOH = 0x01,
RYM_CODE_STX = 0x02,
@@ -44,6 +47,10 @@ enum rym_code {
#define RYM_ERR_DSZ 0x74
/* the transmission is aborted by user */
#define RYM_ERR_CAN 0x75
+/* wrong answer, wrong ACK or C */
+#define RYM_ERR_ACK 0x76
+/* transmit file invalid */
+#define RYM_ERR_FILE 0x77
/* how many ticks wait for chars between packet. */
#ifndef RYM_WAIT_CHR_TICK
@@ -63,7 +70,8 @@ enum rym_code {
#define RYM_END_SESSION_SEND_CAN_NUM 0x07
#endif
-enum rym_stage {
+enum rym_stage
+{
RYM_STAGE_NONE,
/* set when C is send */
RYM_STAGE_ESTABLISHING,
@@ -80,16 +88,15 @@ enum rym_stage {
};
struct rym_ctx;
-/* when receiving files, the buf will be the data received from ymodem protocol
+/* When receiving files, the buf will be the data received from ymodem protocol
* and the len is the data size.
*
- * TODO:
* When sending files, the len is the buf size in RYM. The callback need to
* fill the buf with data to send. Returning RYM_CODE_EOT will terminate the
* transfer and the buf will be discarded. Any other return values will cause
* the transfer continue.
*/
-typedef enum rym_code (*rym_callback)(struct rym_ctx *ctx, rt_uint8_t *buf, rt_size_t len);
+typedef enum rym_code(*rym_callback)(struct rym_ctx *ctx, rt_uint8_t *buf, rt_size_t len);
/* Currently RYM only support one transfer session(ctx) for simplicity.
*
@@ -112,7 +119,7 @@ struct rym_ctx
rt_device_t dev;
};
-/** recv a file on device dev with ymodem session ctx.
+/* recv a file on device dev with ymodem session ctx.
*
* If an error happens, you can get where it is failed from ctx->stage.
*
@@ -138,7 +145,30 @@ struct rym_ctx
* second.
*/
rt_err_t rym_recv_on_device(struct rym_ctx *ctx, rt_device_t dev, rt_uint16_t oflag,
- rym_callback on_begin, rym_callback on_data, rym_callback on_end,
- int handshake_timeout);
+ rym_callback on_begin, rym_callback on_data, rym_callback on_end,
+ int handshake_timeout);
+
+/* send a file on device dev with ymodem session ctx.
+ *
+ * If an error happens, you can get where it is failed from ctx->stage.
+ *
+ * @param on_begin The callback will be invoked when the first packet is sent.
+ * This packet often contain file names and the size of the file. It is the
+ * on_begin's responsibility to parse the basic information of the file. The
+ * on_begin can not be NULL.
+ *
+ * @param on_data The callback will be invoked when the data packets is sent.
+ * The callback should read file system and prepare the data packets. The
+ * on_data can not be NULL.
+ *
+ * @param on_end The callback will be invoked when one transmission is
+ * finished. The data should be 128 bytes of NULL. The on_end can not be NULL.
+ *
+ * @param handshake_timeout the timeout when hand shaking. The unit is in
+ * second.
+ */
+rt_err_t rym_send_on_device(struct rym_ctx *ctx, rt_device_t dev, rt_uint16_t oflag,
+ rym_callback on_begin, rym_callback on_data, rym_callback on_end,
+ int handshake_timeout);
#endif