optimize OPCUA demo and PLC demo and added PLC channel instead of bus

This commit is contained in:
wlyu
2022-03-03 17:58:14 +08:00
parent eb4538e331
commit 06b2ed5235
22 changed files with 1969 additions and 526 deletions

View File

@@ -1,4 +1,4 @@
SRC_FILES := plc_dev.c plc_bus.c plc_drv.c
SRC_FILES := plc_dev.c plc_ch.c plc_drv.c channel.c
include $(KERNEL_ROOT)/compiler.mk

View File

@@ -0,0 +1,433 @@
/*
* 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 plc_ch.c
* @brief Support channel driver framework provide ch API version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include "string.h"
#include "channel.h"
#include "transform.h"
DoublelistType ch_linklist;
/*Create the ch linklist*/
static void ChannelLinkInit(struct Channel *ch)
{
static uint8 ch_link_flag = RET_FALSE;
if(!ch_link_flag) {
AppInitDoubleList(&ch_linklist);
ch_link_flag = RET_TRUE;
ch->ch_link_flag = RET_TRUE;
}
/*Create the driver of the ch linklist*/
if(!ch->ch_drvlink_flag) {
AppInitDoubleList(&ch->ch_drvlink);
ch->ch_drvlink_flag = RET_TRUE;
}
/*Create the hardware device of the ch linklist*/
if(!ch->ch_devlink_flag) {
AppInitDoubleList(&ch->ch_devlink);
ch->ch_devlink_flag = RET_TRUE;
}
}
static int ChannelMatchDrvDev(struct ChDrv *driver, struct ChDev *device)
{
CHECK_CH_PARAM(driver);
CHECK_CH_PARAM(device);
if(!strncmp(driver->owner_ch->ch_name, device->owner_ch->ch_name, NAME_NUM_MAX)) {
KPrintf("ChannelMatchDrvDev match successfully, ch name %s\n", driver->owner_ch->ch_name);
driver->private_data = device->private_data;//driver get the device param
device->owner_ch->owner_driver = driver;
driver->owner_ch->owner_haldev = device;
return EOK;
}
return ERROR;
}
/**
* @Description: support to obtain ch for a certain dev if necessary, then configure and init its drv
* @param ch - ch pointer
* @param dev - dev pointer
* @param drv_name - drv name
* @param config - ChConfigInfo pointer
* @return successful:EOK,failed:ERROR
*/
int DeviceObtainChannel(struct Channel *ch, struct ChDev *dev, const char *drv_name, struct ChConfigInfo *cfg)
{
CHECK_CH_PARAM(ch);
CHECK_CH_PARAM(dev);
int32 ret = EOK;
ret = PrivMutexObtain(&ch->ch_lock);
if(EOK != ret) {
KPrintf("DevObtainChannel ch_lock error %d!\n", ret);
return ret;
}
if(ch->owner_haldev != dev) {
struct ChDrv *drv = ChannelFindDriver(ch, drv_name);
cfg->configure_cmd = OPE_CFG;
drv->configure(drv, cfg);
cfg->configure_cmd = OPE_INT;
drv->configure(drv, cfg);
ch->owner_haldev = dev;
}
return ret;
}
/**
* @Description: support to register ch pointer with linklist
* @param ch - ch pointer
* @return successful:EOK,failed:NONE
*/
int ChannelRegister(struct Channel *ch)
{
int ret = EOK;
CHECK_CH_PARAM(ch);
ch->match = ChannelMatchDrvDev;
ChannelLinkInit(ch);
PrivMutexCreate(&ch->ch_lock, NULL);
AppDoubleListInsertNodeAfter(&ch_linklist, &(ch->ch_link));
return ret;
}
/**
* @Description: support to release ch pointer in linklist
* @param ch - ch pointer
* @return successful:EOK,failed:NONE
*/
int ChannelRelease(struct Channel *ch)
{
CHECK_CH_PARAM(ch);
PrivMutexAbandon(&ch->ch_lock);
ch->ch_cnt = 0;
ch->driver_cnt = 0;
ch->haldev_cnt = 0;
ch->ch_link_flag = RET_FALSE;
ch->ch_drvlink_flag = RET_FALSE;
ch->ch_devlink_flag = RET_FALSE;
return EOK;
}
/**
* @Description: support to unregister ch pointer and delete its linklist node
* @param ch - ch pointer
* @return successful:EOK,failed:NONE
*/
int ChannelUnregister(struct Channel *ch)
{
CHECK_CH_PARAM(ch);
ch->ch_cnt--;
AppDoubleListRmNode(&(ch->ch_link));
return EOK;
}
/**
* @Description: support to register driver pointer to ch pointer
* @param ch - ch pointer
* @param driver - driver pointer
* @return successful:EOK,failed:NONE
*/
int DriverRegisterToChannel(struct Channel *ch, struct ChDrv *driver)
{
CHECK_CH_PARAM(ch);
CHECK_CH_PARAM(driver);
driver->owner_ch = ch;
ch->driver_cnt++;
AppDoubleListInsertNodeAfter(&ch->ch_drvlink, &(driver->driver_link));
return EOK;
}
/**
* @Description: support to register dev pointer to ch pointer
* @param ch - ch pointer
* @param device - device pointer
* @return successful:EOK,failed:NONE
*/
int DeviceRegisterToChannel(struct Channel *ch, struct ChDev *device)
{
CHECK_CH_PARAM(ch);
CHECK_CH_PARAM(device);
device->owner_ch = ch;
ch->haldev_cnt++;
AppDoubleListInsertNodeAfter(&ch->ch_devlink, &(device->dev_link));
return EOK;
}
/**
* @Description: support to delete driver pointer from ch pointer
* @param ch - ch pointer
* @param driver - driver pointer
* @return successful:EOK,failed:NONE
*/
int DriverDeleteFromChannel(struct Channel *ch, struct ChDrv *driver)
{
CHECK_CH_PARAM(ch);
CHECK_CH_PARAM(driver);
ch->driver_cnt--;
AppDoubleListRmNode(&(driver->driver_link));
free(driver);
return EOK;
}
/**
* @Description: support to delete dev pointer from ch pointer
* @param ch - ch pointer
* @param device - device pointer
* @return successful:EOK,failed:NONE
*/
int DeviceDeleteFromChannel(struct Channel *ch, struct ChDev *device)
{
CHECK_CH_PARAM(ch);
CHECK_CH_PARAM(device);
ch->haldev_cnt--;
AppDoubleListRmNode(&(device->dev_link));
free(device);
return EOK;
}
/**
* @Description: support to find ch pointer by ch name
* @param ch_name - ch name
* @return successful:ch pointer,failed:NONE
*/
ChannelType ChannelFind(const char *ch_name)
{
struct Channel *ch = NONE;
DoublelistType *node = NONE;
DoublelistType *head = &ch_linklist;
for (node = head->node_next; node != head; node = node->node_next)
{
ch = DOUBLE_LIST_ENTRY(node, struct Channel, ch_link);
if(!strcmp(ch->ch_name, ch_name)) {
return ch;
}
}
KPrintf("ChannelFind cannot find the %s ch.return NULL\n", ch_name);
return NONE;
}
/**
* @Description: support to find driver pointer of certain ch by driver name
* @param ch - ch pointer
* @param driver_name - driver name
* @return successful:EOK,failed:NONE
*/
ChDrvType ChannelFindDriver(struct Channel *ch, const char *driver_name)
{
CHECK_CH_PARAM(ch);
struct ChDrv *driver = NONE;
DoublelistType *node = NONE;
DoublelistType *head = &ch->ch_drvlink;
for (node = head->node_next; node != head; node = node->node_next)
{
driver = DOUBLE_LIST_ENTRY(node, struct ChDrv, driver_link);
if(!strcmp(driver->drv_name, driver_name)) {
return driver;
}
}
KPrintf("ChannelFindDriver cannot find the %s driver.return NULL\n", driver_name);
return NONE;
}
/**
* @Description: support to find device pointer of certain ch by device name
* @param ch - ch pointer
* @param device_name - device name
* @return successful:EOK,failed:NONE
*/
ChDevType ChannelFindDevice(struct Channel *ch, const char *device_name)
{
CHECK_CH_PARAM(ch);
struct ChDev *device = NONE;
DoublelistType *node = NONE;
DoublelistType *head = &ch->ch_devlink;
for (node = head->node_next; node != head; node = node->node_next)
{
device = DOUBLE_LIST_ENTRY(node, struct ChDev, dev_link);
if(!strcmp(device->dev_name, device_name)) {
return device;
}
}
KPrintf("ChannelFindDevice cannot find the %s device.return NULL\n", device_name);
return NONE;
}
/**
* @Description: support to set dev receive function callback
* @param dev - dev pointer
* @param dev_recv_callback - callback function
* @return successful:EOK,failed:ERROR
*/
uint32 ChannelDevRecvCallback(struct ChDev *dev, int (*dev_recv_callback) (void *dev, x_size_t length))
{
CHECK_CH_PARAM(dev );
dev->dev_recv_callback = dev_recv_callback;
return EOK;
}
/**
* @Description: support to open dev
* @param dev - dev pointer
* @return successful:EOK,failed:ERROR
*/
uint32 ChannelDevOpen(struct ChDev *dev)
{
CHECK_CH_PARAM(dev);
int ret = EOK;
if (dev->dev_done->open) {
ret = dev->dev_done->open(dev);
if(ret) {
KPrintf("ChannelDevOpen error ret %u\n", ret);
return ERROR;
}
}
return ret;
}
/**
* @Description: support to close dev
* @param dev - dev pointer
* @return successful:EOK,failed:ERROR
*/
uint32 ChannelDevClose(struct ChDev *dev)
{
CHECK_CH_PARAM(dev);
int ret = EOK;
if (dev->dev_done->close) {
ret = dev->dev_done->close(dev);
if(ret) {
KPrintf("ChannelDevClose error ret %u\n", ret);
return ERROR;
}
}
return ret;
}
/**
* @Description: support to write data to dev
* @param dev - dev pointer
* @param write_param - ChWriteParam
* @return successful:EOK,failed:NONE
*/
uint32 ChannelDevWriteData(struct ChDev *dev, struct ChWriteParam *write_param)
{
CHECK_CH_PARAM(dev);
if (dev->dev_done->write) {
return dev->dev_done->write(dev, write_param);
}
return EOK;
}
/**
* @Description: support to read data from dev
* @param dev - dev pointer
* @param read_param - ChReadParam
* @return successful:EOK,failed:NONE
*/
uint32 ChannelDevReadData(struct ChDev *dev, struct ChReadParam *read_param)
{
CHECK_CH_PARAM(dev);
if (dev->dev_done->read) {
return dev->dev_done->read(dev, read_param);
}
return EOK;
}
/**
* @Description: support to configure drv, include OPE_CFG and OPE_INT
* @param drv - drv pointer
* @param config - ChConfigInfo
* @return successful:EOK,failed:NONE
*/
uint32 ChannelDrvConfigure(struct ChDrv *drv, struct ChConfigInfo *config)
{
CHECK_CH_PARAM(drv);
CHECK_CH_PARAM(config);
int ret = EOK;
if (drv->configure) {
ret = drv->configure(drv, config);
if(ret) {
KPrintf("ChannelDrvCfg error, ret %u\n", ret);
return ERROR;
}
}
return ret;
}

View File

@@ -0,0 +1,247 @@
/*
* 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 channel.h
* @brief define ch driver framework function and common API
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-03-01
*/
#ifndef __CHANNEL_H_
#define __CHANNEL_H_
#include "list.h"
#define x_OffPos uint32
#define x_size_t size_t
#ifdef __cplusplus
extern "C" {
#endif
#define OPE_INT 0x0000
#define OPE_CFG 0x0001
#define OPER_WDT_SET_TIMEOUT 0x0002
#define OPER_WDT_KEEPALIVE 0x0003
#define CHECK_CH_PARAM(param) \
do \
{ \
if(param == NONE) { \
KPrintf("PARAM CHECK FAILED ...%s %d %s is NULL.\n",__FUNCTION__,__LINE__,#param); \
while(RET_TRUE); \
} \
}while (0)
typedef struct Channel *ChannelType;
typedef struct ChDev *ChDevType;
typedef struct ChDrv *ChDrvType;
/* need to add new ch type in ../tool/shell/letter-shell/cmd.c, ensure ShowBus cmd supported*/
enum ChType_e
{
CH_PLC_TYPE,
CH_END_TYPE,
};
enum ChState_e
{
CHANNEL_INIT = 0,
CHANNEL_INSTALL,
CHANNEL_UNINSTALL,
};
enum ChDevType_e
{
CHDEV_PLC_TYPE,
CHDEV_END_TYPE,
};
enum ChDevState_e
{
CHDEV_INIT = 0,
CHDEV_INSTALL,
CHDEV_UNINSTALL,
};
enum ChDrvType_e
{
CHDRV_PLC_TYPE,
CHDRV_END_TYPE,
};
enum ChDrvState_e
{
CHDRV_INIT = 0,
CHDRV_INSTALL,
CHDRV_UNINSTALL,
};
struct ChConfigInfo
{
int configure_cmd;
void *private_data;
};
struct ChReadParam
{
x_OffPos pos;
void* buffer;
x_size_t size;
x_size_t read_length;
};
struct ChWriteParam
{
x_OffPos pos;
const void* buffer;
x_size_t size;
};
//struct ChHalDevBlockParam
//{
// uint32 cmd;
////tst by wly
//// struct DeviceBlockArrange dev_block;
//// struct DeviceBlockAddr *dev_addr;
//};
struct ChHalDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev, struct ChWriteParam *write_param);
uint32 (*read) (void *dev, struct ChReadParam *read_param);
};
struct ChDev
{
int8 dev_name[NAME_NUM_MAX];
enum ChDevType_e dev_type;
enum ChDevState_e dev_state;
const struct ChHalDevDone *dev_done;
int (*dev_recv_callback) (void *dev, x_size_t length);
// int (*dev_block_control) (struct ChDev *dev, struct ChHalDevBlockParam *block_param);
struct Channel *owner_ch;
void *private_data;
int32 dev_sem;
DoublelistType dev_link;
};
struct ChDrv
{
int8 drv_name[NAME_NUM_MAX];
enum ChDrvType_e driver_type;
enum ChDrvState_e driver_state;
uint32 (*configure)(void *drv, struct ChConfigInfo *config);
struct Channel *owner_ch;
void *private_data;
DoublelistType driver_link;
};
struct Channel
{
int8 ch_name[NAME_NUM_MAX];
enum ChType_e ch_type;
enum ChState_e ch_state;
int32 (*match)(struct ChDrv *driver, struct ChDev *device);
int ch_lock;
struct ChDev *owner_haldev;
struct ChDrv *owner_driver;
void *private_data;
/*manage the drv of the channel*/
uint8 driver_cnt;
uint8 ch_drvlink_flag;
DoublelistType ch_drvlink;
/*manage the dev of the channel*/
uint8 haldev_cnt;
uint8 ch_devlink_flag;
DoublelistType ch_devlink;
uint8 ch_cnt;
uint8 ch_link_flag;
DoublelistType ch_link;
};
/*Register the BUS,manage with the double linklist*/
int ChannelRegister(struct Channel *ch);
/*Release the BUS framework*/
int ChannelRelease(struct Channel *ch);
/*Unregister a certain kind of BUS*/
int ChannelUnregister(struct Channel *ch);
/*Register the driver to the channel*/
int DriverRegisterToChannel(struct Channel *ch, struct ChDrv *driver);
/*Register the device to the channel*/
int DeviceRegisterToChannel(struct Channel *ch, struct ChDev *device);
/*Delete the driver from the channel*/
int DriverDeleteFromChannel(struct Channel *ch, struct ChDrv *driver);
/*Delete the device from the channel*/
int DeviceDeleteFromChannel(struct Channel *ch, struct ChDev *device);
/*Find the ch with ch name*/
ChannelType ChannelFind(const char *ch_name);
/*Find the driver of cetain channel*/
ChDrvType ChannelFindDriver(struct Channel *ch, const char *driver_name);
/*Find the device of certain channel*/
ChDevType ChannelFindDevice(struct Channel *ch, const char *device_name);
/*Dev receive data callback function*/
uint32 ChannelDevRecvCallback(struct ChDev *dev, int (*dev_recv_callback) (void *dev, x_size_t length));
/*Open the device of the channel*/
uint32 ChannelDevOpen(struct ChDev *dev);
/*Close the device of the channel*/
uint32 ChannelDevClose(struct ChDev *dev);
/*Write data to the device*/
uint32 ChannelDevWriteData(struct ChDev *dev, struct ChWriteParam *write_param);
/*Read data from the device*/
uint32 ChannelDevReadData(struct ChDev *dev, struct ChReadParam *read_param);
/*Configure the driver of the channel*/
uint32 ChannelDrvConfigure(struct ChDrv *drv, struct ChConfigInfo *config);
/*Obtain the ch using a certain dev*/
int DeviceObtainChannel(struct Channel *ch, struct ChDev *dev, const char *drv_name, struct ChConfigInfo *config);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,119 +0,0 @@
/*
* 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 bus_plc.c
* @brief register plc bus function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-01-24
*/
#include "plc_bus.h"
#include "plc_dev.h"
/******************************************************************************/
int PlcBusInit(struct PlcBus *plc_bus, const char *bus_name)
{
NULL_PARAM_CHECK(plc_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != plc_bus->bus.bus_state) {
strncpy(plc_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
plc_bus->bus.bus_type = TYPE_PLC_BUS;
plc_bus->bus.bus_state = BUS_INSTALL;
plc_bus->bus.private_data = plc_bus->private_data;
ret = BusRegister(&plc_bus->bus);
if (EOK != ret) {
KPrintf("PlcBusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("PlcBusInit BusRegister bus has been register state%u\n", plc_bus->bus.bus_state);
}
return ret;
}
int PlcDriverInit(struct PlcDriver *plc_driver, const char *driver_name)
{
NULL_PARAM_CHECK(plc_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != plc_driver->driver.driver_state) {
plc_driver->driver.driver_type = TYPE_PLC_DRV;
plc_driver->driver.driver_state = DRV_INSTALL;
strncpy(plc_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
plc_driver->driver.configure = plc_driver->configure;
ret = PlcDriverRegister(&plc_driver->driver);
if (EOK != ret) {
KPrintf("PlcDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("PlcDriverInit DriverRegister driver has been register state%u\n", plc_driver->driver.driver_state);
}
return ret;
}
int PlcReleaseBus(struct PlcBus *plc_bus)
{
NULL_PARAM_CHECK(plc_bus);
return BusRelease(&plc_bus->bus);
}
int PlcDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct Driver *driver;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("PlcDriverAttachToBus find plc bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_PLC_BUS == bus->bus_type) {
driver = PlcDriverFind(drv_name, TYPE_PLC_DRV);
if (NONE == driver) {
KPrintf("PlcDriverAttachToBus find plc driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_PLC_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("PlcDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}

View File

@@ -0,0 +1,129 @@
/*
* 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_ch.c
* @brief register plc channel function using channel driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-01-24
*/
#include "string.h"
#include "plc_ch.h"
#include "plc_dev.h"
/******************************************************************************/
int PlcChannelInit(struct PlcChannel* plc_ch, const char* ch_name)
{
CHECK_CH_PARAM(plc_ch);
CHECK_CH_PARAM(ch_name);
int ret = EOK;
if(CHANNEL_INSTALL != plc_ch->ch.ch_state)
{
strncpy(plc_ch->ch.ch_name, ch_name, NAME_NUM_MAX);
plc_ch->ch.ch_type = CH_PLC_TYPE;
plc_ch->ch.ch_state = CHANNEL_INSTALL;
plc_ch->ch.private_data = plc_ch->private_data;
ret = ChannelRegister(&plc_ch->ch);
if(EOK != ret)
{
KPrintf("PlcChannelInit ChannelRegister error %u\n", ret);
return ret;
}
}
else
{
KPrintf("PlcChannelInit ChannelRegister channel has been register state %u\n",
plc_ch->ch.ch_state);
}
return ret;
}
int PlcDriverInit(struct PlcDriver* plc_driver, const char* driver_name)
{
CHECK_CH_PARAM(plc_driver);
CHECK_CH_PARAM(driver_name);
int ret = EOK;
if(CHDRV_INSTALL != plc_driver->driver.driver_state)
{
plc_driver->driver.driver_type = CHDRV_PLC_TYPE;
plc_driver->driver.driver_state = CHDRV_INSTALL;
strncpy(plc_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
plc_driver->driver.configure = plc_driver->configure;
ret = PlcDriverRegister(&plc_driver->driver);
if(EOK != ret)
{
KPrintf("PlcDriverInit DriverRegister error %u\n", ret);
return ret;
}
}
else
{
KPrintf("PlcDriverInit Driver %s has been register state %u\n",
driver_name, plc_driver->driver.driver_state);
}
return ret;
}
int PlcReleaseChannel(struct PlcChannel* plc_ch)
{
CHECK_CH_PARAM(plc_ch);
return ChannelRelease(&plc_ch->ch);
}
int PlcDriverAttachToChannel(const char* drv_name, const char* ch_name)
{
CHECK_CH_PARAM(drv_name);
CHECK_CH_PARAM(ch_name);
int ret = EOK;
struct Channel* ch;
struct ChDrv* driver;
ch = ChannelFind(ch_name);
if(NONE == ch)
{
KPrintf("PlcDriverAttachToChannel find plc channel error!name %s\n", ch_name);
return ERROR;
}
if(CH_PLC_TYPE == ch->ch_type)
{
driver = PlcDriverFind(drv_name, CHDRV_PLC_TYPE);
if(NONE == driver)
{
KPrintf("PlcDriverAttachToChannel find plc driver error!name %s\n", drv_name);
return ERROR;
}
if(CHDRV_PLC_TYPE == driver->driver_type)
{
ret = DriverRegisterToChannel(ch, driver);
if(EOK != ret)
{
KPrintf("PlcDriverAttachToChannel DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}

View File

@@ -11,17 +11,17 @@
*/
/**
* @file plc_bus.h
* @file plc_ch.h
* @brief define plc bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-01-24
*/
#ifndef __PLC_BUS_H_
#define __PLC_BUS_H_
#ifndef __PLC_CH_H_
#define __PLC_CH_H_
#include "bus.h"
#include "channel.h"
#ifdef __cplusplus
extern "C" {
@@ -29,33 +29,33 @@ extern "C" {
struct PlcDriver
{
struct Driver driver;
uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info);
struct ChDrv driver;
uint32 (*configure) (void *drv, struct ChConfigInfo *cfg);
};
struct PlcBus
struct PlcChannel
{
struct Bus bus;
struct Channel ch;
void *private_data;
};
/*Register the plc bus*/
int PlcBusInit(struct PlcBus *plc_bus, const char *bus_name);
int PlcChannelInit(struct PlcChannel *plc_ch, const char *ch_name);
/*Register the plc driver*/
int PlcDriverInit(struct PlcDriver *plc_driver, const char *driver_name);
/*Release the plc device*/
int PlcReleaseBus(struct PlcBus *plc_bus);
int PlcReleaseChannel(struct PlcChannel *plc_ch);
/*Register the plc driver to the plc bus*/
int PlcDriverAttachToBus(const char *drv_name, const char *bus_name);
int PlcDriverAttachToChannel(const char *drv_name, const char *ch_name);
/*Register the driver, manage with the double linklist*/
int PlcDriverRegister(struct Driver *driver);
int PlcDriverRegister(struct ChDrv *driver);
/*Find the register driver*/
DriverType PlcDriverFind(const char *drv_name, enum DriverType_e drv_type);
ChDrvType PlcDriverFind(const char *drv_name, enum ChDrvType_e drv_type);
#ifdef __cplusplus
}

View File

@@ -19,22 +19,22 @@
*/
#include "ua_api.h"
#include "plc_bus.h"
#include "plc_ch.h"
#include "plc_dev.h"
static DoubleLinklistType plcdev_list;
DoublelistType plcdev_list;
/******************************************************************************/
/*Create the plc device linklist*/
static void PlcDeviceLinkInit()
{
InitDoubleLinkList(&plcdev_list);
AppInitDoubleList(&plcdev_list);
}
static int PlcDeviceOpen(void *dev)
{
NULL_PARAM_CHECK(dev);
CHECK_CH_PARAM(dev);
struct PlcDevice *plc_dev = (struct PlcDevice *)dev;
@@ -48,7 +48,7 @@ static int PlcDeviceOpen(void *dev)
static void PlcDeviceClose(void *dev)
{
NULL_PARAM_CHECK(dev);
CHECK_CH_PARAM(dev);
struct PlcDevice *plc_dev = (struct PlcDevice *)dev;
@@ -60,8 +60,7 @@ static void PlcDeviceClose(void *dev)
static int PlcDeviceWrite(void *dev, const void *buf, size_t len)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(buf);
CHECK_CH_PARAM(dev);
int ret;
struct PlcDevice *plc_dev = (struct PlcDevice *)dev;
@@ -76,8 +75,8 @@ static int PlcDeviceWrite(void *dev, const void *buf, size_t len)
static int PlcDeviceRead(void *dev, void *buf, size_t len)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(buf);
CHECK_CH_PARAM(dev);
CHECK_CH_PARAM(buf);
int ret;
struct PlcDevice *plc_dev = (struct PlcDevice *)dev;
@@ -99,18 +98,18 @@ static struct PlcOps plc_done =
};
/* find PLC device with device name */
struct HardwareDev *PlcDevFind(const char *dev_name)
struct ChDev *PlcDevFind(const char *dev_name)
{
NULL_PARAM_CHECK(dev_name);
CHECK_CH_PARAM(dev_name);
struct PlcDevice *device = NONE;
struct HardwareDev *haldev = NONE;
struct ChDev *haldev = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &plcdev_list;
DoublelistType *node = NONE;
DoublelistType *head = &plcdev_list;
for (node = head->node_next; node != head; node = node->node_next) {
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct PlcDevice, link);
device = DOUBLE_LIST_ENTRY(node, struct PlcDevice, link);
if (!strcmp(device->name, dev_name)) {
haldev = &device->haldev;
return haldev;
@@ -123,61 +122,63 @@ struct HardwareDev *PlcDevFind(const char *dev_name)
int PlcDevRegister(struct PlcDevice *plc_device, void *plc_param, const char *device_name)
{
NULL_PARAM_CHECK(plc_device);
NULL_PARAM_CHECK(device_name);
CHECK_CH_PARAM(plc_device);
CHECK_CH_PARAM(device_name);
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
int ret = EOK;
static uint8_t dev_link_flag = 0;
if (!dev_link_flag) {
PlcDeviceLinkInit();
dev_link_flag = RET_TRUE;
dev_link_flag = 1;
}
if (DEV_INSTALL != plc_device->state) {
if (CHDEV_INSTALL != plc_device->state) {
strncpy(plc_device->haldev.dev_name, device_name, NAME_NUM_MAX);
plc_device->haldev.dev_type = TYPE_PLC_DEV;
plc_device->haldev.dev_state = DEV_INSTALL;
plc_device->haldev.dev_type = CHDEV_PLC_TYPE;
plc_device->haldev.dev_state = CHDEV_INSTALL;
strncpy(plc_device->name, device_name, strlen(device_name));
plc_device->ops = &plc_done;
DoubleLinkListInsertNodeAfter(&plcdev_list, &(plc_device->link));
plc_device->state = DEV_INSTALL;
AppDoubleListInsertNodeAfter(&plcdev_list, &(plc_device->link));
plc_device->state = CHDEV_INSTALL;
} else {
KPrintf("PlcDevRegister device has been register state%u\n", plc_device->type);
KPrintf("PlcDevRegister device %s has been register state%u\n", device_name, plc_device->state);
ret = ERROR;
}
return ret;
}
int PlcDeviceAttachToBus(const char *dev_name, const char *bus_name)
int PlcDeviceAttachToChannel(const char *dev_name, const char *ch_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
CHECK_CH_PARAM(dev_name);
CHECK_CH_PARAM(ch_name);
x_err_t ret = EOK;
int ret = EOK;
struct Bus *bus;
struct HardwareDev *device;
struct Channel *ch;
struct ChDev *device;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("PlcDeviceAttachToBus find plc bus error!name %s\n", bus_name);
ch = ChannelFind(ch_name);
if (NONE == ch) {
KPrintf("PlcDeviceAttachToChannel find plc ch error!name %s\n", ch_name);
return ERROR;
}
if (TYPE_PLC_BUS == bus->bus_type) {
if (CH_PLC_TYPE == ch->ch_type) {
device = PlcDevFind(dev_name);
if (NONE == device) {
KPrintf("PlcDeviceAttachToBus find plc device error!name %s\n", dev_name);
KPrintf("PlcDeviceAttachToChannel find plc device %s error!\n", dev_name);
return ERROR;
}
if (TYPE_PLC_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
if (CHDEV_PLC_TYPE == device->dev_type) {
ret = DeviceRegisterToChannel(ch, device);
if (EOK != ret) {
KPrintf("PlcDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
KPrintf("PlcDeviceAttachToChannel DeviceRegisterToChannel error %u\n", ret);
return ERROR;
}
}

View File

@@ -21,8 +21,8 @@
#ifndef __PLC_DEV_H_
#define __PLC_DEV_H_
#include "bus.h"
#include "xs_klist.h"
#include "list.h"
#include "plc_ch.h"
#undef open
#undef close
@@ -33,15 +33,16 @@
#define PLC_NAME_SIZE 32
// PLC device information
struct PlcInfo {
typedef struct PlcInfo {
uint32_t ability; // PLC ability
uint32_t id; // PLC Device ID
uint32_t soft_version; // software version
uint32_t hard_version; // hardware version
uint32_t date; // manufact date
const char *vendor; // vendor
const char *model; // product model
};
const char *model; // model
const char *product; // product
}PlcInfoType;
enum PlcSerialType {
PLC_SERIAL_232,
@@ -64,13 +65,13 @@ union PlcCfg {
struct PlcDevice;
// operation API
struct PlcOps {
typedef struct PlcOps {
int (*open)(void *dev); // open and connect PLC device
void (*close)(void* dev); // close and disconnect PLC device
int (*read)(void* dev, void *buf, size_t len); // read data from PLC
int (*write)(void* dev, const void *buf, size_t len); // write data from PLC
int (*ioctl)(void* dev, int cmd, void *arg); // send control command to PLC
};
}PlcOpsType;
enum PlcCtlType {
PLC_CTRL_TYPE_HSC,
@@ -78,12 +79,10 @@ enum PlcCtlType {
PLC_CTRL_TYPE_PHASING
};
#define PLC_ABILITY_HSC ((uint32_t)(1 << PLC_CTRL_TYPE_HSC))
#define PLC_ABILITY_PID ((uint32_t)(1 << PLC_CTRL_TYPE_PID))
#define PLC_ABILITY_PHASING ((uint32_t)(1 << PLC_CTRL_TYPE_PHASING))
enum PlcIndHybridNet
{
// PLC Field Bus
@@ -112,18 +111,19 @@ enum PlcTransType
};
//communication interface
struct PlcInterface
typedef struct PlcInterface
{
char ip_addr[IP_ADDR_SIZE];
char attrib;
};
}PlcInterfaceType;
// identify PLC device
struct PlcDevice {
struct HardwareDev haldev; /* hardware device driver for bus */
typedef struct PlcDevice {
struct ChDev haldev; /* hardware device driver for channel */
enum ChDevState_e state;
char name[PLC_NAME_SIZE]; /* name of the device */
enum PlcCtlType type; /* PLC Control Type */
enum DevState state;
enum PlcIndHybridNet net;
enum PlcTransType trans;
@@ -133,16 +133,20 @@ struct PlcDevice {
struct PlcInterface interface; /* protocols used for transferring data from program to plc */
void *priv_data; /* private data for different PLC*/
DoubleLinklistType link;/* link list node */
};
DoublelistType link;/* link list node */
}PlcDeviceType;
typedef struct PlcCtrlParam {
void *node_id; // for node ID
int value;
}PlcCtrlParamType;
#define plc_print KPrintf
/******************************************************************************/
int PlcDevRegister(struct PlcDevice *plc_device, void *plc_param, const char *device_name);
int PlcDeviceAttachToBus(const char *dev_name, const char *bus_name);
int PlcDeviceAttachToChannel(const char *dev_name, const char *ch_name);
/******************************************************************************/

View File

@@ -19,30 +19,30 @@
*/
#include "transform.h"
#include "plc_bus.h"
#include "plc_ch.h"
#include "plc_dev.h"
static DoubleLinklistType plcdrv_linklist;
static DoublelistType plcdrv_linklist;
/******************************************************************************/
/*Create the driver linklist*/
static void PlcDrvLinkInit()
{
InitDoubleLinkList(&plcdrv_linklist);
AppInitDoubleList(&plcdrv_linklist);
}
DriverType PlcDriverFind(const char *drv_name, enum DriverType_e drv_type)
ChDrvType PlcDriverFind(const char *drv_name, enum ChDrvType_e drv_type)
{
NULL_PARAM_CHECK(drv_name);
CHECK_CH_PARAM(drv_name);
struct Driver *driver = NONE;
struct ChDrv *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &plcdrv_linklist;
DoublelistType *node = NONE;
DoublelistType *head = &plcdrv_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
driver = DOUBLE_LIST_ENTRY(node, struct ChDrv, driver_link);
if ((!strcmp(driver->drv_name, drv_name)) && (drv_type == driver->driver_type)) {
return driver;
}
@@ -52,19 +52,19 @@ DriverType PlcDriverFind(const char *drv_name, enum DriverType_e drv_type)
return NONE;
}
int PlcDriverRegister(struct Driver *driver)
int PlcDriverRegister(struct ChDrv *driver)
{
NULL_PARAM_CHECK(driver);
CHECK_CH_PARAM(driver);
x_err_t ret = EOK;
static x_bool driver_link_flag = RET_FALSE;
int ret = EOK;
static uint8_t driver_link_flag = 0;
if (!driver_link_flag) {
PlcDrvLinkInit();
driver_link_flag = RET_TRUE;
driver_link_flag = 1;
}
DoubleLinkListInsertNodeAfter(&plcdrv_linklist, &(driver->driver_link));
AppDoubleListInsertNodeAfter(&plcdrv_linklist, &(driver->driver_link));
return ret;
}