forked from xuos/xiuos
Compare commits
169 Commits
master
...
test_gpio_
| Author | SHA1 | Date |
|---|---|---|
|
|
c570ae6296 | |
|
|
c3f1bcd344 | |
|
|
779444f998 | |
|
|
35dc835d12 | |
|
|
918b3663b8 | |
|
|
eed171df2a | |
|
|
9b3c321150 | |
|
|
a286b2292f | |
|
|
1655d28d63 | |
|
|
5dc639a133 | |
|
|
bebc65607e | |
|
|
10c39d930c | |
|
|
73fbeea117 | |
|
|
002325c1d8 | |
|
|
1b73886dbc | |
|
|
3a5d63762b | |
|
|
3950a6ec28 | |
|
|
ba51d8ba8e | |
|
|
c88ce9d708 | |
|
|
bfe1e72378 | |
|
|
e6fa8a2603 | |
|
|
732320f5c9 | |
|
|
3a6b5d7f4f | |
|
|
8632d37d14 | |
|
|
bcb5e48d6a | |
|
|
d2e6719a0e | |
|
|
b2de31844a | |
|
|
60dbe78045 | |
|
|
ff78fcc100 | |
|
|
aea6a4f63e | |
|
|
d1da6ae35b | |
|
|
df2a1043df | |
|
|
d144306f76 | |
|
|
55654af275 | |
|
|
fb11970cab | |
|
|
806492e271 | |
|
|
8001b07341 | |
|
|
c621db2ca7 | |
|
|
f8b845ca62 | |
|
|
9ad282c39e | |
|
|
a4e37b962f | |
|
|
e4742a480c | |
|
|
6b091797ae | |
|
|
e37d8ed7d1 | |
|
|
1a0880c3f2 | |
|
|
6010fe5654 | |
|
|
a7bdd89097 | |
|
|
32bf012d9a | |
|
|
ce60710fe6 | |
|
|
9f6419e5f6 | |
|
|
4edf73254e | |
|
|
b933e0decb | |
|
|
0b5c6b0f9f | |
|
|
6b4097b941 | |
|
|
d57552e223 | |
|
|
4f7f98b0e9 | |
|
|
27cc89bcef | |
|
|
38c4419ef9 | |
|
|
bc014769f5 | |
|
|
4e1bc3bf04 | |
|
|
5761bd0916 | |
|
|
186790f5ec | |
|
|
1864f39dd2 | |
|
|
59fa5451ca | |
|
|
5a64507a84 | |
|
|
56a014fe98 | |
|
|
9b334f90e0 | |
|
|
6a89a12c49 | |
|
|
04dc796f95 | |
|
|
a3094c1dd6 | |
|
|
2df54e7f41 | |
|
|
6ef80903ce | |
|
|
4f85bc91e5 | |
|
|
5622be48ac | |
|
|
669b7f427e | |
|
|
b20f041722 | |
|
|
e802403362 | |
|
|
19b16f7729 | |
|
|
465241e569 | |
|
|
dc8244cc5d | |
|
|
d0902ca37f | |
|
|
6fa996d132 | |
|
|
a782b53423 | |
|
|
5a3954b726 | |
|
|
0b49dd1a3c | |
|
|
9b83bc586e | |
|
|
2757649473 | |
|
|
100fe8c2d0 | |
|
|
4fd39c0dd7 | |
|
|
d8ac0998b2 | |
|
|
f1029b81c3 | |
|
|
1f97dd3d77 | |
|
|
e5bf0cee41 | |
|
|
d845bd61b6 | |
|
|
334d5f1eee | |
|
|
0125fdf0ef | |
|
|
22e35a70aa | |
|
|
8583ea25b6 | |
|
|
ba31c9e0f8 | |
|
|
f4b21208e8 | |
|
|
2a01ff712d | |
|
|
bc47ae644f | |
|
|
31189c2939 | |
|
|
1061ce4dff | |
|
|
c1976c8d92 | |
|
|
0d93a91829 | |
|
|
7145cd6920 | |
|
|
2a8a11849d | |
|
|
49df162734 | |
|
|
5560fc5318 | |
|
|
987fd6c798 | |
|
|
ebc61431bd | |
|
|
7c252bda56 | |
|
|
e31199a104 | |
|
|
68cdcbdcce | |
|
|
06ed03337a | |
|
|
72e09d82e7 | |
|
|
164614a75a | |
|
|
75259c4006 | |
|
|
992b8f62ab | |
|
|
afc27bce65 | |
|
|
96baeb9482 | |
|
|
2a07e463f6 | |
|
|
629e8893e3 | |
|
|
f22fbc3c94 | |
|
|
14f0e442ad | |
|
|
32c8701391 | |
|
|
452699ac02 | |
|
|
77bae67322 | |
|
|
02cbcf2b23 | |
|
|
2bfd6c9aaa | |
|
|
8bb59ddf3a | |
|
|
8c929ba701 | |
|
|
e7175c2745 | |
|
|
e746639f8a | |
|
|
d89e018d33 | |
|
|
c7c7e700ca | |
|
|
5d6aa56f29 | |
|
|
00b39cdd55 | |
|
|
b8cf052d49 | |
|
|
d3836f1a6f | |
|
|
33984d8872 | |
|
|
2bc1de068c | |
|
|
4f15f1e70b | |
|
|
d6495c03d2 | |
|
|
696c9f6fe0 | |
|
|
9a818b1ef4 | |
|
|
b5e08c5d43 | |
|
|
636f803b7b | |
|
|
51ebd8f604 | |
|
|
5f4922866e | |
|
|
d0e42a9b51 | |
|
|
107913cb61 | |
|
|
7361d1c65f | |
|
|
9965ce4c43 | |
|
|
a39bc41597 | |
|
|
3352d4be6b | |
|
|
485555b3a2 | |
|
|
0bb057c642 | |
|
|
0504cf0e48 | |
|
|
234f4fc2ed | |
|
|
2d7d5d121d | |
|
|
7a8766a74d | |
|
|
e26c93a666 | |
|
|
9802c89fd6 | |
|
|
700a07bc84 | |
|
|
37bdc4a33f | |
|
|
c612502cdc | |
|
|
012fc146cc |
|
|
@ -2,7 +2,6 @@
|
|||
# APP_Framework/Applications/Make.defs
|
||||
############################################################################
|
||||
CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Applications
|
||||
CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Applications/app_test
|
||||
CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Applications/general_functions/list
|
||||
|
||||
include $(wildcard $(APPDIR)/../../../APP_Framework/Applications/*/Make.defs)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ include $(KERNEL_ROOT)/.config
|
|||
|
||||
ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
||||
include $(APPDIR)/Make.defs
|
||||
CSRCS += framework_init.c
|
||||
CSRCS +=
|
||||
include $(APPDIR)/Application.mk
|
||||
endif
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ endif
|
|||
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||
SRC_DIR := general_functions app_test
|
||||
|
||||
SRC_FILES := main.c framework_init.c
|
||||
SRC_FILES := main.c
|
||||
ifeq ($(CONFIG_LIB_LV),y)
|
||||
SRC_DIR += lv_app
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -26,6 +26,182 @@ menu "test app"
|
|||
endif
|
||||
endif
|
||||
|
||||
menuconfig USER_TEST_FS
|
||||
bool "Config test fs with sd or usb"
|
||||
default n
|
||||
if USER_TEST_FS
|
||||
if ADD_XIZI_FETURES
|
||||
config FPATH
|
||||
string "Set test file path"
|
||||
default "/test_file"
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
menuconfig USER_TEST_GPIO
|
||||
select BSP_USING_GPIO
|
||||
select RESOURCES_PIN
|
||||
select BSP_USING_LED
|
||||
select BSP_USING_KEY
|
||||
bool "Config test gpio with led and key"
|
||||
default n
|
||||
if USER_TEST_GPIO
|
||||
if ADD_XIZI_FETURES
|
||||
config GPIO_DEV_DRIVER
|
||||
string "Set gpio dev path"
|
||||
default "/dev/pin_dev"
|
||||
endif
|
||||
config USER_TEST_GPIO_IRQ
|
||||
bool "Config test gpio irq with led and key"
|
||||
default n
|
||||
endif
|
||||
|
||||
menuconfig USER_TEST_LORA
|
||||
select BSP_USING_UART
|
||||
select BSP_USING_GPIO
|
||||
select RESOURCES_PIN
|
||||
select BSP_USING_UART2
|
||||
select BSP_USING_LORA
|
||||
bool "Config test uart(loraE220)"
|
||||
default n
|
||||
if USER_TEST_LORA
|
||||
if ADD_XIZI_FETURES
|
||||
config LORA_UART_DEV_DRIVER
|
||||
string "Set uart dev path"
|
||||
default "/dev/uart2_dev2"
|
||||
config LORA_PIN_DEV_DRIVER
|
||||
string "Set pin dev path"
|
||||
default "/dev/pin_dev"
|
||||
endif
|
||||
endif
|
||||
|
||||
menuconfig USER_TEST_RS485
|
||||
select BSP_USING_UART
|
||||
select BSP_USING_GPIO
|
||||
select RESOURCES_PIN
|
||||
select BSP_USING_UART1
|
||||
bool "Config test uart(RS485)"
|
||||
default n
|
||||
if USER_TEST_RS485
|
||||
if ADD_XIZI_FETURES
|
||||
config RS485_UART_DEV_DRIVER
|
||||
string "Set uart dev path"
|
||||
default "/dev/uart1_dev1"
|
||||
config RS485_PIN_DEV_DRIVER
|
||||
string "Set pin dev path"
|
||||
default "/dev/pin_dev"
|
||||
endif
|
||||
endif
|
||||
|
||||
menuconfig USER_TEST_RTC
|
||||
select BSP_USING_RTC
|
||||
bool "Config test rtc"
|
||||
default n
|
||||
if USER_TEST_RTC
|
||||
if ADD_XIZI_FETURES
|
||||
config RTC_DEV_DRIVER
|
||||
string "Set rtc dev path"
|
||||
default "/dev/rtc_dev"
|
||||
endif
|
||||
endif
|
||||
|
||||
menuconfig USER_TEST_HWTIMER
|
||||
select BSP_USING_HWTIMER
|
||||
select BSP_USING_GPIO
|
||||
select RESOURCES_PIN
|
||||
select BSP_USING_LED
|
||||
bool "Config test hwtimer"
|
||||
default n
|
||||
if USER_TEST_HWTIMER
|
||||
if ADD_XIZI_FETURES
|
||||
config HWTIMER_TIMER_DEV_DRIVER
|
||||
string "Set pin dev path"
|
||||
default "/dev/timer0_dev0"
|
||||
config HWTIMER_PIN_DEV_DRIVER
|
||||
string "Set pin dev path"
|
||||
default "/dev/pin_dev"
|
||||
endif
|
||||
endif
|
||||
|
||||
menuconfig USER_TEST_WDT
|
||||
select BSP_USING_WDT0
|
||||
bool "Config test watchdog"
|
||||
default n
|
||||
if USER_TEST_WDT
|
||||
if ADD_XIZI_FETURES
|
||||
config WDT0_DEV_DRIVER
|
||||
string "Set wdt dev path"
|
||||
default "/dev/wdt0_dev0"
|
||||
endif
|
||||
endif
|
||||
|
||||
menuconfig USER_TEST_LCD_EDU
|
||||
select BSP_USING_LCD
|
||||
bool "Config test lcd in PrivOpen"
|
||||
default n
|
||||
if USER_TEST_LCD_EDU
|
||||
if ADD_XIZI_FETURES
|
||||
config EDU_LCD_DEV_DRIVER
|
||||
string "Set lcd dev path"
|
||||
default "/dev/lcd_dev"
|
||||
endif
|
||||
endif
|
||||
|
||||
menuconfig USER_TEST_TOUCH
|
||||
select BSP_USING_TOUCH
|
||||
bool "Config test touch"
|
||||
default n
|
||||
if USER_TEST_TOUCH
|
||||
if ADD_XIZI_FETURES
|
||||
config TOUCH_DEV_DRIVER
|
||||
string "Set touch dev path"
|
||||
default "/dev/touch_dev"
|
||||
config TOUCH_LCD_DEV_DRIVER
|
||||
string "Set lcd dev path"
|
||||
default "/dev/lcd_dev"
|
||||
endif
|
||||
endif
|
||||
|
||||
menuconfig USER_TEST_I2C
|
||||
select BSP_USING_I2C
|
||||
bool "Config test i2c"
|
||||
default n
|
||||
if USER_TEST_I2C
|
||||
if ADD_XIZI_FETURES
|
||||
config I2C_DEV_DRIVER
|
||||
string "Set i2c dev path"
|
||||
default "/dev/i2c1_dev0"
|
||||
endif
|
||||
endif
|
||||
|
||||
menuconfig USER_TEST_CAN
|
||||
select BSP_USING_CAN
|
||||
bool "Config test can"
|
||||
default n
|
||||
if USER_TEST_CAN
|
||||
if ADD_XIZI_FETURES
|
||||
config CAN_DEV_DRIVER
|
||||
string "Set can dev path"
|
||||
default "/dev/can2_dev1"
|
||||
endif
|
||||
endif
|
||||
|
||||
menuconfig USER_TEST_CAMERA
|
||||
select BSP_USING_CAMERA
|
||||
select BSP_USING_LCD
|
||||
bool "Config test camera with lcd"
|
||||
default n
|
||||
if USER_TEST_CAMERA
|
||||
if ADD_XIZI_FETURES
|
||||
config CAMERA_DEV_DRIVER
|
||||
string "Set camera dev path"
|
||||
default "/dev/camera_dev"
|
||||
config CAMERA_LCD_DEV_DRIVER
|
||||
string "Set lcd dev path"
|
||||
default "/dev/lcd_dev"
|
||||
endif
|
||||
endif
|
||||
|
||||
config USER_TEST_SEMC
|
||||
bool "Config test semc sdram"
|
||||
default n
|
||||
|
|
@ -33,5 +209,35 @@ menu "test app"
|
|||
config USER_TEST_LCD
|
||||
bool "Config test lcd device"
|
||||
default n
|
||||
|
||||
menuconfig USER_TEST_ETHERNET
|
||||
bool "Config test ethernet only for edu-riscv64"
|
||||
default n
|
||||
if USER_TEST_ETHERNET
|
||||
if ADD_XIZI_FETURES
|
||||
choice
|
||||
prompt "set ethernet role as client or server"
|
||||
default ETHERNET_AS_SERVER
|
||||
|
||||
config ETHERNET_AS_SERVER
|
||||
bool "test as server"
|
||||
|
||||
config ETHERNET_AS_CLIENT
|
||||
bool "test as client"
|
||||
endchoice
|
||||
endif
|
||||
endif
|
||||
|
||||
menuconfig USER_TEST_FLASH
|
||||
bool "Config test w25q128 device"
|
||||
default n
|
||||
if USER_TEST_FLASH
|
||||
if ADD_XIZI_FETURES
|
||||
config FLASH_DEV_DRIVER
|
||||
string "Set flash dev path"
|
||||
default "/dev/qspi_W25Q128"
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -10,6 +10,14 @@ ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
|||
CSRCS += test_lcd.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_TOUCH),y)
|
||||
CSRCS += test_touch.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MUSL_LIBC),y)
|
||||
CSRCS += test_musl.c
|
||||
endif
|
||||
|
||||
include $(APPDIR)/Application.mk
|
||||
|
||||
endif
|
||||
|
|
@ -25,6 +33,10 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
|||
SRC_FILES += test_dac.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_FS),y)
|
||||
SRC_FILES += test_fs.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_SEMC),y)
|
||||
SRC_FILES += test_extsram.c
|
||||
endif
|
||||
|
|
@ -33,5 +45,61 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
|||
SRC_FILES +=
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_I2C),y)
|
||||
SRC_FILES += test_i2c.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_GPIO),y)
|
||||
SRC_FILES += test_gpio.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_GPIO_IRQ),y)
|
||||
SRC_FILES += test_gpio_irq.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_LORA),y)
|
||||
SRC_FILES += test_loraE220.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_RTC),y)
|
||||
SRC_FILES += test_rtc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_RS485),y)
|
||||
SRC_FILES += test_rs485.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_HWTIMER),y)
|
||||
SRC_FILES += test_hwtimer.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_LCD_EDU),y)
|
||||
SRC_FILES += test_lcd_edu.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_WDT),y)
|
||||
SRC_FILES += test_wdt.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_TOUCH),y)
|
||||
SRC_FILES += test_touch.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_CAMERA),y)
|
||||
SRC_FILES += test_camera.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_ETHERNET),y)
|
||||
SRC_FILES += test_ethernet.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_FLASH),y)
|
||||
SRC_FILES += test_flash.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USER_TEST_CAN),y)
|
||||
SRC_FILES += test_can.c
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -56,4 +56,4 @@ void TestAdc(void)
|
|||
|
||||
return;
|
||||
}
|
||||
PRIV_SHELL_CMD_FUNCTION(TestAdc, a adc test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
PRIV_SHELL_CMD_FUNCTION(TestAdc, a adc test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
|
||||
static uint16_t image_buff[384000];
|
||||
|
||||
void TestCamera(int argc, char *argv[])
|
||||
{
|
||||
int frame_counter = 10000;
|
||||
if (argc > 1)
|
||||
{
|
||||
frame_counter = atoi(argv[1]);
|
||||
}
|
||||
printf("This test will refresh %d frames\n", frame_counter);
|
||||
|
||||
int camera_fd = PrivOpen(CAMERA_DEV_DRIVER, O_RDWR);
|
||||
if (camera_fd < 0)
|
||||
{
|
||||
printf("open camera fd error:%d\n", camera_fd);
|
||||
return;
|
||||
}
|
||||
int lcd_fd = PrivOpen(CAMERA_LCD_DEV_DRIVER, O_RDWR);
|
||||
if (lcd_fd < 0)
|
||||
{
|
||||
printf("open lcd fd error:%d\n", lcd_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
//configure the camera's output address
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = CAMERA_TYPE;
|
||||
struct CameraCfg camera_cfg ={
|
||||
.gain_manu_enable = 0,
|
||||
.gain = 0xFF,
|
||||
.window_w = 800,
|
||||
.window_h = 600,
|
||||
.output_w = IMAGE_WIDTH,
|
||||
.output_h = IMAGE_HEIGHT,
|
||||
.window_xoffset = 0,
|
||||
.window_yoffset = 0
|
||||
};
|
||||
ioctl_cfg.args = &camera_cfg;
|
||||
if (0 != PrivIoctl(camera_fd, OPE_CFG, &ioctl_cfg))
|
||||
{
|
||||
printf("camera pin fd error %d\n", camera_fd);
|
||||
PrivClose(camera_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
ioctl_cfg.args = (void *)image_buff;
|
||||
|
||||
if (0 != PrivRead(camera_fd, image_buff, NULL_PARAMETER))
|
||||
{
|
||||
printf("camera pin fd error %d\n", camera_fd);
|
||||
PrivClose(camera_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("address buff is %x\n", image_buff);
|
||||
|
||||
|
||||
LcdWriteParam graph_param;
|
||||
graph_param.type = LCD_DOT_TYPE;
|
||||
|
||||
//clear the LCD
|
||||
uint16_t back_color[LCD_SIZE];
|
||||
memset(back_color,0,sizeof(back_color));
|
||||
for (int i = 0; i < LCD_SIZE; i++)
|
||||
{
|
||||
graph_param.pixel_info.pixel_color = &back_color;
|
||||
graph_param.pixel_info.x_startpos = 0;
|
||||
graph_param.pixel_info.y_startpos = i;
|
||||
graph_param.pixel_info.x_endpos = LCD_SIZE -1;
|
||||
graph_param.pixel_info.y_endpos = i;
|
||||
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
|
||||
}
|
||||
|
||||
//refresh the LCD using photo of camera
|
||||
while (frame_counter--)
|
||||
{
|
||||
for (int i = 0; i < IMAGE_HEIGHT; i++)
|
||||
{
|
||||
graph_param.pixel_info.pixel_color = image_buff + i * IMAGE_WIDTH;
|
||||
graph_param.pixel_info.x_startpos = 0;
|
||||
graph_param.pixel_info.y_startpos = i + (LCD_SIZE - IMAGE_HEIGHT) / 2;
|
||||
graph_param.pixel_info.x_endpos = IMAGE_WIDTH - 1;
|
||||
graph_param.pixel_info.y_endpos = i + (LCD_SIZE - IMAGE_HEIGHT) / 2;
|
||||
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
|
||||
}
|
||||
}
|
||||
|
||||
// close test
|
||||
PrivClose(lcd_fd);
|
||||
PrivClose(camera_fd);
|
||||
printf("The camera test is finished successfully\n");
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestCamera, a camera test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
|
||||
void TestCAN(void)
|
||||
{
|
||||
// config CAN pin(SCL:34.SDA:35) in menuconfig
|
||||
int can_fd = PrivOpen(CAN_DEV_DRIVER, O_RDWR);
|
||||
if (can_fd < 0)
|
||||
{
|
||||
printf("open can_fd fd error:%d\n", can_fd);
|
||||
return;
|
||||
}
|
||||
printf("CAN open successful!\n");
|
||||
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = CAN_TYPE;
|
||||
|
||||
struct CanDriverConfigure can_config;
|
||||
can_config.brp = 8U;
|
||||
can_config.tbs1 = 1U + 8U;
|
||||
can_config.tbs2 = 4U;
|
||||
can_config.tsjw = 4U;
|
||||
can_config.mode = 0U;
|
||||
|
||||
ioctl_cfg.args = (void *)&can_config;
|
||||
|
||||
if (0 != PrivIoctl(can_fd, OPE_INT, &ioctl_cfg))
|
||||
{
|
||||
printf("init can fd error %d\n", can_fd);
|
||||
PrivClose(can_fd);
|
||||
return;
|
||||
}
|
||||
printf("CAN configure successful!\n");
|
||||
|
||||
uint8_t data_buff[64u] = {1,2,3,4,4,3,2,1};
|
||||
struct CanSendConfigure frame_send;
|
||||
frame_send.ide=0;
|
||||
frame_send.stdid = 0x55;
|
||||
frame_send.rtr=0;
|
||||
frame_send.data_lenth=8;
|
||||
frame_send.data = data_buff;
|
||||
|
||||
struct CanSendConfigure frame_recv;
|
||||
uint8_t recv_buff[65U] = {0};
|
||||
frame_recv.data = recv_buff;
|
||||
|
||||
// CAN write
|
||||
while (1)
|
||||
{
|
||||
PrivTaskDelay(500);
|
||||
PrivWrite(can_fd, &frame_send, NONE);
|
||||
PrivTaskDelay(500);
|
||||
PrivRead(can_fd, &frame_recv, NONE);
|
||||
// if any data has received,Then printf message
|
||||
if(frame_recv.data_lenth > 0){
|
||||
printf("ID %08x:%s\n",frame_recv.exdid,frame_recv.data);
|
||||
}
|
||||
}
|
||||
|
||||
PrivClose(can_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestCAN, a can test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
#include <socket.h>
|
||||
|
||||
#define BUFF_SIZE 128
|
||||
#define RECV_SIZE 16
|
||||
#define TCP_PORT 12345
|
||||
|
||||
const static uint32_t sn = 0;
|
||||
|
||||
#ifdef ETHERNET_AS_SERVER
|
||||
static int32_t wiz_server_op(uint8_t sn, uint8_t *buf, uint32_t buf_size,
|
||||
uint16_t port, enum TCP_OPTION opt) {
|
||||
int32_t ret = 0;
|
||||
uint16_t size = 0, sentsize = 0;
|
||||
switch (getSn_SR(sn)) {
|
||||
case SOCK_ESTABLISHED:
|
||||
if (getSn_IR(sn) & Sn_IR_CON) {
|
||||
printf("%d:Connected\r\n", sn);
|
||||
setSn_IR(sn, Sn_IR_CON);
|
||||
}
|
||||
if (opt == SEND_DATA) {
|
||||
uint32_t sent_size = 0;
|
||||
memset(buf,0,buf_size);
|
||||
strcpy(buf,"The message has been recved");
|
||||
ret = wiz_sock_send(sn, buf, buf_size);
|
||||
if (ret < 0) {
|
||||
wiz_sock_close(sn);
|
||||
return ret;
|
||||
}
|
||||
} else if (opt == RECV_DATA) {
|
||||
uint32_t size = 0;
|
||||
if ((size = getSn_RX_RSR(sn)) > 0) {
|
||||
if (size > buf_size) size = buf_size;
|
||||
memset(buf,0,buf_size);
|
||||
ret = wiz_sock_recv(sn, buf, size);
|
||||
printf("Recv message: %s\n",buf);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SOCK_CLOSE_WAIT:
|
||||
printf("%d:CloseWait\r\n", sn);
|
||||
if ((ret = wiz_sock_disconnect(sn)) != SOCK_OK) return ret;
|
||||
printf("%d:Closed\r\n", sn);
|
||||
break;
|
||||
case SOCK_INIT:
|
||||
printf("%d:Listen, port [%d]\r\n", sn, port);
|
||||
if ((ret = wiz_sock_listen(sn)) != SOCK_OK) return ret;
|
||||
break;
|
||||
case SOCK_CLOSED:
|
||||
printf("%d:LBTStart\r\n", sn);
|
||||
if ((ret = wiz_socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret;
|
||||
printf("%d:Opened\r\n", sn);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TestSocketAsServer(int argc, char *argv[])
|
||||
{
|
||||
x_err_t ret;
|
||||
uint8_t buf[BUFF_SIZE] = {0};
|
||||
|
||||
while (1) {
|
||||
ret = wiz_server_op(0, buf, BUFF_SIZE, TCP_PORT, RECV_DATA);
|
||||
if (ret > 0) {
|
||||
wiz_server_op(0, buf, BUFF_SIZE, TCP_PORT, SEND_DATA);
|
||||
};
|
||||
}
|
||||
|
||||
return ;
|
||||
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestSocketAsServer, a w5500 server test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
||||
#elif defined ETHERNET_AS_CLIENT
|
||||
|
||||
static uint32_t wiz_client_op(uint8_t sn, uint8_t *buf, uint32_t buf_size,
|
||||
uint8_t dst_ip[4], uint16_t dst_port,
|
||||
enum TCP_OPTION opt) {
|
||||
// assert(buf_size <= g_wiznet_buf_size);
|
||||
int32_t ret;
|
||||
switch (getSn_SR(sn)) {
|
||||
case SOCK_CLOSE_WAIT:
|
||||
wiz_sock_disconnect(sn);
|
||||
break;
|
||||
case SOCK_CLOSED:
|
||||
wiz_socket(sn, Sn_MR_TCP, 5000, 0x00);
|
||||
break;
|
||||
case SOCK_INIT:
|
||||
KPrintf("[SOCKET CLIENT] sock init.\n");
|
||||
wiz_sock_connect(sn, dst_ip, dst_port);
|
||||
break;
|
||||
case SOCK_ESTABLISHED:
|
||||
if (getSn_IR(sn) & Sn_IR_CON) {
|
||||
printf("[SOCKET CLIENT] %d:Connected\r\n", sn);
|
||||
setSn_IR(sn, Sn_IR_CON);
|
||||
}
|
||||
if (opt == SEND_DATA) {
|
||||
uint32_t sent_size = 0;
|
||||
ret = wiz_sock_send(sn, buf, buf_size);
|
||||
if (ret < 0) {
|
||||
wiz_sock_close(sn);
|
||||
return ret;
|
||||
}
|
||||
} else if (opt == RECV_DATA) {
|
||||
uint32_t size = 0;
|
||||
if ((size = getSn_RX_RSR(sn)) > 0) {
|
||||
if (size > buf_size) size = buf_size;
|
||||
ret = wiz_sock_recv(sn, buf, size);
|
||||
if (ret <= 0) return ret;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TestSocketAsClient(int argc, char *argv[])
|
||||
{
|
||||
x_err_t ret;
|
||||
uint8_t buf[BUFF_SIZE] = {0};
|
||||
uint32_t tmp_ip[4];
|
||||
uint32_t port;
|
||||
const uint8_t client_sock = 2;
|
||||
|
||||
if(argc<3){
|
||||
printf("Please enter command like TestSocketAsClient ip:port msg\n");
|
||||
}
|
||||
|
||||
sscanf(argv[1],"%d.%d.%d.%d:%d",tmp_ip,tmp_ip+1,tmp_ip+2,tmp_ip+3,&port);
|
||||
printf("Client to %d.%d.%d.%d:%d\n",tmp_ip[0],tmp_ip[1],tmp_ip[2],tmp_ip[3],port);
|
||||
uint8_t destination_ip[4]={0};
|
||||
for(int i=0;i<4;i++){
|
||||
destination_ip[i]=tmp_ip[i];
|
||||
}
|
||||
|
||||
while(1){
|
||||
ret = wiz_client_op(client_sock, argv[2], strlen(argv[2]), destination_ip, port,SEND_DATA);
|
||||
printf("sizeof:%d\n",strlen(argv[2]));
|
||||
PrivTaskDelay(1000);
|
||||
if (ret > 0) {
|
||||
ret=wiz_client_op(client_sock, buf, BUFF_SIZE, destination_ip, port, RECV_DATA);
|
||||
printf("read ret is %d\n",ret);
|
||||
if(ret>0){
|
||||
printf("client recv msg successfully!\n");
|
||||
printf("%s\n",buf);
|
||||
}
|
||||
};
|
||||
PrivTaskDelay(1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return ;
|
||||
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestSocketAsClient, a w5500 client-ip-port-msg test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
void TestFlash(void)
|
||||
{
|
||||
int fd = open(FLASH_DEV_DRIVER,O_RDWR);
|
||||
if(fd<0){
|
||||
printf("fs fd open error:%d\n",fd);
|
||||
return;
|
||||
}
|
||||
struct BusBlockWriteParam flash_writer;
|
||||
uint8_t read_buff[8] = {1,2,3,4,5,6,7,8};
|
||||
flash_writer.pos = 0x000000L;
|
||||
flash_writer.size = 8;
|
||||
flash_writer.buffer = read_buff;
|
||||
struct BusBlockReadParam flash_reader;
|
||||
flash_reader.pos = 0x000000L;
|
||||
flash_reader.size = 8;
|
||||
flash_reader.buffer = read_buff;
|
||||
|
||||
PrivRead(fd,&flash_reader,NONE);
|
||||
printf("Read data is:");
|
||||
for(int i=0;i<flash_writer.size;i++){
|
||||
printf("%02x ",read_buff[i]);
|
||||
read_buff[i]++;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
PrivWrite(fd,&flash_writer,NONE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestFlash, a flash test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
#define MAX_READ_LENGTH 1000
|
||||
|
||||
// sd card here is loaded as "/"
|
||||
void TestFs(void)
|
||||
{
|
||||
//open the file in sdcard
|
||||
int fd = open(FPATH,O_RDWR|O_CREAT);
|
||||
if(fd<0){
|
||||
printf("fs fd open error:%d\n",fd);
|
||||
return;
|
||||
}
|
||||
|
||||
char filewords[MAX_READ_LENGTH];
|
||||
memset(filewords,0,MAX_READ_LENGTH);
|
||||
const char *input_words = "these words are going to write in fs\n";
|
||||
|
||||
//read and write then close file
|
||||
int err_flag = read(fd,filewords,MAX_READ_LENGTH);
|
||||
if(err_flag<0){
|
||||
printf("read failed,error:%d\n",err_flag);
|
||||
return;
|
||||
}
|
||||
printf("read data is \n%s\n",filewords);
|
||||
|
||||
err_flag = write(fd,input_words,strlen(input_words));
|
||||
if(err_flag<0){
|
||||
printf("write failed,error:%d\n",err_flag);
|
||||
return;
|
||||
}
|
||||
err_flag = close(fd);
|
||||
if(err_flag<0){
|
||||
printf("close failed,error %d\n",err_flag);
|
||||
return ;
|
||||
}
|
||||
|
||||
//re-open the file and re-read the file
|
||||
fd = open(FPATH,O_RDWR);
|
||||
if(fd<0){
|
||||
printf("fs fd open error:%d\n",fd);
|
||||
return;
|
||||
}
|
||||
err_flag = read(fd,filewords,MAX_READ_LENGTH);
|
||||
if(err_flag<0){
|
||||
printf("read failed,error:%d\n",err_flag);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("read data is \n%s\n",filewords);
|
||||
err_flag = close(fd);
|
||||
if(err_flag<0){
|
||||
printf("close failed,error:%d\n",err_flag);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestFs, a sd or usb filesystem test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
#define BSP_LED_PIN 29
|
||||
#define BSP_KEY_PIN 31
|
||||
#define NULL_PARAMETER 0
|
||||
|
||||
void TestGpio(void)
|
||||
{
|
||||
int pin_fd = PrivOpen(GPIO_DEV_DRIVER, O_RDWR);
|
||||
if(pin_fd<0){
|
||||
printf("open pin fd error:%d\n",pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
//config led pin in board
|
||||
struct PinParam parameter;
|
||||
parameter.cmd = GPIO_CONFIG_MODE;
|
||||
parameter.pin = BSP_LED_PIN;
|
||||
parameter.mode = GPIO_CFG_OUTPUT;
|
||||
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
|
||||
ioctl_cfg.args = (void *)¶meter;
|
||||
|
||||
if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) {
|
||||
printf("ioctl pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
//config key pin in board
|
||||
parameter.pin = BSP_KEY_PIN;
|
||||
parameter.mode = GPIO_CFG_INPUT;
|
||||
|
||||
if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) {
|
||||
printf("ioctl pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
struct PinStat pin_led;
|
||||
struct PinStat pin_key;
|
||||
|
||||
pin_led.pin = BSP_LED_PIN;
|
||||
pin_key.pin = BSP_KEY_PIN;
|
||||
|
||||
//recycle read pin and write pin until key break
|
||||
while(1){
|
||||
if(0>PrivRead(pin_fd,&pin_key,NULL_PARAMETER)){
|
||||
printf("read pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
//led on if key pressed,or led off
|
||||
if(pin_key.val){
|
||||
pin_led.val = GPIO_HIGH;
|
||||
}else{
|
||||
pin_led.val = GPIO_LOW;
|
||||
}
|
||||
|
||||
if(0>PrivWrite(pin_fd,&pin_led,NULL_PARAMETER)){
|
||||
printf("write pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestGpio, a gpio test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
#define BSP_LED_PIN 29
|
||||
#define BSP_KEY_PIN 31
|
||||
#define NULL_PARAMETER 0
|
||||
|
||||
void PinIsr_UserKeyRising(void* args)
|
||||
{
|
||||
printf("User Key Pressed!\n");
|
||||
int pin_fd = PrivOpen(GPIO_DEV_DRIVER, O_RDWR);
|
||||
struct PinStat pin_led;
|
||||
pin_led.pin = BSP_LED_PIN;
|
||||
pin_led.val = GPIO_HIGH;
|
||||
if(0 > PrivWrite(pin_fd, &pin_led, NULL_PARAMETER)) {
|
||||
printf("write pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Disable Key irq\n");
|
||||
struct PinParam parameter;
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
|
||||
ioctl_cfg.args = (void *)¶meter;
|
||||
parameter.cmd = GPIO_IRQ_DISABLE;
|
||||
parameter.pin = BSP_KEY_PIN;
|
||||
if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) {
|
||||
printf("ioctl pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
PrivClose(pin_fd);
|
||||
|
||||
printf("exit LedFlip task\n");
|
||||
int32 taskid = *(int32*)args;
|
||||
KTaskDelete(taskid);
|
||||
}
|
||||
|
||||
void LedFlip(void *arg)
|
||||
{
|
||||
int pin_fd = PrivOpen(GPIO_DEV_DRIVER, O_RDWR);
|
||||
if(pin_fd < 0) {
|
||||
printf("open pin fd error:%d\n",pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
struct PinStat pin_led;
|
||||
pin_led.pin = BSP_LED_PIN;
|
||||
pin_led.val = GPIO_LOW;
|
||||
while(1){
|
||||
pin_led.val = !pin_led.val;
|
||||
if(0 > PrivWrite(pin_fd, &pin_led, NULL_PARAMETER)) {
|
||||
printf("write pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
PrivTaskDelay(500);
|
||||
}
|
||||
}
|
||||
|
||||
void TestGpioIrq(void)
|
||||
{
|
||||
int pin_fd = PrivOpen(GPIO_DEV_DRIVER, O_RDWR);
|
||||
if(pin_fd < 0) {
|
||||
printf("open pin fd error:%d\n",pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
struct PinParam parameter;
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
|
||||
ioctl_cfg.args = (void *)¶meter;
|
||||
|
||||
//config led pin in board
|
||||
parameter.cmd = GPIO_CONFIG_MODE;
|
||||
parameter.pin = BSP_LED_PIN;
|
||||
parameter.mode = GPIO_CFG_OUTPUT;
|
||||
if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) {
|
||||
printf("ioctl pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
//config key pin in board
|
||||
parameter.cmd = GPIO_CONFIG_MODE;
|
||||
parameter.pin = BSP_KEY_PIN;
|
||||
parameter.mode = GPIO_CFG_INPUT;
|
||||
if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) {
|
||||
printf("ioctl pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
int32 taskid = KTaskCreate("LedFlip", LedFlip, NULL, 4096, 25);
|
||||
//config key irq
|
||||
parameter.cmd = GPIO_IRQ_REGISTER;
|
||||
parameter.pin = BSP_KEY_PIN;
|
||||
parameter.irq_set.irq_mode = GPIO_IRQ_EDGE_FALLING;
|
||||
parameter.irq_set.hdr = PinIsr_UserKeyRising;
|
||||
parameter.irq_set.args = (void *)&taskid;
|
||||
if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) {
|
||||
printf("ioctl pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
//enable irq
|
||||
parameter.cmd = GPIO_IRQ_ENABLE;
|
||||
parameter.pin = BSP_KEY_PIN;
|
||||
if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) {
|
||||
printf("ioctl pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
StartupKTask(taskid);
|
||||
|
||||
while(1){
|
||||
PrivTaskDelay(1000);
|
||||
if(KTaskSearch("LedFlip") == 0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestGpioIrq, a gpio irq test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
#define BSP_LED_PIN 134
|
||||
#define NULL_PARAMETER 0
|
||||
|
||||
static uint16_t pin_fd=0;
|
||||
static struct PinStat pin_led;
|
||||
|
||||
void ledflip(void *parameter)
|
||||
{
|
||||
pin_led.pin = BSP_LED_PIN;
|
||||
pin_led.val = !pin_led.val;
|
||||
PrivWrite(pin_fd,&pin_led,NULL_PARAMETER);
|
||||
}
|
||||
|
||||
void TestHwTimer(void)
|
||||
{
|
||||
x_ticks_t period = 100000;
|
||||
|
||||
pin_fd = PrivOpen(HWTIMER_PIN_DEV_DRIVER, O_RDWR);
|
||||
if(pin_fd<0){
|
||||
printf("open pin fd error:%d\n",pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
int timer_fd = PrivOpen(HWTIMER_TIMER_DEV_DRIVER, O_RDWR);
|
||||
if(timer_fd<0){
|
||||
printf("open timer fd error:%d\n",timer_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
//config led pin in board
|
||||
struct PinParam parameter;
|
||||
parameter.cmd = GPIO_CONFIG_MODE;
|
||||
parameter.pin = BSP_LED_PIN;
|
||||
parameter.mode = GPIO_CFG_OUTPUT;
|
||||
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
|
||||
ioctl_cfg.args = (void *)¶meter;
|
||||
|
||||
if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) {
|
||||
printf("ioctl pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
ioctl_cfg.ioctl_driver_type = TIME_TYPE;
|
||||
ioctl_cfg.args = (void *)&ledflip;
|
||||
if (0 != PrivIoctl(timer_fd, OPE_INT, &ioctl_cfg)) {
|
||||
printf("timer pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
ioctl_cfg.args = (void *).
|
||||
if (0 != PrivIoctl(timer_fd, OPE_CFG, &ioctl_cfg)) {
|
||||
printf("timer pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
while(1){
|
||||
|
||||
}
|
||||
|
||||
// int32 timer_handle = KCreateTimer("LED on and off by 1s",&ledflip,&pin_fd,period,TIMER_TRIGGER_PERIODIC);
|
||||
|
||||
// KTimerStartRun(timer_handle);
|
||||
PrivClose(pin_fd);
|
||||
PrivClose(timer_fd);
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestHwTimer, a timer test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
#define I2C_SLAVE_ADDRESS 0x0012U
|
||||
|
||||
void TestI2C(void)
|
||||
{
|
||||
// config IIC pin(SCL:34.SDA:35) in menuconfig
|
||||
int iic_fd = PrivOpen(I2C_DEV_DRIVER, O_RDWR);
|
||||
if (iic_fd < 0)
|
||||
{
|
||||
printf("open iic_fd fd error:%d\n", iic_fd);
|
||||
return;
|
||||
}
|
||||
printf("IIC open successful!\n");
|
||||
|
||||
// init iic
|
||||
uint16 iic_address = I2C_SLAVE_ADDRESS;
|
||||
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = I2C_TYPE;
|
||||
ioctl_cfg.args = (void *)&iic_address;
|
||||
|
||||
if (0 != PrivIoctl(iic_fd, OPE_INT, &ioctl_cfg))
|
||||
{
|
||||
printf("ioctl iic fd error %d\n", iic_fd);
|
||||
PrivClose(iic_fd);
|
||||
return;
|
||||
}
|
||||
printf("IIC configure successful!\n");
|
||||
|
||||
// I2C read and write
|
||||
char tmp_buff[100];
|
||||
while (1)
|
||||
{
|
||||
PrivTaskDelay(1000);
|
||||
PrivWrite(iic_fd, "Hello World!\n", sizeof("Hello World!\n"));
|
||||
printf("msg send:%s\n", "Hello World!\n");
|
||||
PrivTaskDelay(1000);
|
||||
memset(tmp_buff, 0, sizeof(tmp_buff));
|
||||
PrivRead(iic_fd, tmp_buff, sizeof(tmp_buff));
|
||||
printf("msg recv:%s\n", tmp_buff);
|
||||
}
|
||||
|
||||
PrivClose(iic_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestI2C, a iic test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -1,26 +1,22 @@
|
|||
/****************************************************************************
|
||||
* apps/examples/fb/fb_main.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
/**
|
||||
* @file: test_lcd.c
|
||||
* @brief: a application of dac function
|
||||
* @version: 2.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2022/1/11
|
||||
*/
|
||||
|
||||
#include <transform.h>
|
||||
|
||||
|
|
@ -29,40 +25,39 @@
|
|||
#ifdef CONFIG_K210_LCD
|
||||
void LcdDemo(void)
|
||||
{
|
||||
int x1 = 50, y1 = 50, x2 = LCD_XSIZE_TFT - 50, y2 = LCD_YSIZE_TFT - 50;
|
||||
int lcd_fd = PrivOpen("/dev/lcd_dev",O_RDWR);
|
||||
LcdWriteParam disp_info;
|
||||
|
||||
Main_Image_Start_Address(LCD_START_ADDR);
|
||||
Main_Image_Width(LCD_XSIZE_TFT);
|
||||
Main_Window_Start_XY(0, 0);
|
||||
Canvas_Image_Start_address(LCD_START_ADDR);
|
||||
Canvas_image_width(LCD_XSIZE_TFT);
|
||||
Active_Window_XY(0, 0);
|
||||
Active_Window_WH(LCD_XSIZE_TFT, LCD_YSIZE_TFT);
|
||||
up_mdelay(10);
|
||||
Canvas_Image_Start_address(LCD_START_ADDR);
|
||||
disp_info.type = 0;
|
||||
disp_info.string_info.x_pos = 80;
|
||||
disp_info.string_info.y_pos = 80;
|
||||
disp_info.string_info.width = 250;
|
||||
disp_info.string_info.height = 24;
|
||||
disp_info.string_info.font_size = 24;
|
||||
disp_info.string_info.addr = "wecome test lcd";
|
||||
disp_info.string_info.font_color = GREEN;
|
||||
disp_info.string_info.back_color = BLUE;
|
||||
PrivWrite(lcd_fd, &disp_info, sizeof(LcdWriteParam));
|
||||
PrivTaskDelay(2000);
|
||||
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
x1 = 50;
|
||||
y1 = 50;
|
||||
x2 = LCD_XSIZE_TFT - 50;
|
||||
y2 = LCD_YSIZE_TFT - 50;
|
||||
syslog(LOG_NOTICE, "Disp_demo %d (%d,%d - %d,%d)\n", i, x1, y1, x2, y2);
|
||||
LT768_DrawSquare_Fill(x1, y1, x2, y2, Red);
|
||||
up_mdelay(2000);
|
||||
x1 += 20;
|
||||
y1 += 20;
|
||||
x2 -= 20;
|
||||
y2 -= 20;
|
||||
LT768_DrawSquare_Fill(x1, y1, x2, y2, Green);
|
||||
up_mdelay(2000);
|
||||
x1 += 20;
|
||||
y1 += 20;
|
||||
x2 -= 20;
|
||||
y2 -= 20;
|
||||
LT768_DrawSquare_Fill(x1, y1, x2, y2, Blue);
|
||||
up_mdelay(2000);
|
||||
}
|
||||
disp_info.type = 1;
|
||||
lv_color_t redcolor = {
|
||||
.ch = {
|
||||
.red = 0b11111,
|
||||
.green = 0,
|
||||
.blue = 0
|
||||
}
|
||||
};
|
||||
disp_info.pixel_info.x_startpos = 0;
|
||||
disp_info.pixel_info.x_endpos = 50;
|
||||
disp_info.pixel_info.y_startpos = 0;
|
||||
disp_info.pixel_info.y_endpos = 50;
|
||||
disp_info.pixel_info.pixel_color = &redcolor;
|
||||
PrivWrite(lcd_fd, &disp_info, sizeof(LcdWriteParam));
|
||||
PrivTaskDelay(2000);
|
||||
|
||||
disp_info.type = SHOW_TRIANGLE;
|
||||
PrivWrite(lcd_fd, &disp_info, sizeof(LcdWriteParam));
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
#define GRAPHIC_CTRL_RECT_UPDATE 0x00
|
||||
#define LCD_STRING_TYPE 0
|
||||
#define LCD_DOT_TYPE 1
|
||||
#define LCD_FONT_RECT_WIDTH 150
|
||||
#define LCD_FONT_RECT_HEIGHT 50
|
||||
#define NULL_PARAMETER 0
|
||||
|
||||
void TestLcd(void)
|
||||
{
|
||||
int lcd_fd = PrivOpen(EDU_LCD_DEV_DRIVER, O_RDWR);
|
||||
if (lcd_fd < 0)
|
||||
{
|
||||
printf("open lcd fd error:%d\n", lcd_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
// draw text
|
||||
LcdWriteParam graph_param;
|
||||
graph_param.type = LCD_STRING_TYPE;
|
||||
graph_param.string_info.x_pos = 0;
|
||||
graph_param.string_info.y_pos = 0;
|
||||
graph_param.string_info.width = 250;
|
||||
graph_param.string_info.height = 24;
|
||||
graph_param.string_info.font_size = 24;
|
||||
graph_param.string_info.back_color = 0xFFFF;
|
||||
graph_param.string_info.font_color = 0x0000;
|
||||
graph_param.string_info.addr = "hello_world!";
|
||||
|
||||
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
|
||||
|
||||
uint16 color_select = 0xF800;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
graph_param.type = LCD_DOT_TYPE;
|
||||
graph_param.pixel_info.x_startpos = 0;
|
||||
graph_param.pixel_info.y_startpos = 50 * i;
|
||||
graph_param.pixel_info.x_endpos = 320;
|
||||
graph_param.pixel_info.y_endpos = 50 * i;
|
||||
graph_param.pixel_info.pixel_color = &color_select;
|
||||
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
|
||||
}
|
||||
|
||||
PrivClose(lcd_fd);
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestLcd, a lcd test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
#define NULL_PARAMETER 0
|
||||
#define E220_CFG_LENGTH
|
||||
#define GPIOSET(fd, buf, bit) \
|
||||
{ \
|
||||
buf.val = bit; \
|
||||
if (0 > PrivWrite(fd, &buf, NULL_PARAMETER)) \
|
||||
{ \
|
||||
printf("write pin fd error %d\n", fd); \
|
||||
PrivClose(fd); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
#define BSP_E220_M0_PIN 32
|
||||
#define BSP_E220_M1_PIN 33
|
||||
|
||||
void TestLora(int argc, char *argv[])
|
||||
{
|
||||
char uart_recvbuff[100];
|
||||
memset(uart_recvbuff, 0, sizeof(uart_recvbuff));
|
||||
|
||||
int pin_fd = PrivOpen(LORA_PIN_DEV_DRIVER, O_RDWR);
|
||||
if (pin_fd < 0)
|
||||
{
|
||||
printf("open pin fd error:%d\n", pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
int uart_fd = PrivOpen(LORA_UART_DEV_DRIVER, O_RDWR);
|
||||
if (uart_fd < 0)
|
||||
{
|
||||
printf("open pin fd error:%d\n", uart_fd);
|
||||
return;
|
||||
}
|
||||
printf("uart and pin fopen success\n");
|
||||
|
||||
struct PinStat pin_m0;
|
||||
struct PinStat pin_m1;
|
||||
pin_m0.pin = BSP_E220_M0_PIN;
|
||||
pin_m1.pin = BSP_E220_M1_PIN;
|
||||
|
||||
// config led pin in board
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
struct PinParam pin_param;
|
||||
pin_param.cmd = GPIO_CONFIG_MODE;
|
||||
pin_param.mode = GPIO_CFG_OUTPUT;
|
||||
pin_param.pin = BSP_E220_M0_PIN;
|
||||
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
|
||||
ioctl_cfg.args = &pin_param;
|
||||
if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg))
|
||||
{
|
||||
printf("ioctl pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
pin_param.pin = BSP_E220_M1_PIN;
|
||||
if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg))
|
||||
{
|
||||
printf("ioctl pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("pin configure success\n");
|
||||
struct SerialDataCfg uart_cfg;
|
||||
|
||||
// loraE220 support only 9600bps with 8N1 during initializing
|
||||
uart_cfg.serial_baud_rate = BAUD_RATE_9600;
|
||||
uart_cfg.serial_data_bits = DATA_BITS_8;
|
||||
uart_cfg.serial_stop_bits = STOP_BITS_1;
|
||||
uart_cfg.serial_parity_mode = PARITY_NONE;
|
||||
uart_cfg.serial_bit_order = BIT_ORDER_LSB;
|
||||
uart_cfg.serial_invert_mode = NRZ_NORMAL;
|
||||
uart_cfg.serial_buffer_size = SERIAL_RB_BUFSZ;
|
||||
uart_cfg.serial_timeout = 1000;
|
||||
uart_cfg.is_ext_uart = 0;
|
||||
|
||||
ioctl_cfg.ioctl_driver_type = SERIAL_TYPE;
|
||||
ioctl_cfg.args = (void *)&uart_cfg;
|
||||
|
||||
if (0 != PrivIoctl(uart_fd, OPE_INT, &ioctl_cfg))
|
||||
{
|
||||
printf("ioctl uart fd error %d\n", uart_fd);
|
||||
PrivClose(uart_fd);
|
||||
return;
|
||||
}
|
||||
printf("uart configure success\n");
|
||||
|
||||
GPIOSET(pin_fd, pin_m0, GPIO_HIGH);
|
||||
GPIOSET(pin_fd, pin_m1, GPIO_HIGH);
|
||||
printf("lora configure into sleep(configure) mode\n");
|
||||
|
||||
// send configure data, and receive the same length of data
|
||||
// configure loraE220 as address 1949 CH17 36.8kps
|
||||
char sendbuff[] = {0xC0, 0x00, 0x05, 0x19, 0x49, 0xE6, 0x00, 0x17};
|
||||
|
||||
PrivTaskDelay(2000);
|
||||
|
||||
printf("Sending lora configure information(SIZE:%d)\n", sizeof(sendbuff));
|
||||
PrivWrite(uart_fd, sendbuff, sizeof(sendbuff));
|
||||
printf("lora configure information send\n");
|
||||
|
||||
PrivTaskDelay(2000);
|
||||
|
||||
PrivRead(uart_fd, uart_recvbuff, sizeof(sendbuff));
|
||||
printf("%x %x %x %x", uart_recvbuff[0], uart_recvbuff[1], uart_recvbuff[2], uart_recvbuff[3]);
|
||||
printf("lora configure success\n");
|
||||
|
||||
// error when all bytes are 0xff
|
||||
if (0xFF == (uart_recvbuff[0] & uart_recvbuff[1] & uart_recvbuff[2]))
|
||||
{
|
||||
printf("from lora receive error:%d\n", 0xff);
|
||||
return;
|
||||
}
|
||||
|
||||
uart_cfg.serial_baud_rate = BAUD_RATE_115200;
|
||||
if (0 != PrivIoctl(uart_fd, OPE_INT, &ioctl_cfg))
|
||||
{
|
||||
printf("ioctl uart fd error %d\n", uart_fd);
|
||||
PrivClose(uart_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
// into transparent transmission mode
|
||||
GPIOSET(pin_fd, pin_m0, GPIO_LOW);
|
||||
GPIOSET(pin_fd, pin_m1, GPIO_LOW);
|
||||
// receive and send "Hello World"
|
||||
while (1)
|
||||
{
|
||||
PrivTaskDelay(500);
|
||||
PrivWrite(uart_fd, "Hello_World!", sizeof("Hello_World!"));
|
||||
printf("Data Send:\n%s\n", "Hello_World!");
|
||||
|
||||
PrivTaskDelay(500);
|
||||
memset(uart_recvbuff, 0, sizeof(uart_recvbuff));
|
||||
PrivRead(uart_fd, uart_recvbuff, sizeof(uart_recvbuff));
|
||||
printf("Receive Data is :\n%s\n", uart_recvbuff);
|
||||
}
|
||||
PrivClose(pin_fd);
|
||||
PrivClose(uart_fd);
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestLora, a lora test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: test_musl.c
|
||||
* @brief: a application of musl test function
|
||||
* @version: 2.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2022/11/8
|
||||
*/
|
||||
|
||||
#include <transform.h>
|
||||
|
||||
#ifdef ADD_NUTTX_FETURES
|
||||
|
||||
#if defined(CONFIG_MUSL_LIBC) && defined(CONFIG_FS_AUTOMOUNTER)
|
||||
|
||||
static void file_read_and_write(void)
|
||||
{
|
||||
FILE *p;
|
||||
char s[] = "good luck to you!";
|
||||
char buffer[20];
|
||||
|
||||
if((p = fopen("/mnt/sdcard/test.txt","w+")) == NULL)
|
||||
{
|
||||
printf("Can not open file!\n");
|
||||
}
|
||||
fwrite(s, sizeof(s) + 1, 1, p);
|
||||
fseek(p, SEEK_SET, 0);
|
||||
fread(buffer, sizeof(buffer) + 1, 1, p);
|
||||
printf("read string is: %s\n", buffer);
|
||||
fclose(p);
|
||||
}
|
||||
|
||||
static void file_operations(void)
|
||||
{
|
||||
int ret;
|
||||
FILE *fp;
|
||||
char filename1[] = "/mnt/sdcard/file1.txt";
|
||||
char filename2[] = "/mnt/sdcard/file2.txt";
|
||||
|
||||
fp = fopen(filename1, "w");
|
||||
|
||||
fprintf(fp, "%s", "this is runoob.com");
|
||||
fclose(fp);
|
||||
|
||||
ret = remove(filename1);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
printf("remove file1 success!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("error,can not remove file1!\n");
|
||||
}
|
||||
|
||||
ret = remove(filename2);
|
||||
if(ret == 0)
|
||||
{
|
||||
printf("remove file2 success!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("error,can not remove file2!\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void malloc_and_free(void)
|
||||
{
|
||||
int *p;
|
||||
int len;
|
||||
for(int i = 0; i < 100; i++)
|
||||
{
|
||||
len = 1024*(i+1);
|
||||
p = malloc(len);
|
||||
if(p)
|
||||
{
|
||||
printf("malloc %d bytes success!\n",len);
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
void Testmusl(void)
|
||||
{
|
||||
printf("--------start test file read and write!--------\n");
|
||||
file_read_and_write();
|
||||
printf("----------start test file operationsn!---------\n");
|
||||
file_operations();
|
||||
printf("---------start test malloc and free!-----------\n");
|
||||
malloc_and_free();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
#define BSP_485_DIR_PIN 24
|
||||
|
||||
void Test485(void)
|
||||
{
|
||||
int pin_fd = PrivOpen(RS485_PIN_DEV_DRIVER, O_RDWR);
|
||||
if (pin_fd < 0)
|
||||
{
|
||||
printf("open pin fd error:%d\n", pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
int uart_fd = PrivOpen(RS485_UART_DEV_DRIVER, O_RDWR);
|
||||
if (uart_fd < 0)
|
||||
{
|
||||
printf("open pin fd error:%d\n", uart_fd);
|
||||
return;
|
||||
}
|
||||
printf("uart and pin fopen success\n");
|
||||
|
||||
//config led pin in board
|
||||
struct PinParam pin_parameter;
|
||||
memset(&pin_parameter, 0, sizeof(struct PinParam));
|
||||
pin_parameter.cmd = GPIO_CONFIG_MODE;
|
||||
pin_parameter.pin = BSP_485_DIR_PIN;
|
||||
pin_parameter.mode = GPIO_CFG_OUTPUT;
|
||||
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
|
||||
ioctl_cfg.args = (void *)&pin_parameter;
|
||||
|
||||
if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) {
|
||||
printf("ioctl pin fd error %d\n", pin_fd);
|
||||
PrivClose(pin_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
struct SerialDataCfg uart_cfg;
|
||||
memset(&uart_cfg, 0, sizeof(struct SerialDataCfg));
|
||||
|
||||
uart_cfg.serial_baud_rate = BAUD_RATE_115200;
|
||||
uart_cfg.serial_data_bits = DATA_BITS_8;
|
||||
uart_cfg.serial_stop_bits = STOP_BITS_1;
|
||||
uart_cfg.serial_parity_mode = PARITY_NONE;
|
||||
uart_cfg.serial_bit_order = BIT_ORDER_LSB;
|
||||
uart_cfg.serial_invert_mode = NRZ_NORMAL;
|
||||
uart_cfg.serial_buffer_size = SERIAL_RB_BUFSZ;
|
||||
uart_cfg.serial_timeout = 1000;
|
||||
uart_cfg.is_ext_uart = 0;
|
||||
|
||||
ioctl_cfg.ioctl_driver_type = SERIAL_TYPE;
|
||||
ioctl_cfg.args = (void *)&uart_cfg;
|
||||
|
||||
if (0 != PrivIoctl(uart_fd, OPE_INT, &ioctl_cfg))
|
||||
{
|
||||
printf("ioctl uart fd error %d\n", uart_fd);
|
||||
PrivClose(uart_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
struct PinStat pin_dir;
|
||||
pin_dir.pin = BSP_485_DIR_PIN;
|
||||
while (1)
|
||||
{
|
||||
pin_dir.val = GPIO_HIGH;
|
||||
PrivWrite(pin_fd,&pin_dir,0);
|
||||
PrivWrite(uart_fd,"Hello world!\n",sizeof("Hello world!\n"));
|
||||
PrivTaskDelay(100);
|
||||
|
||||
pin_dir.val = GPIO_LOW;
|
||||
PrivWrite(pin_fd,&pin_dir,0);
|
||||
char recv_buff[100];
|
||||
memset(recv_buff,0,sizeof(recv_buff));
|
||||
PrivRead(uart_fd,recv_buff,20);
|
||||
printf("%s",recv_buff);
|
||||
PrivTaskDelay(100);
|
||||
}
|
||||
PrivClose(pin_fd);
|
||||
PrivClose(uart_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(Test485, a RS485 test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
void TestRTC(int argc,char *argv[])
|
||||
{
|
||||
int rtc_fd = PrivOpen(RTC_DEV_DRIVER, O_RDWR);
|
||||
if(rtc_fd<0){
|
||||
printf("open rtc fd error:%d\n",rtc_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if(argc>1){
|
||||
int times = atoi(argv[1]);
|
||||
printf("Time will be printf %d times\n",times);
|
||||
|
||||
struct RtcDrvConfigureParam rtc_para;
|
||||
time_t my_time=0;
|
||||
|
||||
rtc_para.rtc_operation_cmd = OPER_RTC_SET_TIME;
|
||||
rtc_para.time = &my_time;
|
||||
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = RTC_TYPE;
|
||||
ioctl_cfg.args = (void *)&rtc_para;
|
||||
|
||||
PrivIoctl(rtc_fd,0,&ioctl_cfg);
|
||||
|
||||
rtc_para.rtc_operation_cmd = OPER_RTC_GET_TIME;
|
||||
for(size_t i=0;i<times;i++){
|
||||
PrivIoctl(rtc_fd,0,&ioctl_cfg);
|
||||
printf("The time now is %d\n",*(rtc_para.time));
|
||||
PrivTaskDelay(5000);
|
||||
}
|
||||
}
|
||||
|
||||
PrivClose(rtc_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestRTC, a rtc test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/****************************************************************************
|
||||
* apps/examples/fb/fb_main.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <transform.h>
|
||||
|
||||
#ifdef ADD_NUTTX_FETURES
|
||||
|
||||
#ifdef CONFIG_BSP_USING_TOUCH
|
||||
void TestTouch(void)
|
||||
{
|
||||
int fd;
|
||||
TouchDataParam point = {0, 0, 0};
|
||||
fd = PrivOpen("/dev/touch_dev", O_RDWR);
|
||||
while(1)
|
||||
{
|
||||
PrivRead(fd,&point,1);
|
||||
printf("Now touch point:(%d,%d)\n",point.x,point.y);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
#define NULL_PARAMETER 0
|
||||
#define LCD_DOT_TYPE 1
|
||||
#define LCD_SIZE 320
|
||||
|
||||
|
||||
void TestTouch(void)
|
||||
{
|
||||
int touch_fd = PrivOpen(TOUCH_DEV_DRIVER, O_RDWR);
|
||||
if (touch_fd < 0)
|
||||
{
|
||||
printf("open touch fd error:%d\n", touch_fd);
|
||||
return;
|
||||
}
|
||||
int lcd_fd = PrivOpen(TOUCH_LCD_DEV_DRIVER, O_RDWR);
|
||||
if (lcd_fd < 0)
|
||||
{
|
||||
printf("open lcd fd error:%d\n", lcd_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
// draw text
|
||||
struct TouchDataStandard touch_pixel;
|
||||
memset(&touch_pixel,0,sizeof(touch_pixel));
|
||||
LcdWriteParam graph_param;
|
||||
|
||||
|
||||
graph_param.type = LCD_DOT_TYPE;
|
||||
|
||||
uint16_t back_color[LCD_SIZE];
|
||||
memset(back_color,0x00,sizeof(back_color));
|
||||
for (int i = 0; i < LCD_SIZE; i++)
|
||||
{
|
||||
graph_param.pixel_info.pixel_color = &back_color;
|
||||
graph_param.pixel_info.x_startpos = 0;
|
||||
graph_param.pixel_info.y_startpos = i;
|
||||
graph_param.pixel_info.x_endpos = LCD_SIZE -1;
|
||||
graph_param.pixel_info.y_endpos = i;
|
||||
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
|
||||
}
|
||||
|
||||
uint16 color_select[LCD_SIZE];
|
||||
memset(color_select,0xff,sizeof(color_select));
|
||||
graph_param.pixel_info.pixel_color = &color_select;
|
||||
while(1){
|
||||
if(0 > PrivRead(touch_fd, &touch_pixel, NULL_PARAMETER)){
|
||||
printf("read touch error\n");
|
||||
return;
|
||||
}
|
||||
printf("touch pixel position x:%d,y:%d\n",touch_pixel.x,touch_pixel.y);
|
||||
graph_param.pixel_info.x_startpos = touch_pixel.x-10>0?touch_pixel.x-10:0;
|
||||
graph_param.pixel_info.y_startpos = touch_pixel.y;
|
||||
graph_param.pixel_info.x_endpos = touch_pixel.x+10;
|
||||
graph_param.pixel_info.y_endpos = touch_pixel.y;
|
||||
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
|
||||
graph_param.pixel_info.x_startpos = touch_pixel.x;
|
||||
graph_param.pixel_info.y_startpos = touch_pixel.y-10>0?touch_pixel.y-10:0;
|
||||
graph_param.pixel_info.x_endpos = touch_pixel.x;
|
||||
graph_param.pixel_info.y_endpos = touch_pixel.y+10;
|
||||
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
|
||||
}
|
||||
PrivClose(lcd_fd);
|
||||
PrivClose(touch_fd);
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestTouch, a touch test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
void TestWDT(int argc, char *agrv[])
|
||||
{
|
||||
int wdt_fd = PrivOpen(WDT0_DEV_DRIVER, O_RDWR);
|
||||
if (wdt_fd < 0)
|
||||
{
|
||||
printf("open wdt_fd fd error:%d\n", wdt_fd);
|
||||
return;
|
||||
}
|
||||
printf("hw watchdog open!\n");
|
||||
|
||||
// init watchdog
|
||||
int wdt_time = 1000;
|
||||
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = WDT_TYPE;
|
||||
ioctl_cfg.args = (void *)&wdt_time;
|
||||
|
||||
if (0 != PrivIoctl(wdt_fd, OPER_WDT_SET_TIMEOUT, &ioctl_cfg))
|
||||
{
|
||||
printf("ioctl wdt fd error %d\n", wdt_fd);
|
||||
PrivClose(wdt_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
int test_counter = 100;
|
||||
|
||||
// wdt feed or not according to argc,if argc!=1 then dog won't be feed
|
||||
while (test_counter--)
|
||||
{
|
||||
if (1 == argc)
|
||||
{
|
||||
printf("dog is feed\n");
|
||||
PrivIoctl(wdt_fd, OPER_WDT_KEEPALIVE, &ioctl_cfg); // feed dog
|
||||
}
|
||||
PrivTaskDelay(100);
|
||||
}
|
||||
PrivClose(wdt_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
PRIV_SHELL_CMD_FUNCTION(TestWDT, a wdt test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file 4g_app.c
|
||||
* @brief support get data from and send data to 4g server
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.12.12
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
#include <adapter.h>
|
||||
|
||||
static uint8_t adapter_4g_status = 0;
|
||||
static pthread_t recv_4g_heart_task;
|
||||
struct Adapter *adapter_4g;
|
||||
|
||||
static const uint8_t server_addr[] = "xxx.xxx.xxx.xxx";
|
||||
static const uint8_t server_port[] = "xxx";
|
||||
|
||||
#define ADAPTER_4G_HEART "HEART"
|
||||
|
||||
int Adapter4GConnectFunction(struct Adapter *adapter, uint8_t reconnect)
|
||||
{
|
||||
int ret = 0;
|
||||
int baud_rate = BAUD_RATE_115200;
|
||||
|
||||
if (1 != reconnect) {
|
||||
ret = AdapterDeviceOpen(adapter);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = AdapterDeviceControl(adapter, OPE_INT, &baud_rate);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = AdapterDeviceConnect(adapter, CLIENT, server_addr, server_port, IPV4);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (ret < 0) {
|
||||
AdapterDeviceClose(adapter);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Adapter4gSend(uint8_t *send_data, size_t length)
|
||||
{
|
||||
if (adapter_4g_status) {
|
||||
AdapterDeviceSend(adapter_4g, send_data, length);
|
||||
}
|
||||
}
|
||||
|
||||
static void *Receive4gHeartTask(void* parameter)
|
||||
{
|
||||
char recv_msg[16] = {0};
|
||||
ssize_t recv_length = 0;
|
||||
uint8_t net_status_cnt = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
SetTaskStatus(0x01);
|
||||
|
||||
if (net_status_cnt > 5) {
|
||||
adapter_4g_status = 0;
|
||||
|
||||
while (Adapter4GConnectFunction(adapter_4g, 1) < 0) {
|
||||
PrivTaskDelay(10000);
|
||||
}
|
||||
|
||||
net_status_cnt = 0;
|
||||
}
|
||||
|
||||
adapter_4g_status = 1;
|
||||
|
||||
recv_length = AdapterDeviceRecv(adapter_4g, recv_msg, 6);
|
||||
if (recv_length > 0) {
|
||||
//if (0 == strcmp(recv_msg, ADAPTER_4G_HEART)) {
|
||||
net_status_cnt = 0;
|
||||
//}
|
||||
} else {
|
||||
printf("4G recv heart error re-recv cnt %d\n", net_status_cnt);
|
||||
net_status_cnt++;
|
||||
}
|
||||
memset(recv_msg, 0, sizeof(recv_msg));
|
||||
}
|
||||
}
|
||||
|
||||
int Adapter4GActive(void)
|
||||
{
|
||||
int ret = 0;
|
||||
adapter_4g = AdapterDeviceFindByName(ADAPTER_4G_NAME);
|
||||
|
||||
#ifdef ADAPTER_EC200T
|
||||
adapter_4g->socket.socket_id = 0;
|
||||
|
||||
ret = Adapter4GConnectFunction(adapter_4g, 0);
|
||||
if (ret < 0) {
|
||||
printf("Adapter4GConnect failed %d\n", ret);
|
||||
}
|
||||
|
||||
adapter_4g_status = 1;
|
||||
|
||||
pthread_attr_t attr;
|
||||
attr.schedparam.sched_priority = 22;
|
||||
attr.stacksize = 2048;
|
||||
|
||||
PrivTaskCreate(&recv_4g_heart_task, &attr, &Receive4gHeartTask, NULL);
|
||||
PrivTaskStartup(&recv_4g_heart_task);
|
||||
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := 4g_app.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
ifeq ($(CONFIG_SOCKET_DEMO),y)
|
||||
|
||||
include $(KERNEL_ROOT)/.config
|
||||
|
||||
ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
||||
|
|
@ -10,6 +7,10 @@ endif
|
|||
|
||||
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||
|
||||
ifeq ($(CONFIG_CONNECTION_ADAPTER_4G),y)
|
||||
SRC_DIR += 4g_app
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_RESOURCES_LWIP),y)
|
||||
SRC_DIR += socket_demo
|
||||
endif
|
||||
|
|
@ -17,4 +18,3 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
|||
include $(KERNEL_ROOT)/compiler.mk
|
||||
endif
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include <transform.h>
|
||||
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
#include "sys_arch.h"
|
||||
#include <sys_arch.h>
|
||||
#include <lwip/sockets.h>
|
||||
#include "lwip/sys.h"
|
||||
#endif
|
||||
|
|
@ -33,9 +33,17 @@
|
|||
#include "stdio.h"
|
||||
#endif
|
||||
|
||||
#define TCP_DEMO_BUF_SIZE 65535
|
||||
#define TCP_DEMO_BUF_SIZE 65535
|
||||
#define TCP_DEMO_SEND_TIMES 20
|
||||
#define LWIP_TCP_DEMO_TASK_STACK_SIZE 4096
|
||||
#define LWIP_TCP_DEMO_TASK_PRIO 20
|
||||
|
||||
char tcp_socket_ip[] = {192, 168, 250, 252};
|
||||
static pthread_t tcp_client_task;
|
||||
static pthread_t tcp_server_task;
|
||||
|
||||
static char tcp_demo_ipaddr[] = {192, 168, 131, 77};
|
||||
static char tcp_demo_netmask[] = {255, 255, 254, 0};
|
||||
static char tcp_demo_gwaddr[] = {192, 168, 131, 1};
|
||||
|
||||
#ifdef ADD_NUTTX_FETURES
|
||||
#define lw_print printf
|
||||
|
|
@ -46,8 +54,8 @@ char tcp_socket_ip[] = {192, 168, 250, 252};
|
|||
#define LWIP_TARGET_PORT 4840
|
||||
#endif
|
||||
|
||||
uint16_t tcp_socket_port = LWIP_TARGET_PORT;
|
||||
char tcp_ip_str[128] = {0};
|
||||
static uint16_t tcp_socket_port = 8888;
|
||||
static char tcp_ip_str[128] = {0};
|
||||
|
||||
/******************************************************************************/
|
||||
void TcpSocketConfigParam(char *ip_str)
|
||||
|
|
@ -55,35 +63,23 @@ void TcpSocketConfigParam(char *ip_str)
|
|||
int ip1, ip2, ip3, ip4, port = 0;
|
||||
|
||||
if(ip_str == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(sscanf(ip_str, "%d.%d.%d.%d:%d", &ip1, &ip2, &ip3, &ip4, &port))
|
||||
{
|
||||
if(sscanf(ip_str, "%d.%d.%d.%d:%d", &ip1, &ip2, &ip3, &ip4, &port)) {
|
||||
printf("config ip %s port %d\n", ip_str, port);
|
||||
strcpy(tcp_ip_str, ip_str);
|
||||
tcp_socket_ip[0] = ip1;
|
||||
tcp_socket_ip[1] = ip2;
|
||||
tcp_socket_ip[2] = ip3;
|
||||
tcp_socket_ip[3] = ip4;
|
||||
if(port)
|
||||
tcp_socket_port = port;
|
||||
return;
|
||||
}
|
||||
|
||||
if(sscanf(ip_str, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4))
|
||||
{
|
||||
if(sscanf(ip_str, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4)) {
|
||||
printf("config ip %s\n", ip_str);
|
||||
tcp_socket_ip[0] = ip1;
|
||||
tcp_socket_ip[1] = ip2;
|
||||
tcp_socket_ip[2] = ip3;
|
||||
tcp_socket_ip[3] = ip4;
|
||||
strcpy(tcp_ip_str, ip_str);
|
||||
}
|
||||
}
|
||||
|
||||
static void TcpSocketRecvTask(void *arg)
|
||||
static void *TcpSocketRecvTask(void *arg)
|
||||
{
|
||||
int fd = -1, clientfd;
|
||||
int recv_len;
|
||||
|
|
@ -91,18 +87,15 @@ static void TcpSocketRecvTask(void *arg)
|
|||
struct sockaddr_in tcp_addr;
|
||||
socklen_t addr_len;
|
||||
|
||||
while(1)
|
||||
{
|
||||
while(1) {
|
||||
recv_buf = (char *)malloc(TCP_DEMO_BUF_SIZE);
|
||||
if (recv_buf == NULL)
|
||||
{
|
||||
if (recv_buf == NULL) {
|
||||
lw_error("No memory\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
if (fd < 0) {
|
||||
lw_error("Socket error\n");
|
||||
free(recv_buf);
|
||||
continue;
|
||||
|
|
@ -113,8 +106,7 @@ static void TcpSocketRecvTask(void *arg)
|
|||
tcp_addr.sin_port = htons(tcp_socket_port);
|
||||
memset(&(tcp_addr.sin_zero), 0, sizeof(tcp_addr.sin_zero));
|
||||
|
||||
if (bind(fd, (struct sockaddr *)&tcp_addr, sizeof(struct sockaddr)) == -1)
|
||||
{
|
||||
if (bind(fd, (struct sockaddr *)&tcp_addr, sizeof(struct sockaddr)) == -1) {
|
||||
lw_error("Unable to bind\n");
|
||||
close(fd);
|
||||
free(recv_buf);
|
||||
|
|
@ -125,8 +117,7 @@ static void TcpSocketRecvTask(void *arg)
|
|||
lw_notice("\nLocal Port:%d\n", tcp_socket_port);
|
||||
|
||||
// setup socket fd as listening mode
|
||||
if (listen(fd, 5) != 0 )
|
||||
{
|
||||
if (listen(fd, 5) != 0 ) {
|
||||
lw_error("Unable to listen\n");
|
||||
close(fd);
|
||||
free(recv_buf);
|
||||
|
|
@ -137,13 +128,11 @@ static void TcpSocketRecvTask(void *arg)
|
|||
clientfd = accept(fd, (struct sockaddr *)&tcp_addr, (socklen_t*)&addr_len);
|
||||
lw_notice("client %s connected\n", inet_ntoa(tcp_addr.sin_addr));
|
||||
|
||||
while(1)
|
||||
{
|
||||
while(1) {
|
||||
memset(recv_buf, 0, TCP_DEMO_BUF_SIZE);
|
||||
recv_len = recvfrom(clientfd, recv_buf, TCP_DEMO_BUF_SIZE, 0,
|
||||
(struct sockaddr *)&tcp_addr, &addr_len);
|
||||
if(recv_len > 0)
|
||||
{
|
||||
if(recv_len > 0) {
|
||||
lw_notice("Receive from : %s\n", inet_ntoa(tcp_addr.sin_addr));
|
||||
lw_notice("Receive data : %d - %s\n\n", recv_len, recv_buf);
|
||||
}
|
||||
|
|
@ -157,26 +146,33 @@ static void TcpSocketRecvTask(void *arg)
|
|||
|
||||
void TcpSocketRecvTest(int argc, char *argv[])
|
||||
{
|
||||
if(argc >= 2)
|
||||
{
|
||||
if(argc >= 2) {
|
||||
lw_print("lw: [%s] target ip %s\n", __func__, argv[1]);
|
||||
TcpSocketConfigParam(argv[1]);
|
||||
}
|
||||
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, tcp_socket_ip);
|
||||
sys_thread_new("TcpSocketRecvTask", TcpSocketRecvTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
||||
lwip_config_tcp(0, tcp_demo_ipaddr, tcp_demo_netmask, tcp_demo_gwaddr);
|
||||
|
||||
pthread_attr_t attr;
|
||||
attr.schedparam.sched_priority = LWIP_TCP_DEMO_TASK_PRIO;
|
||||
attr.stacksize = LWIP_TCP_DEMO_TASK_STACK_SIZE;
|
||||
#endif
|
||||
|
||||
#ifdef ADD_NUTTX_FETURES
|
||||
TcpSocketRecvTask(NULL);
|
||||
pthread_attr_t attr = PTHREAD_ATTR_INITIALIZER;
|
||||
attr.priority = LWIP_TCP_DEMO_TASK_PRIO;
|
||||
attr.stacksize = LWIP_TCP_DEMO_TASK_STACK_SIZE;
|
||||
#endif
|
||||
|
||||
PrivTaskCreate(&tcp_server_task, &attr, &TcpSocketRecvTask, NULL);
|
||||
PrivTaskStartup(&tcp_server_task);
|
||||
}
|
||||
PRIV_SHELL_CMD_FUNCTION(TcpSocketRecvTest, a tcp receive sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
||||
static void TcpSocketSendTask(void *arg)
|
||||
static void *TcpSocketSendTask(void *arg)
|
||||
{
|
||||
int cnt = LWIP_DEMO_TIMES;
|
||||
int cnt = TCP_DEMO_SEND_TIMES;
|
||||
int fd = -1;
|
||||
int ret;
|
||||
char send_msg[128];
|
||||
|
|
@ -186,10 +182,9 @@ static void TcpSocketSendTask(void *arg)
|
|||
|
||||
memset(send_msg, 0, sizeof(send_msg));
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
if (fd < 0) {
|
||||
lw_print("Socket error\n");
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct sockaddr_in tcp_sock;
|
||||
|
|
@ -200,17 +195,15 @@ static void TcpSocketSendTask(void *arg)
|
|||
memset(&(tcp_sock.sin_zero), 0, sizeof(tcp_sock.sin_zero));
|
||||
|
||||
ret = connect(fd, (struct sockaddr *)&tcp_sock, sizeof(struct sockaddr));
|
||||
if (ret)
|
||||
{
|
||||
lw_print("Unable to connect %s = %d\n", tcp_ip_str, ret);
|
||||
if (ret < 0) {
|
||||
lw_print("Unable to connect %s:%d = %d\n", tcp_ip_str, tcp_socket_port, ret);
|
||||
close(fd);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lw_print("TCP connect %s:%d success, start to send.\n", tcp_ip_str, tcp_socket_port);
|
||||
|
||||
while (cnt --)
|
||||
{
|
||||
while (cnt --) {
|
||||
lw_print("Lwip client is running.\n");
|
||||
snprintf(send_msg, sizeof(send_msg), "TCP test package times %d\r\n", cnt);
|
||||
send(fd, send_msg, strlen(send_msg), 0);
|
||||
|
|
@ -219,24 +212,31 @@ static void TcpSocketSendTask(void *arg)
|
|||
}
|
||||
|
||||
close(fd);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void TcpSocketSendTest(int argc, char *argv[])
|
||||
{
|
||||
if(argc >= 2)
|
||||
{
|
||||
if(argc >= 2) {
|
||||
lw_print("lw: [%s] target ip %s\n", __func__, argv[1]);
|
||||
TcpSocketConfigParam(argv[1]);
|
||||
}
|
||||
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, tcp_socket_ip);
|
||||
sys_thread_new("Tcp Socket Send", TcpSocketSendTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
||||
lwip_config_tcp(0, tcp_demo_ipaddr, tcp_demo_netmask, tcp_demo_gwaddr);
|
||||
|
||||
pthread_attr_t attr;
|
||||
attr.schedparam.sched_priority = LWIP_TCP_DEMO_TASK_PRIO;
|
||||
attr.stacksize = LWIP_TCP_DEMO_TASK_STACK_SIZE;
|
||||
#endif
|
||||
#ifdef ADD_NUTTX_FETURES
|
||||
TcpSocketSendTask(NULL);
|
||||
pthread_attr_t attr = PTHREAD_ATTR_INITIALIZER;
|
||||
attr.priority = LWIP_TCP_DEMO_TASK_PRIO;
|
||||
attr.stacksize = LWIP_TCP_DEMO_TASK_STACK_SIZE;
|
||||
#endif
|
||||
|
||||
PrivTaskCreate(&tcp_client_task, &attr, &TcpSocketSendTask, NULL);
|
||||
PrivTaskStartup(&tcp_client_task);
|
||||
}
|
||||
PRIV_SHELL_CMD_FUNCTION(TcpSocketSendTest, a tcp send sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include <transform.h>
|
||||
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
#include "sys_arch.h"
|
||||
#include <sys_arch.h>
|
||||
#include "lwip/sockets.h"
|
||||
#endif
|
||||
|
||||
|
|
@ -38,11 +38,20 @@
|
|||
#define lw_print printf
|
||||
#endif
|
||||
|
||||
#define UDP_BUF_SIZE 65536
|
||||
#define UDP_DEMO_BUF_SIZE 65535
|
||||
#define UDP_DEMO_SEND_TIMES 20
|
||||
#define LWIP_UDP_DEMO_TASK_STACK_SIZE 4096
|
||||
#define LWIP_UDP_DEMO_TASK_PRIO 20
|
||||
|
||||
char udp_socket_ip[] = {192, 168, 250, 252};
|
||||
char udp_ip_str[128] = {0};
|
||||
uint16_t udp_socket_port = LWIP_LOCAL_PORT;
|
||||
static pthread_t udp_client_task;
|
||||
static pthread_t udp_server_task;
|
||||
|
||||
static char udp_demo_ipaddr[] = {192, 168, 131, 77};
|
||||
static char udp_demo_netmask[] = {255, 255, 254, 0};
|
||||
static char udp_demo_gwaddr[] = {192, 168, 131, 1};
|
||||
|
||||
static char udp_ip_str[128] = {0};
|
||||
static uint16_t udp_socket_port = 8888;
|
||||
|
||||
/*****************************************************************************/
|
||||
void UdpSocketConfigParam(char *ip_str)
|
||||
|
|
@ -50,53 +59,38 @@ void UdpSocketConfigParam(char *ip_str)
|
|||
int ip1, ip2, ip3, ip4, port = 0;
|
||||
|
||||
if(ip_str == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(sscanf(ip_str, "%d.%d.%d.%d:%d", &ip1, &ip2, &ip3, &ip4, &port))
|
||||
{
|
||||
if(sscanf(ip_str, "%d.%d.%d.%d:%d", &ip1, &ip2, &ip3, &ip4, &port)) {
|
||||
printf("config ip %s port %d\n", ip_str, port);
|
||||
strcpy(udp_ip_str, ip_str);
|
||||
udp_socket_ip[0] = ip1;
|
||||
udp_socket_ip[1] = ip2;
|
||||
udp_socket_ip[2] = ip3;
|
||||
udp_socket_ip[3] = ip4;
|
||||
if(port)
|
||||
udp_socket_port = port;
|
||||
return;
|
||||
}
|
||||
|
||||
if(sscanf(ip_str, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4))
|
||||
{
|
||||
if(sscanf(ip_str, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4)) {
|
||||
printf("config ip %s\n", ip_str);
|
||||
udp_socket_ip[0] = ip1;
|
||||
udp_socket_ip[1] = ip2;
|
||||
udp_socket_ip[2] = ip3;
|
||||
udp_socket_ip[3] = ip4;
|
||||
strcpy(udp_ip_str, ip_str);
|
||||
}
|
||||
}
|
||||
|
||||
static void UdpSocketRecvTask(void *arg)
|
||||
static void *UdpSocketRecvTask(void *arg)
|
||||
{
|
||||
int fd = -1;
|
||||
char *recv_buf;
|
||||
struct sockaddr_in udp_addr, server_addr;
|
||||
int recv_len;
|
||||
|
||||
while(1)
|
||||
{
|
||||
recv_buf = (char *)malloc(UDP_BUF_SIZE);
|
||||
if(recv_buf == NULL)
|
||||
{
|
||||
while(1) {
|
||||
recv_buf = (char *)PrivMalloc(UDP_DEMO_BUF_SIZE);
|
||||
if(recv_buf == NULL) {
|
||||
lw_error("No memory\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if(fd < 0)
|
||||
{
|
||||
if(fd < 0) {
|
||||
lw_error("Socket error\n");
|
||||
free(recv_buf);
|
||||
continue;
|
||||
|
|
@ -107,8 +101,7 @@ static void UdpSocketRecvTask(void *arg)
|
|||
udp_addr.sin_port = htons(udp_socket_port);
|
||||
memset(&(udp_addr.sin_zero), 0, sizeof(udp_addr.sin_zero));
|
||||
|
||||
if(bind(fd, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr)) == -1)
|
||||
{
|
||||
if(bind(fd, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr)) == -1) {
|
||||
lw_error("Unable to bind\n");
|
||||
close(fd);
|
||||
free(recv_buf);
|
||||
|
|
@ -118,12 +111,10 @@ static void UdpSocketRecvTask(void *arg)
|
|||
lw_notice("UDP bind success, start to receive.\n");
|
||||
lw_notice("\n\nLocal Port:%d\n\n", udp_socket_port);
|
||||
|
||||
while(1)
|
||||
{
|
||||
memset(recv_buf, 0, UDP_BUF_SIZE);
|
||||
recv_len = recv(fd, recv_buf, UDP_BUF_SIZE, 0);
|
||||
if(recv_len > 0)
|
||||
{
|
||||
while(1) {
|
||||
memset(recv_buf, 0, UDP_DEMO_BUF_SIZE);
|
||||
recv_len = recv(fd, recv_buf, UDP_DEMO_BUF_SIZE, 0);
|
||||
if(recv_len > 0) {
|
||||
lw_notice("Receive from : %s\n", inet_ntoa(server_addr.sin_addr));
|
||||
lw_notice("Receive data : %s\n\n", recv_buf);
|
||||
}
|
||||
|
|
@ -137,36 +128,41 @@ static void UdpSocketRecvTask(void *arg)
|
|||
|
||||
void UdpSocketRecvTest(int argc, char *argv[])
|
||||
{
|
||||
if(argc >= 2)
|
||||
{
|
||||
if(argc >= 2) {
|
||||
lw_notice("lw: [%s] target ip %s\n", __func__, argv[1]);
|
||||
UdpSocketConfigParam(argv[1]);
|
||||
}
|
||||
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, udp_socket_ip);
|
||||
sys_thread_new("UdpSocketRecvTask", UdpSocketRecvTask, NULL,
|
||||
LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
||||
lwip_config_tcp(0, udp_demo_ipaddr, udp_demo_netmask, udp_demo_gwaddr);
|
||||
|
||||
pthread_attr_t attr;
|
||||
attr.schedparam.sched_priority = LWIP_UDP_DEMO_TASK_PRIO;
|
||||
attr.stacksize = LWIP_UDP_DEMO_TASK_STACK_SIZE;
|
||||
#endif
|
||||
#ifdef ADD_NUTTX_FETURES
|
||||
UdpSocketRecvTask(NULL);
|
||||
pthread_attr_t attr = PTHREAD_ATTR_INITIALIZER;
|
||||
attr.priority = LWIP_TCP_DEMO_TASK_PRIO;
|
||||
attr.stacksize = LWIP_TCP_DEMO_TASK_STACK_SIZE;
|
||||
#endif
|
||||
|
||||
PrivTaskCreate(&udp_server_task, &attr, &UdpSocketRecvTask, NULL);
|
||||
PrivTaskStartup(&udp_server_task);
|
||||
}
|
||||
PRIV_SHELL_CMD_FUNCTION(UdpSocketRecvTest, a udp receive sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
||||
static void UdpSocketSendTask(void *arg)
|
||||
static void *UdpSocketSendTask(void *arg)
|
||||
{
|
||||
int cnt = LWIP_DEMO_TIMES;
|
||||
int cnt = UDP_DEMO_SEND_TIMES;
|
||||
char send_str[128];
|
||||
int fd = -1;
|
||||
|
||||
memset(send_str, 0, sizeof(send_str));
|
||||
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if(fd < 0)
|
||||
{
|
||||
if(fd < 0) {
|
||||
lw_error("Socket error\n");
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct sockaddr_in udp_sock;
|
||||
|
|
@ -175,19 +171,17 @@ static void UdpSocketSendTask(void *arg)
|
|||
udp_sock.sin_addr.s_addr = inet_addr(udp_ip_str);
|
||||
memset(&(udp_sock.sin_zero), 0, sizeof(udp_sock.sin_zero));
|
||||
|
||||
if(connect(fd, (struct sockaddr *)&udp_sock, sizeof(struct sockaddr)))
|
||||
{
|
||||
lw_error("Unable to connect\n");
|
||||
if(connect(fd, (struct sockaddr *)&udp_sock, sizeof(struct sockaddr)) < 0) {
|
||||
lw_error("Unable to connect %s:%d\n", udp_ip_str, udp_socket_port);
|
||||
close(fd);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lw_print("UDP connect %s:%d success, start to send.\n",
|
||||
udp_ip_str,
|
||||
udp_socket_port);
|
||||
|
||||
while(cnt --)
|
||||
{
|
||||
while(cnt --) {
|
||||
snprintf(send_str, sizeof(send_str), "UDP test package times %d\r\n", cnt);
|
||||
send(fd, send_str, strlen(send_str), 0);
|
||||
lw_notice("Send UDP msg: %s ", send_str);
|
||||
|
|
@ -195,25 +189,31 @@ static void UdpSocketSendTask(void *arg)
|
|||
}
|
||||
|
||||
close(fd);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void UdpSocketSendTest(int argc, char *argv[])
|
||||
{
|
||||
if(argc >= 2)
|
||||
{
|
||||
if(argc >= 2) {
|
||||
lw_notice("lw: [%s] target ip %s\n", __func__, argv[1]);
|
||||
UdpSocketConfigParam(argv[1]);
|
||||
}
|
||||
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, udp_socket_ip);
|
||||
sys_thread_new("UdpSocketSendTask", UdpSocketSendTask, NULL, LWIP_TASK_STACK_SIZE,
|
||||
LWIP_DEMO_TASK_PRIO);
|
||||
lwip_config_tcp(0, udp_demo_ipaddr, udp_demo_netmask, udp_demo_gwaddr);
|
||||
|
||||
pthread_attr_t attr;
|
||||
attr.schedparam.sched_priority = LWIP_UDP_DEMO_TASK_PRIO;
|
||||
attr.stacksize = LWIP_UDP_DEMO_TASK_STACK_SIZE;
|
||||
#endif
|
||||
#ifdef ADD_NUTTX_FETURES
|
||||
UdpSocketSendTask(NULL);
|
||||
pthread_attr_t attr = PTHREAD_ATTR_INITIALIZER;
|
||||
attr.priority = LWIP_TCP_DEMO_TASK_PRIO;
|
||||
attr.stacksize = LWIP_TCP_DEMO_TASK_STACK_SIZE;
|
||||
#endif
|
||||
|
||||
PrivTaskCreate(&udp_client_task, &attr, &UdpSocketSendTask, NULL);
|
||||
PrivTaskStartup(&udp_client_task);
|
||||
}
|
||||
PRIV_SHELL_CMD_FUNCTION(UdpSocketSendTest, a udp send sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,47 @@
|
|||
* @date 2022.9.27
|
||||
*/
|
||||
|
||||
|
||||
#include <control.h>
|
||||
|
||||
extern int Adapter4GActive(void);
|
||||
|
||||
void ControlFx3uTest(void)
|
||||
{
|
||||
int i, j = 0;
|
||||
int read_data_length = 0;
|
||||
uint8_t read_data[128] = {0};
|
||||
|
||||
#ifdef CONNECTION_ADAPTER_4G
|
||||
Adapter4GActive();
|
||||
#endif
|
||||
|
||||
ControlProtocolType modbus_tcp_protocol = ControlProtocolFind();
|
||||
if (NULL == modbus_tcp_protocol) {
|
||||
printf("%s get modbus tcp protocol %p failed\n", __func__, modbus_tcp_protocol);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s get modbus tcp protocol %p successfull\n", __func__, modbus_tcp_protocol);
|
||||
|
||||
if (CONTROL_REGISTERED == modbus_tcp_protocol->protocol_status) {
|
||||
ControlProtocolOpen(modbus_tcp_protocol);
|
||||
|
||||
for (;;) {
|
||||
read_data_length = ControlProtocolRead(modbus_tcp_protocol, read_data, sizeof(read_data));
|
||||
printf("%s read [%d] modbus tcp data %d using receipe file\n", __func__, i, read_data_length);
|
||||
if (read_data_length) {
|
||||
for (j = 0; j < read_data_length; j ++) {
|
||||
printf("j %d data 0x%x\n", j, read_data[j]);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
memset(read_data, 0, sizeof(read_data));
|
||||
PrivTaskDelay(10000);
|
||||
}
|
||||
|
||||
//ControlProtocolClose(modbus_tcp_protocol);
|
||||
}
|
||||
}
|
||||
PRIV_SHELL_CMD_FUNCTION(ControlFx3uTest, Mitsubishi fx3u Demo, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,32 @@
|
|||
* @date 2022.9.27
|
||||
*/
|
||||
|
||||
#include <control.h>
|
||||
|
||||
void ControlOmronTest(void)
|
||||
{
|
||||
int i = 0;
|
||||
uint16_t read_data_length = 0;
|
||||
uint8_t read_data[1024] = {0};
|
||||
ControlProtocolType fins_protocol = ControlProtocolFind();
|
||||
if (NULL == fins_protocol) {
|
||||
printf("%s get fins protocol %p failed\n", __func__, fins_protocol);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s get fins protocol %p successfull\n", __func__, fins_protocol);
|
||||
|
||||
if (CONTROL_REGISTERED == fins_protocol->protocol_status) {
|
||||
ControlProtocolOpen(fins_protocol);
|
||||
|
||||
for (;;) {
|
||||
read_data_length = ControlProtocolRead(fins_protocol, read_data, sizeof(read_data));
|
||||
printf("%s read [%d] fins data %d using receipe file\n", __func__, i, read_data_length);
|
||||
i++;
|
||||
PrivTaskDelay(100000);
|
||||
}
|
||||
|
||||
//ControlProtocolClose(fins_protocol);
|
||||
}
|
||||
}
|
||||
PRIV_SHELL_CMD_FUNCTION(ControlOmronTest, Omron Plc FINS Demo, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
SRC_DIR := list
|
||||
SRC_DIR := list circular_area
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
include $(KERNEL_ROOT)/.config
|
||||
ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
||||
include $(APPDIR)/Make.defs
|
||||
CSRCS += circular_area_app.c
|
||||
include $(APPDIR)/Application.mk
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||
SRC_FILES := circular_area_app.c
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
endif
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import os
|
||||
from building import *
|
||||
Import('RTT_ROOT')
|
||||
Import('rtconfig')
|
||||
cwd = GetCurrentDir()
|
||||
DEPENDS = [""]
|
||||
|
||||
SOURCES = ['circular_area_app.c']
|
||||
path = [cwd]
|
||||
objs = DefineGroup('circular_area', src = SOURCES, depend = DEPENDS,CPPPATH = path)
|
||||
Return("objs")
|
||||
|
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: circular_area_app.c
|
||||
* @brief: circular area file for applications
|
||||
* @version: 3.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2022/11/21
|
||||
*
|
||||
*/
|
||||
|
||||
#include "circular_area_app.h"
|
||||
|
||||
/**
|
||||
* This function will return whether the circular_area is full or not
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
*/
|
||||
int CircularAreaAppIsFull(CircularAreaAppType circular_area)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
|
||||
if((circular_area->readidx == circular_area->writeidx) && (circular_area->b_status)) {
|
||||
printf("the circular area is full\n");
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return whether the circular_area is empty or not
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
*/
|
||||
int CircularAreaAppIsEmpty(CircularAreaAppType circular_area)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
|
||||
if((circular_area->readidx == circular_area->writeidx) && (!circular_area->b_status)) {
|
||||
//printf("the circular area is empty\n");
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will reset the circular_area and set the descriptor to default
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
*/
|
||||
void CircularAreaAppReset(CircularAreaAppType circular_area)
|
||||
{
|
||||
circular_area->writeidx = 0;
|
||||
circular_area->readidx = 0;
|
||||
circular_area->b_status = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will release the circular_area descriptor and free the memory
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
*/
|
||||
void CircularAreaAppRelease(CircularAreaAppType circular_area)
|
||||
{
|
||||
circular_area->readidx = 0;
|
||||
circular_area->writeidx = 0;
|
||||
circular_area->p_head = NULL;
|
||||
circular_area->p_tail = NULL;
|
||||
circular_area->b_status = 0;
|
||||
circular_area->area_length = 0;
|
||||
|
||||
PrivFree(circular_area->data_buffer);
|
||||
PrivFree(circular_area);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the circual_area max length
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
*/
|
||||
uint32_t CircularAreaAppGetMaxLength(CircularAreaAppType circular_area)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
|
||||
return circular_area->area_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the data length of the circular_area
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
*/
|
||||
uint32_t CircularAreaAppGetDataLength(CircularAreaAppType circular_area)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
|
||||
if(CircularAreaAppIsFull(circular_area)) {
|
||||
return circular_area->area_length;
|
||||
} else {
|
||||
return (circular_area->writeidx - circular_area->readidx + circular_area->area_length) % circular_area->area_length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return whether it is need to divide the read data into two parts or not
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
* @param data_length output data length
|
||||
*/
|
||||
static uint32_t CircularAreaAppDivideRdData(CircularAreaAppType circular_area, uint32_t data_length)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
|
||||
if(circular_area->readidx + data_length <= circular_area->area_length) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return whether it is need to divide the write data into two parts or not
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
* @param data_length input data length
|
||||
*/
|
||||
static uint32_t CircularAreaAppDivideWrData(CircularAreaAppType circular_area, uint32_t data_length)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
|
||||
if(circular_area->writeidx + data_length <= circular_area->area_length) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will read data from the circular_area
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
* @param output_buffer output data buffer poniter
|
||||
* @param data_length output data length
|
||||
*/
|
||||
int CircularAreaAppRead(CircularAreaAppType circular_area, uint8_t *output_buffer, uint32_t data_length)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
CA_PARAM_CHECK(output_buffer);
|
||||
CHECK(data_length > 0);
|
||||
|
||||
if(CircularAreaAppIsEmpty(circular_area)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int read_length = (data_length > CircularAreaAppGetDataLength(circular_area)) ? CircularAreaAppGetDataLength(circular_area) : data_length;
|
||||
// if (data_length > CircularAreaAppGetDataLength(circular_area)) {
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
if(CircularAreaAppDivideRdData(circular_area, read_length)) {
|
||||
uint32_t read_len_up = circular_area->area_length - circular_area->readidx;
|
||||
uint32_t read_len_down = read_length - read_len_up;
|
||||
|
||||
memcpy(output_buffer, &circular_area->data_buffer[circular_area->readidx], read_len_up);
|
||||
memcpy(output_buffer + read_len_up, circular_area->p_head, read_len_down);
|
||||
|
||||
circular_area->readidx = read_len_down;
|
||||
} else {
|
||||
memcpy(output_buffer, &circular_area->data_buffer[circular_area->readidx], read_length);
|
||||
circular_area->readidx = (circular_area->readidx + read_length) % circular_area->area_length;
|
||||
}
|
||||
|
||||
circular_area->b_status = 0;
|
||||
|
||||
return read_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will write data to the circular_area
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
* @param input_buffer input data buffer poniter
|
||||
* @param data_length input data length
|
||||
* @param b_force whether to force to write data disregard the length limit
|
||||
*/
|
||||
int CircularAreaAppWrite(CircularAreaAppType circular_area, uint8_t *input_buffer, uint32_t data_length, int b_force)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
CA_PARAM_CHECK(input_buffer);
|
||||
CHECK(data_length > 0);
|
||||
|
||||
if(CircularAreaAppIsFull(circular_area) && (!b_force)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t write_data_length = circular_area->area_length - CircularAreaAppGetDataLength(circular_area);
|
||||
//data_length = (data_length > write_data_length) ? write_data_length : data_length;
|
||||
if (data_length > write_data_length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(CircularAreaAppDivideWrData(circular_area, data_length)) {
|
||||
uint32_t write_len_up = circular_area->area_length - circular_area->writeidx;
|
||||
uint32_t write_len_down = data_length - write_len_up;
|
||||
|
||||
memcpy(&circular_area->data_buffer[circular_area->writeidx], input_buffer, write_len_up);
|
||||
memcpy(circular_area->p_head, input_buffer + write_len_up, write_len_down);
|
||||
|
||||
circular_area->writeidx = write_len_down;
|
||||
} else {
|
||||
memcpy(&circular_area->data_buffer[circular_area->writeidx], input_buffer, data_length);
|
||||
circular_area->writeidx = (circular_area->writeidx + data_length) % circular_area->area_length;
|
||||
}
|
||||
|
||||
circular_area->b_status = 1;
|
||||
|
||||
if(b_force) {
|
||||
circular_area->readidx = circular_area->writeidx;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct CircularAreaAppOps CircularAreaAppOperations =
|
||||
{
|
||||
CircularAreaAppRead,
|
||||
CircularAreaAppWrite,
|
||||
CircularAreaAppRelease,
|
||||
CircularAreaAppReset,
|
||||
};
|
||||
|
||||
/**
|
||||
* This function will initialize the circular_area
|
||||
*
|
||||
* @param circular_area_length circular_area length
|
||||
*/
|
||||
CircularAreaAppType CircularAreaAppInit(uint32_t circular_area_length)
|
||||
{
|
||||
CHECK(circular_area_length > 0);
|
||||
|
||||
circular_area_length = CA_ALIGN_DOWN(circular_area_length, 8);
|
||||
|
||||
CircularAreaAppType circular_area = PrivMalloc(sizeof(struct CircularAreaApp));
|
||||
if(NULL == circular_area) {
|
||||
printf("CircularAreaAppInit malloc struct circular_area failed\n");
|
||||
PrivFree(circular_area);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CircularAreaAppReset(circular_area);
|
||||
|
||||
circular_area->data_buffer = PrivMalloc(circular_area_length);
|
||||
if(NULL == circular_area->data_buffer) {
|
||||
printf("CircularAreaAppInit malloc circular_area data_buffer failed\n");
|
||||
PrivFree(circular_area->data_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
circular_area->p_head = circular_area->data_buffer;
|
||||
circular_area->p_tail = circular_area->data_buffer + circular_area_length;
|
||||
circular_area->area_length = circular_area_length;
|
||||
|
||||
printf("CircularAreaAppInit done p_head %8p p_tail %8p length %u\n",
|
||||
circular_area->p_head, circular_area->p_tail, circular_area->area_length);
|
||||
|
||||
circular_area->CircularAreaAppOperations = &CircularAreaAppOperations;
|
||||
|
||||
return circular_area;
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: circular_area_app.h
|
||||
* @brief: function declaration and structure defintion of circular area for applications
|
||||
* @version: 3.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2022/11/21
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CIRCULAR_AREA_APP_H
|
||||
#define CIRCULAR_AREA_APP_H
|
||||
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CA_PARAM_CHECK(param) \
|
||||
do \
|
||||
{ \
|
||||
if(param == NULL) { \
|
||||
KPrintf("PARAM CHECK FAILED ...%s %d %s is NULL.\n", __func__, __LINE__, #param); \
|
||||
while(1); \
|
||||
} \
|
||||
}while (0)
|
||||
|
||||
#define CA_ALIGN_DOWN(size, align) ((size)/(align)*(align))
|
||||
|
||||
typedef struct CircularAreaApp *CircularAreaAppType;
|
||||
|
||||
struct CircularAreaAppOps
|
||||
{
|
||||
int (*read) (CircularAreaAppType circular_area, uint8_t *output_buffer, uint32_t data_length);
|
||||
int (*write) (CircularAreaAppType circular_area, uint8_t *input_buffer, uint32_t data_length, int b_force);
|
||||
void (*release) (CircularAreaAppType circular_area);
|
||||
void (*reset) (CircularAreaAppType circular_area);
|
||||
};
|
||||
|
||||
struct CircularAreaApp
|
||||
{
|
||||
uint8_t *data_buffer;
|
||||
|
||||
uint32_t readidx;
|
||||
uint32_t writeidx;
|
||||
|
||||
uint8_t *p_head;
|
||||
uint8_t *p_tail;
|
||||
|
||||
uint32_t area_length;
|
||||
int b_status;
|
||||
|
||||
struct CircularAreaAppOps *CircularAreaAppOperations;
|
||||
};
|
||||
|
||||
/*This function will return whether the circular_area is full or not*/
|
||||
int CircularAreaAppIsFull(CircularAreaAppType circular_area);
|
||||
|
||||
/*This function will return whether the circular_area is empty or not*/
|
||||
int CircularAreaAppIsEmpty(CircularAreaAppType circular_area);
|
||||
|
||||
/*This function will reset the circular_area and set the descriptor to default*/
|
||||
void CircularAreaAppReset(CircularAreaAppType circular_area);
|
||||
|
||||
/*This function will release the circular_area descriptor and free the memory*/
|
||||
void CircularAreaAppRelease(CircularAreaAppType circular_area);
|
||||
|
||||
/*This function will read data from the circular_area*/
|
||||
int CircularAreaAppRead(CircularAreaAppType circular_area, uint8_t *output_buffer, uint32_t data_length);
|
||||
|
||||
/*This function will write data to the circular_area*/
|
||||
int CircularAreaAppWrite(CircularAreaAppType circular_area, uint8_t *input_buffer, uint32_t data_length, int b_force);
|
||||
|
||||
/*This function will get the circual_area max length*/
|
||||
uint32_t CircularAreaAppGetMaxLength(CircularAreaAppType circular_area);
|
||||
|
||||
/*This function will get the data length of the circular_area*/
|
||||
uint32_t CircularAreaAppGetDataLength(CircularAreaAppType circular_area);
|
||||
|
||||
/*This function will initialize the circular_area*/
|
||||
CircularAreaAppType CircularAreaAppInit(uint32_t circular_area_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,3 +1,15 @@
|
|||
SRC_DIR := mnist
|
||||
SRC_DIR :=
|
||||
|
||||
ifeq ($(CONFIG_APP_MNIST),y)
|
||||
SRC_DIR += mnist
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USING_NNOM_DEMOAPP),y)
|
||||
SRC_DIR += nnom_demo
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USING_CMSIS_5_DEMOAPP),y)
|
||||
SRC_DIR += cmsis_5_demo
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
SRC_DIR :=
|
||||
|
||||
ifeq ($(CONFIG_USING_CMSIS_5_NN_DEMOAPP),y)
|
||||
SRC_DIR += cmsisnn-cifar10
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_USING_CMSIS_5_NN_DEMOAPP_VEG_CLASSIFY),y)
|
||||
SRC_DIR += cmsisnn_vegetable_classify
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := demo/cmsisnn_demo.c demo/tjpgd.c model/m4/nn.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := cmsisnn_vegetable_classify.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
SRC_FILES :=
|
||||
ifeq ($(CONFIG_APP_MNIST),y)
|
||||
SRC_FILES := \
|
||||
main.cpp \
|
||||
mnistmain.c
|
||||
CPPPATHS += -I.
|
||||
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
ifeq ($(CONFIG_USING_NNOM_DEMOAPP),y)
|
||||
SRC_DIR := mnist_nnom
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := main.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
@ -71,7 +71,9 @@ void mnist_nnom(int argc, char **argv)
|
|||
printf("Predicted label: %d\n", predic_label);
|
||||
printf("Probability: %d%%\n", (int)(prob * 100));
|
||||
}
|
||||
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
PRIV_SHELL_CMD_FUNCTION(mnist_nnom, a mnist_nnom test sample, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
#endif
|
||||
#ifdef __RT_THREAD_H__
|
||||
MSH_CMD_EXPORT(mnist_nnom, nnom mnist demo and image number should be followed);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@ void HumiHs300x(void)
|
|||
int32_t humidity;
|
||||
struct SensorQuantity *humi = SensorQuantityFind(SENSOR_QUANTITY_HS300X_HUMIDITY, SENSOR_QUANTITY_HUMI);
|
||||
SensorQuantityOpen(humi);
|
||||
for (i = 0; i < 100; i ++) {
|
||||
for (i = 0; i < 10; i ++) {
|
||||
humidity = SensorQuantityReadValue(humi);
|
||||
printf("Humidity : %d.%d %%RH\n", humidity/10, humidity%10);
|
||||
PrivTaskDelay(5000);
|
||||
PrivTaskDelay(500);
|
||||
}
|
||||
SensorQuantityClose(humi);
|
||||
}
|
||||
|
|
@ -30,14 +30,14 @@ void TempHs300x(void)
|
|||
int32_t temperature;
|
||||
struct SensorQuantity *temp = SensorQuantityFind(SENSOR_QUANTITY_HS300X_TEMPERATURE, SENSOR_QUANTITY_TEMP);
|
||||
SensorQuantityOpen(temp);
|
||||
for (i = 0; i < 100; i ++) {
|
||||
for (i = 0; i < 10; i ++) {
|
||||
temperature = SensorQuantityReadValue(temp);
|
||||
if (temperature > 0)
|
||||
printf("Temperature : %d.%d ℃\n", temperature/10, temperature%10);
|
||||
else
|
||||
printf("Temperature : %d.%d ℃\n", temperature/10, -temperature%10);
|
||||
|
||||
PrivTaskDelay(5000);
|
||||
PrivTaskDelay(500);
|
||||
}
|
||||
|
||||
SensorQuantityClose(temp);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,14 @@ void WindDirectionQsFx(void)
|
|||
struct SensorQuantity *wind_direction = SensorQuantityFind(SENSOR_QUANTITY_QS_FX_WINDDIRECTION, SENSOR_QUANTITY_WINDDIRECTION);
|
||||
SensorQuantityOpen(wind_direction);
|
||||
PrivTaskDelay(2000);
|
||||
uint16_t result = SensorQuantityReadValue(wind_direction);
|
||||
printf("wind direction : %d degree\n", result);
|
||||
int result = 0;
|
||||
for(int i=0;i<2000;i++)
|
||||
{
|
||||
result = 0;
|
||||
PrivTaskDelay(1000);
|
||||
result = SensorQuantityReadValue(wind_direction);
|
||||
if(result > 0)
|
||||
printf("wind direction : %d degree\n", result);
|
||||
}
|
||||
SensorQuantityClose(wind_direction);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,14 @@ void WindSpeedQsFs(void)
|
|||
struct SensorQuantity *wind_speed = SensorQuantityFind(SENSOR_QUANTITY_QS_FS_WINDSPEED, SENSOR_QUANTITY_WINDSPEED);
|
||||
SensorQuantityOpen(wind_speed);
|
||||
PrivTaskDelay(2000);
|
||||
uint16_t result = SensorQuantityReadValue(wind_speed);
|
||||
printf("wind speed : %d.%d m/s\n", result/10, result%10);
|
||||
int result = 0;
|
||||
for(int i=0;i<2000;i++)
|
||||
{
|
||||
result = 0;
|
||||
PrivTaskDelay(1000);
|
||||
result = SensorQuantityReadValue(wind_speed);
|
||||
if(result > 0)
|
||||
printf("wind speed : %d.%d m/s\n", result/10, result%10);
|
||||
}
|
||||
SensorQuantityClose(wind_speed);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
############################################################################
|
||||
# APP_Framework/Framework/Make.defs
|
||||
############################################################################
|
||||
CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework
|
||||
CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework/transform_layer/nuttx
|
||||
include $(wildcard $(APPDIR)/../../../APP_Framework/Framework/*/Make.defs)
|
||||
|
|
|
|||
|
|
@ -1,28 +1,40 @@
|
|||
SRC_DIR := transform_layer
|
||||
include $(KERNEL_ROOT)/.config
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_SENSOR_FRAMEWORK),y)
|
||||
SRC_DIR += sensor
|
||||
ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
||||
include $(APPDIR)/Make.defs
|
||||
CSRCS += framework_init.c
|
||||
include $(APPDIR)/Application.mk
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_CONNECTION_FRAMEWORK),y)
|
||||
SRC_DIR += connection
|
||||
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||
SRC_FILES := framework_init.c
|
||||
SRC_DIR := transform_layer
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_SENSOR_FRAMEWORK),y)
|
||||
SRC_DIR += sensor
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_CONNECTION_FRAMEWORK),y)
|
||||
SRC_DIR += connection
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_KNOWING_FRAMEWORK),y)
|
||||
SRC_DIR += knowing
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_CONTROL_FRAMEWORK),y)
|
||||
SRC_DIR += control
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CRYPTO),y)
|
||||
SRC_DIR += security
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MBEDTLS), y)
|
||||
SRC_DIR += security
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_KNOWING_FRAMEWORK),y)
|
||||
SRC_DIR += knowing
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_CONTROL_FRAMEWORK),y)
|
||||
SRC_DIR += control
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CRYPTO),y)
|
||||
SRC_DIR += security
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MBEDTLS), y)
|
||||
SRC_DIR += security
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
|
|
|||
|
|
@ -21,11 +21,8 @@
|
|||
#include <adapter.h>
|
||||
|
||||
static DoublelistType adapter_list;
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
static int adapter_list_lock;
|
||||
#else
|
||||
static pthread_mutex_t adapter_list_lock;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @description: Init adapter framework
|
||||
* @return 0
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ config ADAPTER_E220
|
|||
default n
|
||||
|
||||
config ADAPTER_E22
|
||||
bool "Using lora adapter device E22-400T33D"
|
||||
bool "Using lora adapter device E22-400T30S"
|
||||
default n
|
||||
|
||||
choice
|
||||
|
|
|
|||
|
|
@ -1,28 +1,34 @@
|
|||
config ADAPTER_LORA_E22
|
||||
string "E22-400T33D adapter name"
|
||||
string "E22-400T30S adapter name"
|
||||
default "e22"
|
||||
|
||||
if ADD_XIZI_FETURES
|
||||
|
||||
endif
|
||||
|
||||
if ADD_NUTTX_FETURES
|
||||
|
||||
config ADAPTER_E22_M0_PATH
|
||||
string "E22 M0 pin device"
|
||||
default "/dev/gpio0"
|
||||
config ADAPTER_E22_M0_PATH
|
||||
string "E22 M0 pin device"
|
||||
default "/dev/gpio0"
|
||||
|
||||
config ADAPTER_E22_M1_PATH
|
||||
string "E22 M1 pin device"
|
||||
default "/dev/gpio1"
|
||||
|
||||
config ADAPTER_E22_M1_PATH
|
||||
string "E22 M1 pin device"
|
||||
default "/dev/gpio1"
|
||||
|
||||
config ADAPTER_E22_DRIVER_EXTUART
|
||||
bool "Using extra uart to support lora"
|
||||
default n
|
||||
|
||||
config ADAPTER_E22_DRIVER
|
||||
string "E22 device uart driver path"
|
||||
default "/dev/ttyS3"
|
||||
|
||||
endif
|
||||
|
||||
if ADD_RTTHREAD_FETURES
|
||||
config ADAPTER_E22_DRIVER
|
||||
string "E22 device uart driver path"
|
||||
default "/dev/ttyS2"
|
||||
depends on !ADAPTER_E22_DRIVER_EXTUART
|
||||
|
||||
if ADAPTER_E22_DRIVER_EXTUART
|
||||
config ADAPTER_E22_DRIVER
|
||||
string "E22 device extra uart driver path"
|
||||
default "/dev/extuart_dev3"
|
||||
|
||||
config ADAPTER_E22_DRIVER_EXT_PORT
|
||||
int "if E22 device using extuart, choose port"
|
||||
default "3"
|
||||
endif
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
|||
CSRCS += e22.c
|
||||
include $(APPDIR)/Application.mk
|
||||
|
||||
endif
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ enum E22LoraMode
|
|||
static void E22LoraModeConfig(enum E22LoraMode mode)
|
||||
{
|
||||
int m0_fd, m1_fd;
|
||||
char value0, value1;
|
||||
|
||||
//delay 1s , wait AUX ready
|
||||
PrivTaskDelay(1000);
|
||||
|
|
@ -68,23 +69,31 @@ static void E22LoraModeConfig(enum E22LoraMode mode)
|
|||
switch (mode)
|
||||
{
|
||||
case DATA_TRANSFER_MODE:
|
||||
PrivIoctl(m1_fd, GPIOC_WRITE, (unsigned long)GPIO_LOW);
|
||||
PrivIoctl(m0_fd, GPIOC_WRITE, (unsigned long)GPIO_LOW);
|
||||
value1 = '0';
|
||||
value0 = '0';
|
||||
PrivWrite(m1_fd, &value1, 1);
|
||||
PrivWrite(m0_fd, &value0, 1);
|
||||
break;
|
||||
|
||||
case WOR_SEND_MODE:
|
||||
PrivIoctl(m1_fd, GPIOC_WRITE, (unsigned long)GPIO_LOW);
|
||||
PrivIoctl(m0_fd, GPIOC_WRITE, (unsigned long)GPIO_HIGH);
|
||||
value1 = '0';
|
||||
value0 = '1';
|
||||
PrivWrite(m1_fd, &value1, 1);
|
||||
PrivWrite(m0_fd, &value0, 1);
|
||||
break;
|
||||
|
||||
case CONFIGURE_MODE:
|
||||
PrivIoctl(m1_fd, GPIOC_WRITE, (unsigned long)GPIO_HIGH);
|
||||
PrivIoctl(m0_fd, GPIOC_WRITE,(unsigned long)GPIO_LOW);
|
||||
value1 = '1';
|
||||
value0 = '0';
|
||||
PrivWrite(m1_fd, &value1, 1);
|
||||
PrivWrite(m0_fd, &value0, 1);
|
||||
break;
|
||||
|
||||
case SLEEP_MODE:
|
||||
PrivIoctl(m1_fd, GPIOC_WRITE, (unsigned long)GPIO_HIGH);
|
||||
PrivIoctl(m0_fd, GPIOC_WRITE, (unsigned long)GPIO_HIGH);
|
||||
value1 = '1';
|
||||
value0 = '1';
|
||||
PrivWrite(m1_fd, &value1, 1);
|
||||
PrivWrite(m0_fd, &value0, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -246,8 +255,6 @@ static int E22GetRegisterParam(uint8 *buf)
|
|||
*/
|
||||
static int E22Open(struct Adapter *adapter)
|
||||
{
|
||||
int ret = 0;
|
||||
struct termios cfg;
|
||||
/*step1: open e22 uart port*/
|
||||
adapter->fd = PrivOpen(ADAPTER_E22_DRIVER, O_RDWR);
|
||||
if (adapter->fd < 0) {
|
||||
|
|
@ -255,22 +262,53 @@ static int E22Open(struct Adapter *adapter)
|
|||
return -1;
|
||||
}
|
||||
|
||||
tcgetattr(adapter->fd, &cfg);
|
||||
cfsetspeed(&cfg, BAUD_RATE_9600);
|
||||
tcsetattr(adapter->fd, TCSANOW, &cfg);
|
||||
struct SerialDataCfg cfg;
|
||||
memset(&cfg, 0 ,sizeof(struct SerialDataCfg));
|
||||
|
||||
cfg.serial_baud_rate = BAUD_RATE_9600;
|
||||
cfg.serial_data_bits = DATA_BITS_8;
|
||||
cfg.serial_stop_bits = STOP_BITS_1;
|
||||
cfg.serial_parity_mode = PARITY_NONE;
|
||||
cfg.serial_bit_order = BIT_ORDER_LSB;
|
||||
cfg.serial_invert_mode = NRZ_NORMAL;
|
||||
cfg.serial_buffer_size = SERIAL_RB_BUFSZ;
|
||||
cfg.is_ext_uart = 0;
|
||||
|
||||
/*aiit board use ch438, so it needs more serial configuration*/
|
||||
#ifdef ADAPTER_E22_DRIVER_EXTUART
|
||||
cfg.is_ext_uart = 1;
|
||||
cfg.ext_uart_no = ADAPTER_E22_DRIVER_EXT_PORT;
|
||||
cfg.port_configure = PORT_CFG_INIT;
|
||||
#endif
|
||||
|
||||
#ifdef AS_LORA_GATEWAY_ROLE
|
||||
//serial receive timeout 10s
|
||||
cfg.serial_timeout = 10000;
|
||||
#endif
|
||||
|
||||
#ifdef AS_LORA_CLIENT_ROLE
|
||||
//serial receive wait forever
|
||||
cfg.serial_timeout = -1;
|
||||
#endif
|
||||
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = SERIAL_TYPE;
|
||||
ioctl_cfg.args = &cfg;
|
||||
|
||||
PrivIoctl(adapter->fd, OPE_INT, &ioctl_cfg);
|
||||
|
||||
E22SetRegisterParam(adapter, E22_ADDRESS, E22_CHANNEL, E22_UART_BAUD_RATE);
|
||||
|
||||
cfg.serial_baud_rate = E22_UART_BAUD_RATE;
|
||||
ioctl_cfg.args = &cfg;
|
||||
|
||||
cfsetspeed(&cfg, E22_UART_BAUD_RATE);
|
||||
tcsetattr(adapter->fd, TCSANOW, &cfg);
|
||||
PrivIoctl(adapter->fd, OPE_INT, &ioctl_cfg);
|
||||
|
||||
ADAPTER_DEBUG("E22Open done\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description: Close E22 uart function
|
||||
* @param adapter - Lora device pointer
|
||||
|
|
@ -351,7 +389,7 @@ static int E22Send(struct Adapter *adapter, const void *buf, size_t len)
|
|||
*/
|
||||
static int E22Recv(struct Adapter *adapter, void *buf, size_t len)
|
||||
{
|
||||
int recv_len, recv_len_continue;
|
||||
int recv_len = 0, recv_len_continue = 0;
|
||||
|
||||
uint8 *recv_buf = PrivMalloc(len);
|
||||
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ static int E220SetRegisterParam(struct Adapter *adapter, uint16 address, uint8 c
|
|||
uint8 baud_rate_bit = E220BaudRateSwitch(baud_rate);
|
||||
|
||||
E220LoraModeConfig(CONFIGURE_MODE_MODE);
|
||||
PrivTaskDelay(30);
|
||||
PrivTaskDelay(2000);
|
||||
|
||||
buffer[0] = 0xC0; //write register order
|
||||
buffer[1] = 0x00; //register start-address
|
||||
|
|
@ -286,6 +286,7 @@ static int E220SetRegisterParam(struct Adapter *adapter, uint16 address, uint8 c
|
|||
printf("E220SetRegisterParam send failed %d!\n", ret);
|
||||
}
|
||||
|
||||
PrivTaskDelay(2000);
|
||||
|
||||
PrivRead(adapter->fd, buffer, 11);
|
||||
E220LoraModeConfig(DATA_TRANSFER_MODE);
|
||||
|
|
|
|||
|
|
@ -17,5 +17,9 @@ ifeq ($(CONFIG_ADAPTER_ESP07S_WIFI),y)
|
|||
SRC_DIR += esp07s_wifi
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ADAPTER_ESP8285_WIFI),y)
|
||||
SRC_DIR += esp8285_wifi
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -8,3 +8,9 @@ if ADD_NUTTX_FETURES
|
|||
default "/dev/ttyS1"
|
||||
endif
|
||||
|
||||
if ADD_XIZI_FETURES
|
||||
config ADAPTER_ESP8285_DRIVER
|
||||
string "ESP8285 device uart driver path"
|
||||
default "/dev/uart1_dev1"
|
||||
endif
|
||||
|
||||
|
|
|
|||
|
|
@ -5,3 +5,8 @@ ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
|||
include $(APPDIR)/Application.mk
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||
SRC_FILES := esp8285_wifi.c
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
endif
|
||||
|
|
@ -205,16 +205,16 @@ static int Esp8285WifiSetUp(struct Adapter *adapter)
|
|||
PrivTaskDelay(2000);
|
||||
/* connect the router */
|
||||
memset(cmd,0,sizeof(cmd));
|
||||
strncpy(cmd,"AT+CWJAP=",strlen("AT+CWJAP="));
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd,param->wifi_ssid,strlen(param->wifi_ssid));
|
||||
strcat(cmd,"AT+CWJAP=");
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd,param->wifi_ssid);
|
||||
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd,",",1);
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd,param->wifi_pwd,strlen(param->wifi_pwd));
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd,",");
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd,param->wifi_pwd);
|
||||
|
||||
strncat(cmd,"\"",1);
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd,"\r\n");
|
||||
|
||||
ret = AtCmdConfigAndCheck(agent, cmd, "OK");
|
||||
|
|
@ -279,17 +279,17 @@ static int Esp8285WifiSetAddr(struct Adapter *adapter, const char *ip, const cha
|
|||
/* e.g. AT+CIPSTA_DEF="192.168.6.100","192.168.6.1","255.255.255.0" */
|
||||
memset(cmd,0,sizeof(cmd));
|
||||
strncpy(cmd,"AT+CIPAP_DEF=",strlen(" AT+CIPAP_DEF="));
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd,ip,strlen(ip));
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd,",",1);
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd,gateway,strlen(gateway));
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd,",",1);
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd,netmask,strlen(netmask));
|
||||
strncat(cmd,"\"",1);
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd,ip);
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd,",");
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd,gateway);
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd,",");
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd,netmask);
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd,"\r\n");
|
||||
|
||||
ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK");
|
||||
|
|
@ -314,9 +314,9 @@ static int Esp8285WifiPing(struct Adapter *adapter, const char *destination)
|
|||
|
||||
memset(cmd,0,sizeof(cmd));
|
||||
strncpy(cmd,"AT+PING=",strlen("AT+PING="));
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd,destination,strlen(destination));
|
||||
strncat(cmd,"\"",1);
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd,destination);
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd,"\r\n");
|
||||
|
||||
ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK"); ///< config as softAP+station mode
|
||||
|
|
@ -387,15 +387,15 @@ static int Esp8285WifiConnect(struct Adapter *adapter, enum NetRoleType net_role
|
|||
{
|
||||
//e.g. AT+CIPSTART="TCP","192.168.3.116",8080 protocol, server IP and port
|
||||
strncpy(cmd,"AT+CIPSTART=",strlen("AT+CIPSTART="));
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd,"TCP",strlen("TCP"));
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd, ",", 1);
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd, ip, strlen(ip));
|
||||
strncat(cmd, "\"", 1);
|
||||
strncat(cmd, ",", 1);
|
||||
strncat(cmd, port, strlen(port));
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd,"TCP");
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd, ",");
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd, ip);
|
||||
strcat(cmd, "\"");
|
||||
strcat(cmd, ",");
|
||||
strcat(cmd, port);
|
||||
strcat(cmd,"\r\n");
|
||||
|
||||
ret = AtCmdConfigAndCheck(agent, cmd, "OK");
|
||||
|
|
@ -408,19 +408,19 @@ static int Esp8285WifiConnect(struct Adapter *adapter, enum NetRoleType net_role
|
|||
{
|
||||
//e.g. AT+CIPSTART="UDP","192.168.3.116",8080,2233,0 UDP protocol, server IP, port,local port,udp mode
|
||||
strncpy(cmd,"AT+CIPSTART=",strlen("AT+CIPSTART="));
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd,"UDP",strlen("UDP"));
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd, ",", 1);
|
||||
strncat(cmd,"\"",1);
|
||||
strncat(cmd, ip, strlen(ip));
|
||||
strncat(cmd, "\"", 1);
|
||||
strncat(cmd, ",", 1);
|
||||
strncat(cmd, port, strlen(port));
|
||||
strncat(cmd, ",", 1);
|
||||
strncat(cmd, "2233", strlen("2233")); ///< local port
|
||||
strncat(cmd, ",", 1);
|
||||
strncat(cmd, "0", 1); ///< udp transparent transmission mode must be 0
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd,"UDP");
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd, ",");
|
||||
strcat(cmd,"\"");
|
||||
strcat(cmd, ip);
|
||||
strcat(cmd, "\"");
|
||||
strcat(cmd, ",");
|
||||
strcat(cmd, port);
|
||||
strcat(cmd, ",");
|
||||
strcat(cmd, "2233"); ///< local port
|
||||
strcat(cmd, ",");
|
||||
strcat(cmd, "0"); ///< udp transparent transmission mode must be 0
|
||||
strcat(cmd,"\r\n");
|
||||
|
||||
ret = AtCmdConfigAndCheck(agent, cmd, "OK");
|
||||
|
|
@ -523,15 +523,15 @@ static int Esp8285WifiIoctl(struct Adapter *adapter, int cmd, void *args)
|
|||
itoa(baud_rate, baud_str, 10);
|
||||
|
||||
strncpy(at_cmd, "AT+UART_DEF=", strlen("AT+UART_DEF="));
|
||||
strncat(at_cmd, baud_str, strlen(baud_str));
|
||||
strncat(at_cmd, ",", 1);
|
||||
strncat(at_cmd, "8", 1);
|
||||
strncat(at_cmd, ",", 1);
|
||||
strncat(at_cmd, "1", 1);
|
||||
strncat(at_cmd, ",", 1);
|
||||
strncat(at_cmd, "0", 1);
|
||||
strncat(at_cmd, ",", 1);
|
||||
strncat(at_cmd, "3", 1);
|
||||
strcat(at_cmd, baud_str);
|
||||
strcat(at_cmd, ",");
|
||||
strcat(at_cmd, "8");
|
||||
strcat(at_cmd, ",");
|
||||
strcat(at_cmd, "1");
|
||||
strcat(at_cmd, ",");
|
||||
strcat(at_cmd, "0");
|
||||
strcat(at_cmd, ",");
|
||||
strcat(at_cmd, "3");
|
||||
strcat(at_cmd,"\r\n");
|
||||
|
||||
ret = AtCmdConfigAndCheck(adapter->agent, at_cmd, "OK");
|
||||
|
|
|
|||
|
|
@ -2,8 +2,49 @@ menuconfig SUPPORT_CONTROL_FRAMEWORK
|
|||
bool "support control framework"
|
||||
default n
|
||||
select TRANSFORM_LAYER_ATTRIUBUTE
|
||||
select BSP_USING_SDIO
|
||||
select MOUNT_SDCARD_FS
|
||||
select LIB_USING_CJSON
|
||||
|
||||
if SUPPORT_CONTROL_FRAMEWORK
|
||||
source "$APP_DIR/Framework/control/ipc_protocol/Kconfig"
|
||||
source "$APP_DIR/Framework/control/plc_protocol/Kconfig"
|
||||
config CONTROL_USING_SERIAL_485
|
||||
bool
|
||||
default n
|
||||
|
||||
config CONTROL_USING_SOCKET
|
||||
bool
|
||||
default n
|
||||
if CONTROL_USING_SOCKET
|
||||
choice
|
||||
prompt "select socket lib"
|
||||
default CONTROL_SOCKET_LWIP
|
||||
|
||||
config CONTROL_SOCKET_LWIP
|
||||
bool "support socket, using LwIP"
|
||||
select BSP_USING_LWIP
|
||||
|
||||
config CONTROL_SOCKET_W5500
|
||||
bool "support socket, using W5500"
|
||||
select BSP_USING_W5500
|
||||
endchoice
|
||||
endif
|
||||
|
||||
config CONTROL_RECIPE_FILE
|
||||
string "control framework recipe file name"
|
||||
default "test_recipe.json"
|
||||
|
||||
menuconfig CONTROL_IPC_PROTOCOL
|
||||
bool "Using ipc protocol"
|
||||
default n
|
||||
if CONTROL_IPC_PROTOCOL
|
||||
source "$APP_DIR/Framework/control/ipc_protocol/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig CONTROL_PLC_PROTOCOL
|
||||
bool "Using plc protocol"
|
||||
default n
|
||||
if CONTROL_PLC_PROTOCOL
|
||||
source "$APP_DIR/Framework/control/plc_protocol/Kconfig"
|
||||
endif
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -1,3 +1,11 @@
|
|||
SRC_DIR := ipc_protocol plc_protocol shared
|
||||
SRC_DIR := shared
|
||||
|
||||
ifeq ($(CONFIG_CONTROL_IPC_PROTOCOL), y)
|
||||
SRC_DIR += ipc_protocol
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONTROL_PLC_PROTOCOL), y)
|
||||
SRC_DIR += plc_protocol
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
|||
|
|
@ -1,2 +1,15 @@
|
|||
config CONTROL_PROTOCOL_MODBUS_TCP
|
||||
bool "Using modbus_tcp control protocol"
|
||||
default n
|
||||
select CONTROL_USING_SOCKET
|
||||
if CONTROL_PROTOCOL_MODBUS_TCP
|
||||
source "$APP_DIR/Framework/control/ipc_protocol/modbus_tcp/Kconfig"
|
||||
endif
|
||||
|
||||
|
||||
config CONTROL_PROTOCOL_MODBUS_UART
|
||||
bool "Using modbus_uart control protocol"
|
||||
default n
|
||||
select CONTROL_USING_SERIAL_485
|
||||
if CONTROL_PROTOCOL_MODBUS_UART
|
||||
source "$APP_DIR/Framework/control/ipc_protocol/modbus_uart/Kconfig"
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,10 @@
|
|||
SRC_DIR := modbus_tcp modbus_uart
|
||||
ifeq ($(CONFIG_CONTROL_PROTOCOL_MODBUS_TCP), y)
|
||||
SRC_DIR := modbus_tcp
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONTROL_PROTOCOL_MODBUS_UART), y)
|
||||
SRC_DIR := modbus_uart
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modbus_tcp.h
|
||||
* @brief support modbus_tcp function
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.09.27
|
||||
*/
|
||||
|
||||
#ifndef MODBUS_TCP_H
|
||||
#define MODBUS_TCP_H
|
||||
|
||||
#include <control_def.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MODBUS_TCP_UNIT_ID 0x01
|
||||
#define MODBUS_TCP_READ_CMD_LENGTH 0x0C
|
||||
#define MODBUS_TCP_WRITE_SINGLE_CMD_LENGTH 0x0C
|
||||
|
||||
#define MODBUS_TCP_WRITE_MULTI_HEAD 0x07
|
||||
|
||||
typedef enum
|
||||
{
|
||||
READ_COIL_STATUS = 0x01, //read coil cmd
|
||||
READ_INPUT_STATUS = 0x02, //read input colr cmd
|
||||
READ_HOLDING_REGISTER = 0x03, //read register info cmd
|
||||
READ_INPUT_REGISTER = 0x04, //read input register cmd
|
||||
WRITE_SINGLE_COIL = 0x05, //write coil cmd
|
||||
WRITE_SINGLE_REGISTER = 0x06, //write single register cmd
|
||||
WRITE_MULTIPLE_COIL = 0x0F, //write multi coil cmd
|
||||
WRITE_MULTIPLE_REGISTER = 0x10 //write multi register cmd
|
||||
}ModbusTcpFunctionCode;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BasicPlcDataInfo base_data_info;
|
||||
ModbusTcpFunctionCode function_code;
|
||||
}ModbusTcpDataInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ModbusTcpDataInfo data_info;
|
||||
|
||||
UniformValueType value_type;
|
||||
char value_name[20];
|
||||
|
||||
uint16_t start_address;
|
||||
uint16_t quantity;
|
||||
}ModbusTcpReadItem;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modbus_uart.h
|
||||
* @brief support modbus_uart function
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.12.29
|
||||
*/
|
||||
|
||||
#ifndef MODBUS_UART_H
|
||||
#define MODBUS_UART_H
|
||||
|
||||
#include <control_def.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MODBUS_UART_READ_CMD_LENGTH 0x08
|
||||
#define MODBUS_UART_WRITE_CMD_LENGTH 0x08
|
||||
|
||||
typedef enum
|
||||
{
|
||||
READ_COIL_STATUS = 0x01, //read coil cmd
|
||||
READ_INPUT_STATUS = 0x02, //read input colr cmd
|
||||
READ_HOLDING_REGISTER = 0x03, //read register info cmd
|
||||
READ_INPUT_REGISTER = 0x04, //read input register cmd
|
||||
WRITE_SINGLE_COIL = 0x05, //write coil cmd
|
||||
WRITE_SINGLE_REGISTER = 0x06, //write single register cmd
|
||||
WRITE_MULTIPLE_COIL = 0x0F, //write multi coil cmd
|
||||
WRITE_MULTIPLE_REGISTER = 0x10 //write multi register cmd
|
||||
}ModbusUartFunctionCode;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BasicPlcDataInfo base_data_info;
|
||||
ModbusUartFunctionCode function_code;
|
||||
}ModbusUartDataInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ModbusUartDataInfo data_info;
|
||||
|
||||
UniformValueType value_type;
|
||||
char value_name[20];
|
||||
|
||||
uint8_t station;
|
||||
uint16_t start_address;
|
||||
uint16_t quantity;
|
||||
}ModbusUartReadItem;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -15,6 +15,465 @@
|
|||
* @brief support modbus_tcp function
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.09.27
|
||||
* @date 2022.12.09
|
||||
*/
|
||||
|
||||
#include <modbus_tcp.h>
|
||||
|
||||
/*using cirtular area to receive write-data*/
|
||||
#define CA_DATA_LENGTH 512
|
||||
struct CircularAreaApp *g_write_data;
|
||||
|
||||
static BasicSocketPlc plc_socket = {0};
|
||||
static uint8_t recv_buff[1024] = {0};
|
||||
|
||||
/**
|
||||
* @description: Modbus Tcp Data Transform from Receive Buffer To Control-Data
|
||||
* @param p_read_item - read item pointer
|
||||
* @param recv_buff - receive buff
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static void ModbusTcpTransformRecvBuffToData(ModbusTcpReadItem *p_read_item, uint8_t *recv_buff)
|
||||
{
|
||||
uint8_t head_length = 9;
|
||||
uint8_t *data_buffer;
|
||||
ModbusTcpDataInfo *p_modbus_tcp_data_info = &(p_read_item->data_info);
|
||||
uint16_t quantity = p_read_item->quantity;
|
||||
|
||||
ModbusTcpFunctionCode function_code = p_modbus_tcp_data_info->function_code;
|
||||
uint8_t *p_data = p_modbus_tcp_data_info->base_data_info.p_data;
|
||||
|
||||
uint8_t bytes_count = recv_buff[8];
|
||||
|
||||
if ((WRITE_SINGLE_COIL == function_code) || (WRITE_SINGLE_REGISTER == function_code) ||
|
||||
(WRITE_MULTIPLE_COIL == function_code) || (WRITE_MULTIPLE_REGISTER == function_code)) {
|
||||
head_length = 10;
|
||||
if (p_modbus_tcp_data_info->base_data_info.command_ready) {
|
||||
p_modbus_tcp_data_info->base_data_info.command_ready = 0;
|
||||
}
|
||||
}
|
||||
|
||||
data_buffer = recv_buff + head_length;//remove head data
|
||||
|
||||
if (READ_COIL_STATUS == function_code || READ_INPUT_STATUS == function_code) {
|
||||
printf("Receive data is ");
|
||||
for (int i = 0;i < bytes_count;i ++) {
|
||||
for (int j = 0;j < 8;j ++) {
|
||||
if ((i * 8 + j) < p_read_item->quantity) {
|
||||
*(uint8_t *)(p_data + i * 8 + j) = ((data_buffer[i] >> j) & 0x01) ? 1 : 0;
|
||||
printf("0x%x", *(uint8_t *)(p_data + i * 8 + j));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (READ_HOLDING_REGISTER == function_code || READ_INPUT_REGISTER == function_code) {
|
||||
printf("Receive data is ");
|
||||
for (uint16_t i = 0; i < quantity; i ++) {
|
||||
((int16_t *)p_data)[i] = ((int16_t *)data_buffer)[quantity - i - 1];
|
||||
printf("0x%x 0x%x ", p_data[2 * i], p_data[2 * i + 1]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#ifdef CONTROL_USING_SOCKET
|
||||
/**
|
||||
* @description: Modbus Tcp Get Data From Socket
|
||||
* @param socket - socket
|
||||
* @param p_read_item - read item pointer
|
||||
* @return success : 0 error : -1 -2
|
||||
*/
|
||||
static int ModbusTcpGetData(int32_t socket, ModbusTcpReadItem *p_read_item)
|
||||
{
|
||||
uint8_t try_count = 0;
|
||||
int32_t write_error = 0;
|
||||
|
||||
ModbusTcpDataInfo *p_modbus_tcp_data_info = &(p_read_item->data_info);
|
||||
BasicPlcDataInfo *p_base_data_info = &(p_modbus_tcp_data_info->base_data_info);
|
||||
|
||||
if (!p_base_data_info->command_ready) {
|
||||
//command not ready, just return
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(recv_buff, 0, sizeof(recv_buff));
|
||||
|
||||
while (try_count < 10) {
|
||||
ControlPrintfList("SEND", p_base_data_info->p_command, p_base_data_info->command_length);
|
||||
try_count++;
|
||||
|
||||
write_error = socket_write(socket, p_base_data_info->p_command, p_base_data_info->command_length);
|
||||
if (write_error < 0) {
|
||||
printf("Write socket error, errno is %d!\n", errno);
|
||||
} else {
|
||||
PrivTaskDelay(20);
|
||||
|
||||
int32_t recv_length = socket_read(socket, recv_buff, sizeof(recv_buff));
|
||||
if (recv_length < 0) {
|
||||
printf("Read socket error, errno is %d! read again\n", errno);
|
||||
memset(recv_buff, 0, sizeof(recv_buff));
|
||||
recv_length = socket_read(socket, recv_buff, sizeof(recv_buff));
|
||||
if (recv_length > 0) {
|
||||
ControlPrintfList("RECV", recv_buff, recv_length);
|
||||
ModbusTcpTransformRecvBuffToData(p_read_item, recv_buff);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
ControlPrintfList("RECV", recv_buff, recv_length);
|
||||
ModbusTcpTransformRecvBuffToData(p_read_item, recv_buff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
|
||||
printf("Send command failed, errno is %d!\n", errno);
|
||||
continue;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @description: Modbus Tcp Data Info Init
|
||||
* @param p_read_item - read item pointer
|
||||
* @param index - read item index
|
||||
* @param p_data - control-data pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static int ModbusTcpInitialDataInfo(ModbusTcpReadItem *p_read_item, uint16_t index, uint8_t *p_data)
|
||||
{
|
||||
uint16_t command_index = 0;
|
||||
uint8_t function_code = p_read_item->data_info.function_code;
|
||||
uint16_t start_address = p_read_item->start_address;
|
||||
uint16_t quantity = p_read_item->quantity;
|
||||
|
||||
BasicPlcDataInfo *p_base_data_info = &(p_read_item->data_info.base_data_info);
|
||||
|
||||
switch (function_code)
|
||||
{
|
||||
case READ_COIL_STATUS:
|
||||
case READ_INPUT_STATUS:
|
||||
case READ_HOLDING_REGISTER:
|
||||
case READ_INPUT_REGISTER:
|
||||
p_base_data_info->command_length = MODBUS_TCP_READ_CMD_LENGTH;
|
||||
p_base_data_info->p_command = PrivMalloc(p_base_data_info->command_length);
|
||||
p_base_data_info->p_data = p_data;
|
||||
p_base_data_info->command_ready = 1;
|
||||
break;
|
||||
case WRITE_SINGLE_COIL:
|
||||
case WRITE_SINGLE_REGISTER:
|
||||
if (p_data == NULL) {
|
||||
return -1;
|
||||
} else {
|
||||
p_base_data_info->command_length = MODBUS_TCP_WRITE_SINGLE_CMD_LENGTH;
|
||||
p_base_data_info->p_command = PrivMalloc(p_base_data_info->command_length);
|
||||
p_base_data_info->p_data = p_data;
|
||||
p_base_data_info->data_size = 2;
|
||||
p_base_data_info->command_ready = 0;
|
||||
}
|
||||
break;
|
||||
case WRITE_MULTIPLE_COIL:
|
||||
if (p_data == NULL) {
|
||||
return -1;
|
||||
} else {
|
||||
//"quantity" define how many coil need to be written,"n_byte" define the bytes of write-data(counted by bit)
|
||||
uint16_t n_byte = (quantity - 1) / 8 + 1;
|
||||
p_base_data_info->command_length = n_byte + MODBUS_TCP_WRITE_MULTI_HEAD + 6;
|
||||
p_base_data_info->p_command = PrivMalloc(p_base_data_info->command_length);
|
||||
|
||||
//13th command define the bytes of write-data
|
||||
p_base_data_info->p_command[12] = ((quantity - 1) / 8 + 1);
|
||||
p_base_data_info->p_data = p_data;
|
||||
p_base_data_info->data_size = n_byte;
|
||||
p_base_data_info->command_ready = 0;
|
||||
}
|
||||
break;
|
||||
case WRITE_MULTIPLE_REGISTER:
|
||||
if (p_data == NULL) {
|
||||
return -1;
|
||||
} else {
|
||||
//"quantity" define how many register need to be written
|
||||
p_base_data_info->command_length = quantity * 2 + MODBUS_TCP_WRITE_MULTI_HEAD + 6;
|
||||
p_base_data_info->p_command = PrivMalloc(p_base_data_info->command_length);
|
||||
|
||||
//13th command define the bytes of write-data
|
||||
p_base_data_info->p_command[12] = 2 * quantity;
|
||||
p_base_data_info->p_data = p_data;
|
||||
p_base_data_info->data_size = quantity * 2;
|
||||
p_base_data_info->command_ready = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -2;
|
||||
break;
|
||||
}
|
||||
|
||||
memset(p_base_data_info->p_command, 0, p_base_data_info->command_length);
|
||||
|
||||
p_base_data_info->p_command[0] = index >> 8;
|
||||
p_base_data_info->p_command[1] = index;
|
||||
p_base_data_info->p_command[2] = 0x00;
|
||||
p_base_data_info->p_command[3] = 0x00;
|
||||
p_base_data_info->p_command[4] = 0x00;
|
||||
|
||||
if (function_code < WRITE_MULTIPLE_COIL) {
|
||||
p_base_data_info->p_command[5] = 0x06;
|
||||
} else {
|
||||
p_base_data_info->p_command[5] = 0x09;
|
||||
}
|
||||
|
||||
p_base_data_info->p_command[6] = MODBUS_TCP_UNIT_ID;
|
||||
p_base_data_info->p_command[7] = function_code;
|
||||
p_base_data_info->p_command[8] = start_address >> 8;
|
||||
p_base_data_info->p_command[9] = start_address;
|
||||
|
||||
if ((function_code != WRITE_SINGLE_COIL) && (function_code != WRITE_SINGLE_REGISTER)) {
|
||||
p_base_data_info->p_command[10] = quantity >> 8;
|
||||
p_base_data_info->p_command[11] = quantity;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Tcp Format write data from "g_write_data"
|
||||
* @param p_read_item - read item pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static int ModbusTcpForamatWriteData(ModbusTcpReadItem *p_read_item)
|
||||
{
|
||||
int i = 0;
|
||||
uint16_t command_index = 0;
|
||||
int write_data_length = 0;
|
||||
uint8_t write_data_buffer[32] = {0};
|
||||
|
||||
BasicPlcDataInfo *p_base_data_info = &(p_read_item->data_info.base_data_info);
|
||||
uint8_t *p_command = p_base_data_info->p_command;
|
||||
uint8_t function_code = p_read_item->data_info.function_code;
|
||||
|
||||
if (function_code < WRITE_SINGLE_COIL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
write_data_length = CircularAreaAppRead(g_write_data, write_data_buffer, p_base_data_info->data_size);
|
||||
if (p_base_data_info->data_size != write_data_length) {
|
||||
//printf("%s get write data %d [should be %d]failed!\n", __func__, write_data_length, p_base_data_info->data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (function_code)
|
||||
{
|
||||
case WRITE_SINGLE_COIL:
|
||||
case WRITE_SINGLE_REGISTER:
|
||||
command_index = 10;
|
||||
break;
|
||||
case WRITE_MULTIPLE_COIL:
|
||||
case WRITE_MULTIPLE_REGISTER:
|
||||
command_index = 13;
|
||||
break;
|
||||
default:
|
||||
return -2;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < write_data_length; i ++) {
|
||||
p_base_data_info->p_command[command_index + i] = write_data_buffer[i];
|
||||
}
|
||||
|
||||
p_base_data_info->command_ready = 1;
|
||||
|
||||
return write_data_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Tcp Receive Plc Data Task
|
||||
* @param parameter - parameter pointer
|
||||
* @return
|
||||
*/
|
||||
void *ReceivePlcDataTask(void *parameter)
|
||||
{
|
||||
int i = 0;
|
||||
uint8_t try_count = 0;
|
||||
uint16_t data_length = 0;
|
||||
uint8_t *modbus_tcp_data;
|
||||
uint16_t read_item_size = sizeof(ModbusTcpReadItem);
|
||||
|
||||
struct ControlProtocol *control_protocol = (struct ControlProtocol *)parameter;
|
||||
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
|
||||
ModbusTcpReadItem *modbus_tcp_read_item = (ModbusTcpReadItem *)control_protocol->recipe->read_item;
|
||||
modbus_tcp_data = control_protocol->recipe->protocol_data.data;
|
||||
data_length = control_protocol->recipe->protocol_data.data_length;
|
||||
|
||||
memset(&plc_socket, 0, sizeof(BasicSocketPlc));
|
||||
memcpy(plc_socket.ip, control_protocol->recipe->socket_config.plc_ip, 4);
|
||||
plc_socket.port = control_protocol->recipe->socket_config.port;
|
||||
plc_socket.socket = -1;
|
||||
plc_socket.secondary_connect_flag = 0;
|
||||
|
||||
while (1) {
|
||||
for (i = 0; i < control_protocol->recipe->read_item_count; i ++) {
|
||||
#ifdef CONTROL_USING_SOCKET
|
||||
/*only connect socket when close socket or init*/
|
||||
while (ControlConnectSocket(&plc_socket) < 0) {
|
||||
PrivTaskDelay(1000);
|
||||
}
|
||||
|
||||
ModbusTcpForamatWriteData((ModbusTcpReadItem *)modbus_tcp_read_item + i);
|
||||
|
||||
ModbusTcpGetData(plc_socket.socket, (ModbusTcpReadItem *)modbus_tcp_read_item + i);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*read all variable item data, put them into circular_area*/
|
||||
if (i == control_protocol->recipe->read_item_count) {
|
||||
printf("%s get %d item %d length modbus_tcp_data %p\n", __func__, i, data_length, modbus_tcp_data);
|
||||
CircularAreaAppWrite(circular_area, modbus_tcp_data, data_length, 0);
|
||||
}
|
||||
|
||||
/*read data every single 'read_period' ms*/
|
||||
PrivTaskDelay(control_protocol->recipe->read_period);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Tcp Protocol Open
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @return success : 0 error
|
||||
*/
|
||||
int ModbusTcpOpen(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
ControlProtocolOpenDef(control_protocol);
|
||||
|
||||
g_write_data = CircularAreaAppInit(CA_DATA_LENGTH);
|
||||
if (NULL == g_write_data) {
|
||||
printf("%s CircularAreaInit error\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Tcp Protocol Close
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @return success : 0 error
|
||||
*/
|
||||
int ModbusTcpClose(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
CircularAreaAppRelease(g_write_data);
|
||||
|
||||
#ifdef CONTROL_USING_SOCKET
|
||||
ControlDisconnectSocket(&plc_socket);
|
||||
#endif
|
||||
|
||||
ControlProtocolCloseDef();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Tcp Protocol Read Data
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @param buf - read data buffer
|
||||
* @param len - read data length
|
||||
* @return success : data length error : 0
|
||||
*/
|
||||
int ModbusTcpRead(struct ControlProtocol *control_protocol, void *buf, size_t len)
|
||||
{
|
||||
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
|
||||
return CircularAreaAppRead(circular_area, buf, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Tcp Protocol Write Data
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @param buf - write data buffer
|
||||
* @param len - write data length
|
||||
* @return success : data length error : 0
|
||||
*/
|
||||
int ModbusTcpWrite(struct ControlProtocol *control_protocol, const void *buf, size_t len)
|
||||
{
|
||||
CircularAreaAppWrite(g_write_data, (uint8_t *)buf, len, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Tcp Protocol Ioctl
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @param cmd - ioctl cmd
|
||||
* @param args - ioctl args
|
||||
* @return success : data length error : 0
|
||||
*/
|
||||
int ModbusTcpIoctl(struct ControlProtocol *control_protocol, int cmd, void *args)
|
||||
{
|
||||
//to do
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ControlDone modbustcp_protocol_done =
|
||||
{
|
||||
._open = ModbusTcpOpen,
|
||||
._close = ModbusTcpClose,
|
||||
._read = ModbusTcpRead,
|
||||
._write = ModbusTcpWrite,
|
||||
._ioctl = ModbusTcpIoctl,
|
||||
};
|
||||
|
||||
/**
|
||||
* @description: Modbus TCP Protocol Cmd Generate
|
||||
* @param p_recipe - recipe pointer
|
||||
* @param protocol_format_info - protocol format info pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ModbusTcpProtocolFormatCmd(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info)
|
||||
{
|
||||
int ret = 0;
|
||||
static uint8_t last_item_size = 0;
|
||||
uint8_t *p_read_item_data = protocol_format_info->p_read_item_data + last_item_size;
|
||||
|
||||
ModbusTcpReadItem *modbustcp_read_item = (ModbusTcpReadItem *)(p_recipe->read_item) + protocol_format_info->read_item_index;
|
||||
|
||||
modbustcp_read_item->value_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_type")->valueint;
|
||||
strncpy(modbustcp_read_item->value_name, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_name")->valuestring, 20);
|
||||
modbustcp_read_item->data_info.function_code = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "function_code")->valueint;
|
||||
modbustcp_read_item->start_address = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "start_address")->valueint;
|
||||
modbustcp_read_item->quantity = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "quantity")->valueint;
|
||||
|
||||
ret = ModbusTcpInitialDataInfo(modbustcp_read_item,
|
||||
protocol_format_info->read_item_index,
|
||||
p_read_item_data);
|
||||
|
||||
ControlPrintfList("CMD", modbustcp_read_item->data_info.base_data_info.p_command, modbustcp_read_item->data_info.base_data_info.command_length);
|
||||
protocol_format_info->last_item_size = GetValueTypeMemorySize(modbustcp_read_item->value_type);
|
||||
|
||||
last_item_size += protocol_format_info->last_item_size;
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus TCP Protocol Init
|
||||
* @param p_recipe - recipe pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ModbusTcpProtocolInit(struct ControlRecipe *p_recipe)
|
||||
{
|
||||
p_recipe->read_item = PrivMalloc(sizeof(ModbusTcpReadItem) * p_recipe->read_item_count);
|
||||
if (NULL == p_recipe->read_item) {
|
||||
PrivFree(p_recipe->read_item);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(p_recipe->read_item, 0, sizeof(ModbusTcpReadItem));
|
||||
|
||||
p_recipe->ControlProtocolFormatCmd = ModbusTcpProtocolFormatCmd;
|
||||
|
||||
p_recipe->done = &modbustcp_protocol_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modbus_tcp.h
|
||||
* @brief support modbus_tcp function
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.09.27
|
||||
*/
|
||||
|
||||
#ifndef MODBUS_TCP_H
|
||||
#define MODBUS_TCP_H
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
{
|
||||
"device_id": 4,
|
||||
"device_name": "GJ2",
|
||||
"communication_type": 0,
|
||||
"socket_config": {
|
||||
"plc_ip": "192.168.250.9",
|
||||
"local_ip": "192.168.250.233",
|
||||
"gateway": "192.168.250.1",
|
||||
"netmask": "255.255.254.0",
|
||||
"port": 502
|
||||
},
|
||||
"protocol_type": 2,
|
||||
"read_period": 100,
|
||||
"read_item_list": [
|
||||
{
|
||||
"value_name": "M0",
|
||||
"value_type": 1,
|
||||
"function_code": 1,
|
||||
"start_address": 8192,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "M1",
|
||||
"value_type": 1,
|
||||
"function_code": 1,
|
||||
"start_address":8193,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "M102",
|
||||
"value_type": 1,
|
||||
"function_code": 1,
|
||||
"start_address": 8294,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "M200",
|
||||
"value_type": 1,
|
||||
"function_code": 1,
|
||||
"start_address": 8392,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "M201",
|
||||
"value_type": 1,
|
||||
"function_code": 1,
|
||||
"start_address":8393,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "M202",
|
||||
"value_type": 1,
|
||||
"function_code": 1,
|
||||
"start_address": 8394,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "M203",
|
||||
"value_type": 1,
|
||||
"function_code": 1,
|
||||
"start_address": 8395,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "M204",
|
||||
"value_type": 1,
|
||||
"function_code": 1,
|
||||
"start_address": 8396,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "M205",
|
||||
"value_type": 1,
|
||||
"function_code": 1,
|
||||
"start_address": 8397,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "M206",
|
||||
"value_type": 1,
|
||||
"function_code": 1,
|
||||
"start_address": 8398,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "D20",
|
||||
"value_type": 3,
|
||||
"function_code": 3,
|
||||
"start_address": 20,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "D21",
|
||||
"value_type": 3,
|
||||
"function_code": 3,
|
||||
"start_address": 21,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "D22",
|
||||
"value_type": 3,
|
||||
"function_code": 3,
|
||||
"start_address": 22,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "D23",
|
||||
"value_type": 3,
|
||||
"function_code": 3,
|
||||
"start_address": 23,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "D202",
|
||||
"value_type": 9,
|
||||
"function_code": 3,
|
||||
"start_address": 202,
|
||||
"quantity": 2
|
||||
},
|
||||
{
|
||||
"value_name": "D204",
|
||||
"value_type": 9,
|
||||
"function_code": 3,
|
||||
"start_address": 204,
|
||||
"quantity": 2
|
||||
},
|
||||
{
|
||||
"value_name": "D206",
|
||||
"value_type": 9,
|
||||
"function_code": 3,
|
||||
"start_address": 206,
|
||||
"quantity": 2
|
||||
},
|
||||
{
|
||||
"value_name": "D208",
|
||||
"value_type": 9,
|
||||
"function_code": 3,
|
||||
"start_address": 208,
|
||||
"quantity": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,2 +1,37 @@
|
|||
if ADD_XIZI_FETURES
|
||||
config CONTROL_FRAMEWORK_UART_485_DIR
|
||||
int "control framework 485 direction pin number"
|
||||
default "2"
|
||||
|
||||
config CONTROL_FRAMEWORK_PIN_DEV
|
||||
string "control framework device pin dev path"
|
||||
default "/dev/pin_dev"
|
||||
|
||||
config CONTROL_FRAMEWORK_DRIVER_EXTUART
|
||||
bool "Using extra uart to control framework"
|
||||
default n
|
||||
|
||||
config CONTROL_FRAMEWORK_UART_DEV
|
||||
string "control framework device uart dev path"
|
||||
default "/dev/uart3_dev3"
|
||||
depends on !CONTROL_FRAMEWORK_DRIVER_EXTUART
|
||||
|
||||
if CONTROL_FRAMEWORK_DRIVER_EXTUART
|
||||
config CONTROL_FRAMEWORK_UART_DEV
|
||||
string "control framework device extra uart dev path"
|
||||
default "/dev/extuart_dev0"
|
||||
|
||||
config CONTROL_FRAMEWORK_DEV_EXT_PORT
|
||||
int "if control framework device using extuart, choose port"
|
||||
default "0"
|
||||
endif
|
||||
endif
|
||||
|
||||
if ADD_NUTTX_FETURES
|
||||
|
||||
endif
|
||||
|
||||
if ADD_RTTHREAD_FETURES
|
||||
|
||||
endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
SRC_FILES :=
|
||||
SRC_FILES := modbus_uart.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,424 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file modbus_uart.c
|
||||
* @brief support modbus_uart function
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.12.29
|
||||
*/
|
||||
|
||||
#include <modbus_uart.h>
|
||||
|
||||
/*using cirtular area to receive write-data*/
|
||||
#define CA_DATA_LENGTH 512
|
||||
struct CircularAreaApp *g_write_data;
|
||||
|
||||
static BasicSocketPlc plc_socket = {0};
|
||||
static uint8_t recv_buff[1024] = {0};
|
||||
|
||||
/**
|
||||
* @description: CRC16 check
|
||||
* @param data data buffer
|
||||
* @param length data length
|
||||
* @return check code
|
||||
*/
|
||||
static uint16_t ModbusUartCrc16(uint8_t *data, uint32_t length)
|
||||
{
|
||||
int j;
|
||||
uint16_t reg_crc = 0xFFFF;
|
||||
|
||||
while (length--) {
|
||||
reg_crc ^= *data++;
|
||||
for (j = 0;j < 8;j ++) {
|
||||
if(reg_crc & 0x01)
|
||||
reg_crc = reg_crc >> 1 ^ 0xA001;
|
||||
else
|
||||
reg_crc = reg_crc >> 1;
|
||||
}
|
||||
}
|
||||
printf(" crc = [0x%x]\n", reg_crc);
|
||||
return reg_crc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Uart Data Transform from Receive Buffer To Control-Data
|
||||
* @param p_read_item - read item pointer
|
||||
* @param recv_buff - receive buff
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static int ModbusUartTransformRecvBuffToData(ModbusUartReadItem *p_read_item, uint8_t *recv_buff)
|
||||
{
|
||||
uint8_t head_length = 3;
|
||||
uint8_t *data_buffer;
|
||||
ModbusUartDataInfo *p_modbus_uart_data_info = &(p_read_item->data_info);
|
||||
uint16_t quantity = p_read_item->quantity;
|
||||
|
||||
ModbusUartFunctionCode function_code = p_modbus_uart_data_info->function_code;
|
||||
uint8_t *p_data = p_modbus_uart_data_info->base_data_info.p_data;
|
||||
|
||||
uint8_t bytes_count = recv_buff[2];
|
||||
|
||||
if ((WRITE_SINGLE_COIL == function_code) || (WRITE_SINGLE_REGISTER == function_code)) {
|
||||
head_length = 4;
|
||||
if (p_modbus_uart_data_info->base_data_info.command_ready) {
|
||||
p_modbus_uart_data_info->base_data_info.command_ready = 0;
|
||||
}
|
||||
}
|
||||
|
||||
data_buffer = recv_buff + head_length;//remove head data
|
||||
|
||||
if (READ_COIL_STATUS == function_code || READ_INPUT_STATUS == function_code) {
|
||||
printf("Receive data is ");
|
||||
for (int i = 0;i < bytes_count;i ++) {
|
||||
for (int j = 0;j < 8;j ++) {
|
||||
if ((i * 8 + j) < p_read_item->quantity) {
|
||||
*(uint8_t *)(p_data + i * 8 + j) = ((data_buffer[i] >> j) & 0x01) ? 1 : 0;
|
||||
printf("0x%x", *(uint8_t *)(p_data + i * 8 + j));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (READ_HOLDING_REGISTER == function_code || READ_INPUT_REGISTER == function_code) {
|
||||
printf("Receive data is ");
|
||||
for (uint16_t i = 0; i < quantity; i ++) {
|
||||
((int16_t *)p_data)[i] = ((int16_t *)data_buffer)[quantity - i - 1];
|
||||
printf("0x%x 0x%x ", p_data[2 * i], p_data[2 * i + 1]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Uart Get Data From Serial
|
||||
* @param p_read_item - read item pointer
|
||||
* @return success : 0 error : -1 -2
|
||||
*/
|
||||
static int ModbusUartGetDataBySerial(ModbusUartReadItem *p_read_item)
|
||||
{
|
||||
uint32_t cmd_length, read_length = 0;
|
||||
memset(recv_buff, 0, sizeof(recv_buff));
|
||||
|
||||
ModbusUartDataInfo *p_modbus_uart_data_info = &(p_read_item->data_info);
|
||||
BasicPlcDataInfo *p_base_data_info = &(p_modbus_uart_data_info->base_data_info);
|
||||
ModbusUartFunctionCode function_code = p_modbus_uart_data_info->function_code;
|
||||
|
||||
ControlPrintfList("SEND", p_base_data_info->p_command, p_base_data_info->command_length);
|
||||
SerialWrite(p_base_data_info->p_command, p_base_data_info->command_length);
|
||||
|
||||
if (READ_COIL_STATUS == function_code || READ_INPUT_STATUS == function_code) {
|
||||
cmd_length = 6;
|
||||
} else if (READ_HOLDING_REGISTER == function_code || READ_INPUT_REGISTER == function_code) {
|
||||
cmd_length = 7;
|
||||
} else if (WRITE_SINGLE_COIL == function_code || WRITE_SINGLE_REGISTER == function_code) {
|
||||
cmd_length = 8;
|
||||
} else {
|
||||
//MULTIPLE_COIL and MULTIPLE_REGISTER to do
|
||||
cmd_length = 0;
|
||||
}
|
||||
|
||||
read_length = SerialRead(recv_buff, cmd_length);
|
||||
if (read_length) {
|
||||
ControlPrintfList("RECV", recv_buff, read_length);
|
||||
return ModbusUartTransformRecvBuffToData(p_read_item, recv_buff);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Uart Data Info Init
|
||||
* @param p_read_item - read item pointer
|
||||
* @param station - uart station number
|
||||
* @param p_data - control-data pointer
|
||||
* @return success : 0 error : -1 -2
|
||||
*/
|
||||
static int ModbusUartInitialDataInfo(ModbusUartReadItem *p_read_item, uint8_t station, uint8_t *p_data)
|
||||
{
|
||||
uint16_t command_crc = 0;
|
||||
uint8_t function_code = p_read_item->data_info.function_code;
|
||||
uint16_t start_address = p_read_item->start_address;
|
||||
uint16_t quantity = p_read_item->quantity;
|
||||
|
||||
BasicPlcDataInfo *p_base_data_info = &(p_read_item->data_info.base_data_info);
|
||||
|
||||
switch (function_code)
|
||||
{
|
||||
case READ_COIL_STATUS:
|
||||
case READ_INPUT_STATUS:
|
||||
case READ_HOLDING_REGISTER:
|
||||
case READ_INPUT_REGISTER:
|
||||
p_base_data_info->command_length = MODBUS_UART_READ_CMD_LENGTH;
|
||||
p_base_data_info->p_command = PrivMalloc(p_base_data_info->command_length);
|
||||
p_base_data_info->p_data = p_data;
|
||||
p_base_data_info->command_ready = 1;
|
||||
break;
|
||||
case WRITE_SINGLE_COIL:
|
||||
case WRITE_SINGLE_REGISTER:
|
||||
if (p_data == NULL) {
|
||||
return -1;
|
||||
} else {
|
||||
p_base_data_info->command_length = MODBUS_UART_WRITE_CMD_LENGTH;
|
||||
p_base_data_info->p_command = PrivMalloc(p_base_data_info->command_length);
|
||||
p_base_data_info->p_data = p_data;
|
||||
p_base_data_info->data_size = 2;
|
||||
p_base_data_info->command_ready = 0;
|
||||
}
|
||||
break;
|
||||
case WRITE_MULTIPLE_COIL:
|
||||
case WRITE_MULTIPLE_REGISTER:
|
||||
//to do
|
||||
printf("%s unsupported function code %d\n", __func__, function_code);
|
||||
return -1;
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
memset(p_base_data_info->p_command, 0, p_base_data_info->command_length);
|
||||
|
||||
p_base_data_info->p_command[0] = station;
|
||||
p_base_data_info->p_command[1] = function_code;
|
||||
p_base_data_info->p_command[2] = start_address >> 8;
|
||||
p_base_data_info->p_command[3] = start_address;
|
||||
if ((function_code != WRITE_SINGLE_COIL) && (function_code != WRITE_SINGLE_REGISTER)) {
|
||||
p_base_data_info->p_command[4] = quantity >> 8;
|
||||
p_base_data_info->p_command[5] = quantity;
|
||||
command_crc = ModbusUartCrc16(p_base_data_info->p_command, 6);
|
||||
p_base_data_info->p_command[6] = command_crc & 0xFF;
|
||||
p_base_data_info->p_command[7] = (command_crc >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Uart Format write data from "g_write_data"
|
||||
* @param p_read_item - read item pointer
|
||||
* @return success : 0 error : -1 -2
|
||||
*/
|
||||
static int ModbusUartForamatWriteData(ModbusUartReadItem *p_read_item)
|
||||
{
|
||||
int i = 0;
|
||||
uint16_t command_index = 0;
|
||||
int write_data_length = 0;
|
||||
uint8_t write_data_buffer[32] = {0};
|
||||
|
||||
BasicPlcDataInfo *p_base_data_info = &(p_read_item->data_info.base_data_info);
|
||||
uint8_t *p_command = p_base_data_info->p_command;
|
||||
uint8_t function_code = p_read_item->data_info.function_code;
|
||||
|
||||
if (function_code < WRITE_SINGLE_COIL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
write_data_length = CircularAreaAppRead(g_write_data, write_data_buffer, p_base_data_info->data_size);
|
||||
if (p_base_data_info->data_size != write_data_length) {
|
||||
//printf("%s get write data %d [should be %d]failed!\n", __func__, write_data_length, p_base_data_info->data_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (function_code)
|
||||
{
|
||||
case WRITE_SINGLE_COIL:
|
||||
case WRITE_SINGLE_REGISTER:
|
||||
command_index = 4;
|
||||
break;
|
||||
case WRITE_MULTIPLE_COIL:
|
||||
case WRITE_MULTIPLE_REGISTER:
|
||||
printf("%s unsupported function code %d\n", __func__, function_code);
|
||||
return -1;
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
for (i = 0; i < write_data_length; i ++) {
|
||||
p_base_data_info->p_command[command_index + i] = write_data_buffer[i];
|
||||
}
|
||||
|
||||
p_base_data_info->command_ready = 1;
|
||||
|
||||
return write_data_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Uart Receive Plc Data Task
|
||||
* @param parameter - parameter pointer
|
||||
* @return
|
||||
*/
|
||||
void *ReceivePlcDataTask(void *parameter)
|
||||
{
|
||||
int i = 0;
|
||||
uint8_t try_count = 0;
|
||||
uint16_t data_length = 0;
|
||||
uint8_t *modbus_uart_data;
|
||||
uint16_t read_item_size = sizeof(ModbusUartReadItem);
|
||||
|
||||
struct ControlProtocol *control_protocol = (struct ControlProtocol *)parameter;
|
||||
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
|
||||
ModbusUartReadItem *modbus_uart_read_item = (ModbusUartReadItem *)control_protocol->recipe->read_item;
|
||||
modbus_uart_data = control_protocol->recipe->protocol_data.data;
|
||||
data_length = control_protocol->recipe->protocol_data.data_length;
|
||||
|
||||
while (1) {
|
||||
for (i = 0; i < control_protocol->recipe->read_item_count; i ++) {
|
||||
|
||||
ModbusUartForamatWriteData((ModbusUartReadItem *)modbus_uart_read_item + i);
|
||||
|
||||
ModbusUartGetDataBySerial((ModbusUartReadItem *)modbus_uart_read_item + i);
|
||||
}
|
||||
|
||||
/*read all variable item data, put them into circular_area*/
|
||||
if (i == control_protocol->recipe->read_item_count) {
|
||||
printf("%s get %d item %d length modbus_uart_data %p\n", __func__, i, data_length, modbus_uart_data);
|
||||
CircularAreaAppWrite(circular_area, modbus_uart_data, data_length, 0);
|
||||
}
|
||||
|
||||
/*read data every single 'read_period' ms*/
|
||||
PrivTaskDelay(control_protocol->recipe->read_period);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Uart Protocol Open
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @return success : 0 error
|
||||
*/
|
||||
int ModbusUartOpen(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
ControlProtocolOpenDef(control_protocol);
|
||||
|
||||
g_write_data = CircularAreaAppInit(CA_DATA_LENGTH);
|
||||
if (NULL == g_write_data) {
|
||||
printf("%s CircularAreaInit error\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Uart Protocol Close
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @return success : 0 error
|
||||
*/
|
||||
int ModbusUartClose(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
CircularAreaAppRelease(g_write_data);
|
||||
|
||||
ControlProtocolCloseDef();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Uart Protocol Read Data
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @param buf - read data buffer
|
||||
* @param len - read data length
|
||||
* @return success : data length error : 0
|
||||
*/
|
||||
int ModbusUartRead(struct ControlProtocol *control_protocol, void *buf, size_t len)
|
||||
{
|
||||
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
|
||||
return CircularAreaAppRead(circular_area, buf, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Uart Protocol Write Data
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @param buf - write data buffer
|
||||
* @param len - write data length
|
||||
* @return success : data length error : 0
|
||||
*/
|
||||
int ModbusUartWrite(struct ControlProtocol *control_protocol, const void *buf, size_t len)
|
||||
{
|
||||
CircularAreaAppWrite(g_write_data, (uint8_t *)buf, len, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus Uart Protocol Ioctl
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @param cmd - ioctl cmd
|
||||
* @param args - ioctl args
|
||||
* @return success : data length error : 0
|
||||
*/
|
||||
int ModbusUartIoctl(struct ControlProtocol *control_protocol, int cmd, void *args)
|
||||
{
|
||||
//to do
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ControlDone modbusuart_protocol_done =
|
||||
{
|
||||
._open = ModbusUartOpen,
|
||||
._close = ModbusUartClose,
|
||||
._read = ModbusUartRead,
|
||||
._write = ModbusUartWrite,
|
||||
._ioctl = ModbusUartIoctl,
|
||||
};
|
||||
|
||||
/**
|
||||
* @description: Modbus TCP Protocol Cmd Generate
|
||||
* @param p_recipe - recipe pointer
|
||||
* @param protocol_format_info - protocol format info pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ModbusUartProtocolFormatCmd(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info)
|
||||
{
|
||||
int ret = 0;
|
||||
static uint8_t last_item_size = 0;
|
||||
uint8_t *p_read_item_data = protocol_format_info->p_read_item_data + last_item_size;
|
||||
|
||||
ModbusUartReadItem *modbusuart_read_item = (ModbusUartReadItem *)(p_recipe->read_item) + protocol_format_info->read_item_index;
|
||||
|
||||
modbusuart_read_item->value_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_type")->valueint;
|
||||
strncpy(modbusuart_read_item->value_name, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_name")->valuestring, 20);
|
||||
modbusuart_read_item->data_info.function_code = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "function_code")->valueint;
|
||||
modbusuart_read_item->start_address = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "start_address")->valueint;
|
||||
modbusuart_read_item->quantity = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "quantity")->valueint;
|
||||
|
||||
ret = ModbusUartInitialDataInfo(modbusuart_read_item,
|
||||
p_recipe->serial_config.station,
|
||||
p_read_item_data);
|
||||
|
||||
ControlPrintfList("CMD", modbusuart_read_item->data_info.base_data_info.p_command, modbusuart_read_item->data_info.base_data_info.command_length);
|
||||
protocol_format_info->last_item_size = GetValueTypeMemorySize(modbusuart_read_item->value_type);
|
||||
|
||||
last_item_size += protocol_format_info->last_item_size;
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Modbus TCP Protocol Init
|
||||
* @param p_recipe - recipe pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ModbusUartProtocolInit(struct ControlRecipe *p_recipe)
|
||||
{
|
||||
p_recipe->read_item = PrivMalloc(sizeof(ModbusUartReadItem) * p_recipe->read_item_count);
|
||||
if (NULL == p_recipe->read_item) {
|
||||
PrivFree(p_recipe->read_item);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(p_recipe->read_item, 0, sizeof(ModbusUartReadItem));
|
||||
|
||||
p_recipe->ControlProtocolFormatCmd = ModbusUartProtocolFormatCmd;
|
||||
|
||||
p_recipe->done = &modbusuart_protocol_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"device_id": 1,
|
||||
"device_name": "GJ2",
|
||||
"communication_type": 1,
|
||||
"serial_config": {
|
||||
"station": 1,
|
||||
"baud_rate": 9600,
|
||||
"data_bits": 8,
|
||||
"stop_bits": 1,
|
||||
"check_mode": 0
|
||||
},
|
||||
"protocol_type": 3,
|
||||
"read_period": 100,
|
||||
"read_item_list": [
|
||||
{
|
||||
"value_name": "M0",
|
||||
"value_type": 1,
|
||||
"function_code": 1,
|
||||
"start_address": 8192,
|
||||
"quantity": 1
|
||||
},
|
||||
{
|
||||
"value_name": "D208",
|
||||
"value_type": 9,
|
||||
"function_code": 3,
|
||||
"start_address": 208,
|
||||
"quantity": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,365 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file plc_socket.c
|
||||
* @brief Demo for PLC socket communication function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.03.16
|
||||
*/
|
||||
|
||||
#include "transform.h"
|
||||
#include "plc_socket.h"
|
||||
#include "sys_arch.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "control_file.h"
|
||||
|
||||
// max support plc socket test commands number
|
||||
#define PLC_SOCK_CMD_NUM CTL_CMD_NUM
|
||||
#define PLC_SOCK_TIMEOUT 50000
|
||||
|
||||
// for saving PLC command index
|
||||
int plc_cmd_index = 0;
|
||||
|
||||
// only for test
|
||||
#define SUPPORT_PLC_SIEMENS
|
||||
|
||||
//siemens test
|
||||
PlcBinCmdType TestPlcCmd[PLC_SOCK_CMD_NUM] = {0};
|
||||
|
||||
//Test information
|
||||
//SIEMENS ip: 192.168.250.9 port: 102
|
||||
//S7-200 ip: 192.168.250.8 port: 102
|
||||
//S7-1200 ip: 192.168.250.6 port: 102
|
||||
//OML ip: 192.168.250.3 port: 9600
|
||||
|
||||
PlcSocketParamType plc_socket_demo_data = {
|
||||
#ifdef SUPPORT_PLC_SIEMENS
|
||||
.ip = {192, 168, 250, 6},
|
||||
.port = 102,
|
||||
.device_type = PLC_DEV_TYPE_SIEMENS,
|
||||
.socket_type = SOCK_STREAM,
|
||||
.cmd_num = 3,
|
||||
#else
|
||||
.ip = {192, 168, 250, 3},
|
||||
.port = 9600,
|
||||
.device_type = PLC_DEV_TYPE_OML,
|
||||
.socket_type = SOCK_DGRAM,
|
||||
.cmd_num = 1,
|
||||
#endif
|
||||
.recv_len = PLC_RECV_BUF_LEN,
|
||||
.recv_buf = NULL,
|
||||
};
|
||||
|
||||
#define OML_HEADER_LEN 78
|
||||
#define CHECK_OML_HEADER(_s) ((0xC0 == *(_s)) && (0x00 == *(_s + 1)) && (0x02 == *(_s + 2)) && (0x00 == *(_s + 3)))
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void plc_print_array(char *title, int size, uint8_t *cmd)
|
||||
{
|
||||
lw_notice("%s : %d - ", title, size);
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
lw_notice(" %#x", cmd[i]);
|
||||
}
|
||||
lw_notice("\n");
|
||||
}
|
||||
|
||||
static void *PlcSocketStart(void *arg)
|
||||
{
|
||||
int fd = -1;
|
||||
int timeout, recv_len;
|
||||
struct sockaddr_in sock_addr;
|
||||
socklen_t addr_len = sizeof(struct sockaddr_in);
|
||||
PlcSocketParamType *param = (PlcSocketParamType *)&plc_socket_demo_data;
|
||||
|
||||
plc_print("start %d.%d.%d.%d:%d dev %d sock %d\n",
|
||||
param->ip[0],
|
||||
param->ip[1],
|
||||
param->ip[2],
|
||||
param->ip[3],
|
||||
param->port,
|
||||
param->device_type,
|
||||
param->socket_type);
|
||||
|
||||
param->recv_len = PLC_RECV_BUF_LEN;
|
||||
|
||||
//malloc memory
|
||||
param->recv_buf = (char *)malloc(param->recv_len);
|
||||
if (param->recv_buf == NULL)
|
||||
{
|
||||
plc_error("No memory\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fd = socket(AF_INET, param->socket_type, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
plc_error("Socket error %d\n", param->socket_type);
|
||||
free(param->recv_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
plc_print("start %d.%d.%d.%d:%d\n", param->ip[0], param->ip[1], param->ip[2], param->ip[3], param->port);
|
||||
|
||||
sock_addr.sin_family = AF_INET;
|
||||
sock_addr.sin_port = htons(param->port);
|
||||
sock_addr.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(param->ip[0], param->ip[1], param->ip[2], param->ip[3]));
|
||||
memset(&(sock_addr.sin_zero), 0, sizeof(sock_addr.sin_zero));
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr)) < 0)
|
||||
{
|
||||
plc_error("Unable to connect\n");
|
||||
closesocket(fd);
|
||||
free(param->recv_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lw_notice("client %s connected\n", inet_ntoa(sock_addr.sin_addr));
|
||||
|
||||
for(int i = 0; i < param->cmd_num; i ++)
|
||||
{
|
||||
PlcBinCmdType *cmd = &TestPlcCmd[i];
|
||||
sendto(fd, cmd->cmd, cmd->cmd_len, 0, (struct sockaddr*)&sock_addr, addr_len);
|
||||
plc_print_array("Send cmd", cmd->cmd_len, cmd->cmd);
|
||||
|
||||
MdelayKTask(cmd->delay_ms);
|
||||
timeout = PLC_SOCK_TIMEOUT;
|
||||
memset(param->recv_buf, 0, param->recv_len);
|
||||
while(timeout --)
|
||||
{
|
||||
recv_len = recvfrom(fd, param->recv_buf, param->recv_len, 0, (struct sockaddr *)&sock_addr, &addr_len);
|
||||
if(recv_len > 0)
|
||||
{
|
||||
if(param->device_type == PLC_DEV_TYPE_OML)
|
||||
{
|
||||
if((recv_len == OML_HEADER_LEN) && (CHECK_OML_HEADER(param->recv_buf)))
|
||||
{
|
||||
lw_notice("This is Oml package!!!\n");
|
||||
}
|
||||
}
|
||||
lw_notice("Receive from : %s\n", inet_ntoa(sock_addr.sin_addr));
|
||||
plc_print_array("Receive data", recv_len, param->recv_buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closesocket(fd);
|
||||
free(param->recv_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void PlcGetParamCmd(char *cmd)
|
||||
{
|
||||
const char s[2] = ",";
|
||||
char *token;
|
||||
uint16_t cmd_index = 0;
|
||||
char bin_cmd[PLC_BIN_CMD_LEN] = {0};
|
||||
token = strtok(cmd, s);
|
||||
while(token != NULL)
|
||||
{
|
||||
sscanf(token, "%x", &bin_cmd[cmd_index]);
|
||||
plc_print("%d - %s %d\n", cmd_index, token, bin_cmd[cmd_index]);
|
||||
token = strtok(NULL, s);
|
||||
cmd_index ++;
|
||||
}
|
||||
TestPlcCmd[plc_cmd_index].cmd_len = cmd_index;
|
||||
memcpy(TestPlcCmd[plc_cmd_index].cmd, bin_cmd, cmd_index);
|
||||
plc_print("get %d cmd len %d\n", plc_cmd_index, TestPlcCmd[plc_cmd_index].cmd_len);
|
||||
plc_cmd_index ++;
|
||||
plc_socket_demo_data.cmd_num = plc_cmd_index;
|
||||
}
|
||||
|
||||
void PlcShowUsage(void)
|
||||
{
|
||||
plc_notice("------------------------------------\n");
|
||||
plc_notice("PlcSocket [ip].[ip].[ip].[ip]:[port]\n");
|
||||
plc_notice("PlcSocket support other param:\n");
|
||||
plc_notice("plc=[] 0: OML 1:SIEMENS\n");
|
||||
plc_notice("tcp=[] 0: udp 1:tcp\n");
|
||||
plc_notice("ip=[ip.ip.ip.ip]\n");
|
||||
plc_notice("port=port\n");
|
||||
plc_notice("file: use %s\n", PLC_SOCK_FILE_NAME);
|
||||
plc_notice("------------------------------------\n");
|
||||
}
|
||||
|
||||
#if defined(MOUNT_SDCARD) && defined(LIB_USING_CJSON)
|
||||
void PlcGetParamFromFile(char *file_name)
|
||||
{
|
||||
PlcSocketParamType *param = &plc_socket_demo_data;
|
||||
|
||||
char *file_buf = malloc(CTL_FILE_LEN);
|
||||
if(file_buf == NULL)
|
||||
{
|
||||
plc_error("No enough buffer %d\n", CTL_FILE_LEN);
|
||||
return;
|
||||
}
|
||||
memset(file_buf, 0, CTL_FILE_LEN);
|
||||
|
||||
if(CtlFileReadWithFilename(file_name, CTL_FILE_LEN, file_buf) != EOK)
|
||||
{
|
||||
plc_error("Can't open file %s\n", file_name);
|
||||
//try again default file
|
||||
if(strcmp(file_name, PLC_SOCK_FILE_NAME) != 0)
|
||||
{
|
||||
if(CtlFileReadWithFilename(PLC_SOCK_FILE_NAME, CTL_FILE_LEN, file_buf) != EOK)
|
||||
{
|
||||
plc_error("Can't open file %s\n", file_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
CtlParseJsonData(file_buf);
|
||||
|
||||
memcpy(param->ip, ctl_file_param.ip, 4);
|
||||
param->port = ctl_file_param.port;
|
||||
param->cmd_num = ctl_file_param.cmd_num;
|
||||
param->socket_type = ctl_file_param.tcp ? SOCK_STREAM : SOCK_DGRAM;
|
||||
|
||||
for(int i = 0; i < param->cmd_num; i++)
|
||||
{
|
||||
TestPlcCmd[i].cmd_len = ctl_file_param.cmd_len[i];
|
||||
memcpy(TestPlcCmd[i].cmd, ctl_file_param.cmd[i], TestPlcCmd[i].cmd_len);
|
||||
}
|
||||
|
||||
plc_print("ip: %d.%d.%d.%d\n", param->ip[0], param->ip[1], param->ip[2], param->ip[3]);
|
||||
plc_print("port: %d", param->port);
|
||||
plc_print("tcp: %d", param->socket_type);
|
||||
plc_print("cmd number: %d\n", param->cmd_num);
|
||||
|
||||
for(int i = 0; i < param->cmd_num; i++)
|
||||
{
|
||||
plc_print_array("cmd", TestPlcCmd[i].cmd_len, TestPlcCmd[i].cmd);
|
||||
}
|
||||
free(file_buf);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void PlcCheckParam(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
PlcSocketParamType *param = &plc_socket_demo_data;
|
||||
plc_cmd_index = 0;
|
||||
|
||||
for(i = 0; i < argc; i++)
|
||||
{
|
||||
char *str = argv[i];
|
||||
int is_tcp = 0;
|
||||
char cmd_str[PLC_BIN_CMD_LEN] = {0};
|
||||
|
||||
plc_print("check %d %s\n", i, str);
|
||||
|
||||
#if defined(MOUNT_SDCARD) && defined(LIB_USING_CJSON)
|
||||
if(strncmp(str, "file", 4) == 0)
|
||||
{
|
||||
char file_name[CTL_FILE_NAME_LEN] = {0};
|
||||
if(sscanf(str, "file=%s", file_name) == EOF)
|
||||
{
|
||||
strcpy(file_name, PLC_SOCK_FILE_NAME);
|
||||
}
|
||||
plc_notice("get %s parameter file %s\n", str, file_name);
|
||||
PlcGetParamFromFile(file_name);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if(sscanf(str, "ip=%d.%d.%d.%d",
|
||||
¶m->ip[0],
|
||||
¶m->ip[1],
|
||||
¶m->ip[2],
|
||||
¶m->ip[3]) == 4)
|
||||
{
|
||||
plc_print("find ip %d %d %d %d\n", param->ip[0], param->ip[1], param->ip[2], param->ip[3]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(sscanf(str, "port=%d", ¶m->port) == 1)
|
||||
{
|
||||
plc_print("find port %d\n", param->port);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(sscanf(str, "tcp=%d", &is_tcp) == 1)
|
||||
{
|
||||
plc_print("find tcp %d\n", is_tcp);
|
||||
param->socket_type = is_tcp ? SOCK_STREAM:SOCK_DGRAM;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(sscanf(str, "plc=%d", ¶m->device_type) == 1)
|
||||
{
|
||||
plc_print("find device %d\n", param->device_type);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(sscanf(str, "cmd=%s", cmd_str) == 1)
|
||||
{
|
||||
plc_print("find cmd %s\n", cmd_str);
|
||||
PlcGetParamCmd(cmd_str);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(argc >= 2)
|
||||
{
|
||||
if(sscanf(argv[1], "%d.%d.%d.%d:%d",
|
||||
¶m->ip[0],
|
||||
¶m->ip[1],
|
||||
¶m->ip[2],
|
||||
¶m->ip[3],
|
||||
¶m->port) != EOF)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(sscanf(argv[1], "%d.%d.%d.%d",
|
||||
¶m->ip[0],
|
||||
¶m->ip[1],
|
||||
¶m->ip[2],
|
||||
¶m->ip[3]) != EOF)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PlcShowUsage();
|
||||
}
|
||||
}
|
||||
|
||||
void PlcSocketTask(int argc, char *argv[])
|
||||
{
|
||||
int result = 0;
|
||||
pthread_t th_id;
|
||||
uint8_t enet_port = 0; ///< test enet port 0
|
||||
|
||||
pthread_attr_t attr;
|
||||
attr.schedparam.sched_priority = LWIP_DEMO_TASK_PRIO;
|
||||
attr.stacksize = LWIP_TASK_STACK_SIZE;
|
||||
PlcSocketParamType *param = &plc_socket_demo_data;
|
||||
|
||||
PlcCheckParam(argc, argv);
|
||||
|
||||
lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, param->ip);
|
||||
PrivTaskCreate(&th_id, &attr, PlcSocketStart, param);
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
||||
PlcSocket, PlcSocketTask, Test PLC Socket);
|
||||
|
||||
|
|
@ -1,2 +1,28 @@
|
|||
config CONTROL_PROTOCOL_FINS
|
||||
bool "Using fins control protocol"
|
||||
default n
|
||||
select CONTROL_USING_SOCKET
|
||||
if CONTROL_PROTOCOL_FINS
|
||||
source "$APP_DIR/Framework/control/plc_protocol/fins/Kconfig"
|
||||
endif
|
||||
|
||||
config CONTROL_PROTOCOL_MELSEC
|
||||
bool "Using melsec control protocol"
|
||||
default n
|
||||
if CONTROL_PROTOCOL_MELSEC
|
||||
source "$APP_DIR/Framework/control/plc_protocol/melsec/Kconfig"
|
||||
endif
|
||||
|
||||
config CONTROL_PROTOCOL_OPCUA
|
||||
bool "Using opcua control protocol"
|
||||
default n
|
||||
if CONTROL_PROTOCOL_OPCUA
|
||||
source "$APP_DIR/Framework/control/plc_protocol/opcua/Kconfig"
|
||||
endif
|
||||
|
||||
config CONTROL_PROTOCOL_S7
|
||||
bool "Using s7 control protocol"
|
||||
default n
|
||||
if CONTROL_PROTOCOL_S7
|
||||
source "$APP_DIR/Framework/control/plc_protocol/s7/Kconfig"
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,17 @@
|
|||
SRC_DIR := fins melsec opcua s7
|
||||
ifeq ($(CONFIG_CONTROL_PROTOCOL_FINS), y)
|
||||
SRC_DIR := fins
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONTROL_PROTOCOL_MELSEC), y)
|
||||
SRC_DIR := melsec
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONTROL_PROTOCOL_OPCUA), y)
|
||||
SRC_DIR := opcua
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONTROL_PROTOCOL_S7), y)
|
||||
SRC_DIR := s7
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
SRC_FILES :=
|
||||
SRC_FILES := fins.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,448 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fins.c
|
||||
* @brief plc protocol fins
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-10-08
|
||||
*/
|
||||
|
||||
#include <fins.h>
|
||||
|
||||
#define FINS_COMMAND_LENGTH 34
|
||||
|
||||
static BasicSocketPlc plc_socket = {0};
|
||||
|
||||
static uint8_t handshake_require_command[] = {0x46, 0x49, 0x4E, 0x53, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
static uint8_t handshake_respond_buff[24] = {0};
|
||||
static uint8_t recv_buff[1024] = {0};
|
||||
|
||||
/**
|
||||
* @description: Fins Get Area Code
|
||||
* @param area_char - area char
|
||||
* @param type - fins data type
|
||||
* @return success : area_char error : 0
|
||||
*/
|
||||
static uint8_t FinsAreaCode(char area_char, FinsDataType type)
|
||||
{
|
||||
uint8_t area_code = 0;
|
||||
if (area_char == 'C')
|
||||
area_code = (type == FINS_DATA_TYPE_BIT ? 0x30 : 0xB0);
|
||||
if (area_char == 'W')
|
||||
area_code = (type == FINS_DATA_TYPE_BIT ? 0x31 : 0xB1);
|
||||
if (area_char == 'H')
|
||||
area_code = (type == FINS_DATA_TYPE_BIT ? 0x32 : 0xB2);
|
||||
if (area_char == 'D')
|
||||
area_code = (type == FINS_DATA_TYPE_BIT ? 0x02 : 0x82);
|
||||
return area_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Cmd Genetare
|
||||
* @param p_command - command pointer
|
||||
* @param plc_ip_4 - last plc ip
|
||||
* @param local_ip_4 - last local ip
|
||||
* @param p_read_item - p_read_item pointer
|
||||
* @return success : index error : 0
|
||||
*/
|
||||
static uint16_t FinsCommandGenerate(uint8_t *p_command, uint16_t plc_ip_4, uint16_t local_ip_4, FinsReadItem *p_read_item)
|
||||
{
|
||||
uint8_t index = 0;
|
||||
uint16_t command_code = p_read_item->data_info.command_code;
|
||||
uint8_t area_char = p_read_item->area_char;
|
||||
uint16_t data_type = p_read_item->data_type;
|
||||
uint16_t start_address = p_read_item->start_address;
|
||||
uint8_t bit_address = p_read_item->bit_address;
|
||||
uint16_t data_length = p_read_item->data_length;
|
||||
|
||||
p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (3 * 8));
|
||||
p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (2 * 8));
|
||||
p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (1 * 8));
|
||||
p_command[index++] = (uint8_t)FINS_HEADER_HEAD;
|
||||
p_command[index++] = (uint8_t)FINS_HEADER_READ_COMMAND_LENGTH >> (3 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH >> (2 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH >> (1 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH;
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (3 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (2 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (1 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND;
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (3 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (2 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (1 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE;
|
||||
p_command[index++] = FINS_ICF;
|
||||
p_command[index++] = FINS_RSV;
|
||||
p_command[index++] = FINS_GCT;
|
||||
|
||||
p_command[index++] = FINS_DNA;
|
||||
p_command[index++] = plc_ip_4;
|
||||
p_command[index++] = FINS_DA2;
|
||||
|
||||
p_command[index++] = FINS_SNA;
|
||||
p_command[index++] = local_ip_4;
|
||||
p_command[index++] = FINS_SA2;
|
||||
|
||||
p_command[index++] = FINS_SID;
|
||||
|
||||
p_command[index++] = command_code >> 8;
|
||||
p_command[index++] = command_code;
|
||||
p_command[index++] = FinsAreaCode(area_char, data_type);
|
||||
p_command[index++] = start_address >> 8;
|
||||
p_command[index++] = start_address;
|
||||
p_command[index++] = bit_address;
|
||||
p_command[index++] = data_length >> 8;
|
||||
p_command[index++] = data_length;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Data Transform from Receive Buffer To Control-Data
|
||||
* @param p_read_item - read item pointer
|
||||
* @param recv_buff - receive buff
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static int FinsTransformRecvBuffToData(FinsReadItem *p_read_item, uint8_t *recv_buff)
|
||||
{
|
||||
FinsDataInfo *p_fins_data_info = &(p_read_item->data_info);
|
||||
uint8_t error_code = recv_buff[15];
|
||||
if (error_code) {
|
||||
printf("Data abnormal, abnormal error code is 0x%x!\n", error_code);
|
||||
return -1;
|
||||
}
|
||||
recv_buff += 30;
|
||||
|
||||
FinsCommandCode command_code = p_fins_data_info->command_code;
|
||||
if (FINS_COMMAND_CODE_READ == command_code) {
|
||||
|
||||
uint16_t data_length = p_read_item->data_length;
|
||||
ControlPrintfList("DATA", recv_buff, data_length * (FINS_DATA_TYPE_BIT == p_read_item->data_type ? 1 : 2));
|
||||
printf("Receive data is ");
|
||||
|
||||
if (FINS_DATA_TYPE_BIT == p_read_item->data_type) {
|
||||
memcpy(p_fins_data_info->base_data_info.p_data, recv_buff, data_length);
|
||||
|
||||
printf("0x%x", p_fins_data_info->base_data_info.p_data[0]);
|
||||
} else {
|
||||
uint8_t *p_data = p_fins_data_info->base_data_info.p_data;
|
||||
|
||||
for (uint16_t i = 0; i < data_length; i ++) {
|
||||
p_data[2 * i] = recv_buff[2 * (data_length - i - 1)];
|
||||
p_data[2 * i + 1] = recv_buff[2 * (data_length - i - 1) + 1];
|
||||
printf("0x%x 0x%x", p_data[2 * i], p_data[2 * i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nRead fins plc data success!\n");
|
||||
} else if (FINS_COMMAND_CODE_WRITE == command_code) {
|
||||
/*to do*/
|
||||
printf("Write fins plc cmd success!\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONTROL_USING_SOCKET
|
||||
/**
|
||||
* @description: Fins Protocol Handshake
|
||||
* @param socket - socket
|
||||
* @param local_ip_4 - last local ip
|
||||
* @return success : 0 error : -1 -2
|
||||
*/
|
||||
static int FinsHandshake(int32_t socket, uint16_t local_ip_4)
|
||||
{
|
||||
handshake_require_command[18] = (uint8_t)(local_ip_4 >> 8);
|
||||
handshake_require_command[19] = (uint8_t)local_ip_4;
|
||||
uint8_t try_count = 0;
|
||||
|
||||
while (try_count < 10) {
|
||||
ControlPrintfList("SEND", (uint8_t *)handshake_require_command, sizeof(handshake_require_command));
|
||||
int32_t write_error = socket_write(socket, handshake_require_command, sizeof(handshake_require_command));
|
||||
if (write_error < 0) {
|
||||
printf("Write socket error, errno is %d!", errno);
|
||||
} else {
|
||||
int32_t recv_length = socket_read(socket, (uint8_t *)handshake_respond_buff, sizeof(handshake_respond_buff));
|
||||
if (recv_length < 0) {
|
||||
printf("Read socket error, errno is %d!", errno);
|
||||
} else {
|
||||
ControlPrintfList("RECV", (uint8_t *)handshake_respond_buff, recv_length);
|
||||
|
||||
/*check fins handshake respond*/
|
||||
uint8_t error_code = handshake_respond_buff[15];
|
||||
if (error_code == 0 || error_code == 0x21) {
|
||||
return 0;
|
||||
} else {
|
||||
printf("Fins handshake failed, errno is %05x!", handshake_respond_buff[15]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
|
||||
printf("Send plc command failed, errno is %d!", errno);
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Get Data From Socket
|
||||
* @param socket - socket
|
||||
* @param p_read_item - read item pointer
|
||||
* @return success : 0 error : -1 -2
|
||||
*/
|
||||
static int FinsGetData(int32_t socket, FinsReadItem *p_read_item)
|
||||
{
|
||||
uint8_t try_count = 0;
|
||||
int32_t write_error = 0;
|
||||
|
||||
FinsDataInfo *p_fins_data_info = &(p_read_item->data_info);
|
||||
BasicPlcDataInfo *p_base_data_info = &(p_fins_data_info->base_data_info);
|
||||
|
||||
memset(recv_buff, 0, sizeof(recv_buff));
|
||||
|
||||
while (try_count < 10) {
|
||||
ControlPrintfList("SEND", p_base_data_info->p_command, p_base_data_info->command_length);
|
||||
try_count++;
|
||||
|
||||
write_error = socket_write(socket, p_base_data_info->p_command, p_base_data_info->command_length);
|
||||
if (write_error < 0) {
|
||||
printf("Write socket error, errno is %d!", errno);
|
||||
} else {
|
||||
PrivTaskDelay(20);
|
||||
|
||||
int32_t recv_length = socket_read(socket, recv_buff, sizeof(recv_buff));
|
||||
if (recv_length < 0) {
|
||||
printf("Read socket error, errno is %d!", errno);
|
||||
} else {
|
||||
ControlPrintfList("RECV", recv_buff, recv_length);
|
||||
return FinsTransformRecvBuffToData(p_read_item, recv_buff);
|
||||
}
|
||||
}
|
||||
|
||||
if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
|
||||
printf("Send plc command failed, errno is %d!", errno);
|
||||
continue;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @description: Fins Data Info Init
|
||||
* @param p_read_item - read item pointer
|
||||
* @param plc_ip_4 - last plc ip
|
||||
* @param local_ip_4 - last local ip
|
||||
* @param p_data - control-data pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static int FinsInitialDataInfo(FinsReadItem *p_read_item, uint16_t plc_ip_4, uint16_t local_ip_4, uint8_t *p_data)
|
||||
{
|
||||
uint16_t data_length = p_read_item->data_length;
|
||||
|
||||
BasicPlcDataInfo *p_base_data_info = &(p_read_item->data_info.base_data_info);
|
||||
switch (p_read_item->data_info.command_code)
|
||||
{
|
||||
case FINS_COMMAND_CODE_READ:
|
||||
data_length *= (p_read_item->data_type == FINS_DATA_TYPE_BIT ? 1 : 2);
|
||||
p_base_data_info->command_length = FINS_COMMAND_LENGTH;
|
||||
p_base_data_info->p_command = PrivMalloc(FINS_COMMAND_LENGTH);
|
||||
p_base_data_info->data_size = data_length;
|
||||
p_base_data_info->p_data = p_data;
|
||||
break;
|
||||
case FINS_COMMAND_CODE_WRITE:
|
||||
//To Do
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
FinsCommandGenerate(p_base_data_info->p_command, plc_ip_4, local_ip_4, p_read_item);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Receive Plc Data Task
|
||||
* @param parameter - parameter pointer
|
||||
* @return
|
||||
*/
|
||||
void *ReceivePlcDataTask(void *parameter)
|
||||
{
|
||||
int i = 0;
|
||||
uint8_t try_count = 0;
|
||||
uint16_t data_length = 0;
|
||||
uint8_t *fins_data;
|
||||
uint16_t read_item_size = sizeof(FinsReadItem);
|
||||
|
||||
struct ControlProtocol *control_protocol = (struct ControlProtocol *)parameter;
|
||||
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
|
||||
FinsReadItem *fins_read_item = (FinsReadItem *)control_protocol->recipe->read_item;
|
||||
fins_data = control_protocol->recipe->protocol_data.data;
|
||||
data_length = control_protocol->recipe->protocol_data.data_length;
|
||||
|
||||
memset(&plc_socket, 0, sizeof(BasicSocketPlc));
|
||||
memcpy(plc_socket.ip, control_protocol->recipe->socket_config.plc_ip, 4);
|
||||
plc_socket.port = control_protocol->recipe->socket_config.port;
|
||||
plc_socket.socket = -1;
|
||||
plc_socket.secondary_connect_flag = 0;
|
||||
|
||||
while (1) {
|
||||
for (i = 0; i < control_protocol->recipe->read_item_count; i ++) {
|
||||
#ifdef CONTROL_USING_SOCKET
|
||||
/*only connect socket when close socket or init*/
|
||||
while (ControlConnectSocket(&plc_socket) < 0) {
|
||||
PrivTaskDelay(1000);
|
||||
}
|
||||
|
||||
/*need to handshake after connect socket using FINS protocol*/
|
||||
if (0 == plc_socket.secondary_connect_flag) {
|
||||
if (FinsHandshake(plc_socket.socket, control_protocol->recipe->socket_config.local_ip[3]) < 0) {
|
||||
plc_socket.secondary_connect_flag = 0;
|
||||
ControlDisconnectSocket(&plc_socket);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
plc_socket.secondary_connect_flag = 1;
|
||||
|
||||
FinsGetData(plc_socket.socket, (FinsReadItem *)fins_read_item + i);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*read all variable item data, put them into circular_area*/
|
||||
if (i == control_protocol->recipe->read_item_count) {
|
||||
printf("%s get %d item %d length\n", __func__, i, data_length);
|
||||
CircularAreaAppWrite(circular_area, fins_data, data_length, 0);
|
||||
}
|
||||
|
||||
/*read data every single 'read_period' ms*/
|
||||
PrivTaskDelay(control_protocol->recipe->read_period);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Protocol Open
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @return success : 0 error
|
||||
*/
|
||||
int FinsOpen(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
ControlProtocolOpenDef(control_protocol);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Protocol Close
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @return success : 0 error
|
||||
*/
|
||||
int FinsClose(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
#ifdef CONTROL_USING_SOCKET
|
||||
ControlDisconnectSocket(&plc_socket);
|
||||
#endif
|
||||
|
||||
ControlProtocolCloseDef();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Protocol Read Data
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @param buf - read data buffer
|
||||
* @param len - read data length
|
||||
* @return success : data length error : 0
|
||||
*/
|
||||
int FinsRead(struct ControlProtocol *control_protocol, void *buf, size_t len)
|
||||
{
|
||||
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
|
||||
return CircularAreaAppRead(circular_area, buf, len);
|
||||
}
|
||||
|
||||
static struct ControlDone fins_protocol_done =
|
||||
{
|
||||
._open = FinsOpen,
|
||||
._close = FinsClose,
|
||||
._read = FinsRead,
|
||||
._write = NULL,
|
||||
._ioctl = NULL,
|
||||
};
|
||||
|
||||
/**
|
||||
* @description: Fins Protocol Cmd Generate
|
||||
* @param p_recipe - recipe pointer
|
||||
* @param protocol_format_info - protocol format info pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int FinsProtocolFormatCmd(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info)
|
||||
{
|
||||
int ret = 0;
|
||||
static uint8_t last_item_size = 0;
|
||||
uint8_t *p_read_item_data = protocol_format_info->p_read_item_data + last_item_size;
|
||||
|
||||
FinsReadItem *fins_read_item = (FinsReadItem *)(p_recipe->read_item) + protocol_format_info->read_item_index;
|
||||
|
||||
fins_read_item->value_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_type")->valueint;
|
||||
strncpy(fins_read_item->value_name, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_name")->valuestring, 20);
|
||||
strncpy(&fins_read_item->area_char, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "area_char")->valuestring, 1);
|
||||
fins_read_item->data_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "data_type")->valueint;
|
||||
fins_read_item->data_info.command_code = FINS_COMMAND_CODE_READ;
|
||||
fins_read_item->start_address = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "start_address")->valueint;
|
||||
fins_read_item->bit_address = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "bit_address")->valueint;
|
||||
fins_read_item->data_length = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "data_length")->valueint;
|
||||
|
||||
ret = FinsInitialDataInfo(fins_read_item,
|
||||
p_recipe->socket_config.plc_ip[3],
|
||||
p_recipe->socket_config.local_ip[3],
|
||||
p_read_item_data);
|
||||
|
||||
ControlPrintfList("CMD", fins_read_item->data_info.base_data_info.p_command, fins_read_item->data_info.base_data_info.command_length);
|
||||
protocol_format_info->last_item_size = GetValueTypeMemorySize(fins_read_item->value_type);
|
||||
|
||||
last_item_size += protocol_format_info->last_item_size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Protocol Init
|
||||
* @param p_recipe - recipe pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int FinsProtocolInit(struct ControlRecipe *p_recipe)
|
||||
{
|
||||
p_recipe->read_item = PrivMalloc(sizeof(FinsReadItem) * p_recipe->read_item_count);
|
||||
if (NULL == p_recipe->read_item) {
|
||||
PrivFree(p_recipe->read_item);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(p_recipe->read_item, 0, sizeof(FinsReadItem));
|
||||
|
||||
p_recipe->ControlProtocolFormatCmd = FinsProtocolFormatCmd;
|
||||
|
||||
p_recipe->done = &fins_protocol_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,331 @@
|
|||
{
|
||||
"device_id": 769,
|
||||
"device_name": "S01",
|
||||
"communication_type": 0,
|
||||
"socket_config": {
|
||||
"plc_ip": "192.168.250.22",
|
||||
"local_ip": "192.168.250.233",
|
||||
"gateway": "192.168.250.1",
|
||||
"netmask": "255.255.254.0",
|
||||
"port": 9600
|
||||
},
|
||||
"protocol_type": 5,
|
||||
"read_period": 100,
|
||||
"read_item_list": [
|
||||
{
|
||||
"value_name": "启动",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 0,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "停止",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 0,
|
||||
"bit_address": 1,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "使能",
|
||||
"value_type": 1,
|
||||
"area_char": "H",
|
||||
"data_type": 0,
|
||||
"start_address": 0,
|
||||
"bit_address": 2,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "回零",
|
||||
"value_type": 1,
|
||||
"area_char": "D",
|
||||
"data_type": 0,
|
||||
"start_address": 0,
|
||||
"bit_address": 3,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "急停",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 0,
|
||||
"bit_address": 4,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "正限位",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 10,
|
||||
"bit_address": 11,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "负限位",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 10,
|
||||
"bit_address": 12,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "自动运行中",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 200,
|
||||
"bit_address": 5,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "故障",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 200,
|
||||
"bit_address": 6,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "待机",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 200,
|
||||
"bit_address": 7,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "手动模式",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 300,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "自动模式",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 300,
|
||||
"bit_address": 1,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "运行方向",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 300,
|
||||
"bit_address": 2,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "复位",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 400,
|
||||
"bit_address": 3,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "备用1",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 400,
|
||||
"bit_address": 4,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "产量",
|
||||
"value_type": 3,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 10,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型1",
|
||||
"value_type": 3,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 11,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型2",
|
||||
"value_type": 3,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 20,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型3",
|
||||
"value_type": 3,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 100,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型4",
|
||||
"value_type": 3,
|
||||
"area_char": "W",
|
||||
"data_type": 1,
|
||||
"start_address": 100,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型5",
|
||||
"value_type": 3,
|
||||
"area_char": "W",
|
||||
"data_type": 1,
|
||||
"start_address": 101,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型6",
|
||||
"value_type": 3,
|
||||
"area_char": "W",
|
||||
"data_type": 1,
|
||||
"start_address": 110,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型7",
|
||||
"value_type": 3,
|
||||
"area_char": "H",
|
||||
"data_type": 1,
|
||||
"start_address": 10,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型8",
|
||||
"value_type": 3,
|
||||
"area_char": "H",
|
||||
"data_type": 1,
|
||||
"start_address": 20,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型9",
|
||||
"value_type": 3,
|
||||
"area_char": "H",
|
||||
"data_type": 1,
|
||||
"start_address": 21,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "速度",
|
||||
"value_type": 9,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 2000,
|
||||
"bit_address": 0,
|
||||
"data_length": 2
|
||||
},
|
||||
{
|
||||
"value_name": "加速度",
|
||||
"value_type": 9,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 2002,
|
||||
"bit_address": 0,
|
||||
"data_length": 2
|
||||
},
|
||||
{
|
||||
"value_name": "减速度",
|
||||
"value_type": 9,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 2004,
|
||||
"bit_address": 0,
|
||||
"data_length": 2
|
||||
},
|
||||
{
|
||||
"value_name": "起始位置",
|
||||
"value_type": 9,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 300,
|
||||
"bit_address": 0,
|
||||
"data_length": 2
|
||||
},
|
||||
{
|
||||
"value_name": "终点位置",
|
||||
"value_type": 9,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 302,
|
||||
"bit_address": 0,
|
||||
"data_length": 2
|
||||
},
|
||||
{
|
||||
"value_name": "张力值",
|
||||
"value_type": 9,
|
||||
"area_char": "W",
|
||||
"data_type": 1,
|
||||
"start_address": 80,
|
||||
"bit_address": 0,
|
||||
"data_length": 2
|
||||
},
|
||||
{
|
||||
"value_name": "浮点型1",
|
||||
"value_type": 8,
|
||||
"area_char": "H",
|
||||
"data_type": 1,
|
||||
"start_address": 100,
|
||||
"bit_address": 0,
|
||||
"data_length": 4
|
||||
},
|
||||
{
|
||||
"value_name": "浮点型2",
|
||||
"value_type": 8,
|
||||
"area_char": "H",
|
||||
"data_type": 1,
|
||||
"start_address": 104,
|
||||
"bit_address": 0,
|
||||
"data_length": 4
|
||||
},
|
||||
{
|
||||
"value_name": "浮点型3",
|
||||
"value_type": 8,
|
||||
"area_char": "H",
|
||||
"data_type": 1,
|
||||
"start_address": 108,
|
||||
"bit_address": 0,
|
||||
"data_length": 4
|
||||
},
|
||||
{
|
||||
"value_name": "浮点型4",
|
||||
"value_type": 8,
|
||||
"area_char": "H",
|
||||
"data_type": 1,
|
||||
"start_address": 112,
|
||||
"bit_address": 0,
|
||||
"data_length": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fins.h
|
||||
* @brief plc protocol fins
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-10-08
|
||||
*/
|
||||
|
||||
#ifndef FINS_H
|
||||
#define FINS_H
|
||||
|
||||
#include <control_def.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define FINS_HEADER_HEAD 0x46494E53
|
||||
#define FINS_HEADER_READ_COMMAND_LENGTH 0x0000001A
|
||||
#define FINS_HEADER_COMMAND 0x00000002
|
||||
#define FINS_HEADER_ERROR_CODE 0x00000000
|
||||
#define FINS_ICF 0x80
|
||||
#define FINS_RSV 0x00
|
||||
#define FINS_REPLY_ICF 0xC0
|
||||
#define FINS_GCT 0x02
|
||||
#define FINS_DNA 0x00
|
||||
#define FINS_DA2 0x00
|
||||
#define FINS_SNA 0x00
|
||||
#define FINS_SA2 0x00
|
||||
#define FINS_SID 0x00
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FINS_COMMAND_CODE_READ = 0x0101,
|
||||
FINS_COMMAND_CODE_WRITE = 0x0102
|
||||
}FinsCommandCode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FINS_DATA_TYPE_BIT,
|
||||
FINS_DATA_TYPE_WORD
|
||||
}FinsDataType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BasicPlcDataInfo base_data_info;
|
||||
FinsCommandCode command_code;
|
||||
}FinsDataInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t socket;
|
||||
uint16_t plc_ip_4;
|
||||
}FinsHandshakeParameter;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FinsDataInfo data_info;
|
||||
|
||||
UniformValueType value_type;
|
||||
uint8_t value_name[20];
|
||||
|
||||
uint8_t area_char;
|
||||
FinsDataType data_type;
|
||||
uint16_t start_address;
|
||||
uint8_t bit_address;
|
||||
uint16_t data_length;
|
||||
}FinsReadItem;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file melsec.h
|
||||
* @brief plc protocol melsec
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-11-29
|
||||
*/
|
||||
|
||||
#ifndef MELSEC_H
|
||||
#define MELSEC_H
|
||||
|
||||
#include <control_def.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SUB_HEADER 0x5000
|
||||
#define NETWORK_NUMBER 0x00
|
||||
#define PC_NUMBER 0xFF
|
||||
#define QEQUEST_DESTINSTION_MODULE_IO_NUMBER 0x03FF
|
||||
#define QEQUEST_DESTINSTION_MODULE_STATION_NUMBER 0x00
|
||||
#define STATION_NUMBER 0x00
|
||||
#define FRAME_NUMBER 0x4639
|
||||
#define SELF_STATION_NUMBER 0x00
|
||||
|
||||
#define MELSEC_NAK 0x15
|
||||
#define MELSEC_STX 0x02
|
||||
#define MELSEC_ETX 0x03
|
||||
#define MELSEC_ENQ 0x05
|
||||
|
||||
#define MELSEC_1E_FRAME_RB 0x00
|
||||
#define MELSEC_1E_FRAME_RW 0x01
|
||||
#define MELSEC_1E_FRAME_WB 0x02
|
||||
#define MELSEC_1E_FRAME_WW 0x03
|
||||
|
||||
#define MELSEC_1C_FRAME_RB 0x4252
|
||||
#define MELSEC_1C_FRAME_RW 0x5752
|
||||
#define MELSEC_1C_FRAME_WB 0x4257
|
||||
#define MELSEC_1C_FRAME_WW 0x5757
|
||||
|
||||
//same as MELSEC_3E_Q_L_FRAME
|
||||
#define MELSEC_3C_FRAME_RB 0x04010001
|
||||
#define MELSEC_3C_FRAME_RW 0x04010000
|
||||
#define MELSEC_3C_FRAME_WB 0x14010001
|
||||
#define MELSEC_3C_FRAME_WW 0x14010000
|
||||
|
||||
//same as MELSEC_3C_FRAME
|
||||
#define MELSEC_3E_Q_L_FRAME_RB 0x04010001
|
||||
#define MELSEC_3E_Q_L_FRAME_RW 0x04010000
|
||||
#define MELSEC_3E_Q_L_FRAME_WB 0x14010001
|
||||
#define MELSEC_3E_Q_L_FRAME_WW 0x14010000
|
||||
|
||||
#define MELSEC_3E_IQ_R_FRAME_RB 0x04010003
|
||||
#define MELSEC_3E_IQ_R_FRAME_RW 0x04010002
|
||||
#define MELSEC_3E_IQ_R_FRAME_WB 0x14010003
|
||||
#define MELSEC_3E_IQ_R_FRAME_WW 0x14010002
|
||||
|
||||
typedef enum {
|
||||
READ_IN_BITS,
|
||||
READ_IN_WORD,
|
||||
WRITE_IN_BITS,
|
||||
WRITE_IN_WORD,
|
||||
TEST_IN_BIT,
|
||||
TEST_IN_WORD
|
||||
}MelsecCommandType;
|
||||
|
||||
typedef enum {
|
||||
MELSEC_1E_FRAME,
|
||||
MELSEC_3E_Q_L_FRAME,
|
||||
MELSEC_3E_IQ_R_FRAME,
|
||||
MELSEC_1C_FRAME,
|
||||
MELSEC_3C_FRAME
|
||||
}MelsecFrameType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BasicPlcDataInfo base_data_info;
|
||||
MelsecCommandType command_type;
|
||||
MelsecFrameType frame_type;
|
||||
}MelsecDataInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MelsecDataInfo data_info;
|
||||
|
||||
UniformValueType value_type;
|
||||
uint8_t value_name[20];
|
||||
|
||||
uint16_t monitoring_timer;
|
||||
uint16_t device_code;
|
||||
uint8_t head_device_number_string[6];
|
||||
uint16_t device_points_count;
|
||||
}MelsecReadItem;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
10
APP_Framework/Framework/control/shared/control_file.c → APP_Framework/Framework/control/plc_protocol/include/opcua.h
Executable file → Normal file
10
APP_Framework/Framework/control/shared/control_file.c → APP_Framework/Framework/control/plc_protocol/include/opcua.h
Executable file → Normal file
|
|
@ -11,11 +11,9 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file control_file.c
|
||||
* @brief control relative file operation
|
||||
* @file opcua.h
|
||||
* @brief control protocol opcua
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-09-37
|
||||
*/
|
||||
|
||||
|
||||
* @date 2022-10-08
|
||||
*/
|
||||
15
APP_Framework/Framework/control/shared/control_file.h → APP_Framework/Framework/control/plc_protocol/include/s7.h
Executable file → Normal file
15
APP_Framework/Framework/control/shared/control_file.h → APP_Framework/Framework/control/plc_protocol/include/s7.h
Executable file → Normal file
|
|
@ -11,16 +11,9 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file control_file.h
|
||||
* @brief control file function relative API
|
||||
* @file s7.h
|
||||
* @brief plc protocol s7
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-09-27
|
||||
*/
|
||||
|
||||
#ifndef CONTROL_FILE_H
|
||||
#define CONTROL_FILE_H
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
* @date 2022-10-08
|
||||
*/
|
||||
|
|
@ -1,2 +1,64 @@
|
|||
choice
|
||||
prompt "select melsec protocol"
|
||||
default CONTROL_PROTOCOL_MELSEC_1E
|
||||
|
||||
config CONTROL_PROTOCOL_MELSEC_1E
|
||||
bool "support melsec_1e protocol, using SOCKET"
|
||||
select CONTROL_USING_SOCKET
|
||||
|
||||
config CONTROL_PROTOCOL_MELSEC_3E_Q_L
|
||||
bool "support melsec_3e_q_l protocol, using SOCKET"
|
||||
select CONTROL_USING_SOCKET
|
||||
|
||||
config CONTROL_PROTOCOL_MELSEC_3E_IQ_R
|
||||
bool "support melsec_3e_iq_r protocol, using SOCKET"
|
||||
select CONTROL_USING_SOCKET
|
||||
|
||||
config CONTROL_PROTOCOL_MELSEC_1C
|
||||
bool "support melsec_1c protocol, using SERIAL"
|
||||
select CONTROL_USING_SERIAL_485
|
||||
|
||||
config CONTROL_PROTOCOL_MELSEC_3C
|
||||
bool "support melsec_3c protocol, using SERIAL"
|
||||
select CONTROL_USING_SERIAL_485
|
||||
endchoice
|
||||
|
||||
if CONTROL_USING_SERIAL_485
|
||||
if ADD_XIZI_FETURES
|
||||
config CONTROL_FRAMEWORK_UART_485_DIR
|
||||
int "control framework 485 direction pin number"
|
||||
default "2"
|
||||
|
||||
config CONTROL_FRAMEWORK_PIN_DEV
|
||||
string "control framework device pin dev path"
|
||||
default "/dev/pin_dev"
|
||||
|
||||
config CONTROL_FRAMEWORK_DRIVER_EXTUART
|
||||
bool "Using extra uart to control framework"
|
||||
default n
|
||||
|
||||
config CONTROL_FRAMEWORK_UART_DEV
|
||||
string "control framework device uart dev path"
|
||||
default "/dev/uart3_dev3"
|
||||
depends on !CONTROL_FRAMEWORK_DRIVER_EXTUART
|
||||
|
||||
if CONTROL_FRAMEWORK_DRIVER_EXTUART
|
||||
config CONTROL_FRAMEWORK_UART_DEV
|
||||
string "control framework device extra uart dev path"
|
||||
default "/dev/extuart_dev0"
|
||||
|
||||
config CONTROL_FRAMEWORK_DEV_EXT_PORT
|
||||
int "if control framework device using extuart, choose port"
|
||||
default "0"
|
||||
endif
|
||||
endif
|
||||
|
||||
if ADD_NUTTX_FETURES
|
||||
|
||||
endif
|
||||
|
||||
if ADD_RTTHREAD_FETURES
|
||||
|
||||
endif
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
SRC_FILES :=
|
||||
SRC_FILES := melsec.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,805 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file melsec.c
|
||||
* @brief plc protocol melsec, support 1E、3E_Q_L、3E_IQ_R、1C、3C
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-11-29
|
||||
*/
|
||||
|
||||
#include <melsec.h>
|
||||
|
||||
static BasicSocketPlc plc_socket = {0};
|
||||
static uint8_t recv_buff[1024] = {0};
|
||||
|
||||
/**
|
||||
* @description: Melsec Get Check Sum
|
||||
* @param p_command - p_command pointer
|
||||
* @param command_length - command length
|
||||
* @return checksum
|
||||
*/
|
||||
static uint8_t GetCheckSum(uint8_t *p_command, uint16_t command_length)
|
||||
{
|
||||
uint8_t checksum = 0;
|
||||
for (uint16_t i = 0; i < command_length; i++) {
|
||||
checksum += p_command[i];
|
||||
}
|
||||
return checksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec Transform from Hex to Ascii
|
||||
* @param hex - hex
|
||||
* @return ascii
|
||||
*/
|
||||
static uint8_t TransformHexToAscii(uint8_t hex)
|
||||
{
|
||||
hex %= 0x10;
|
||||
return hex < 0xA ? hex + '0' : hex - 10 + 'A';
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec Transform from Ascii to Hex
|
||||
* @param ascii - ascii
|
||||
* @return hex
|
||||
*/
|
||||
static uint8_t TransformAsciiToHex(uint8_t ascii)
|
||||
{
|
||||
if (ascii > 'F' || ascii < '0' || (ascii > '9' && ascii < 'A'))
|
||||
return 0;
|
||||
else
|
||||
return ascii < 'A' ? ascii - '0' : ascii - 'A' + 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec Get Device Code
|
||||
* @param frame_type - melsec frame type
|
||||
* @param device_string - device string
|
||||
* @return device code
|
||||
*/
|
||||
static int MelsecGetDeviceCode(MelsecFrameType frame_type, char device_string[2])
|
||||
{
|
||||
switch (frame_type) {
|
||||
case MELSEC_1C_FRAME:
|
||||
if (strcmp(device_string, "M") == 0)
|
||||
return 0x4D;
|
||||
if (strcmp(device_string, "D") == 0)
|
||||
return 0x44;
|
||||
if (strcmp(device_string, "B") == 0)
|
||||
return 0x22;
|
||||
if (strcmp(device_string, "W") == 0)
|
||||
return 0x57;
|
||||
if (strcmp(device_string, "X") == 0)
|
||||
return 0x58;
|
||||
if (strcmp(device_string, "Y") == 0)
|
||||
return 0x59;
|
||||
case MELSEC_1E_FRAME:
|
||||
if (strcmp(device_string, "M") == 0)
|
||||
return 0x4D20;
|
||||
if (strcmp(device_string, "D") == 0)
|
||||
return 0x4420;
|
||||
if (strcmp(device_string, "B") == 0)
|
||||
return 0x2220;
|
||||
if (strcmp(device_string, "W") == 0)
|
||||
return 0x5720;
|
||||
if (strcmp(device_string, "X") == 0)
|
||||
return 0x5820;
|
||||
if (strcmp(device_string, "Y") == 0)
|
||||
return 0x5920;
|
||||
case MELSEC_3C_FRAME:
|
||||
if (strcmp(device_string, "M") == 0)
|
||||
return 0x4D2A;
|
||||
if (strcmp(device_string, "D") == 0)
|
||||
return 0x442A;
|
||||
if (strcmp(device_string, "B") == 0)
|
||||
return 0x222A;
|
||||
if (strcmp(device_string, "W") == 0)
|
||||
return 0x572A;
|
||||
case MELSEC_3E_IQ_R_FRAME:
|
||||
if (strcmp(device_string, "M") == 0)
|
||||
return 0x0090;
|
||||
if (strcmp(device_string, "D") == 0)
|
||||
return 0x00A8;
|
||||
if (strcmp(device_string, "B") == 0)
|
||||
return 0x00A0;
|
||||
if (strcmp(device_string, "W") == 0)
|
||||
return 0x00B4;
|
||||
if (strcmp(device_string, "X") == 0)
|
||||
return 0x009C;
|
||||
if (strcmp(device_string, "Y") == 0)
|
||||
return 0x009D;
|
||||
case MELSEC_3E_Q_L_FRAME:
|
||||
if (strcmp(device_string, "M") == 0)
|
||||
return 0x90;
|
||||
if (strcmp(device_string, "D") == 0)
|
||||
return 0xA8;
|
||||
if (strcmp(device_string, "B") == 0)
|
||||
return 0xA0;
|
||||
if (strcmp(device_string, "W") == 0)
|
||||
return 0xB4;
|
||||
if (strcmp(device_string, "X") == 0)
|
||||
return 0x9C;
|
||||
if (strcmp(device_string, "Y") == 0)
|
||||
return 0x9D;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec Get Command Base Length
|
||||
* @param frame_type - melsec frame type
|
||||
* @return command length
|
||||
*/
|
||||
static int MelsecGetCommandBaseLength(MelsecFrameType frame_type)
|
||||
{
|
||||
switch (frame_type) {
|
||||
case MELSEC_1C_FRAME:
|
||||
return 17;
|
||||
case MELSEC_1E_FRAME:
|
||||
return 12;
|
||||
case MELSEC_3C_FRAME:
|
||||
return 33;
|
||||
case MELSEC_3E_IQ_R_FRAME:
|
||||
case MELSEC_3E_Q_L_FRAME:
|
||||
return 21;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec Get Command Code
|
||||
* @param frame_type - melsec frame type
|
||||
* @param command_type - melsec command type
|
||||
* @return command code
|
||||
*/
|
||||
static uint32_t MelsecGetCommandCode(MelsecFrameType frame_type, MelsecCommandType command_type)
|
||||
{
|
||||
switch (frame_type) {
|
||||
case MELSEC_1C_FRAME:
|
||||
switch (command_type) {
|
||||
case READ_IN_BITS:
|
||||
return MELSEC_1C_FRAME_RB;
|
||||
case READ_IN_WORD:
|
||||
return MELSEC_1C_FRAME_RW;
|
||||
case WRITE_IN_BITS:
|
||||
return MELSEC_1C_FRAME_WB;
|
||||
case WRITE_IN_WORD:
|
||||
return MELSEC_1C_FRAME_WW;
|
||||
}
|
||||
case MELSEC_1E_FRAME:
|
||||
return command_type;
|
||||
case MELSEC_3C_FRAME:
|
||||
case MELSEC_3E_Q_L_FRAME:
|
||||
switch (command_type) {
|
||||
case READ_IN_BITS:
|
||||
return MELSEC_3E_Q_L_FRAME_RB;
|
||||
case READ_IN_WORD:
|
||||
return MELSEC_3E_Q_L_FRAME_RW;
|
||||
case WRITE_IN_BITS:
|
||||
return MELSEC_3E_Q_L_FRAME_WB;
|
||||
case WRITE_IN_WORD:
|
||||
return MELSEC_3E_Q_L_FRAME_WW;
|
||||
}
|
||||
case MELSEC_3E_IQ_R_FRAME:
|
||||
switch (command_type) {
|
||||
case READ_IN_BITS:
|
||||
return MELSEC_3E_IQ_R_FRAME_RB;
|
||||
case READ_IN_WORD:
|
||||
return MELSEC_3E_IQ_R_FRAME_RW;
|
||||
case WRITE_IN_BITS:
|
||||
return MELSEC_3E_IQ_R_FRAME_WB;
|
||||
case WRITE_IN_WORD:
|
||||
return MELSEC_3E_IQ_R_FRAME_WW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec_1E Cmd Genetare
|
||||
* @param p_command - command pointer
|
||||
* @param command_code - command code
|
||||
* @param p_read_item - p_read_item pointer
|
||||
* @return success : index error : 0
|
||||
*/
|
||||
static uint16_t Melsec1eGenerateCommand(uint8_t *p_command, uint32_t command_code, MelsecReadItem *p_read_item)
|
||||
{
|
||||
uint16_t index = 0;
|
||||
|
||||
p_command[index++] = command_code;
|
||||
p_command[index++] = PC_NUMBER;
|
||||
p_command[index++] = p_read_item->monitoring_timer / 250;
|
||||
p_command[index++] = (p_read_item->monitoring_timer / 250) >> 8;
|
||||
|
||||
uint16_t head_device_number = 0;
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
if (0 != p_read_item->head_device_number_string[i])
|
||||
head_device_number = TransformAsciiToHex(p_read_item->head_device_number_string[i]) + head_device_number * (((0x5820 == p_read_item->device_code) || (0x5920 == p_read_item->device_code)) ? 8 : 10);
|
||||
else
|
||||
break;
|
||||
}
|
||||
p_command[index++] = head_device_number;
|
||||
p_command[index++] = head_device_number >> (8 * 1);
|
||||
p_command[index++] = head_device_number >> (8 * 2);
|
||||
p_command[index++] = head_device_number >> (8 * 3);
|
||||
p_command[index++] = p_read_item->device_code;
|
||||
p_command[index++] = p_read_item->device_code >> 8;
|
||||
p_command[index++] = p_read_item->device_points_count;
|
||||
p_command[index++] = 0x00;
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec_3E_Q_L Cmd Genetare
|
||||
* @param p_command - command pointer
|
||||
* @param command_code - command code
|
||||
* @param p_read_item - p_read_item pointer
|
||||
* @return success : index error : 0
|
||||
*/
|
||||
static uint16_t Melsec3eqlGenerateCommand(uint8_t *p_command, uint32_t command_code, MelsecReadItem *p_read_item)
|
||||
{
|
||||
p_read_item->monitoring_timer /= 250;
|
||||
uint16_t index = 0;
|
||||
|
||||
p_command[index++] = SUB_HEADER >> 8;
|
||||
p_command[index++] = (uint8_t)SUB_HEADER;
|
||||
p_command[index++] = NETWORK_NUMBER;
|
||||
p_command[index++] = PC_NUMBER;
|
||||
p_command[index++] = (uint8_t)QEQUEST_DESTINSTION_MODULE_IO_NUMBER;
|
||||
p_command[index++] = (uint8_t)(QEQUEST_DESTINSTION_MODULE_IO_NUMBER >> 8);
|
||||
p_command[index++] = QEQUEST_DESTINSTION_MODULE_STATION_NUMBER;
|
||||
p_command[index++] = 0x0C;
|
||||
p_command[index++] = 0x00;
|
||||
p_command[index++] = p_read_item->monitoring_timer;
|
||||
p_command[index++] = p_read_item->monitoring_timer >> 8;
|
||||
p_command[index++] = command_code >> (8 * 2);
|
||||
p_command[index++] = command_code >> (8 * 3);
|
||||
p_command[index++] = command_code;
|
||||
p_command[index++] = command_code >> (8 * 1);
|
||||
|
||||
uint16_t head_device_number = 0;
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
if (0 != p_read_item->head_device_number_string[i])
|
||||
head_device_number = TransformAsciiToHex(p_read_item->head_device_number_string[i]) + head_device_number * (((0x9c == (uint8_t)p_read_item->device_code) || (0x9d == (uint8_t)p_read_item->device_code)) ? 16 : 10);
|
||||
else
|
||||
break;
|
||||
}
|
||||
p_command[index++] = head_device_number;
|
||||
p_command[index++] = head_device_number >> (8 * 1);
|
||||
p_command[index++] = head_device_number >> (8 * 2);
|
||||
p_command[index++] = p_read_item->device_code;
|
||||
p_command[index++] = p_read_item->device_points_count;
|
||||
p_command[index++] = p_read_item->device_points_count >> 8;
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec_3E_IQ_R Cmd Genetare
|
||||
* @param p_command - command pointer
|
||||
* @param command_code - command code
|
||||
* @param p_read_item - p_read_item pointer
|
||||
* @return success : index error : 0
|
||||
*/
|
||||
static uint16_t Melsec3eiqrGenerateCommand(uint8_t *p_command, uint32_t command_code, MelsecReadItem *p_read_item)
|
||||
{
|
||||
uint16_t index = Melsec3eqlGenerateCommand(p_command, command_code, p_read_item) - 6;
|
||||
|
||||
uint16_t head_device_number = 0;
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
if (0 != p_read_item->head_device_number_string[i])
|
||||
head_device_number = TransformAsciiToHex(p_read_item->head_device_number_string[i]) + head_device_number * (((0x9c == (uint8_t)p_read_item->device_code) || (0x9d == (uint8_t)p_read_item->device_code)) ? 16 : 10);
|
||||
else
|
||||
break;
|
||||
}
|
||||
p_command[index++] = head_device_number;
|
||||
p_command[index++] = head_device_number >> (8 * 1);
|
||||
p_command[index++] = head_device_number >> (8 * 2);
|
||||
p_command[index++] = head_device_number >> (8 * 3);
|
||||
p_command[index++] = p_read_item->device_code;
|
||||
p_command[index++] = p_read_item->device_code >> 8;
|
||||
p_command[index++] = p_read_item->device_points_count;
|
||||
p_command[index++] = p_read_item->device_points_count >> 8;
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec_1C Cmd Genetare
|
||||
* @param p_command - command pointer
|
||||
* @param command_code - command code
|
||||
* @param p_read_item - p_read_item pointer
|
||||
* @return success : index error : 0
|
||||
*/
|
||||
static uint16_t Melsec1cGenerateCommand(uint8_t *p_command, uint32_t command_code, MelsecReadItem *p_read_item)
|
||||
{
|
||||
p_read_item->monitoring_timer /= 10;
|
||||
uint16_t index = 0;
|
||||
uint8_t checksum = 0;
|
||||
|
||||
p_command[index++] = MELSEC_ENQ;
|
||||
p_command[index++] = TransformHexToAscii(STATION_NUMBER >> 4);
|
||||
p_command[index++] = TransformHexToAscii(STATION_NUMBER);
|
||||
p_command[index++] = TransformHexToAscii(PC_NUMBER >> 4);
|
||||
p_command[index++] = TransformHexToAscii(PC_NUMBER);
|
||||
p_command[index++] = command_code >> 8;
|
||||
p_command[index++] = command_code;
|
||||
p_command[index++] = TransformHexToAscii(p_read_item->monitoring_timer);
|
||||
p_command[index++] = p_read_item->device_code;
|
||||
uint8_t head_device_number_string_length = 0;
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
if (0 == p_read_item->head_device_number_string[i])
|
||||
break;
|
||||
else
|
||||
head_device_number_string_length++;
|
||||
}
|
||||
p_command[index++] = (head_device_number_string_length - 4 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 4];
|
||||
p_command[index++] = (head_device_number_string_length - 3 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 3];
|
||||
p_command[index++] = (head_device_number_string_length - 2 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 2];
|
||||
p_command[index++] = (head_device_number_string_length - 1 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 1];
|
||||
p_command[index++] = TransformHexToAscii(p_read_item->device_points_count >> 4);
|
||||
p_command[index++] = TransformHexToAscii(p_read_item->device_points_count);
|
||||
checksum = GetCheckSum(p_command + 1, index - 1);
|
||||
p_command[index++] = TransformHexToAscii(checksum >> 4);
|
||||
p_command[index++] = TransformHexToAscii(checksum);
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec_3C Cmd Genetare
|
||||
* @param p_command - command pointer
|
||||
* @param command_code - command code
|
||||
* @param p_read_item - p_read_item pointer
|
||||
* @return success : index error : 0
|
||||
*/
|
||||
static uint16_t Melsec3cGenerateCommand(uint8_t* p_command, uint32_t command_code, MelsecReadItem *p_read_item)
|
||||
{
|
||||
uint16_t index = 0;
|
||||
uint8_t checksum = 0;
|
||||
|
||||
p_command[index++] = MELSEC_ENQ;
|
||||
p_command[index++] = FRAME_NUMBER >> 8;
|
||||
p_command[index++] = (uint8_t)FRAME_NUMBER;
|
||||
p_command[index++] = TransformHexToAscii(STATION_NUMBER >> 4);
|
||||
p_command[index++] = TransformHexToAscii(STATION_NUMBER);
|
||||
p_command[index++] = TransformHexToAscii(NETWORK_NUMBER >> 4);
|
||||
p_command[index++] = TransformHexToAscii(NETWORK_NUMBER);
|
||||
p_command[index++] = TransformHexToAscii(PC_NUMBER >> 4);
|
||||
p_command[index++] = TransformHexToAscii(PC_NUMBER);
|
||||
p_command[index++] = TransformHexToAscii(SELF_STATION_NUMBER >> 4);
|
||||
p_command[index++] = TransformHexToAscii(SELF_STATION_NUMBER);
|
||||
p_command[index++] = TransformHexToAscii(command_code >> (7 * 4));
|
||||
p_command[index++] = TransformHexToAscii(command_code >> (6 * 4));
|
||||
p_command[index++] = TransformHexToAscii(command_code >> (5 * 4));
|
||||
p_command[index++] = TransformHexToAscii(command_code >> (4 * 4));
|
||||
p_command[index++] = TransformHexToAscii(command_code >> (3 * 4));
|
||||
p_command[index++] = TransformHexToAscii(command_code >> (2 * 4));
|
||||
p_command[index++] = TransformHexToAscii(command_code >> (1 * 4));
|
||||
p_command[index++] = TransformHexToAscii(command_code);
|
||||
p_command[index++] = p_read_item->device_code >> 8;
|
||||
p_command[index++] = p_read_item->device_code;
|
||||
uint8_t head_device_number_string_length = 0;
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
if (0 == p_read_item->head_device_number_string[i])
|
||||
break;
|
||||
else
|
||||
head_device_number_string_length++;
|
||||
}
|
||||
p_command[index++] = (head_device_number_string_length - 6 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 6];
|
||||
p_command[index++] = (head_device_number_string_length - 5 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 5];
|
||||
p_command[index++] = (head_device_number_string_length - 4 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 4];
|
||||
p_command[index++] = (head_device_number_string_length - 3 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 3];
|
||||
p_command[index++] = (head_device_number_string_length - 2 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 2];
|
||||
p_command[index++] = (head_device_number_string_length - 1 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 1];
|
||||
p_command[index++] = TransformHexToAscii(p_read_item->device_points_count >> (3 * 8));
|
||||
p_command[index++] = TransformHexToAscii(p_read_item->device_points_count >> (2 * 8));
|
||||
p_command[index++] = TransformHexToAscii(p_read_item->device_points_count >> (1 * 8));
|
||||
p_command[index++] = TransformHexToAscii(p_read_item->device_points_count);
|
||||
checksum = GetCheckSum(p_command + 1, index - 1);
|
||||
p_command[index++] = TransformHexToAscii(checksum >> 4);
|
||||
p_command[index++] = TransformHexToAscii(checksum);
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec Cmd Genetare
|
||||
* @param p_command - command pointer
|
||||
* @param command_code - command code
|
||||
* @param p_read_item - p_read_item pointer
|
||||
* @return success : index error : 0
|
||||
*/
|
||||
static uint16_t MelsecGenerateCommand(uint8_t *p_command, uint32_t command_code, MelsecReadItem *p_read_item)
|
||||
{
|
||||
uint16_t (*GenerateMelsecCommandFunction)(uint8_t *p_command, uint32_t command_code, MelsecReadItem *p_read_item);
|
||||
|
||||
switch (p_read_item->data_info.frame_type) {
|
||||
case MELSEC_1E_FRAME:
|
||||
GenerateMelsecCommandFunction = Melsec1eGenerateCommand;
|
||||
break;
|
||||
case MELSEC_3E_IQ_R_FRAME:
|
||||
GenerateMelsecCommandFunction = Melsec3eiqrGenerateCommand;
|
||||
break;
|
||||
case MELSEC_3E_Q_L_FRAME:
|
||||
GenerateMelsecCommandFunction = Melsec3eqlGenerateCommand;
|
||||
break;
|
||||
case MELSEC_1C_FRAME:
|
||||
GenerateMelsecCommandFunction = Melsec1cGenerateCommand;
|
||||
break;
|
||||
case MELSEC_3C_FRAME:
|
||||
GenerateMelsecCommandFunction = Melsec3cGenerateCommand;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return GenerateMelsecCommandFunction(p_command, command_code, p_read_item);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec Data Info Init
|
||||
* @param p_read_item - read item pointer
|
||||
* @param p_data - control-data pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int MelsecInitialDataInfo(MelsecReadItem *p_read_item, uint8_t *p_data)
|
||||
{
|
||||
uint8_t check_sum = 0;
|
||||
BasicPlcDataInfo *p_base_data_info = &(p_read_item->data_info.base_data_info);
|
||||
|
||||
int command_base_length = MelsecGetCommandBaseLength(p_read_item->data_info.frame_type);
|
||||
if (command_base_length < 0) {
|
||||
printf("%s Not supported device code!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (p_read_item->data_info.command_type) {
|
||||
case READ_IN_BITS:
|
||||
p_base_data_info->command_length = command_base_length;
|
||||
p_base_data_info->p_command = PrivMalloc(command_base_length);
|
||||
p_base_data_info->data_size = p_read_item->device_points_count;
|
||||
p_base_data_info->p_data = p_data;
|
||||
break;
|
||||
case READ_IN_WORD:
|
||||
p_base_data_info->command_length = command_base_length;
|
||||
p_base_data_info->p_command = PrivMalloc(command_base_length);
|
||||
p_base_data_info->data_size = p_read_item->device_points_count * 2;
|
||||
p_base_data_info->p_data = p_data;
|
||||
break;
|
||||
case WRITE_IN_BITS:
|
||||
p_base_data_info->command_length = command_base_length + p_read_item->device_points_count;
|
||||
p_base_data_info->p_command = PrivMalloc(command_base_length + p_read_item->device_points_count);
|
||||
command_base_length -= (p_read_item->data_info.frame_type >= MELSEC_1C_FRAME) ? 2 : 0;
|
||||
memcpy(p_base_data_info->p_command + command_base_length, p_data, p_read_item->device_points_count);
|
||||
break;
|
||||
case WRITE_IN_WORD:
|
||||
p_base_data_info->command_length = command_base_length + p_read_item->device_points_count * 2;
|
||||
p_base_data_info->p_command = PrivMalloc(command_base_length + p_read_item->device_points_count * 2);
|
||||
command_base_length -= (p_read_item->data_info.frame_type >= MELSEC_1C_FRAME) ? 2 : 0;
|
||||
memcpy(p_base_data_info->p_command + command_base_length, p_data, p_read_item->device_points_count * 2);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t command_code = MelsecGetCommandCode(p_read_item->data_info.frame_type, p_read_item->data_info.command_type);
|
||||
MelsecGenerateCommand(p_base_data_info->p_command, command_code, p_read_item);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec Data Transform from Receive Buffer To Control-Data
|
||||
* @param p_read_item - read item pointer
|
||||
* @param recv_buff - receive buff
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static int MelsecTransformRecvBuffToData(MelsecReadItem *p_read_item, uint8_t *recv_buff)
|
||||
{
|
||||
MelsecDataInfo *p_melsec_data_info = &(p_read_item->data_info);
|
||||
MelsecFrameType frame_type = p_melsec_data_info->frame_type;
|
||||
MelsecCommandType command_type = p_melsec_data_info->command_type;
|
||||
uint8_t *p_data = p_melsec_data_info->base_data_info.p_data;
|
||||
|
||||
uint16_t device_points_count = p_read_item->device_points_count;
|
||||
uint8_t is_ascii = ((MELSEC_1E_FRAME == frame_type) || (MELSEC_3E_Q_L_FRAME == frame_type) || (MELSEC_3E_IQ_R_FRAME == frame_type)) ? 0 : 1;
|
||||
uint16_t abnormal_code = 0;
|
||||
|
||||
switch (frame_type) {
|
||||
case MELSEC_3E_IQ_R_FRAME:
|
||||
case MELSEC_3E_Q_L_FRAME:
|
||||
if (recv_buff[9] != 0 || recv_buff[10] != 0)
|
||||
abnormal_code = recv_buff[10] * 256 + recv_buff[9];
|
||||
else
|
||||
recv_buff += 11;
|
||||
break;
|
||||
case MELSEC_1E_FRAME:
|
||||
if (recv_buff[1] != 0)
|
||||
abnormal_code = recv_buff[2];
|
||||
else
|
||||
recv_buff += 2;
|
||||
break;
|
||||
case MELSEC_1C_FRAME:
|
||||
if (MELSEC_NAK == recv_buff[0])
|
||||
abnormal_code = recv_buff[5] * 256 + recv_buff[6];
|
||||
else
|
||||
recv_buff += 5;
|
||||
break;
|
||||
case MELSEC_3C_FRAME:
|
||||
if (MELSEC_NAK == recv_buff[0])
|
||||
abnormal_code = ((uint16_t)TransformAsciiToHex(recv_buff[11])) << 12 + ((uint16_t)TransformAsciiToHex(recv_buff[12])) << 8 +
|
||||
((uint16_t)TransformAsciiToHex(recv_buff[13])) << 4 + ((uint16_t)TransformAsciiToHex(recv_buff[14]));
|
||||
else
|
||||
recv_buff += 11;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (abnormal_code != 0) {
|
||||
printf("Data abnormal, abnormal code is %0x!", abnormal_code);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ControlPrintfList("DATA", recv_buff, (uint16_t)(device_points_count * (READ_IN_BITS == command_type ? 0.5 : 2) * (frame_type >= MELSEC_1C_FRAME ? 2 : 1) + 0.6));
|
||||
printf("Receive data is ");
|
||||
for (uint16_t i = 0; i < device_points_count; i++) {
|
||||
if (READ_IN_BITS == command_type) {
|
||||
if (!is_ascii) {
|
||||
p_data[i] = (recv_buff[i / 2] & (i % 2 == 0 ? 0x10 : 0x01)) || 0;
|
||||
} else {
|
||||
p_data[i] = TransformAsciiToHex(recv_buff[i]);
|
||||
}
|
||||
printf("0x%x", p_data[i]);
|
||||
} else if (READ_IN_WORD == command_type) {
|
||||
if (!is_ascii) {
|
||||
uint16_t recv_buff_index = 2 * (device_points_count - 1 - i);
|
||||
p_data[2 * i] = recv_buff[recv_buff_index + 1];
|
||||
p_data[2 * i + 1] = recv_buff[recv_buff_index];
|
||||
} else {
|
||||
uint16_t recv_buff_index = 4 * (device_points_count - 1 - i);
|
||||
p_data[2 * i] = TransformAsciiToHex(recv_buff[recv_buff_index]) * 16 + TransformAsciiToHex(recv_buff[recv_buff_index + 1]);
|
||||
p_data[2 * i + 1] = TransformAsciiToHex(recv_buff[recv_buff_index + 2]) * 16 + TransformAsciiToHex(recv_buff[recv_buff_index + 3]);
|
||||
}
|
||||
printf("0x%x 0x%x", p_data[2 * i], p_data[2 * i + 1]);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONTROL_USING_SOCKET
|
||||
/**
|
||||
* @description: Melsec Get Data From Socket
|
||||
* @param socket - socket
|
||||
* @param p_read_item - read item pointer
|
||||
* @return success : 0 error : -1 -2
|
||||
*/
|
||||
static int MelsecGetDataBySocket(int32_t socket, MelsecReadItem *p_read_item)
|
||||
{
|
||||
uint8_t try_count = 0;
|
||||
int32_t write_error = 0;
|
||||
|
||||
MelsecDataInfo *p_melsec_data_info = &(p_read_item->data_info);
|
||||
BasicPlcDataInfo *p_base_data_info = &(p_melsec_data_info->base_data_info);
|
||||
|
||||
memset(recv_buff, 0, sizeof(recv_buff));
|
||||
|
||||
while (try_count < 10) {
|
||||
ControlPrintfList("SEND", p_base_data_info->p_command, p_base_data_info->command_length);
|
||||
try_count++;
|
||||
|
||||
write_error = socket_write(socket, p_base_data_info->p_command, p_base_data_info->command_length);
|
||||
if (write_error < 0) {
|
||||
printf("Write socket error, errno is %d!", errno);
|
||||
} else {
|
||||
PrivTaskDelay(20);
|
||||
|
||||
int32_t recv_length = socket_read(socket, recv_buff, sizeof(recv_buff));
|
||||
if (recv_length < 0) {
|
||||
printf("Read socket error, errno is %d!", errno);
|
||||
} else {
|
||||
ControlPrintfList("RECV", recv_buff, recv_length);
|
||||
return MelsecTransformRecvBuffToData(p_read_item, recv_buff);
|
||||
}
|
||||
}
|
||||
|
||||
if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
|
||||
printf("Send plc command failed, errno is %d!", errno);
|
||||
continue;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @description: Melsec Get Data From Serial
|
||||
* @param p_read_item - read item pointer
|
||||
* @return success : 0 error : -1 -2
|
||||
*/
|
||||
static int MelsecGetDataBySerial(MelsecReadItem *p_read_item)
|
||||
{
|
||||
uint32_t read_length = 0;
|
||||
memset(recv_buff, 0, sizeof(recv_buff));
|
||||
|
||||
MelsecDataInfo *p_melsec_data_info = &(p_read_item->data_info);
|
||||
BasicPlcDataInfo *p_base_data_info = &(p_melsec_data_info->base_data_info);
|
||||
|
||||
ControlPrintfList("SEND", p_base_data_info->p_command, p_base_data_info->command_length);
|
||||
SerialWrite(p_base_data_info->p_command, p_base_data_info->command_length);
|
||||
|
||||
read_length = SerialRead(recv_buff, sizeof(recv_buff));
|
||||
if (read_length) {
|
||||
ControlPrintfList("RECV", recv_buff, read_length);
|
||||
return MelsecTransformRecvBuffToData(p_read_item, recv_buff);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec Receive Plc Data Task
|
||||
* @param parameter - parameter pointer
|
||||
* @return
|
||||
*/
|
||||
void *ReceivePlcDataTask(void *parameter)
|
||||
{
|
||||
int i = 0;
|
||||
uint8_t try_count = 0;
|
||||
uint16_t data_length = 0;
|
||||
uint8_t *melsec_data;
|
||||
uint16_t read_item_size = sizeof(MelsecReadItem);
|
||||
|
||||
struct ControlProtocol *control_protocol = (struct ControlProtocol *)parameter;
|
||||
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
|
||||
MelsecReadItem *melsec_read_item = (MelsecReadItem *)control_protocol->recipe->read_item;
|
||||
melsec_data = control_protocol->recipe->protocol_data.data;
|
||||
data_length = control_protocol->recipe->protocol_data.data_length;
|
||||
|
||||
memset(&plc_socket, 0, sizeof(BasicSocketPlc));
|
||||
memcpy(plc_socket.ip, control_protocol->recipe->socket_config.plc_ip, 4);
|
||||
plc_socket.port = control_protocol->recipe->socket_config.port;
|
||||
plc_socket.socket = -1;
|
||||
|
||||
while (1) {
|
||||
for (i = 0; i < control_protocol->recipe->read_item_count; i ++) {
|
||||
|
||||
if ((PROTOCOL_MELSEC_1C == control_protocol->protocol_type) || (PROTOCOL_MELSEC_3C == control_protocol->protocol_type)) {
|
||||
MelsecGetDataBySerial((MelsecReadItem *)melsec_read_item + i);
|
||||
} else {
|
||||
#ifdef CONTROL_USING_SOCKET
|
||||
/*only connect socket when close socket or init*/
|
||||
while (ControlConnectSocket(&plc_socket) < 0) {
|
||||
PrivTaskDelay(1000);
|
||||
}
|
||||
|
||||
MelsecGetDataBySocket(plc_socket.socket, (MelsecReadItem *)melsec_read_item + i);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*read all variable item data, put them into circular_area*/
|
||||
if (i == control_protocol->recipe->read_item_count) {
|
||||
printf("%s get %d item %d length\n", __func__, i, data_length);
|
||||
CircularAreaAppWrite(circular_area, melsec_data, data_length, 0);
|
||||
}
|
||||
|
||||
/*read data every single 'read_period' ms*/
|
||||
PrivTaskDelay(control_protocol->recipe->read_period);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec Protocol Open
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @return success : 0 error
|
||||
*/
|
||||
int MelsecOpen(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
ControlProtocolOpenDef(control_protocol);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec Protocol Close
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @return success : 0 error
|
||||
*/
|
||||
int MelsecClose(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
if ((PROTOCOL_MELSEC_1C != control_protocol->protocol_type) && (PROTOCOL_MELSEC_3C != control_protocol->protocol_type)) {
|
||||
#ifdef CONTROL_USING_SOCKET
|
||||
ControlDisconnectSocket(&plc_socket);
|
||||
#endif
|
||||
}
|
||||
|
||||
ControlProtocolCloseDef();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec Protocol Read Data
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @param buf - read data buffer
|
||||
* @param len - read data length
|
||||
* @return success : data length error : 0
|
||||
*/
|
||||
int MelsecRead(struct ControlProtocol *control_protocol, void *buf, size_t len)
|
||||
{
|
||||
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
|
||||
return CircularAreaAppRead(circular_area, buf, len);
|
||||
}
|
||||
|
||||
static struct ControlDone melsec_protocol_done =
|
||||
{
|
||||
._open = MelsecOpen,
|
||||
._close = MelsecClose,
|
||||
._read = MelsecRead,
|
||||
._write = NULL,
|
||||
._ioctl = NULL,
|
||||
};
|
||||
|
||||
/**
|
||||
* @description: Melsec Protocol Cmd Generate
|
||||
* @param p_recipe - recipe pointer
|
||||
* @param protocol_format_info - protocol format info pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int MelsecProtocolFormatCmd(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info)
|
||||
{
|
||||
int ret = 0;
|
||||
static uint8_t last_item_size = 0;
|
||||
uint8_t *p_read_item_data = protocol_format_info->p_read_item_data + last_item_size;
|
||||
|
||||
MelsecReadItem *melsec_read_item = (MelsecReadItem *)(p_recipe->read_item) + protocol_format_info->read_item_index;
|
||||
|
||||
melsec_read_item->value_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_type")->valueint;
|
||||
strncpy(melsec_read_item->value_name, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_name")->valuestring, 20);
|
||||
melsec_read_item->data_info.command_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "command_type")->valueint;
|
||||
melsec_read_item->data_info.frame_type = p_recipe->protocol_type - PROTOCOL_MELSEC_1E;
|
||||
melsec_read_item->monitoring_timer = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "monitoring_timer")->valueint;
|
||||
melsec_read_item->device_code = MelsecGetDeviceCode(melsec_read_item->data_info.frame_type, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "device_code")->valuestring);
|
||||
strncpy(melsec_read_item->head_device_number_string, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "head_device_number_string")->valuestring, 6);
|
||||
melsec_read_item->device_points_count = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "device_points_count")->valueint;
|
||||
|
||||
ret = MelsecInitialDataInfo(melsec_read_item, p_read_item_data);
|
||||
|
||||
ControlPrintfList("CMD", melsec_read_item->data_info.base_data_info.p_command, melsec_read_item->data_info.base_data_info.command_length);
|
||||
protocol_format_info->last_item_size = GetValueTypeMemorySize(melsec_read_item->value_type);
|
||||
|
||||
last_item_size += protocol_format_info->last_item_size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Melsec Protocol Init
|
||||
* @param p_recipe - recipe pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int MelsecProtocolInit(struct ControlRecipe *p_recipe)
|
||||
{
|
||||
p_recipe->read_item = PrivMalloc(sizeof(MelsecReadItem) * p_recipe->read_item_count);
|
||||
if (NULL == p_recipe->read_item) {
|
||||
PrivFree(p_recipe->read_item);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(p_recipe->read_item, 0, sizeof(MelsecReadItem));
|
||||
|
||||
p_recipe->ControlProtocolFormatCmd = MelsecProtocolFormatCmd;
|
||||
|
||||
p_recipe->done = &melsec_protocol_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"device_id": 769,
|
||||
"device_name": "S01",
|
||||
"communication_type": 1,
|
||||
"serial_config": {
|
||||
"station": 1,
|
||||
"baud_rate": 19200,
|
||||
"data_bits": 7,
|
||||
"stop_bits": 1,
|
||||
"check_mode": 3
|
||||
},
|
||||
"protocol_type": 9,
|
||||
"read_period": 100,
|
||||
"read_item_list": [
|
||||
{
|
||||
"value_name": "启动",
|
||||
"value_type": 1,
|
||||
"device_code": "M",
|
||||
"head_device_number_string": "0",
|
||||
"device_points_count": 1,
|
||||
"command_type": 0,
|
||||
"monitoring_timer": 100
|
||||
},
|
||||
{
|
||||
"value_name": "停止",
|
||||
"value_type": 1,
|
||||
"device_code": "M",
|
||||
"head_device_number_string": "1",
|
||||
"device_points_count": 1,
|
||||
"command_type": 0,
|
||||
"monitoring_timer": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"device_id": 771,
|
||||
"device_name": "S03",
|
||||
"communication_type": 0,
|
||||
"socket_config": {
|
||||
"plc_ip": "192.168.250.20",
|
||||
"local_ip": "192.168.250.233",
|
||||
"gateway": "192.168.250.1",
|
||||
"netmask": "255.255.254.0",
|
||||
"port": 2000
|
||||
},
|
||||
"protocol_type": 6,
|
||||
"read_period": 100,
|
||||
"read_item_list": [
|
||||
{
|
||||
"value_name": "启动",
|
||||
"value_type": 1,
|
||||
"device_code": "M",
|
||||
"head_device_number_string": "0",
|
||||
"device_points_count": 1,
|
||||
"command_type": 0,
|
||||
"monitoring_timer": 100
|
||||
},
|
||||
{
|
||||
"value_name": "停止",
|
||||
"value_type": 1,
|
||||
"device_code": "M",
|
||||
"head_device_number_string": "1",
|
||||
"device_points_count": 1,
|
||||
"command_type": 0,
|
||||
"monitoring_timer": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"device_id": 770,
|
||||
"device_name": "S02",
|
||||
"communication_type": 1,
|
||||
"serial_config": {
|
||||
"station": 1,
|
||||
"baud_rate": 19200,
|
||||
"data_bits": 7,
|
||||
"stop_bits": 1,
|
||||
"check_mode": 3
|
||||
},
|
||||
"protocol_type": 10,
|
||||
"read_period": 100,
|
||||
"read_item_list": [
|
||||
{
|
||||
"value_name": "启动",
|
||||
"value_type": 1,
|
||||
"device_code": "M",
|
||||
"head_device_number_string": "0",
|
||||
"device_points_count": 1,
|
||||
"command_type": 0,
|
||||
"monitoring_timer": 100
|
||||
},
|
||||
{
|
||||
"value_name": "停止",
|
||||
"value_type": 1,
|
||||
"device_code": "M",
|
||||
"head_device_number_string": "1",
|
||||
"device_points_count": 1,
|
||||
"command_type": 0,
|
||||
"monitoring_timer": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"device_id": 773,
|
||||
"device_name": "S05",
|
||||
"communication_type": 0,
|
||||
"socket_config": {
|
||||
"plc_ip": "192.168.250.20",
|
||||
"local_ip": "192.168.250.233",
|
||||
"gateway": "192.168.250.1",
|
||||
"netmask": "255.255.254.0",
|
||||
"port": 2000
|
||||
},
|
||||
"protocol_type": 8,
|
||||
"read_period": 100,
|
||||
"read_item_list": [
|
||||
{
|
||||
"value_name": "启动",
|
||||
"value_type": 1,
|
||||
"device_code": "M",
|
||||
"head_device_number_string": "0",
|
||||
"device_points_count": 1,
|
||||
"command_type": 0,
|
||||
"monitoring_timer": 100
|
||||
},
|
||||
{
|
||||
"value_name": "停止",
|
||||
"value_type": 1,
|
||||
"device_code": "M",
|
||||
"head_device_number_string": "1",
|
||||
"device_points_count": 1,
|
||||
"command_type": 0,
|
||||
"monitoring_timer": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"device_id": 772,
|
||||
"device_name": "S04",
|
||||
"communication_type": 0,
|
||||
"socket_config": {
|
||||
"plc_ip": "192.168.250.20",
|
||||
"local_ip": "192.168.250.233",
|
||||
"gateway": "192.168.250.1",
|
||||
"netmask": "255.255.254.0",
|
||||
"port": 2000
|
||||
},
|
||||
"protocol_type": 7,
|
||||
"read_period": 100,
|
||||
"read_item_list": [
|
||||
{
|
||||
"value_name": "启动",
|
||||
"value_type": 1,
|
||||
"device_code": "M",
|
||||
"head_device_number_string": "0",
|
||||
"device_points_count": 1,
|
||||
"command_type": 0,
|
||||
"monitoring_timer": 100
|
||||
},
|
||||
{
|
||||
"value_name": "停止",
|
||||
"value_type": 1,
|
||||
"device_code": "M",
|
||||
"head_device_number_string": "1",
|
||||
"device_points_count": 1,
|
||||
"command_type": 0,
|
||||
"monitoring_timer": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,8 +1,4 @@
|
|||
SRC_FILES := control.c
|
||||
|
||||
ifeq ($(CONFIG_MOUNT_SDCARD),y)
|
||||
SRC_FILES += control_file.c
|
||||
endif
|
||||
SRC_FILES := control.c control_def.c control_io.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
{
|
||||
"siemens plc":
|
||||
{
|
||||
"device type": "PLC",
|
||||
"control type": "HSC",
|
||||
"info":
|
||||
{
|
||||
"plc ability" : 1,
|
||||
"plc device id": 1,
|
||||
"soft version" : 1,
|
||||
"hardware version": 1,
|
||||
"date": "2022-1-28",
|
||||
"vendor": "siemens",
|
||||
"model":"S300"
|
||||
},
|
||||
|
||||
"serial config":
|
||||
{
|
||||
"serial type":"485",
|
||||
"station id" : "station1",
|
||||
"serial port" : 1
|
||||
},
|
||||
|
||||
"network config":
|
||||
{
|
||||
"ip addr" : "192.168.250.5",
|
||||
"ip port" : 4840
|
||||
},
|
||||
|
||||
"interface":
|
||||
{
|
||||
"inhybridnet":"OPCUA",
|
||||
"transport":"TCP",
|
||||
"ip address": "192.168.250.5",
|
||||
"attribute" : "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,16 +12,278 @@
|
|||
|
||||
/**
|
||||
* @file control.c
|
||||
* @brief control framework code
|
||||
* @brief code for control framework app
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-09-27
|
||||
*/
|
||||
|
||||
#include <control.h>
|
||||
#include <control_def.h>
|
||||
|
||||
void control_init(void)
|
||||
ControlProtocolType control_protocol;
|
||||
|
||||
/**
|
||||
* @description: Control Framework Find certain Protocol
|
||||
* @param void
|
||||
* @return Control Protocol pointer
|
||||
*/
|
||||
ControlProtocolType ControlProtocolFind(void)
|
||||
{
|
||||
//to do
|
||||
return control_protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Init
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static int ControlProtocolInit(ControlProtocolType control_protocol)
|
||||
{
|
||||
CONTROL_PARAM_CHECK(control_protocol);
|
||||
int ret = -1;
|
||||
|
||||
control_protocol->protocol_status = CONTROL_INIT;
|
||||
|
||||
ret = PrivMutexCreate(&control_protocol->lock, 0);
|
||||
if(ret < 0) {
|
||||
printf("ControlProtocolInit mutex create failed.\n");
|
||||
goto _out;
|
||||
}
|
||||
|
||||
ret = PrivSemaphoreCreate(&control_protocol->sem, 0, 0);
|
||||
if (ret < 0) {
|
||||
printf("ControlProtocolInit create sem error\n");
|
||||
goto _out;
|
||||
}
|
||||
|
||||
_out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Analyze Recipe
|
||||
* @param control_protocol - Control Protocol pointer
|
||||
* @param recipe_name - recipe name
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static int ControlAnalyzeRecipe(ControlProtocolType control_protocol, const char *recipe_name)
|
||||
{
|
||||
int recipe_file_fd = -1;
|
||||
struct stat recipe_file_status;
|
||||
uint16_t recipe_file_length = 0;
|
||||
char *recipe_file_buf;
|
||||
|
||||
/*wait for SD-card mount done*/
|
||||
PrivTaskDelay(5000);
|
||||
|
||||
//Step1 : read recipe file data from SD card or other store device
|
||||
recipe_file_fd = PrivOpen(recipe_name, O_RDONLY);
|
||||
if (recipe_file_fd < 0) {
|
||||
printf("Open recipe file %s failed\n", recipe_name);
|
||||
PrivClose(recipe_file_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != fstat(recipe_file_fd, &recipe_file_status)) {
|
||||
printf("Get recipe file information failed!\n");
|
||||
PrivClose(recipe_file_fd);
|
||||
return -1;
|
||||
} else {
|
||||
recipe_file_length = recipe_file_status.st_size;
|
||||
}
|
||||
|
||||
recipe_file_buf = PrivMalloc(recipe_file_length);
|
||||
if (NULL == recipe_file_buf) {
|
||||
printf("Get recipe file memory failed!\n");
|
||||
PrivFree(recipe_file_buf);
|
||||
PrivClose(recipe_file_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PrivRead(recipe_file_fd, recipe_file_buf, recipe_file_length) < 0) {
|
||||
printf("Read recipe file failed!\n");
|
||||
PrivFree(recipe_file_buf);
|
||||
PrivClose(recipe_file_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PrivClose(recipe_file_fd);
|
||||
|
||||
//Step2 : CJSON analyze
|
||||
#ifdef LIB_USING_CJSON
|
||||
cJSON *recipe_file_json = cJSON_Parse(recipe_file_buf);
|
||||
if (NULL == recipe_file_json) {
|
||||
printf("Parse recipe_file_buf failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
control_protocol->recipe = (struct ControlRecipe *)PrivMalloc(sizeof(struct ControlRecipe));
|
||||
memset(control_protocol->recipe, 0, sizeof(struct ControlRecipe));
|
||||
|
||||
/*Get basic information from recipe file*/
|
||||
if (RecipeBasicInformation(control_protocol->recipe, recipe_file_json) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
control_protocol->protocol_type = control_protocol->recipe->protocol_type;
|
||||
|
||||
/*Get the variable need to read from recipe file*/
|
||||
RecipeReadVariableItem(control_protocol->recipe, recipe_file_json);
|
||||
|
||||
control_protocol->done = control_protocol->recipe->done;
|
||||
|
||||
cJSON_Delete(recipe_file_json);
|
||||
|
||||
PrivFree(recipe_file_buf);
|
||||
printf("Read and parse recipe file done!\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Open
|
||||
* @param control_protocol - Control Protocol pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ControlProtocolOpen(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
CONTROL_PARAM_CHECK(control_protocol);
|
||||
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||
int ret = -1;
|
||||
|
||||
if (control_protocol->done->_open) {
|
||||
ret = control_protocol->done->_open(control_protocol);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Close
|
||||
* @param control_protocol - Control Protocol pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ControlProtocolClose(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
CONTROL_PARAM_CHECK(control_protocol);
|
||||
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||
int ret = -1;
|
||||
|
||||
if (control_protocol->done->_close) {
|
||||
ret = control_protocol->done->_close(control_protocol);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Read Data
|
||||
* @param control_protocol - Control Protocol pointer
|
||||
* @param buf - read buffer
|
||||
* @param len - read data length
|
||||
* @return success : data length error : -1
|
||||
*/
|
||||
int ControlProtocolRead(struct ControlProtocol *control_protocol, void *buf, size_t len)
|
||||
{
|
||||
CONTROL_PARAM_CHECK(control_protocol);
|
||||
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||
int ret = -1;
|
||||
|
||||
if (control_protocol->done->_read) {
|
||||
ret = control_protocol->done->_read(control_protocol, buf, len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Write Cmd
|
||||
* @param control_protocol - Control Protocol pointer
|
||||
* @param buf - write buffer
|
||||
* @param len - write data length
|
||||
* @return success : data length error : -1
|
||||
*/
|
||||
int ControlProtocolWrite(struct ControlProtocol *control_protocol, const void *buf, size_t len)
|
||||
{
|
||||
CONTROL_PARAM_CHECK(control_protocol);
|
||||
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||
int ret = -1;
|
||||
|
||||
if (control_protocol->done->_write) {
|
||||
ret = control_protocol->done->_write(control_protocol, buf, len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Ioctl
|
||||
* @param control_protocol - Control Protocol pointer
|
||||
* @param cmd - ioctl cmd
|
||||
* @param args - args
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ControlProtocolIoctl(struct ControlProtocol *control_protocol, int cmd, void *args)
|
||||
{
|
||||
CONTROL_PARAM_CHECK(control_protocol);
|
||||
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||
int ret = -1;
|
||||
|
||||
if (control_protocol->done->_ioctl) {
|
||||
ret = control_protocol->done->_ioctl(control_protocol, cmd, args);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Init
|
||||
* @param void
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ControlFrameworkInit(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
control_protocol = (struct ControlProtocol *)PrivMalloc(sizeof(struct ControlProtocol));
|
||||
if (NULL == control_protocol) {
|
||||
printf("%s malloc control protocol failed!\n", __func__);
|
||||
PrivFree(control_protocol);
|
||||
ret = -1;
|
||||
goto _out;
|
||||
}
|
||||
|
||||
//Control Protocol Struct Init
|
||||
ret = ControlProtocolInit(control_protocol);
|
||||
if (ret < 0) {
|
||||
printf("%s failed!\n", __func__);
|
||||
PrivFree(control_protocol);
|
||||
goto _out;
|
||||
}
|
||||
|
||||
printf("%s malloc CONTROL_RECIPE_FILE %s\n", __func__, CONTROL_RECIPE_FILE);
|
||||
|
||||
//Read Recipe File, Get Control Protocol Configure Param
|
||||
ret = ControlAnalyzeRecipe(control_protocol, CONTROL_RECIPE_FILE);
|
||||
if (ret < 0) {
|
||||
printf("%s failed!\n", __func__);
|
||||
PrivFree(control_protocol);
|
||||
goto _out;
|
||||
}
|
||||
|
||||
control_protocol->protocol_status = CONTROL_REGISTERED;
|
||||
|
||||
ret = ControlPeripheralInit(control_protocol->recipe);
|
||||
if (ret < 0) {
|
||||
printf("%s failed!\n", __func__);
|
||||
PrivFree(control_protocol);
|
||||
goto _out;
|
||||
}
|
||||
|
||||
printf("%s ControlPeripheralInit done\n", __func__);
|
||||
|
||||
_out:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,95 @@
|
|||
|
||||
/**
|
||||
* @file control.h
|
||||
* @brief control framework code
|
||||
* @brief DEFINE code for control framework app
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-09-27
|
||||
*/
|
||||
|
||||
#include <control_file.h>
|
||||
#include <cJSON.h>
|
||||
#ifndef CONTROL_H
|
||||
#define CONTROL_H
|
||||
|
||||
#include <transform.h>
|
||||
#include <list.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct ControlProtocol;
|
||||
typedef struct ControlProtocol *ControlProtocolType;
|
||||
|
||||
struct ControlDone
|
||||
{
|
||||
int (*_open)(struct ControlProtocol *control_protocol);
|
||||
int (*_close)(struct ControlProtocol *control_protocol);
|
||||
int (*_read)(struct ControlProtocol *control_protocol, void *buf, size_t len);
|
||||
int (*_write)(struct ControlProtocol *control_protocol, const void *buf, size_t len);
|
||||
int (*_ioctl)(struct ControlProtocol *control_protocol, int cmd, void *args);
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PROTOCOL_S7 = 1,
|
||||
PROTOCOL_MODBUS_TCP,
|
||||
PROTOCOL_MODBUS_UART,
|
||||
PROTOCOL_OPC_UA,
|
||||
PROTOCOL_FINS,
|
||||
PROTOCOL_MELSEC_1E,
|
||||
PROTOCOL_MELSEC_3E_Q_L,
|
||||
PROTOCOL_MELSEC_3E_IQ_R,
|
||||
PROTOCOL_MELSEC_1C,
|
||||
PROTOCOL_MELSEC_3C,
|
||||
PROTOCOL_END
|
||||
}ProtocolType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CONTROL_INIT,
|
||||
CONTROL_REGISTERED,
|
||||
CONTROL_UNREGISTERED,
|
||||
}ProtocolStatus;
|
||||
|
||||
struct ControlProtocol
|
||||
{
|
||||
char *name;
|
||||
ProtocolType protocol_type;
|
||||
ProtocolStatus protocol_status;
|
||||
|
||||
struct ControlRecipe *recipe;
|
||||
struct ControlDone *done;
|
||||
|
||||
void *args;
|
||||
|
||||
sem_t sem;
|
||||
pthread_mutex_t lock;
|
||||
};
|
||||
|
||||
/*Control Framework Protocol Init*/
|
||||
int ControlFrameworkInit(void);
|
||||
|
||||
/*Control Framework Find certain Protocol*/
|
||||
ControlProtocolType ControlProtocolFind(void);
|
||||
|
||||
/*Control Framework Protocol Open*/
|
||||
int ControlProtocolOpen(struct ControlProtocol *control_protocol);
|
||||
|
||||
/*Control Framework Protocol Close*/
|
||||
int ControlProtocolClose(struct ControlProtocol *control_protocol);
|
||||
|
||||
/*Control Framework Protocol Read*/
|
||||
int ControlProtocolRead(struct ControlProtocol *control_protocol, void *buf, size_t len);
|
||||
|
||||
/*Control Framework Protocol Write*/
|
||||
int ControlProtocolWrite(struct ControlProtocol *control_protocol, const void *buf, size_t len);
|
||||
|
||||
/*Control Framework Protocol Ioctl*/
|
||||
int ControlProtocolIoctl(struct ControlProtocol *control_protocol, int cmd, void *args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,474 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file control_def.c
|
||||
* @brief code for control framework
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-10-9
|
||||
*/
|
||||
|
||||
#include <control_def.h>
|
||||
#include <control_io.h>
|
||||
|
||||
/*using cirtular area to receive data*/
|
||||
#define PLC_DATA_LENGTH 1024
|
||||
struct CircularAreaApp *g_circular_area;
|
||||
static pthread_t recv_plc_data_task;
|
||||
|
||||
/*extern function*/
|
||||
extern void *ReceivePlcDataTask(void *parameter);
|
||||
|
||||
#ifdef CONTROL_PROTOCOL_FINS
|
||||
extern int FinsProtocolInit(struct ControlRecipe *p_recipe);
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_PROTOCOL_MELSEC
|
||||
extern int MelsecProtocolInit(struct ControlRecipe *p_recipe);
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_PROTOCOL_MODBUS_TCP
|
||||
extern int ModbusTcpProtocolInit(struct ControlRecipe *p_recipe);
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_PROTOCOL_MODBUS_UART
|
||||
extern int ModbusUartProtocolInit(struct ControlRecipe *p_recipe);
|
||||
#endif
|
||||
|
||||
/*
|
||||
CONTROL FRAMEWORK READ DATA FORMAT:
|
||||
| HEAD |device_id|read data length|read item count| data |
|
||||
|2 Bytes| 2 Bytes | 2 Bytes | 2 Bytes |read data length Bytes|
|
||||
*/
|
||||
#define CONTROL_DATA_HEAD_LENGTH 8
|
||||
#define CONTROL_DATA_HEAD_1 0xAA
|
||||
#define CONTROL_DATA_HEAD_2 0xBB
|
||||
|
||||
typedef int (*ControlProtocolInitFunc)(struct ControlRecipe *p_recipe);
|
||||
|
||||
struct ControlProtocolInitParam
|
||||
{
|
||||
int protocol_type;
|
||||
const ControlProtocolInitFunc fn;
|
||||
};
|
||||
|
||||
static struct ControlProtocolInitParam protocol_init[] =
|
||||
{
|
||||
#ifdef CONTROL_PROTOCOL_FINS
|
||||
{ PROTOCOL_FINS, FinsProtocolInit },
|
||||
#endif
|
||||
#ifdef CONTROL_PROTOCOL_MELSEC
|
||||
{ PROTOCOL_MELSEC_1E, MelsecProtocolInit },
|
||||
{ PROTOCOL_MELSEC_3E_Q_L, MelsecProtocolInit },
|
||||
{ PROTOCOL_MELSEC_3E_IQ_R, MelsecProtocolInit },
|
||||
{ PROTOCOL_MELSEC_1C, MelsecProtocolInit },
|
||||
{ PROTOCOL_MELSEC_3C, MelsecProtocolInit },
|
||||
#endif
|
||||
#ifdef CONTROL_PROTOCOL_MODBUS_TCP
|
||||
{ PROTOCOL_MODBUS_TCP, ModbusTcpProtocolInit },
|
||||
#endif
|
||||
#ifdef CONTROL_PROTOCOL_MODBUS_UART
|
||||
{ PROTOCOL_MODBUS_UART, ModbusUartProtocolInit },
|
||||
#endif
|
||||
|
||||
{ PROTOCOL_END, NULL },
|
||||
};
|
||||
|
||||
/**
|
||||
* @description: Control Framework Sub_Protocol Desc Init
|
||||
* @param p_recipe - Control recipe pointer
|
||||
* @param sub_protocol_desc - sub_protocol desc
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static int ControlProtocolInitDesc(struct ControlRecipe *p_recipe, struct ControlProtocolInitParam sub_protocol_desc[])
|
||||
{
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
for( i = 0; sub_protocol_desc[i].fn != NULL; i++ ) {
|
||||
if (p_recipe->protocol_type == sub_protocol_desc[i].protocol_type) {
|
||||
ret = sub_protocol_desc[i].fn(p_recipe);
|
||||
printf("%s initialize %d %s\n", __func__, sub_protocol_desc[i].protocol_type, ret == 0 ? "success" : "failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Data Header Format
|
||||
* @param p_recipe - Control recipe pointer
|
||||
* @return
|
||||
*/
|
||||
static void FormatDataHeader(struct ControlRecipe *p_recipe)
|
||||
{
|
||||
uint16_t plc_read_data_length = CONTROL_DATA_HEAD_LENGTH + p_recipe->total_data_length;//Head length is CONTROL_DATA_HEAD_LENGTH
|
||||
uint8_t *data = p_recipe->protocol_data.data;
|
||||
|
||||
data[0] = CONTROL_DATA_HEAD_1;
|
||||
data[1] = CONTROL_DATA_HEAD_2;
|
||||
data[2] = (uint8_t)(p_recipe->device_id >> 8);
|
||||
data[3] = (uint8_t)p_recipe->device_id;
|
||||
data[4] = (uint8_t)(plc_read_data_length >> 8);
|
||||
data[5] = (uint8_t)plc_read_data_length;
|
||||
data[6] = (uint8_t)(p_recipe->read_item_count >> 8);
|
||||
data[7] = (uint8_t)p_recipe->read_item_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Get Recipe Total Data Length
|
||||
* @param read_item_list_json - read_item_list_json pointer
|
||||
* @return success : total_data_length error : 0
|
||||
*/
|
||||
static uint16_t GetRecipeTotalDataLength(cJSON* read_item_list_json)
|
||||
{
|
||||
uint16_t read_item_count = cJSON_GetArraySize(read_item_list_json);
|
||||
uint16_t total_data_length = 0;
|
||||
for (uint16_t read_item_index = 0; read_item_index < read_item_count; read_item_index++) {
|
||||
cJSON* read_item_json = cJSON_GetArrayItem(read_item_list_json, read_item_index);
|
||||
UniformValueType value_type = cJSON_GetObjectItem(read_item_json, "value_type")->valueint;
|
||||
total_data_length += GetValueTypeMemorySize(value_type);
|
||||
}
|
||||
return total_data_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Basic Serial Configure
|
||||
* @param p_recipe - Control recipe pointer
|
||||
* @param p_recipe_file_json - p_recipe_file_json pointer
|
||||
* @return
|
||||
*/
|
||||
static void ControlBasicSerialConfig(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json)
|
||||
{
|
||||
cJSON *p_serial_config_json = cJSON_GetObjectItem(p_recipe_file_json, "serial_config");
|
||||
p_recipe->serial_config.station = cJSON_GetObjectItem(p_serial_config_json, "station")->valueint;
|
||||
p_recipe->serial_config.baud_rate = cJSON_GetObjectItem(p_serial_config_json, "baud_rate")->valueint;
|
||||
p_recipe->serial_config.data_bits = cJSON_GetObjectItem(p_serial_config_json, "data_bits")->valueint;
|
||||
p_recipe->serial_config.stop_bits = cJSON_GetObjectItem(p_serial_config_json, "stop_bits")->valueint;
|
||||
p_recipe->serial_config.check_mode = cJSON_GetObjectItem(p_serial_config_json, "check_mode")->valueint;
|
||||
printf("Serial_config:station: %d baud_rate: %d, data_bits: %d, stop_bits: %d, check_mode is %d\n",
|
||||
p_recipe->serial_config.station, p_recipe->serial_config.baud_rate, p_recipe->serial_config.data_bits, p_recipe->serial_config.stop_bits, p_recipe->serial_config.check_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Basic Socket Configure
|
||||
* @param p_recipe - Control recipe pointer
|
||||
* @param p_recipe_file_json - p_recipe_file_json pointer
|
||||
* @return
|
||||
*/
|
||||
static void ControlBasicSocketConfig(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json)
|
||||
{
|
||||
cJSON *p_socket_address_json = cJSON_GetObjectItem(p_recipe_file_json, "socket_config");
|
||||
char *plc_ip_string = cJSON_GetObjectItem(p_socket_address_json, "plc_ip")->valuestring;
|
||||
sscanf(plc_ip_string, "%d.%d.%d.%d",
|
||||
p_recipe->socket_config.plc_ip,
|
||||
p_recipe->socket_config.plc_ip + 1,
|
||||
p_recipe->socket_config.plc_ip + 2,
|
||||
p_recipe->socket_config.plc_ip + 3);
|
||||
|
||||
char *local_ip_string = cJSON_GetObjectItem(p_socket_address_json, "local_ip")->valuestring;
|
||||
sscanf(local_ip_string, "%d.%d.%d.%d",
|
||||
p_recipe->socket_config.local_ip,
|
||||
p_recipe->socket_config.local_ip + 1,
|
||||
p_recipe->socket_config.local_ip + 2,
|
||||
p_recipe->socket_config.local_ip + 3);
|
||||
|
||||
char *gateway_ip_string = cJSON_GetObjectItem(p_socket_address_json, "gateway")->valuestring;
|
||||
sscanf(gateway_ip_string, "%d.%d.%d.%d",
|
||||
p_recipe->socket_config.gateway,
|
||||
p_recipe->socket_config.gateway + 1,
|
||||
p_recipe->socket_config.gateway + 2,
|
||||
p_recipe->socket_config.gateway + 3);
|
||||
|
||||
char *netmask_string = cJSON_GetObjectItem(p_socket_address_json, "netmask")->valuestring;
|
||||
sscanf(netmask_string, "%d.%d.%d.%d",
|
||||
p_recipe->socket_config.netmask,
|
||||
p_recipe->socket_config.netmask + 1,
|
||||
p_recipe->socket_config.netmask + 2,
|
||||
p_recipe->socket_config.netmask + 3);
|
||||
|
||||
p_recipe->socket_config.port = cJSON_GetObjectItem(p_socket_address_json, "port")->valueint;
|
||||
printf("Socket_config: local ip is %s, plc ip is %s, gateway is %s, port is %d.\n",
|
||||
local_ip_string, plc_ip_string, gateway_ip_string, p_recipe->socket_config.port);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Printf List Function
|
||||
* @param name - printf function name
|
||||
* @param number_list - number_list pointer
|
||||
* @param length - number_list length
|
||||
* @return
|
||||
*/
|
||||
void ControlPrintfList(char name[5], uint8_t *number_list, uint16_t length)
|
||||
{
|
||||
printf("\n******************%s****************\n", name);
|
||||
for (int32_t i = 0;i < length;i ++) {
|
||||
printf("0x%x ", number_list[i]);
|
||||
}
|
||||
printf("\n**************************************\n");
|
||||
}
|
||||
|
||||
#ifdef CONTROL_USING_SOCKET
|
||||
/**
|
||||
* @description: Control Framework Connect Socket
|
||||
* @param p_plc - basic socket plc pointer
|
||||
* @return success : 0 error : -1 -2 -3 -4 -5
|
||||
*/
|
||||
int ControlConnectSocket(BasicSocketPlc *p_plc)
|
||||
{
|
||||
if (p_plc->socket >= 0)
|
||||
return 0;
|
||||
|
||||
struct sockaddr_in plc_addr_in;
|
||||
plc_addr_in.sin_family = AF_INET;
|
||||
plc_addr_in.sin_port = htons(p_plc->port);
|
||||
|
||||
char ip_string[20] = {0};
|
||||
sprintf(ip_string, "%u.%u.%u.%u", p_plc->ip[0], p_plc->ip[1], p_plc->ip[2], p_plc->ip[3]);
|
||||
plc_addr_in.sin_addr.s_addr = inet_addr(ip_string);
|
||||
memset(&(plc_addr_in.sin_zero), 0, sizeof(plc_addr_in.sin_zero));
|
||||
|
||||
int plc_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
int flag = 1;
|
||||
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
if (setsockopt(plc_socket, IPPROTO_TCP, TCP_NODELAY, (void*)&flag, sizeof(flag)) < 0) {
|
||||
printf("Error setting TCP_NODELAY function!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(plc_socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, (socklen_t)sizeof(struct timeval)) < 0) {
|
||||
printf("Error setting SO_SNDTIMEO function!\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (setsockopt(plc_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, (socklen_t)sizeof(struct timeval)) < 0) {
|
||||
printf("Error setting SO_RCVTIMEO function!\n");
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (plc_socket < 0) {
|
||||
printf("Get socket error!\n");
|
||||
return -4;
|
||||
}
|
||||
|
||||
printf("%s %d ip %u.%u.%u.%u port %d\n", __func__, __LINE__,
|
||||
p_plc->ip[0], p_plc->ip[1], p_plc->ip[2], p_plc->ip[3],
|
||||
p_plc->port);
|
||||
|
||||
if (connect(plc_socket, (struct sockaddr*)&plc_addr_in, sizeof(struct sockaddr)) == -1) {
|
||||
printf("Connect plc socket failed!errno %d\n", errno);
|
||||
closesocket(plc_socket);
|
||||
return -5;
|
||||
} else {
|
||||
p_plc->socket = plc_socket;
|
||||
printf("Connect plc socket success!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Disconnect Socket
|
||||
* @param p_plc - basic socket plc pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ControlDisconnectSocket(BasicSocketPlc *p_plc)
|
||||
{
|
||||
if (p_plc->socket < 0)
|
||||
return -1;
|
||||
|
||||
int error = closesocket(p_plc->socket);
|
||||
if (0 == error)
|
||||
p_plc->socket = -1;
|
||||
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Open for Sub_Protocol, Init Circular Area and Receive Data Task
|
||||
* @param control_protocol - Control protocol pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ControlProtocolOpenDef(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
g_circular_area = CircularAreaAppInit(PLC_DATA_LENGTH);
|
||||
if (NULL == g_circular_area) {
|
||||
printf("%s CircularAreaInit error\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
control_protocol->args = (void *)g_circular_area;
|
||||
|
||||
pthread_attr_t attr;
|
||||
attr.schedparam.sched_priority = 19;
|
||||
attr.stacksize = 2048;
|
||||
|
||||
PrivTaskCreate(&recv_plc_data_task, &attr, &ReceivePlcDataTask, control_protocol);
|
||||
PrivTaskStartup(&recv_plc_data_task);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Open for Sub_Protocol, Release Circular Area and Delete Receive Data Task
|
||||
* @param void
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ControlProtocolCloseDef(void)
|
||||
{
|
||||
CircularAreaAppRelease(g_circular_area);
|
||||
|
||||
PrivTaskDelete(recv_plc_data_task, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Get Value Memory Size From Recipe File
|
||||
* @param uniform_value_type - uniform value type
|
||||
* @return success : size error : 0
|
||||
*/
|
||||
uint8_t GetValueTypeMemorySize(UniformValueType uniform_value_type)
|
||||
{
|
||||
switch (uniform_value_type)
|
||||
{
|
||||
case UNIFORM_BOOL:
|
||||
case UNIFORM_INT8:
|
||||
case UNIFORM_UINT8:
|
||||
return 1;
|
||||
break;
|
||||
case UNIFORM_INT16:
|
||||
case UNIFORM_UINT16:
|
||||
return 2;
|
||||
break;
|
||||
case UNIFORM_INT32:
|
||||
case UNIFORM_UINT32:
|
||||
case UNIFORM_FLOAT:
|
||||
return 4;
|
||||
break;
|
||||
case UNIFORM_DOUBLE:
|
||||
return 8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Peripheral Device Init
|
||||
* @param p_recipe - Control recipe pointer
|
||||
* @return success : 0 error :
|
||||
*/
|
||||
int ControlPeripheralInit(struct ControlRecipe *p_recipe)
|
||||
{
|
||||
switch (p_recipe->communication_type)
|
||||
{
|
||||
case 0://Socket Init
|
||||
SocketInit(p_recipe->socket_config.local_ip, p_recipe->socket_config.netmask, p_recipe->socket_config.gateway);
|
||||
break;
|
||||
case 1://Serial Init
|
||||
SerialInit(p_recipe->serial_config.baud_rate, p_recipe->serial_config.data_bits, p_recipe->serial_config.stop_bits, p_recipe->serial_config.check_mode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Get Recipe Basic Information
|
||||
* @param p_recipe - Control recipe pointer
|
||||
* @param p_recipe_file_json - recipe_file_json pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int RecipeBasicInformation(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json)
|
||||
{
|
||||
p_recipe->protocol_type = (ProtocolType)(cJSON_GetObjectItem(p_recipe_file_json, "protocol_type")->valueint);
|
||||
|
||||
p_recipe->device_id = cJSON_GetObjectItem(p_recipe_file_json, "device_id")->valueint;
|
||||
strncpy(p_recipe->device_name, cJSON_GetObjectItem(p_recipe_file_json, "device_name")->valuestring, 20);
|
||||
p_recipe->read_period = cJSON_GetObjectItem(p_recipe_file_json, "read_period")->valueint;
|
||||
p_recipe->communication_type = cJSON_GetObjectItem(p_recipe_file_json, "communication_type")->valueint;
|
||||
|
||||
printf("\n**************** RECIPE BASIC INFORMATION ******************\n");
|
||||
printf("\nprotocol_type: %d, communication_type: %d, device_id: %d, device_name: %s, read_period is %d\n",
|
||||
p_recipe->protocol_type, p_recipe->communication_type, p_recipe->device_id, p_recipe->device_name, p_recipe->read_period);
|
||||
|
||||
switch (p_recipe->communication_type)
|
||||
{
|
||||
case 0://Get Socket Config
|
||||
ControlBasicSocketConfig(p_recipe, p_recipe_file_json);
|
||||
break;
|
||||
case 1://Get Serial Config
|
||||
ControlBasicSerialConfig(p_recipe, p_recipe_file_json);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\n************************************************************\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Read Variable Item Function
|
||||
* @param p_recipe - Control recipe pointer
|
||||
* @param p_recipe_file_json - recipe_file_json pointer
|
||||
* @return
|
||||
*/
|
||||
void RecipeReadVariableItem(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json)
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
||||
ProtocolFormatInfo protocol_format_info;
|
||||
memset(&protocol_format_info, 0, sizeof(ProtocolFormatInfo));
|
||||
|
||||
cJSON *read_item_list_json = cJSON_GetObjectItem(p_recipe_file_json, "read_item_list");
|
||||
if (cJSON_IsArray(read_item_list_json)) {
|
||||
/*Get Recipe Variable Item Count and total length*/
|
||||
p_recipe->read_item_count = cJSON_GetArraySize(read_item_list_json);
|
||||
p_recipe->total_data_length = GetRecipeTotalDataLength(read_item_list_json);
|
||||
|
||||
/*Malloc Read Data Pointer, Reference "CONTROL FRAMEWORK READ DATA FORMAT"*/
|
||||
p_recipe->protocol_data.data = PrivMalloc(CONTROL_DATA_HEAD_LENGTH + p_recipe->total_data_length);
|
||||
p_recipe->protocol_data.data_length = CONTROL_DATA_HEAD_LENGTH + p_recipe->total_data_length;
|
||||
memset(p_recipe->protocol_data.data, 0, p_recipe->protocol_data.data_length);
|
||||
|
||||
protocol_format_info.p_read_item_data = p_recipe->protocol_data.data + CONTROL_DATA_HEAD_LENGTH;
|
||||
|
||||
/*Init The Control Protocol*/
|
||||
ControlProtocolInitDesc(p_recipe, protocol_init);
|
||||
|
||||
/*Format Data Header, Reference "CONTROL FRAMEWORK READ DATA FORMAT"*/
|
||||
FormatDataHeader(p_recipe);
|
||||
|
||||
uint16_t read_item_count = p_recipe->read_item_count;
|
||||
|
||||
for (i = 0; i < read_item_count; i ++) {
|
||||
cJSON *read_single_item_json = cJSON_GetArrayItem(read_item_list_json, i);
|
||||
|
||||
protocol_format_info.read_single_item_json = read_single_item_json;
|
||||
protocol_format_info.read_item_index = i;
|
||||
|
||||
/*Format Protocol Cmd By Analyze Variable Item One By One*/
|
||||
ret = p_recipe->ControlProtocolFormatCmd(p_recipe, &protocol_format_info);
|
||||
if (ret < 0) {
|
||||
printf("%s read %d item failed!\n", __func__, i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file control_def.h
|
||||
* @brief DEFINE code for control framework
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-10-08
|
||||
*/
|
||||
|
||||
#ifndef CONTROL_DEF_H
|
||||
#define CONTROL_DEF_H
|
||||
|
||||
#include <transform.h>
|
||||
#include <list.h>
|
||||
#include <circular_area_app.h>
|
||||
#include <control.h>
|
||||
#include <control_io.h>
|
||||
|
||||
#ifdef LIB_USING_CJSON
|
||||
#include <cJSON.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CONTROL_PARAM_CHECK(param) \
|
||||
do \
|
||||
{ \
|
||||
if(NULL == param) { \
|
||||
KPrintf("CONTROL CHECK FAILED ...%s %d %s is NULL.\n", __FUNCTION__, __LINE__, #param); \
|
||||
return -1; \
|
||||
} \
|
||||
}while (0)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNIFORM_BOOL = 1,
|
||||
UNIFORM_INT8,
|
||||
UNIFORM_INT16,
|
||||
UNIFORM_INT32,
|
||||
UNIFORM_UINT8,
|
||||
UNIFORM_UINT16,
|
||||
UNIFORM_UINT32,
|
||||
UNIFORM_DOUBLE,
|
||||
UNIFORM_FLOAT
|
||||
}UniformValueType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ip[4];
|
||||
uint16_t port;
|
||||
int32_t socket;
|
||||
int8_t secondary_connect_flag;//0: enble, no connected; 1: enable, connected; -1: disable
|
||||
}BasicSocketPlc;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t command_length;
|
||||
uint16_t data_size;
|
||||
uint8_t command_ready;
|
||||
uint8_t *p_command;
|
||||
uint8_t *p_data;
|
||||
}BasicPlcDataInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cJSON *read_single_item_json;
|
||||
uint8_t *p_read_item_data;
|
||||
uint16_t read_item_index;//Variable item index(1 ++)
|
||||
uint8_t last_item_size;
|
||||
}ProtocolFormatInfo;
|
||||
|
||||
struct ProtocolData
|
||||
{
|
||||
uint8_t *data;
|
||||
uint16_t data_length;
|
||||
};
|
||||
|
||||
struct SerialConfig
|
||||
{
|
||||
uint8_t station;
|
||||
uint32_t baud_rate;
|
||||
uint8_t data_bits;
|
||||
uint8_t stop_bits;
|
||||
uint8_t check_mode;
|
||||
};
|
||||
|
||||
struct SocketConfig
|
||||
{
|
||||
uint16_t port;
|
||||
uint8_t plc_ip[4];
|
||||
uint8_t local_ip[4];
|
||||
uint8_t gateway[4];
|
||||
uint8_t netmask[4];
|
||||
};
|
||||
|
||||
struct ControlRecipe
|
||||
{
|
||||
uint8_t device_name[20];
|
||||
uint16_t device_id;
|
||||
uint16_t read_period;
|
||||
uint16_t read_item_count;
|
||||
uint16_t total_data_length;
|
||||
uint8_t communication_type;
|
||||
|
||||
ProtocolType protocol_type;
|
||||
|
||||
void *read_item;
|
||||
struct ControlDone *done;
|
||||
|
||||
struct SerialConfig serial_config;
|
||||
struct SocketConfig socket_config;
|
||||
|
||||
struct ProtocolData protocol_data;
|
||||
|
||||
int (*ControlProtocolFormatCmd)(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info);
|
||||
};
|
||||
|
||||
/*Get Value Type Memory Size*/
|
||||
uint8_t GetValueTypeMemorySize(UniformValueType uniform_value_type);
|
||||
|
||||
/*Get basic information from recipe file*/
|
||||
int RecipeBasicInformation(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json);
|
||||
|
||||
/*Get the variable need to read from recipe file*/
|
||||
void RecipeReadVariableItem(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json);
|
||||
|
||||
/*Control Framework Peripheral Device Init*/
|
||||
int ControlPeripheralInit(struct ControlRecipe *p_recipe);
|
||||
|
||||
/*Control Framework Printf List Function*/
|
||||
void ControlPrintfList(char name[5], uint8_t *number_list, uint16_t length);
|
||||
|
||||
/*Control Framework Connect Socket*/
|
||||
int ControlConnectSocket(BasicSocketPlc *p_plc);
|
||||
|
||||
/*Control Framework Disconnect Socket*/
|
||||
int ControlDisconnectSocket(BasicSocketPlc *p_plc);
|
||||
|
||||
/*Control Framework Protocol Open for Sub_Protocol, Init Circular Area and Receive Data Task*/
|
||||
int ControlProtocolOpenDef(struct ControlProtocol *control_protocol);
|
||||
|
||||
/*Control Framework Protocol Open for Sub_Protocol, Release Circular Area and Delete Receive Data Task*/
|
||||
int ControlProtocolCloseDef(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file control_io.c
|
||||
* @brief low level io code for control framework
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-11-21
|
||||
*/
|
||||
|
||||
#include <control_io.h>
|
||||
|
||||
#ifdef CONTROL_USING_SERIAL_485
|
||||
static int pin_fd = 0;
|
||||
static int uart_fd = 0;
|
||||
|
||||
/**
|
||||
* @description: Set Uart 485 Input
|
||||
* @return
|
||||
*/
|
||||
static void Set485Input(void)
|
||||
{
|
||||
struct PinStat pin_stat;
|
||||
pin_stat.pin = CONTROL_FRAMEWORK_UART_485_DIR;
|
||||
pin_stat.val = GPIO_LOW;
|
||||
PrivWrite(pin_fd, &pin_stat, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Set Uart 485 Output
|
||||
* @return
|
||||
*/
|
||||
static void Set485Output(void)
|
||||
{
|
||||
struct PinStat pin_stat;
|
||||
pin_stat.pin = CONTROL_FRAMEWORK_UART_485_DIR;
|
||||
pin_stat.val = GPIO_HIGH;
|
||||
PrivWrite(pin_fd, &pin_stat, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Uart 485 Init
|
||||
* @param baud_rate - baud rate
|
||||
* @param data_bits - data bits
|
||||
* @param stop_bits - stop bits
|
||||
* @param check_mode - check mode, even、odd、none
|
||||
* @return
|
||||
*/
|
||||
void Uart485Init(uint32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, uint8_t check_mode)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
pin_fd = PrivOpen(CONTROL_FRAMEWORK_PIN_DEV, O_RDWR);
|
||||
if (pin_fd < 0) {
|
||||
printf("open %s error\n", CONTROL_FRAMEWORK_PIN_DEV);
|
||||
return;
|
||||
}
|
||||
|
||||
struct PinParam pin_param;
|
||||
pin_param.cmd = GPIO_CONFIG_MODE;
|
||||
pin_param.mode = GPIO_CFG_OUTPUT;
|
||||
pin_param.pin = CONTROL_FRAMEWORK_UART_485_DIR;
|
||||
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
|
||||
ioctl_cfg.args = &pin_param;
|
||||
PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg);
|
||||
|
||||
uart_fd = open(CONTROL_FRAMEWORK_UART_DEV, O_RDWR);
|
||||
if (uart_fd < 0) {
|
||||
printf("open fd error %d\n", uart_fd);
|
||||
return;
|
||||
}
|
||||
printf("Uart485Init open fd %d baud_rate %d data_bits %d stop_bits %d check_mode %d\n",
|
||||
uart_fd, baud_rate, data_bits, stop_bits, check_mode);
|
||||
|
||||
struct SerialDataCfg cfg;
|
||||
cfg.serial_baud_rate = baud_rate;
|
||||
cfg.serial_data_bits = data_bits;
|
||||
cfg.serial_stop_bits = stop_bits;
|
||||
cfg.serial_buffer_size = 128;
|
||||
cfg.serial_parity_mode = check_mode;
|
||||
cfg.serial_bit_order = 0;
|
||||
cfg.serial_invert_mode = 0;
|
||||
#ifdef CONTROL_FRAMEWORK_DRIVER_EXTUART
|
||||
cfg.ext_uart_no = 0;
|
||||
cfg.port_configure = PORT_CFG_INIT;
|
||||
#endif
|
||||
cfg.serial_timeout = 10000;
|
||||
|
||||
ioctl_cfg.ioctl_driver_type = SERIAL_TYPE;
|
||||
ioctl_cfg.args = &cfg;
|
||||
ret = PrivIoctl(uart_fd, OPE_INT, &ioctl_cfg);
|
||||
if (0 != ret) {
|
||||
printf("ioctl fd error %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s done!\n", __func__);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @description: Control Framework Socket Init
|
||||
* @param ip - local ip pointer
|
||||
* @param mask - netmask pointer
|
||||
* @param gw - gateway pointer
|
||||
* @return
|
||||
*/
|
||||
void SocketInit(char *ip, char *mask, char *gw)
|
||||
{
|
||||
printf("%s ip %d.%d.%d.%d mask %d.%d.%d.%d gw %d.%d.%d.%d\n", __func__,
|
||||
ip[0], ip[1], ip[2], ip[3],
|
||||
mask[0], mask[1], mask[2], mask[3],
|
||||
gw[0], gw[1], gw[2], gw[3]);
|
||||
#ifdef CONTROL_USING_SOCKET
|
||||
#ifdef BSP_USING_LWIP
|
||||
lwip_config_tcp(0, ip, mask, gw);
|
||||
#endif
|
||||
#ifdef BSP_USING_W5500
|
||||
//to do
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Serial Init
|
||||
* @param baud_rate - baud rate
|
||||
* @param data_bits - data bits
|
||||
* @param stop_bits - stop bits
|
||||
* @param check_mode - check mode
|
||||
* @return
|
||||
*/
|
||||
void SerialInit(uint32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, uint8_t check_mode)
|
||||
{
|
||||
#ifdef CONTROL_USING_SERIAL_485
|
||||
Uart485Init(baud_rate, data_bits, stop_bits, check_mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Serial Write
|
||||
* @param write_data - write data
|
||||
* @param length - length
|
||||
* @return
|
||||
*/
|
||||
void SerialWrite(uint8_t *write_data, int length)
|
||||
{
|
||||
#ifdef CONTROL_USING_SERIAL_485
|
||||
Set485Output();
|
||||
PrivTaskDelay(20);
|
||||
|
||||
PrivWrite(uart_fd, write_data, length);
|
||||
|
||||
PrivTaskDelay(15);
|
||||
Set485Input();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Serial Read
|
||||
* @param read_data - read data
|
||||
* @param length - length
|
||||
* @return read data size
|
||||
*/
|
||||
int SerialRead(uint8_t *read_data, int length)
|
||||
{
|
||||
#ifdef CONTROL_USING_SERIAL_485
|
||||
int data_size = 0;
|
||||
int data_recv_size = 0;
|
||||
|
||||
while (data_size < length) {
|
||||
data_recv_size = PrivRead(uart_fd, read_data + data_recv_size, length);
|
||||
data_size += data_recv_size;
|
||||
}
|
||||
|
||||
//need to wait 30ms , make sure write cmd again and receive data successfully
|
||||
PrivTaskDelay(30);
|
||||
|
||||
return data_size;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file control_io.h
|
||||
* @brief code for control framework io adapter
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-11-21
|
||||
*/
|
||||
|
||||
#ifndef CONTROL_IO_H
|
||||
#define CONTROL_IO_H
|
||||
|
||||
#include <transform.h>
|
||||
#include <list.h>
|
||||
|
||||
#ifdef CONTROL_USING_SOCKET
|
||||
#ifdef BSP_USING_LWIP
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/sockets.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_USING_SOCKET
|
||||
#ifdef BSP_USING_LWIP
|
||||
#define socket_write lwip_write
|
||||
#define socket_read lwip_read
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_W5500
|
||||
//to do
|
||||
#define socket_write
|
||||
#define socket_read
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Control Framework Socket Init*/
|
||||
void SocketInit(char *ip, char *mask, char *gw);
|
||||
|
||||
/*Control Framework Serial Init*/
|
||||
void SerialInit(uint32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, uint8_t check_mode);
|
||||
|
||||
/*Control Framework Serial Write*/
|
||||
void SerialWrite(uint8_t *write_data, int length);
|
||||
|
||||
/*Control Framework Serial Read*/
|
||||
int SerialRead(uint8_t *read_data, int length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
extern int SensorFrameworkInit(void);
|
||||
extern int AdapterFrameworkInit(void);
|
||||
extern int ControlFrameworkInit(void);
|
||||
|
||||
extern int Adapter4GInit(void);
|
||||
extern int AdapterNbiotInit(void);
|
||||
|
|
@ -73,6 +74,10 @@ static struct InitDesc framework[] =
|
|||
{ "connection_framework", AdapterFrameworkInit },
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_CONTROL_FRAMEWORK
|
||||
{ "control_framework", ControlFrameworkInit },
|
||||
#endif
|
||||
|
||||
{ "NULL", NULL },
|
||||
};
|
||||
|
||||
|
|
@ -229,6 +234,10 @@ int FrameworkInit(void)
|
|||
ConnectionDeviceFrameworkInit(framework);
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_CONTROL_FRAMEWORK
|
||||
ControlFrameworkInit();
|
||||
#endif
|
||||
|
||||
#ifdef LIB_LV
|
||||
lv_port_init();
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
SRC_DIR := tensorflow-lite
|
||||
SRC_DIR := cmsis_5 filter image_processing kpu nnom ota tensorflow-lite
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue