Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
luozhenger
rt-thread
提交
15129278
R
rt-thread
项目概览
luozhenger
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
15129278
编写于
2月 05, 2015
作者:
B
Bernard Xiong
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #427 from armink/master
更新FreeModbus主机及从机
上级
204298c1
b3290f6e
变更
21
展开全部
隐藏空白更改
内联
并排
Showing
21 changed file
with
1579 addition
and
832 deletion
+1579
-832
components/net/freemodbus-v1.6.0/SConscript
components/net/freemodbus-v1.6.0/SConscript
+4
-1
components/net/freemodbus-v1.6.0/modbus/functions/mbfunccoils_m.c
...ts/net/freemodbus-v1.6.0/modbus/functions/mbfunccoils_m.c
+59
-14
components/net/freemodbus-v1.6.0/modbus/functions/mbfuncdisc_m.c
...nts/net/freemodbus-v1.6.0/modbus/functions/mbfuncdisc_m.c
+22
-6
components/net/freemodbus-v1.6.0/modbus/functions/mbfuncholding_m.c
.../net/freemodbus-v1.6.0/modbus/functions/mbfuncholding_m.c
+80
-21
components/net/freemodbus-v1.6.0/modbus/functions/mbfuncinput_m.c
...ts/net/freemodbus-v1.6.0/modbus/functions/mbfuncinput_m.c
+22
-6
components/net/freemodbus-v1.6.0/modbus/include/mb_m.h
components/net/freemodbus-v1.6.0/modbus/include/mb_m.h
+162
-18
components/net/freemodbus-v1.6.0/modbus/include/mbconfig.h
components/net/freemodbus-v1.6.0/modbus/include/mbconfig.h
+3
-3
components/net/freemodbus-v1.6.0/modbus/include/mbport.h
components/net/freemodbus-v1.6.0/modbus/include/mbport.h
+40
-10
components/net/freemodbus-v1.6.0/modbus/mb_m.c
components/net/freemodbus-v1.6.0/modbus/mb_m.c
+79
-35
components/net/freemodbus-v1.6.0/modbus/rtu/mbrtu_m.c
components/net/freemodbus-v1.6.0/modbus/rtu/mbrtu_m.c
+25
-11
components/net/freemodbus-v1.6.0/port/port.c
components/net/freemodbus-v1.6.0/port/port.c
+7
-8
components/net/freemodbus-v1.6.0/port/port.h
components/net/freemodbus-v1.6.0/port/port.h
+7
-13
components/net/freemodbus-v1.6.0/port/portevent.c
components/net/freemodbus-v1.6.0/port/portevent.c
+24
-14
components/net/freemodbus-v1.6.0/port/portevent_m.c
components/net/freemodbus-v1.6.0/port/portevent_m.c
+192
-14
components/net/freemodbus-v1.6.0/port/portserial.c
components/net/freemodbus-v1.6.0/port/portserial.c
+155
-122
components/net/freemodbus-v1.6.0/port/portserial_m.c
components/net/freemodbus-v1.6.0/port/portserial_m.c
+155
-122
components/net/freemodbus-v1.6.0/port/porttimer.c
components/net/freemodbus-v1.6.0/port/porttimer.c
+14
-58
components/net/freemodbus-v1.6.0/port/porttimer_m.c
components/net/freemodbus-v1.6.0/port/porttimer_m.c
+35
-85
components/net/freemodbus-v1.6.0/port/user_mb_app.c
components/net/freemodbus-v1.6.0/port/user_mb_app.c
+175
-238
components/net/freemodbus-v1.6.0/port/user_mb_app.h
components/net/freemodbus-v1.6.0/port/user_mb_app.h
+25
-33
components/net/freemodbus-v1.6.0/port/user_mb_app_m.c
components/net/freemodbus-v1.6.0/port/user_mb_app_m.c
+294
-0
未找到文件。
components/net/freemodbus-v1.6.0/SConscript
浏览文件 @
15129278
...
...
@@ -7,7 +7,6 @@ modbus/functions/mbutils.c
modbus/functions/mbfuncother.c
modbus/rtu/mbcrc.c
port/port.c
port/user_mb_app.c
"""
)
master_rtu_src
=
Split
(
"""
...
...
@@ -20,6 +19,7 @@ modbus/mb_m.c
port/portevent_m.c
port/portserial_m.c
port/porttimer_m.c
port/user_mb_app_m.c
"""
)
slave_rtu_src
=
Split
(
"""
...
...
@@ -32,6 +32,7 @@ modbus/mb.c
port/portevent.c
port/portserial.c
port/porttimer.c
port/user_mb_app.c
"""
)
master_slave_rtu_src
=
Split
(
"""
...
...
@@ -53,6 +54,8 @@ port/portserial.c
port/portserial_m.c
port/porttimer.c
port/porttimer_m.c
port/user_mb_app.c
port/user_mb_app_m.c
"""
)
# The set of source files associated with this SConscript file.
...
...
components/net/freemodbus-v1.6.0/modbus/functions/mbfunccoils_m.c
浏览文件 @
15129278
...
...
@@ -74,14 +74,24 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
#if MB_FUNC_READ_COILS_ENABLED > 0
/**
* This function will request read coil.
*
* @param ucSndAddr salve address
* @param usCoilAddr coil start address
* @param usNCoils coil total number
* @param lTimeOut timeout (-1 will waiting forever)
*
* @return error code
*/
eMBMasterReqErrCode
eMBMasterReqReadCoils
(
UCHAR
ucSndAddr
,
USHORT
usCoilAddr
,
USHORT
usNCoils
)
eMBMasterReqReadCoils
(
UCHAR
ucSndAddr
,
USHORT
usCoilAddr
,
USHORT
usNCoils
,
LONG
lTimeOut
)
{
UCHAR
*
ucMBFrame
;
eMBMasterReqErrCode
eErrStatus
=
MB_MRE_NO_ERR
;
if
(
xMBMasterGetIsBusy
()
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
else
if
(
xMBMasterRunResTake
(
lTimeOut
)
==
FALSE
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
...
...
@@ -93,6 +103,8 @@ eMBMasterReqReadCoils( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usNCoils )
ucMBFrame
[
MB_PDU_REQ_READ_COILCNT_OFF
+
1
]
=
usNCoils
;
vMBMasterSetPDUSndLength
(
MB_PDU_SIZE_MIN
+
MB_PDU_REQ_READ_SIZE
);
(
void
)
xMBMasterPortEventPost
(
EV_MASTER_FRAME_SENT
);
eErrStatus
=
eMBMasterWaitRequestFinish
(
);
}
return
eErrStatus
;
}
...
...
@@ -108,7 +120,12 @@ eMBMasterFuncReadCoils( UCHAR * pucFrame, USHORT * usLen )
eMBException
eStatus
=
MB_EX_NONE
;
eMBErrorCode
eRegStatus
;
if
(
*
usLen
>=
MB_PDU_SIZE_MIN
+
MB_PDU_FUNC_READ_SIZE_MIN
)
/* If this request is broadcast, and it's read mode. This request don't need execute. */
if
(
xMBMasterRequestIsBroadcast
()
)
{
eStatus
=
MB_EX_NONE
;
}
else
if
(
*
usLen
>=
MB_PDU_SIZE_MIN
+
MB_PDU_FUNC_READ_SIZE_MIN
)
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
usRegAddress
=
(
USHORT
)(
ucMBFrame
[
MB_PDU_REQ_READ_ADDR_OFF
]
<<
8
);
...
...
@@ -136,7 +153,7 @@ eMBMasterFuncReadCoils( UCHAR * pucFrame, USHORT * usLen )
(
ucByteCount
==
pucFrame
[
MB_PDU_FUNC_READ_COILCNT_OFF
]
)
)
{
/* Make callback to fill the buffer. */
eRegStatus
=
eMBRegCoilsCB
(
&
pucFrame
[
MB_PDU_FUNC_READ_VALUES_OFF
],
usRegAddress
,
usCoilCount
,
MB_REG_READ
);
eRegStatus
=
eMB
Master
RegCoilsCB
(
&
pucFrame
[
MB_PDU_FUNC_READ_VALUES_OFF
],
usRegAddress
,
usCoilCount
,
MB_REG_READ
);
/* If an error occured convert it into a Modbus exception. */
if
(
eRegStatus
!=
MB_ENOERR
)
...
...
@@ -161,15 +178,27 @@ eMBMasterFuncReadCoils( UCHAR * pucFrame, USHORT * usLen )
#if MB_FUNC_WRITE_COIL_ENABLED > 0
/**
* This function will request write one coil.
*
* @param ucSndAddr salve address
* @param usCoilAddr coil start address
* @param usCoilData data to be written
* @param lTimeOut timeout (-1 will waiting forever)
*
* @return error code
*
* @see eMBMasterReqWriteMultipleCoils
*/
eMBMasterReqErrCode
eMBMasterReqWriteCoil
(
UCHAR
ucSndAddr
,
USHORT
usCoilAddr
,
USHORT
usCoilData
)
eMBMasterReqWriteCoil
(
UCHAR
ucSndAddr
,
USHORT
usCoilAddr
,
USHORT
usCoilData
,
LONG
lTimeOut
)
{
UCHAR
*
ucMBFrame
;
eMBMasterReqErrCode
eErrStatus
=
MB_MRE_NO_ERR
;
if
(
xMBMasterGetIsBusy
()
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
if
(
usCoilAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
if
(
usCoilAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
else
if
(
(
usCoilData
!=
0xFF00
)
&&
(
usCoilData
!=
0x0000
)
)
eErrStatus
=
MB_MRE_ILL_ARG
;
else
if
(
xMBMasterRunResTake
(
lTimeOut
)
==
FALSE
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
...
...
@@ -181,6 +210,7 @@ eMBMasterReqWriteCoil( UCHAR ucSndAddr, USHORT usCoilAddr, USHORT usCoilData )
ucMBFrame
[
MB_PDU_REQ_WRITE_VALUE_OFF
+
1
]
=
usCoilData
;
vMBMasterSetPDUSndLength
(
MB_PDU_SIZE_MIN
+
MB_PDU_REQ_WRITE_SIZE
);
(
void
)
xMBMasterPortEventPost
(
EV_MASTER_FRAME_SENT
);
eErrStatus
=
eMBMasterWaitRequestFinish
(
);
}
return
eErrStatus
;
}
...
...
@@ -214,7 +244,7 @@ eMBMasterFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen )
ucBuf
[
0
]
=
0
;
}
eRegStatus
=
eMBRegCoilsCB
(
&
ucBuf
[
0
],
usRegAddress
,
1
,
MB_REG_WRITE
);
eMB
Master
RegCoilsCB
(
&
ucBuf
[
0
],
usRegAddress
,
1
,
MB_REG_WRITE
);
/* If an error occured convert it into a Modbus exception. */
if
(
eRegStatus
!=
MB_ENOERR
)
...
...
@@ -240,18 +270,31 @@ eMBMasterFuncWriteCoil( UCHAR * pucFrame, USHORT * usLen )
#if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
/**
* This function will request write multiple coils.
*
* @param ucSndAddr salve address
* @param usCoilAddr coil start address
* @param usNCoils coil total number
* @param usCoilData data to be written
* @param lTimeOut timeout (-1 will waiting forever)
*
* @return error code
*
* @see eMBMasterReqWriteCoil
*/
eMBMasterReqErrCode
eMBMasterReqWriteMultipleCoils
(
UCHAR
ucSndAddr
,
USHORT
usCoilAddr
,
USHORT
usNCoils
,
UCHAR
*
pucDataBuffer
)
USHORT
usCoilAddr
,
USHORT
usNCoils
,
UCHAR
*
pucDataBuffer
,
LONG
lTimeOut
)
{
UCHAR
*
ucMBFrame
;
USHORT
usRegIndex
=
0
;
UCHAR
ucByteCount
;
eMBMasterReqErrCode
eErrStatus
=
MB_MRE_NO_ERR
;
if
(
xMBMasterGetIsBusy
()
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
else
if
(
usNCoils
>
MB_PDU_REQ_WRITE_MUL_COILCNT_MAX
)
eErrStatus
=
MB_MRE_ILL_ARG
;
else
if
(
xMBMasterRunResTake
(
lTimeOut
)
==
FALSE
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
...
...
@@ -277,6 +320,7 @@ eMBMasterReqWriteMultipleCoils( UCHAR ucSndAddr,
}
vMBMasterSetPDUSndLength
(
MB_PDU_SIZE_MIN
+
MB_PDU_REQ_WRITE_MUL_SIZE_MIN
+
ucByteCount
);
(
void
)
xMBMasterPortEventPost
(
EV_MASTER_FRAME_SENT
);
eErrStatus
=
eMBMasterWaitRequestFinish
(
);
}
return
eErrStatus
;
}
...
...
@@ -293,7 +337,8 @@ eMBMasterFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen )
eMBException
eStatus
=
MB_EX_NONE
;
eMBErrorCode
eRegStatus
;
if
(
*
usLen
==
MB_PDU_FUNC_WRITE_MUL_SIZE
)
/* If this request is broadcast, the *usLen is not need check. */
if
(
(
*
usLen
==
MB_PDU_FUNC_WRITE_MUL_SIZE
)
||
xMBMasterRequestIsBroadcast
()
)
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
usRegAddress
=
(
USHORT
)(
pucFrame
[
MB_PDU_FUNC_WRITE_MUL_ADDR_OFF
]
<<
8
);
...
...
@@ -318,7 +363,7 @@ eMBMasterFuncWriteMultipleCoils( UCHAR * pucFrame, USHORT * usLen )
if
(
(
usCoilCnt
>=
1
)
&&
(
ucByteCountVerify
==
ucByteCount
)
)
{
eRegStatus
=
eMBRegCoilsCB
(
&
ucMBFrame
[
MB_PDU_REQ_WRITE_MUL_VALUES_OFF
],
eMB
Master
RegCoilsCB
(
&
ucMBFrame
[
MB_PDU_REQ_WRITE_MUL_VALUES_OFF
],
usRegAddress
,
usCoilCnt
,
MB_REG_WRITE
);
/* If an error occured convert it into a Modbus exception. */
...
...
components/net/freemodbus-v1.6.0/modbus/functions/mbfuncdisc_m.c
浏览文件 @
15129278
...
...
@@ -57,16 +57,26 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
/* ----------------------- Start implementation -----------------------------*/
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
#if MB_FUNC_READ_
COIL
S_ENABLED > 0
#if MB_FUNC_READ_
DISCRETE_INPUT
S_ENABLED > 0
/**
* This function will request read discrete inputs.
*
* @param ucSndAddr salve address
* @param usDiscreteAddr discrete start address
* @param usNDiscreteIn discrete total number
* @param lTimeOut timeout (-1 will waiting forever)
*
* @return error code
*/
eMBMasterReqErrCode
eMBMasterReqReadDiscreteInputs
(
UCHAR
ucSndAddr
,
USHORT
usDiscreteAddr
,
USHORT
usNDiscreteIn
)
eMBMasterReqReadDiscreteInputs
(
UCHAR
ucSndAddr
,
USHORT
usDiscreteAddr
,
USHORT
usNDiscreteIn
,
LONG
lTimeOut
)
{
UCHAR
*
ucMBFrame
;
eMBMasterReqErrCode
eErrStatus
=
MB_MRE_NO_ERR
;
if
(
xMBMasterGetIsBusy
()
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
else
if
(
xMBMasterRunResTake
(
lTimeOut
)
==
FALSE
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
...
...
@@ -78,6 +88,7 @@ eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT u
ucMBFrame
[
MB_PDU_REQ_READ_DISCCNT_OFF
+
1
]
=
usNDiscreteIn
;
vMBMasterSetPDUSndLength
(
MB_PDU_SIZE_MIN
+
MB_PDU_REQ_READ_SIZE
);
(
void
)
xMBMasterPortEventPost
(
EV_MASTER_FRAME_SENT
);
eErrStatus
=
eMBMasterWaitRequestFinish
(
);
}
return
eErrStatus
;
}
...
...
@@ -93,7 +104,12 @@ eMBMasterFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen )
eMBException
eStatus
=
MB_EX_NONE
;
eMBErrorCode
eRegStatus
;
if
(
*
usLen
>=
MB_PDU_SIZE_MIN
+
MB_PDU_FUNC_READ_SIZE_MIN
)
/* If this request is broadcast, and it's read mode. This request don't need execute. */
if
(
xMBMasterRequestIsBroadcast
()
)
{
eStatus
=
MB_EX_NONE
;
}
else
if
(
*
usLen
>=
MB_PDU_SIZE_MIN
+
MB_PDU_FUNC_READ_SIZE_MIN
)
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
usRegAddress
=
(
USHORT
)(
ucMBFrame
[
MB_PDU_REQ_READ_ADDR_OFF
]
<<
8
);
...
...
@@ -120,7 +136,7 @@ eMBMasterFuncReadDiscreteInputs( UCHAR * pucFrame, USHORT * usLen )
if
((
usDiscreteCnt
>=
1
)
&&
ucNBytes
==
pucFrame
[
MB_PDU_FUNC_READ_DISCCNT_OFF
])
{
/* Make callback to fill the buffer. */
eRegStatus
=
eMBRegDiscreteCB
(
&
pucFrame
[
MB_PDU_FUNC_READ_VALUES_OFF
],
usRegAddress
,
usDiscreteCnt
);
eRegStatus
=
eMB
Master
RegDiscreteCB
(
&
pucFrame
[
MB_PDU_FUNC_READ_VALUES_OFF
],
usRegAddress
,
usDiscreteCnt
);
/* If an error occured convert it into a Modbus exception. */
if
(
eRegStatus
!=
MB_ENOERR
)
...
...
components/net/freemodbus-v1.6.0/modbus/functions/mbfuncholding_m.c
浏览文件 @
15129278
...
...
@@ -86,14 +86,24 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
#if MB_FUNC_WRITE_HOLDING_ENABLED > 0
/**
* This function will request write holding register.
*
* @param ucSndAddr salve address
* @param usRegAddr register start address
* @param usRegData register data to be written
* @param lTimeOut timeout (-1 will waiting forever)
*
* @return error code
*/
eMBMasterReqErrCode
eMBMasterReqWriteHoldingRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usRegData
)
eMBMasterReqWriteHoldingRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usRegData
,
LONG
lTimeOut
)
{
UCHAR
*
ucMBFrame
;
eMBMasterReqErrCode
eErrStatus
=
MB_MRE_NO_ERR
;
if
(
xMBMasterGetIsBusy
()
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
else
if
(
xMBMasterRunResTake
(
lTimeOut
)
==
FALSE
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
...
...
@@ -105,6 +115,7 @@ eMBMasterReqWriteHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRe
ucMBFrame
[
MB_PDU_REQ_WRITE_VALUE_OFF
+
1
]
=
usRegData
;
vMBMasterSetPDUSndLength
(
MB_PDU_SIZE_MIN
+
MB_PDU_REQ_WRITE_SIZE
);
(
void
)
xMBMasterPortEventPost
(
EV_MASTER_FRAME_SENT
);
eErrStatus
=
eMBMasterWaitRequestFinish
(
);
}
return
eErrStatus
;
}
...
...
@@ -123,7 +134,7 @@ eMBMasterFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
usRegAddress
++
;
/* Make callback to update the value. */
eRegStatus
=
eMBRegHoldingCB
(
&
pucFrame
[
MB_PDU_FUNC_WRITE_VALUE_OFF
],
eRegStatus
=
eMB
Master
RegHoldingCB
(
&
pucFrame
[
MB_PDU_FUNC_WRITE_VALUE_OFF
],
usRegAddress
,
1
,
MB_REG_WRITE
);
/* If an error occured convert it into a Modbus exception. */
...
...
@@ -143,16 +154,27 @@ eMBMasterFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
#if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
/**
* This function will request write multiple holding register.
*
* @param ucSndAddr salve address
* @param usRegAddr register start address
* @param usNRegs register total number
* @param pusDataBuffer data to be written
* @param lTimeOut timeout (-1 will waiting forever)
*
* @return error code
*/
eMBMasterReqErrCode
eMBMasterReqWriteMultipleHoldingRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usNRegs
,
USHORT
*
pusDataBuffer
)
USHORT
usRegAddr
,
USHORT
usNRegs
,
USHORT
*
pusDataBuffer
,
LONG
lTimeOut
)
{
UCHAR
*
ucMBFrame
;
USHORT
usRegIndex
=
0
;
eMBMasterReqErrCode
eErrStatus
=
MB_MRE_NO_ERR
;
if
(
xMBMasterGetIsBusy
()
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
else
if
(
xMBMasterRunResTake
(
lTimeOut
)
==
FALSE
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
...
...
@@ -171,6 +193,7 @@ eMBMasterReqWriteMultipleHoldingRegister( UCHAR ucSndAddr,
}
vMBMasterSetPDUSndLength
(
MB_PDU_SIZE_MIN
+
MB_PDU_REQ_WRITE_MUL_SIZE_MIN
+
2
*
usNRegs
);
(
void
)
xMBMasterPortEventPost
(
EV_MASTER_FRAME_SENT
);
eErrStatus
=
eMBMasterWaitRequestFinish
(
);
}
return
eErrStatus
;
}
...
...
@@ -186,7 +209,8 @@ eMBMasterFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
eMBException
eStatus
=
MB_EX_NONE
;
eMBErrorCode
eRegStatus
;
if
(
*
usLen
==
MB_PDU_SIZE_MIN
+
MB_PDU_FUNC_WRITE_MUL_SIZE
)
/* If this request is broadcast, the *usLen is not need check. */
if
(
(
*
usLen
==
MB_PDU_SIZE_MIN
+
MB_PDU_FUNC_WRITE_MUL_SIZE
)
||
xMBMasterRequestIsBroadcast
()
)
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
usRegAddress
=
(
USHORT
)(
ucMBFrame
[
MB_PDU_REQ_WRITE_MUL_ADDR_OFF
]
<<
8
);
...
...
@@ -202,7 +226,7 @@ eMBMasterFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
{
/* Make callback to update the register values. */
eRegStatus
=
eMBRegHoldingCB
(
&
ucMBFrame
[
MB_PDU_REQ_WRITE_MUL_VALUES_OFF
],
eMB
Master
RegHoldingCB
(
&
ucMBFrame
[
MB_PDU_REQ_WRITE_MUL_VALUES_OFF
],
usRegAddress
,
usRegCount
,
MB_REG_WRITE
);
/* If an error occured convert it into a Modbus exception. */
...
...
@@ -227,14 +251,24 @@ eMBMasterFuncWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
#if MB_FUNC_READ_HOLDING_ENABLED > 0
/**
* This function will request read holding register.
*
* @param ucSndAddr salve address
* @param usRegAddr register start address
* @param usNRegs register total number
* @param lTimeOut timeout (-1 will waiting forever)
*
* @return error code
*/
eMBMasterReqErrCode
eMBMasterReqReadHoldingRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usNRegs
)
eMBMasterReqReadHoldingRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usNRegs
,
LONG
lTimeOut
)
{
UCHAR
*
ucMBFrame
;
eMBMasterReqErrCode
eErrStatus
=
MB_MRE_NO_ERR
;
if
(
xMBMasterGetIsBusy
()
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
else
if
(
xMBMasterRunResTake
(
lTimeOut
)
==
FALSE
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
...
...
@@ -246,6 +280,7 @@ eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRe
ucMBFrame
[
MB_PDU_REQ_READ_REGCNT_OFF
+
1
]
=
usNRegs
;
vMBMasterSetPDUSndLength
(
MB_PDU_SIZE_MIN
+
MB_PDU_REQ_READ_SIZE
);
(
void
)
xMBMasterPortEventPost
(
EV_MASTER_FRAME_SENT
);
eErrStatus
=
eMBMasterWaitRequestFinish
(
);
}
return
eErrStatus
;
}
...
...
@@ -260,7 +295,12 @@ eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
eMBException
eStatus
=
MB_EX_NONE
;
eMBErrorCode
eRegStatus
;
if
(
*
usLen
>=
MB_PDU_SIZE_MIN
+
MB_PDU_FUNC_READ_SIZE_MIN
)
/* If this request is broadcast, and it's read mode. This request don't need execute. */
if
(
xMBMasterRequestIsBroadcast
()
)
{
eStatus
=
MB_EX_NONE
;
}
else
if
(
*
usLen
>=
MB_PDU_SIZE_MIN
+
MB_PDU_FUNC_READ_SIZE_MIN
)
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
usRegAddress
=
(
USHORT
)(
ucMBFrame
[
MB_PDU_REQ_READ_ADDR_OFF
]
<<
8
);
...
...
@@ -268,7 +308,7 @@ eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
usRegAddress
++
;
usRegCount
=
(
USHORT
)(
ucMBFrame
[
MB_PDU_REQ_READ_REGCNT_OFF
]
<<
8
);
usRegCount
=
(
USHORT
)(
ucMBFrame
[
MB_PDU_REQ_READ_REGCNT_OFF
+
1
]
);
usRegCount
|
=
(
USHORT
)(
ucMBFrame
[
MB_PDU_REQ_READ_REGCNT_OFF
+
1
]
);
/* Check if the number of registers to read is valid. If not
* return Modbus illegal data value exception.
...
...
@@ -276,7 +316,7 @@ eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
if
(
(
usRegCount
>=
1
)
&&
(
2
*
usRegCount
==
pucFrame
[
MB_PDU_FUNC_READ_BYTECNT_OFF
]
)
)
{
/* Make callback to fill the buffer. */
eRegStatus
=
eMBRegHoldingCB
(
&
pucFrame
[
MB_PDU_FUNC_READ_VALUES_OFF
],
usRegAddress
,
usRegCount
,
MB_REG_READ
);
eRegStatus
=
eMB
Master
RegHoldingCB
(
&
pucFrame
[
MB_PDU_FUNC_READ_VALUES_OFF
],
usRegAddress
,
usRegCount
,
MB_REG_READ
);
/* If an error occured convert it into a Modbus exception. */
if
(
eRegStatus
!=
MB_ENOERR
)
{
...
...
@@ -300,17 +340,30 @@ eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )
#if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
/**
* This function will request read and write holding register.
*
* @param ucSndAddr salve address
* @param usReadRegAddr read register start address
* @param usNReadRegs read register total number
* @param pusDataBuffer data to be written
* @param usWriteRegAddr write register start address
* @param usNWriteRegs write register total number
* @param lTimeOut timeout (-1 will waiting forever)
*
* @return error code
*/
eMBMasterReqErrCode
eMBMasterReqReadWriteMultipleHoldingRegister
(
UCHAR
ucSndAddr
,
USHORT
usReadRegAddr
,
USHORT
usNReadRegs
,
USHORT
*
pusDataBuffer
,
USHORT
usWriteRegAddr
,
USHORT
usNWriteRegs
)
USHORT
usWriteRegAddr
,
USHORT
usNWriteRegs
,
LONG
lTimeOut
)
{
UCHAR
*
ucMBFrame
;
USHORT
usRegIndex
=
0
;
eMBMasterReqErrCode
eErrStatus
=
MB_MRE_NO_ERR
;
if
(
xMBMasterGetIsBusy
()
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
else
if
(
xMBMasterRunResTake
(
lTimeOut
)
==
FALSE
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
...
...
@@ -333,6 +386,7 @@ eMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,
}
vMBMasterSetPDUSndLength
(
MB_PDU_SIZE_MIN
+
MB_PDU_REQ_READWRITE_SIZE_MIN
+
2
*
usNWriteRegs
);
(
void
)
xMBMasterPortEventPost
(
EV_MASTER_FRAME_SENT
);
eErrStatus
=
eMBMasterWaitRequestFinish
(
);
}
return
eErrStatus
;
}
...
...
@@ -349,7 +403,12 @@ eMBMasterFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen
eMBException
eStatus
=
MB_EX_NONE
;
eMBErrorCode
eRegStatus
;
if
(
*
usLen
>=
MB_PDU_SIZE_MIN
+
MB_PDU_FUNC_READWRITE_SIZE_MIN
)
/* If this request is broadcast, and it's read mode. This request don't need execute. */
if
(
xMBMasterRequestIsBroadcast
()
)
{
eStatus
=
MB_EX_NONE
;
}
else
if
(
*
usLen
>=
MB_PDU_SIZE_MIN
+
MB_PDU_FUNC_READWRITE_SIZE_MIN
)
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
usRegReadAddress
=
(
USHORT
)(
ucMBFrame
[
MB_PDU_REQ_READWRITE_READ_ADDR_OFF
]
<<
8U
);
...
...
@@ -369,13 +428,13 @@ eMBMasterFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen
if
(
(
2
*
usRegReadCount
)
==
pucFrame
[
MB_PDU_FUNC_READWRITE_READ_BYTECNT_OFF
]
)
{
/* Make callback to update the register values. */
eRegStatus
=
eMBRegHoldingCB
(
&
ucMBFrame
[
MB_PDU_REQ_READWRITE_WRITE_VALUES_OFF
],
eRegStatus
=
eMB
Master
RegHoldingCB
(
&
ucMBFrame
[
MB_PDU_REQ_READWRITE_WRITE_VALUES_OFF
],
usRegWriteAddress
,
usRegWriteCount
,
MB_REG_WRITE
);
if
(
eRegStatus
==
MB_ENOERR
)
{
/* Make the read callback. */
eRegStatus
=
eMBRegHoldingCB
(
&
pucFrame
[
MB_PDU_FUNC_READWRITE_READ_VALUES_OFF
],
eRegStatus
=
eMB
Master
RegHoldingCB
(
&
pucFrame
[
MB_PDU_FUNC_READWRITE_READ_VALUES_OFF
],
usRegReadAddress
,
usRegReadCount
,
MB_REG_READ
);
}
if
(
eRegStatus
!=
MB_ENOERR
)
...
...
components/net/freemodbus-v1.6.0/modbus/functions/mbfuncinput_m.c
浏览文件 @
15129278
...
...
@@ -59,14 +59,24 @@ eMBException prveMBError2Exception( eMBErrorCode eErrorCode );
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
#if MB_FUNC_READ_INPUT_ENABLED > 0
/**
* This function will request read input register.
*
* @param ucSndAddr salve address
* @param usRegAddr register start address
* @param usNRegs register total number
* @param lTimeOut timeout (-1 will waiting forever)
*
* @return error code
*/
eMBMasterReqErrCode
eMBMasterReqReadInputRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usNRegs
)
eMBMasterReqReadInputRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usNRegs
,
LONG
lTimeOut
)
{
UCHAR
*
ucMBFrame
;
eMBMasterReqErrCode
eErrStatus
=
MB_MRE_NO_ERR
;
if
(
xMBMasterGetIsBusy
()
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
if
(
ucSndAddr
>
MB_MASTER_TOTAL_SLAVE_NUM
)
eErrStatus
=
MB_MRE_ILL_ARG
;
else
if
(
xMBMasterRunResTake
(
lTimeOut
)
==
FALSE
)
eErrStatus
=
MB_MRE_MASTER_BUSY
;
else
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
...
...
@@ -78,6 +88,7 @@ eMBMasterReqReadInputRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs
ucMBFrame
[
MB_PDU_REQ_READ_REGCNT_OFF
+
1
]
=
usNRegs
;
vMBMasterSetPDUSndLength
(
MB_PDU_SIZE_MIN
+
MB_PDU_REQ_READ_SIZE
);
(
void
)
xMBMasterPortEventPost
(
EV_MASTER_FRAME_SENT
);
eErrStatus
=
eMBMasterWaitRequestFinish
(
);
}
return
eErrStatus
;
}
...
...
@@ -92,7 +103,12 @@ eMBMasterFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen )
eMBException
eStatus
=
MB_EX_NONE
;
eMBErrorCode
eRegStatus
;
if
(
*
usLen
>=
MB_PDU_SIZE_MIN
+
MB_PDU_FUNC_READ_SIZE_MIN
)
/* If this request is broadcast, and it's read mode. This request don't need execute. */
if
(
xMBMasterRequestIsBroadcast
()
)
{
eStatus
=
MB_EX_NONE
;
}
else
if
(
*
usLen
>=
MB_PDU_SIZE_MIN
+
MB_PDU_FUNC_READ_SIZE_MIN
)
{
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
usRegAddress
=
(
USHORT
)(
ucMBFrame
[
MB_PDU_REQ_READ_ADDR_OFF
]
<<
8
);
...
...
@@ -100,7 +116,7 @@ eMBMasterFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen )
usRegAddress
++
;
usRegCount
=
(
USHORT
)(
ucMBFrame
[
MB_PDU_REQ_READ_REGCNT_OFF
]
<<
8
);
usRegCount
=
(
USHORT
)(
ucMBFrame
[
MB_PDU_REQ_READ_REGCNT_OFF
+
1
]
);
usRegCount
|
=
(
USHORT
)(
ucMBFrame
[
MB_PDU_REQ_READ_REGCNT_OFF
+
1
]
);
/* Check if the number of registers to read is valid. If not
* return Modbus illegal data value exception.
...
...
@@ -108,7 +124,7 @@ eMBMasterFuncReadInputRegister( UCHAR * pucFrame, USHORT * usLen )
if
(
(
usRegCount
>=
1
)
&&
(
2
*
usRegCount
==
pucFrame
[
MB_PDU_FUNC_READ_BYTECNT_OFF
]
)
)
{
/* Make callback to fill the buffer. */
eRegStatus
=
eMBRegInputCB
(
&
pucFrame
[
MB_PDU_FUNC_READ_VALUES_OFF
],
usRegAddress
,
usRegCount
);
eRegStatus
=
eMB
Master
RegInputCB
(
&
pucFrame
[
MB_PDU_FUNC_READ_VALUES_OFF
],
usRegAddress
,
usRegCount
);
/* If an error occured convert it into a Modbus exception. */
if
(
eRegStatus
!=
MB_ENOERR
)
{
...
...
components/net/freemodbus-v1.6.0/modbus/include/mb_m.h
浏览文件 @
15129278
...
...
@@ -77,13 +77,10 @@ typedef enum
MB_MRE_NO_ERR
,
/*!< no error. */
MB_MRE_NO_REG
,
/*!< illegal register address. */
MB_MRE_ILL_ARG
,
/*!< illegal argument. */
MB_MRE_PORT_ERR
,
/*!< porting layer error. */
MB_MRE_NO_RES
,
/*!< insufficient resources. */
MB_MRE_IO
,
/*!< I/O error. */
MB_MRE_ILL_STATE
,
/*!< protocol stack in illegal state. */
MB_MRE_REV_DATA
,
/*!< receive data error. */
MB_MRE_TIMEDOUT
,
/*!< timeout error occurred. */
MB_MRE_MASTER_BUSY
,
/*!< master is busy now. */
MB_MRE_
SLAVE_EXCE
/*!< slave has exception
. */
MB_MRE_
EXE_FUN
/*!< execute function error
. */
}
eMBMasterReqErrCode
;
/*! \ingroup modbus
* \brief TimerMode is Master 3 kind of Timer modes.
...
...
@@ -189,31 +186,176 @@ eMBErrorCode eMBMasterDisable( void );
*/
eMBErrorCode
eMBMasterPoll
(
void
);
/*! \ingroup modbus
* \brief Registers a callback handler for a given function code.
*
* This function registers a new callback handler for a given function code.
* The callback handler supplied is responsible for interpreting the Modbus PDU and
* the creation of an appropriate response. In case of an error it should return
* one of the possible Modbus exceptions which results in a Modbus exception frame
* sent by the protocol stack.
*
* \param ucFunctionCode The Modbus function code for which this handler should
* be registers. Valid function codes are in the range 1 to 127.
* \param pxHandler The function handler which should be called in case
* such a frame is received. If \c NULL a previously registered function handler
* for this function code is removed.
*
* \return eMBErrorCode::MB_ENOERR if the handler has been installed. If no
* more resources are available it returns eMBErrorCode::MB_ENORES. In this
* case the values in mbconfig.h should be adjusted. If the argument was not
* valid it returns eMBErrorCode::MB_EINVAL.
*/
eMBErrorCode
eMBMasterRegisterCB
(
UCHAR
ucFunctionCode
,
pxMBFunctionHandler
pxHandler
);
/* ----------------------- Callback -----------------------------------------*/
/*! \defgroup modbus_master registers Modbus Registers
* \code #include "mb_m.h" \endcode
* The protocol stack does not internally allocate any memory for the
* registers. This makes the protocol stack very small and also usable on
* low end targets. In addition the values don't have to be in the memory
* and could for example be stored in a flash.<br>
* Whenever the protocol stack requires a value it calls one of the callback
* function with the register address and the number of registers to read
* as an argument. The application should then read the actual register values
* (for example the ADC voltage) and should store the result in the supplied
* buffer.<br>
* If the protocol stack wants to update a register value because a write
* register function was received a buffer with the new register values is
* passed to the callback function. The function should then use these values
* to update the application register values.
*/
/*! \ingroup modbus_registers
* \brief Callback function used if the value of a <em>Input Register</em>
* is required by the protocol stack. The starting register address is given
* by \c usAddress and the last register is given by <tt>usAddress +
* usNRegs - 1</tt>.
*
* \param pucRegBuffer A buffer where the callback function should write
* the current value of the modbus registers to.
* \param usAddress The starting address of the register. Input registers
* are in the range 1 - 65535.
* \param usNRegs Number of registers the callback function must supply.
*
* \return The function must return one of the following error codes:
* - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
* Modbus response is sent.
* - eMBErrorCode::MB_ENOREG If the application does not map an coils
* within the requested address range. In this case a
* <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
*/
eMBErrorCode
eMBMasterRegInputCB
(
UCHAR
*
pucRegBuffer
,
USHORT
usAddress
,
USHORT
usNRegs
);
/*! \ingroup modbus_registers
* \brief Callback function used if a <em>Holding Register</em> value is
* read or written by the protocol stack. The starting register address
* is given by \c usAddress and the last register is given by
* <tt>usAddress + usNRegs - 1</tt>.
*
* \param pucRegBuffer If the application registers values should be updated the
* buffer points to the new registers values. If the protocol stack needs
* to now the current values the callback function should write them into
* this buffer.
* \param usAddress The starting address of the register.
* \param usNRegs Number of registers to read or write.
* \param eMode If eMBRegisterMode::MB_REG_WRITE the application register
* values should be updated from the values in the buffer. For example
* this would be the case when the Modbus master has issued an
* <b>WRITE SINGLE REGISTER</b> command.
* If the value eMBRegisterMode::MB_REG_READ the application should copy
* the current values into the buffer \c pucRegBuffer.
*
* \return The function must return one of the following error codes:
* - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
* Modbus response is sent.
* - eMBErrorCode::MB_ENOREG If the application does not map an coils
* within the requested address range. In this case a
* <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
*/
eMBErrorCode
eMBMasterRegHoldingCB
(
UCHAR
*
pucRegBuffer
,
USHORT
usAddress
,
USHORT
usNRegs
,
eMBRegisterMode
eMode
);
/*! \ingroup modbus_registers
* \brief Callback function used if a <em>Coil Register</em> value is
* read or written by the protocol stack. If you are going to use
* this function you might use the functions xMBUtilSetBits( ) and
* xMBUtilGetBits( ) for working with bitfields.
*
* \param pucRegBuffer The bits are packed in bytes where the first coil
* starting at address \c usAddress is stored in the LSB of the
* first byte in the buffer <code>pucRegBuffer</code>.
* If the buffer should be written by the callback function unused
* coil values (I.e. if not a multiple of eight coils is used) should be set
* to zero.
* \param usAddress The first coil number.
* \param usNCoils Number of coil values requested.
* \param eMode If eMBRegisterMode::MB_REG_WRITE the application values should
* be updated from the values supplied in the buffer \c pucRegBuffer.
* If eMBRegisterMode::MB_REG_READ the application should store the current
* values in the buffer \c pucRegBuffer.
*
* \return The function must return one of the following error codes:
* - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
* Modbus response is sent.
* - eMBErrorCode::MB_ENOREG If the application does not map an coils
* within the requested address range. In this case a
* <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
*/
eMBErrorCode
eMBMasterRegCoilsCB
(
UCHAR
*
pucRegBuffer
,
USHORT
usAddress
,
USHORT
usNCoils
,
eMBRegisterMode
eMode
);
/*! \ingroup modbus_registers
* \brief Callback function used if a <em>Input Discrete Register</em> value is
* read by the protocol stack.
*
* If you are going to use his function you might use the functions
* xMBUtilSetBits( ) and xMBUtilGetBits( ) for working with bitfields.
*
* \param pucRegBuffer The buffer should be updated with the current
* coil values. The first discrete input starting at \c usAddress must be
* stored at the LSB of the first byte in the buffer. If the requested number
* is not a multiple of eight the remaining bits should be set to zero.
* \param usAddress The starting address of the first discrete input.
* \param usNDiscrete Number of discrete input values.
* \return The function must return one of the following error codes:
* - eMBErrorCode::MB_ENOERR If no error occurred. In this case a normal
* Modbus response is sent.
* - eMBErrorCode::MB_ENOREG If the application does not map an coils
* within the requested address range. In this case a
* <b>ILLEGAL DATA ADDRESS</b> is sent as a response.
*/
eMBErrorCode
eMBMasterRegDiscreteCB
(
UCHAR
*
pucRegBuffer
,
USHORT
usAddress
,
USHORT
usNDiscrete
);
/*! \ingroup modbus
*\brief These Modbus functions are called for user when Modbus run in Master Mode.
*/
eMBMasterReqErrCode
eMBMasterReqReadInputRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usNRegs
);
eMBMasterReqReadInputRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usNRegs
,
LONG
lTimeOut
);
eMBMasterReqErrCode
eMBMasterReqWriteHoldingRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usRegData
);
eMBMasterReqWriteHoldingRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usRegData
,
LONG
lTimeOut
);
eMBMasterReqErrCode
eMBMasterReqWriteMultipleHoldingRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usNRegs
,
USHORT
*
pusDataBuffer
);
eMBMasterReqWriteMultipleHoldingRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usNRegs
,
USHORT
*
pusDataBuffer
,
LONG
lTimeOut
);
eMBMasterReqErrCode
eMBMasterReqReadHoldingRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usNRegs
);
eMBMasterReqReadHoldingRegister
(
UCHAR
ucSndAddr
,
USHORT
usRegAddr
,
USHORT
usNRegs
,
LONG
lTimeOut
);
eMBMasterReqErrCode
eMBMasterReqReadWriteMultipleHoldingRegister
(
UCHAR
ucSndAddr
,
USHORT
usReadRegAddr
,
USHORT
usNReadRegs
,
USHORT
*
pusDataBuffer
,
USHORT
usWriteRegAddr
,
USHORT
usNWriteRegs
);
USHORT
usWriteRegAddr
,
USHORT
usNWriteRegs
,
LONG
lTimeOut
);
eMBMasterReqErrCode
eMBMasterReqReadCoils
(
UCHAR
ucSndAddr
,
USHORT
usCoilAddr
,
USHORT
usNCoils
);
eMBMasterReqReadCoils
(
UCHAR
ucSndAddr
,
USHORT
usCoilAddr
,
USHORT
usNCoils
,
LONG
lTimeOut
);
eMBMasterReqErrCode
eMBMasterReqWriteCoil
(
UCHAR
ucSndAddr
,
USHORT
usCoilAddr
,
USHORT
usCoilData
);
eMBMasterReqWriteCoil
(
UCHAR
ucSndAddr
,
USHORT
usCoilAddr
,
USHORT
usCoilData
,
LONG
lTimeOut
);
eMBMasterReqErrCode
eMBMasterReqWriteMultipleCoils
(
UCHAR
ucSndAddr
,
USHORT
usCoilAddr
,
USHORT
usNCoils
,
UCHAR
*
pucDataBuffer
);
USHORT
usCoilAddr
,
USHORT
usNCoils
,
UCHAR
*
pucDataBuffer
,
LONG
lTimeOut
);
eMBMasterReqErrCode
eMBMasterReqReadDiscreteInputs
(
UCHAR
ucSndAddr
,
USHORT
usDiscreteAddr
,
USHORT
usNDiscreteIn
);
eMBMasterReqReadDiscreteInputs
(
UCHAR
ucSndAddr
,
USHORT
usDiscreteAddr
,
USHORT
usNDiscreteIn
,
LONG
lTimeOut
);
eMBException
eMBMasterFuncReportSlaveID
(
UCHAR
*
pucFrame
,
USHORT
*
usLen
);
...
...
@@ -239,16 +381,18 @@ eMBMasterFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen
/*£¡ \ingroup modbus
*\brief These functions are interface for Modbus Master
*/
BOOL
xMBMasterGetIsBusy
(
void
);
void
vMBMasterGetPDUSndBuf
(
UCHAR
**
pucFrame
);
UCHAR
ucMBMasterGetDestAddress
(
void
);
void
vMBMasterSetDestAddress
(
UCHAR
Address
);
void
vMBMasterSetIsBusy
(
BOOL
IsBusy
);
BOOL
xMBMasterGetCBRunInMasterMode
(
void
);
void
vMBMasterSetCBRunInMasterMode
(
BOOL
IsMasterMode
);
U
CHAR
uc
MBMasterGetPDUSndLength
(
void
);
void
vMBMasterSetPDUSndLength
(
U
CHAR
SendPDULength
);
U
SHORT
us
MBMasterGetPDUSndLength
(
void
);
void
vMBMasterSetPDUSndLength
(
U
SHORT
SendPDULength
);
void
vMBMasterSetCurTimerMode
(
eMBMasterTimerMode
eMBTimerMode
);
BOOL
xMBMasterRequestIsBroadcast
(
void
);
eMBMasterErrorEventType
eMBMasterGetErrorType
(
void
);
void
vMBMasterSetErrorType
(
eMBMasterErrorEventType
errorType
);
eMBMasterReqErrCode
eMBMasterWaitRequestFinish
(
void
);
/* ----------------------- Callback -----------------------------------------*/
...
...
components/net/freemodbus-v1.6.0/modbus/include/mbconfig.h
浏览文件 @
15129278
...
...
@@ -115,9 +115,9 @@ PR_BEGIN_EXTERN_C
/*! \brief If master send a frame which is not broadcast,the master will wait sometime for slave.
* And if slave is not respond in this time,the master will process this timeout error.
* Then master can send other frame */
#define MB_MASTER_TIMEOUT_MS_RESPOND (
2000
)
/*! \brief The total slaves in Modbus Master system.Default 16.
*
Note : The slave ID must be continuous from 0
.*/
#define MB_MASTER_TIMEOUT_MS_RESPOND (
100
)
/*! \brief The total slaves in Modbus Master system.
Default 16.
*
\note : The slave ID must be continuous from 1
.*/
#define MB_MASTER_TOTAL_SLAVE_NUM ( 16 )
#endif
...
...
components/net/freemodbus-v1.6.0/modbus/include/mbport.h
浏览文件 @
15129278
...
...
@@ -36,25 +36,38 @@
PR_BEGIN_EXTERN_C
#endif
/* ----------------------- Defines ------------------------------------------*/
/* ----------------------- Type definitions ---------------------------------*/
typedef
enum
{
EV_READY
,
/*!< Startup finished. */
EV_FRAME_RECEIVED
,
/*!< Frame received. */
EV_EXECUTE
,
/*!< Execute function. */
EV_FRAME_SENT
/*!< Frame sent. */
EV_READY
=
1
<<
0
,
/*!< Startup finished. */
EV_FRAME_RECEIVED
=
1
<<
1
,
/*!< Frame received. */
EV_EXECUTE
=
1
<<
2
,
/*!< Execute function. */
EV_FRAME_SENT
=
1
<<
3
/*!< Frame sent. */
}
eMBEventType
;
typedef
enum
{
EV_MASTER_READY
,
/*!< Startup finished. */
EV_MASTER_FRAME_RECEIVED
,
/*!< Frame received. */
EV_MASTER_EXECUTE
,
/*!< Execute function. */
EV_MASTER_FRAME_SENT
,
/*!< Frame sent. */
EV_MASTER_ERROR_PROCESS
/*!< Frame error process*/
EV_MASTER_READY
=
1
<<
0
,
/*!< Startup finished. */
EV_MASTER_FRAME_RECEIVED
=
1
<<
1
,
/*!< Frame received. */
EV_MASTER_EXECUTE
=
1
<<
2
,
/*!< Execute function. */
EV_MASTER_FRAME_SENT
=
1
<<
3
,
/*!< Frame sent. */
EV_MASTER_ERROR_PROCESS
=
1
<<
4
,
/*!< Frame error process. */
EV_MASTER_PROCESS_SUCESS
=
1
<<
5
,
/*!< Request process success. */
EV_MASTER_ERROR_RESPOND_TIMEOUT
=
1
<<
6
,
/*!< Request respond timeout. */
EV_MASTER_ERROR_RECEIVE_DATA
=
1
<<
7
,
/*!< Request receive data error. */
EV_MASTER_ERROR_EXECUTE_FUNCTION
=
1
<<
8
,
/*!< Request execute function error. */
}
eMBMasterEventType
;
typedef
enum
{
EV_ERROR_RESPOND_TIMEOUT
,
/*!< Slave respond timeout. */
EV_ERROR_RECEIVE_DATA
,
/*!< Receive frame data erroe. */
EV_ERROR_EXECUTE_FUNCTION
,
/*!< Execute function error. */
}
eMBMasterErrorEventType
;
/*! \ingroup modbus
* \brief Parity used for characters in serial mode.
*
...
...
@@ -82,6 +95,12 @@ BOOL xMBMasterPortEventPost( eMBMasterEventType eEvent );
BOOL
xMBMasterPortEventGet
(
/*@out@ */
eMBMasterEventType
*
eEvent
);
void
vMBMasterOsResInit
(
void
);
BOOL
xMBMasterRunResTake
(
int32_t
time
);
void
vMBMasterRunResRelease
(
void
);
/* ----------------------- Serial port functions ----------------------------*/
BOOL
xMBPortSerialInit
(
UCHAR
ucPort
,
ULONG
ulBaudRate
,
...
...
@@ -97,7 +116,6 @@ INLINE BOOL xMBPortSerialGetByte( CHAR * pucByte );
INLINE
BOOL
xMBPortSerialPutByte
(
CHAR
ucByte
);
BOOL
xMBMasterPortSerialInit
(
UCHAR
ucPort
,
ULONG
ulBaudRate
,
UCHAR
ucDataBits
,
eMBParity
eParity
);
...
...
@@ -132,6 +150,18 @@ INLINE void vMBMasterPortTimersRespondTimeoutEnable( void );
INLINE
void
vMBMasterPortTimersDisable
(
void
);
/* ----------------- Callback for the master error process ------------------*/
void
vMBMasterErrorCBRespondTimeout
(
UCHAR
ucDestAddress
,
const
UCHAR
*
pucPDUData
,
USHORT
ucPDULength
);
void
vMBMasterErrorCBReceiveData
(
UCHAR
ucDestAddress
,
const
UCHAR
*
pucPDUData
,
USHORT
ucPDULength
);
void
vMBMasterErrorCBExecuteFunction
(
UCHAR
ucDestAddress
,
const
UCHAR
*
pucPDUData
,
USHORT
ucPDULength
);
void
vMBMasterCBRequestScuuess
(
void
);
/* ----------------------- Callback for the protocol stack ------------------*/
/*!
...
...
components/net/freemodbus-v1.6.0/modbus/mb_m.c
浏览文件 @
15129278
...
...
@@ -65,7 +65,7 @@
static
UCHAR
ucMBMasterDestAddress
;
static
BOOL
xMBRunInMasterMode
=
FALSE
;
static
BOOL
xMasterIsBusy
=
FALSE
;
static
eMBMasterErrorEventType
eMBMasterCurErrorType
;
static
enum
{
...
...
@@ -185,6 +185,8 @@ eMBMasterInit( eMBMode eMode, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity
{
eMBState
=
STATE_DISABLED
;
}
/* initialize the OS resource for modbus master. */
vMBMasterOsResInit
();
}
return
eStatus
;
}
...
...
@@ -257,9 +259,10 @@ eMBMasterPoll( void )
static
USHORT
usLength
;
static
eMBException
eException
;
int
i
;
int
i
,
j
;
eMBErrorCode
eStatus
=
MB_ENOERR
;
eMBMasterEventType
eEvent
;
eMBMasterErrorEventType
errorType
;
/* Check if the protocol stack is ready. */
if
(
eMBState
!=
STATE_ENABLED
)
...
...
@@ -285,6 +288,7 @@ eMBMasterPoll( void )
}
else
{
vMBMasterSetErrorType
(
EV_ERROR_RECEIVE_DATA
);
(
void
)
xMBMasterPortEventPost
(
EV_MASTER_ERROR_PROCESS
);
}
break
;
...
...
@@ -292,52 +296,80 @@ eMBMasterPoll( void )
case
EV_MASTER_EXECUTE
:
ucFunctionCode
=
ucMBFrame
[
MB_PDU_FUNC_OFF
];
eException
=
MB_EX_ILLEGAL_FUNCTION
;
for
(
i
=
0
;
i
<
MB_FUNC_HANDLERS_MAX
;
i
++
)
{
/* No more function handlers registered. Abort. */
if
(
xMasterFuncHandlers
[
i
].
ucFunctionCode
==
0
)
{
break
;
}
else
if
(
xMasterFuncHandlers
[
i
].
ucFunctionCode
==
ucFunctionCode
)
{
vMBMasterSetCBRunInMasterMode
(
TRUE
);
eException
=
xMasterFuncHandlers
[
i
].
pxHandler
(
ucMBFrame
,
&
usLength
);
vMBMasterSetCBRunInMasterMode
(
FALSE
);
break
;
}
}
/* If receive frame has exception .The receive function code highest bit is 1.*/
if
(
ucFunctionCode
>>
7
)
eException
=
(
eMBException
)
ucMBFrame
[
MB_PDU_DATA_OFF
];
if
(
ucFunctionCode
>>
7
)
{
eException
=
(
eMBException
)
ucMBFrame
[
MB_PDU_DATA_OFF
];
}
else
{
for
(
i
=
0
;
i
<
MB_FUNC_HANDLERS_MAX
;
i
++
)
{
/* No more function handlers registered. Abort. */
if
(
xMasterFuncHandlers
[
i
].
ucFunctionCode
==
0
)
{
break
;
}
else
if
(
xMasterFuncHandlers
[
i
].
ucFunctionCode
==
ucFunctionCode
)
{
vMBMasterSetCBRunInMasterMode
(
TRUE
);
/* If master request is broadcast,
* the master need execute function for all slave.
*/
if
(
xMBMasterRequestIsBroadcast
()
)
{
usLength
=
usMBMasterGetPDUSndLength
();
for
(
j
=
1
;
j
<=
MB_MASTER_TOTAL_SLAVE_NUM
;
j
++
){
vMBMasterSetDestAddress
(
j
);
eException
=
xMasterFuncHandlers
[
i
].
pxHandler
(
ucMBFrame
,
&
usLength
);
}
}
else
{
eException
=
xMasterFuncHandlers
[
i
].
pxHandler
(
ucMBFrame
,
&
usLength
);
}
vMBMasterSetCBRunInMasterMode
(
FALSE
);
break
;
}
}
}
/* If master has exception ,Master will send error process.Otherwise the Master is idle.*/
if
(
eException
!=
MB_EX_NONE
)
(
void
)
xMBMasterPortEventPost
(
EV_MASTER_ERROR_PROCESS
);
else
vMBMasterSetIsBusy
(
FALSE
);
if
(
eException
!=
MB_EX_NONE
)
{
vMBMasterSetErrorType
(
EV_ERROR_EXECUTE_FUNCTION
);
(
void
)
xMBMasterPortEventPost
(
EV_MASTER_ERROR_PROCESS
);
}
else
{
vMBMasterCBRequestScuuess
(
);
vMBMasterRunResRelease
(
);
}
break
;
case
EV_MASTER_FRAME_SENT
:
/* Master is busy now. */
vMBMasterSetIsBusy
(
TRUE
);
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
eStatus
=
peMBMasterFrameSendCur
(
ucMBMasterGetDestAddress
(),
ucMBFrame
,
u
c
MBMasterGetPDUSndLength
()
);
eStatus
=
peMBMasterFrameSendCur
(
ucMBMasterGetDestAddress
(),
ucMBFrame
,
u
s
MBMasterGetPDUSndLength
()
);
break
;
case
EV_MASTER_ERROR_PROCESS
:
vMBMasterSetIsBusy
(
FALSE
);
/* Execute specified error process callback function. */
errorType
=
eMBMasterGetErrorType
();
vMBMasterGetPDUSndBuf
(
&
ucMBFrame
);
switch
(
errorType
)
{
case
EV_ERROR_RESPOND_TIMEOUT
:
vMBMasterErrorCBRespondTimeout
(
ucMBMasterGetDestAddress
(),
ucMBFrame
,
usMBMasterGetPDUSndLength
());
break
;
case
EV_ERROR_RECEIVE_DATA
:
vMBMasterErrorCBReceiveData
(
ucMBMasterGetDestAddress
(),
ucMBFrame
,
usMBMasterGetPDUSndLength
());
break
;
case
EV_ERROR_EXECUTE_FUNCTION
:
vMBMasterErrorCBExecuteFunction
(
ucMBMasterGetDestAddress
(),
ucMBFrame
,
usMBMasterGetPDUSndLength
());
break
;
}
vMBMasterRunResRelease
();
break
;
}
}
return
MB_ENOERR
;
}
/* Get whether the Modbus Master is busy.*/
BOOL
xMBMasterGetIsBusy
(
void
)
{
return
xMasterIsBusy
;
}
/* Set whether the Modbus Master is busy.*/
void
vMBMasterSetIsBusy
(
BOOL
IsBusy
)
{
xMasterIsBusy
=
IsBusy
;
}
/* Get whether the Modbus Master is run in master mode.*/
BOOL
xMBMasterGetCBRunInMasterMode
(
void
)
{
...
...
@@ -348,15 +380,27 @@ void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode )
{
xMBRunInMasterMode
=
IsMasterMode
;
}
/* Get Modbus Master send destination address*/
/* Get Modbus Master send destination address
.
*/
UCHAR
ucMBMasterGetDestAddress
(
void
)
{
return
ucMBMasterDestAddress
;
}
/* Set Modbus Master send destination address*/
/* Set Modbus Master send destination address
.
*/
void
vMBMasterSetDestAddress
(
UCHAR
Address
)
{
ucMBMasterDestAddress
=
Address
;
}
/* Get Modbus Master current error event type. */
eMBMasterErrorEventType
eMBMasterGetErrorType
(
void
)
{
return
eMBMasterCurErrorType
;
}
/* Set Modbus Master current error event type. */
void
vMBMasterSetErrorType
(
eMBMasterErrorEventType
errorType
)
{
eMBMasterCurErrorType
=
errorType
;
}
#endif
components/net/freemodbus-v1.6.0/modbus/rtu/mbrtu_m.c
浏览文件 @
15129278
...
...
@@ -74,7 +74,7 @@ static volatile eMBMasterRcvState eRcvState;
static
volatile
UCHAR
ucMasterRTUSndBuf
[
MB_PDU_SIZE_MAX
];
static
volatile
UCHAR
ucMasterRTURcvBuf
[
MB_SER_PDU_SIZE_MAX
];
static
volatile
U
CHAR
uc
MasterSendPDULength
;
static
volatile
U
SHORT
us
MasterSendPDULength
;
static
volatile
UCHAR
*
pucMasterSndBufferCur
;
static
volatile
USHORT
usMasterSndBufferCount
;
...
...
@@ -235,7 +235,7 @@ xMBMasterRTUReceiveFSM( void )
BOOL
xTaskNeedSwitch
=
FALSE
;
UCHAR
ucByte
;
assert_param
(
eSndState
==
STATE_M_TX_IDLE
);
assert_param
(
(
eSndState
==
STATE_M_TX_IDLE
)
||
(
eSndState
==
STATE_M_TX_XFWR
)
);
/* Always read the character. */
(
void
)
xMBMasterPortSerialGetByte
(
(
CHAR
*
)
&
ucByte
);
...
...
@@ -364,12 +364,15 @@ xMBMasterRTUTimerExpired(void)
/* An error occured while receiving the frame. */
case
STATE_M_RX_ERROR
:
vMBMasterSetErrorType
(
EV_ERROR_RECEIVE_DATA
);
xNeedPoll
=
xMBMasterPortEventPost
(
EV_MASTER_ERROR_PROCESS
);
break
;
/* Function called in an illegal state. */
default:
assert_param
(
(
eRcvState
==
STATE_M_RX_INIT
)
||
(
eRcvState
==
STATE_M_RX_RCV
)
||
(
eRcvState
==
STATE_M_RX_ERROR
));
(
eRcvState
==
STATE_M_RX_INIT
)
||
(
eRcvState
==
STATE_M_RX_RCV
)
||
(
eRcvState
==
STATE_M_RX_ERROR
)
||
(
eRcvState
==
STATE_M_RX_IDLE
));
break
;
}
eRcvState
=
STATE_M_RX_IDLE
;
...
...
@@ -380,18 +383,24 @@ xMBMasterRTUTimerExpired(void)
* If the frame is broadcast,The master will idle,and if the frame is not
* broadcast.Notify the listener process error.*/
case
STATE_M_TX_XFWR
:
if
(
xFrameIsBroadcast
==
FALSE
)
xNeedPoll
=
xMBMasterPortEventPost
(
EV_MASTER_ERROR_PROCESS
);
if
(
xFrameIsBroadcast
==
FALSE
)
{
vMBMasterSetErrorType
(
EV_ERROR_RESPOND_TIMEOUT
);
xNeedPoll
=
xMBMasterPortEventPost
(
EV_MASTER_ERROR_PROCESS
);
}
break
;
/* Function called in an illegal state. */
default:
assert_param
(
eSndState
==
STATE_M_TX_XFWR
);
assert_param
(
(
eSndState
==
STATE_M_TX_XFWR
)
||
(
eSndState
==
STATE_M_TX_IDLE
));
break
;
}
eSndState
=
STATE_M_TX_IDLE
;
vMBMasterPortTimersDisable
(
);
/* If timer mode is convert delay ,then Master is idel now. */
if
(
eMasterCurTimerMode
==
MB_TMODE_CONVERT_DELAY
)
vMBMasterSetIsBusy
(
FALSE
);
/* If timer mode is convert delay, the master event then turns EV_MASTER_EXECUTE status. */
if
(
eMasterCurTimerMode
==
MB_TMODE_CONVERT_DELAY
)
{
xNeedPoll
=
xMBMasterPortEventPost
(
EV_MASTER_EXECUTE
);
}
return
xNeedPoll
;
}
...
...
@@ -409,15 +418,15 @@ void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame )
}
/* Set Modbus Master send PDU's buffer length.*/
void
vMBMasterSetPDUSndLength
(
U
CHAR
SendPDULength
)
void
vMBMasterSetPDUSndLength
(
U
SHORT
SendPDULength
)
{
u
c
MasterSendPDULength
=
SendPDULength
;
u
s
MasterSendPDULength
=
SendPDULength
;
}
/* Get Modbus Master send PDU's buffer length.*/
U
CHAR
uc
MBMasterGetPDUSndLength
(
void
)
U
SHORT
us
MBMasterGetPDUSndLength
(
void
)
{
return
u
c
MasterSendPDULength
;
return
u
s
MasterSendPDULength
;
}
/* Set Modbus Master current timer mode.*/
...
...
@@ -425,5 +434,10 @@ void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode )
{
eMasterCurTimerMode
=
eMBTimerMode
;
}
/* The master request is broadcast? */
BOOL
xMBMasterRequestIsBroadcast
(
void
){
return
xFrameIsBroadcast
;
}
#endif
components/net/freemodbus-v1.6.0/port/port.c
浏览文件 @
15129278
/*
* FreeModbus Libary:
LPC214X
Port
* Copyright (C) 20
07 Tiago Prado Lone <tiago@maxwellbohr.com.br
>
* FreeModbus Libary:
RT-Thread
Port
* Copyright (C) 20
13 Armink <armink.ztl@gmail.com
>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -16,7 +16,7 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* File: $Id: port.c,v 1.
1 2007/04/24 23:15:18 wolti Exp
$
* File: $Id: port.c,v 1.
60 2015/02/01 9:18:05 Armink
$
*/
/* ----------------------- System includes --------------------------------*/
...
...
@@ -24,16 +24,15 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "port.h"
/* ----------------------- Variables ----------------------------------------*/
static
rt_base_t
level
;
/* ----------------------- Start implementation -----------------------------*/
void
EnterCriticalSection
(
void
)
{
//关闭全局中断
__disable_irq
();
level
=
rt_hw_interrupt_disable
();
}
void
ExitCriticalSection
(
void
)
{
//开启全局中断
__enable_irq
();
rt_hw_interrupt_enable
(
level
);
}
components/net/freemodbus-v1.6.0/port/port.h
浏览文件 @
15129278
/*
* FreeModbus Libary: BARE Port
* Copyright (C) 20
06 Christian Walter <wolti@sil.at
>
* Copyright (C) 20
13 Armink <armink.ztl@gmail.com
>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -30,22 +30,13 @@
#include <assert.h>
#include <inttypes.h>
#define
INLINE
#define
INLINE
#define PR_BEGIN_EXTERN_C extern "C" {
#define
PR_END_EXTERN_C }
#define
PR_END_EXTERN_C }
//TODO 暂时先写B13引脚,等组网测试时再确认
#define SLAVE_RS485_SEND_MODE GPIO_SetBits(GPIOB,GPIO_Pin_13)
#define SLAVE_RS485_RECEIVE_MODE GPIO_ResetBits(GPIOB,GPIO_Pin_13)
#define MASTER_RS485_SEND_MODE GPIO_SetBits(GPIOB,GPIO_Pin_13)
#define MASTER_RS485_RECEIVE_MODE GPIO_ResetBits(GPIOB,GPIO_Pin_13)
#define ENTER_CRITICAL_SECTION() EnterCriticalSection()
#define ENTER_CRITICAL_SECTION() EnterCriticalSection()
#define EXIT_CRITICAL_SECTION() ExitCriticalSection()
void
EnterCriticalSection
(
void
);
void
ExitCriticalSection
(
void
);
typedef
uint8_t
BOOL
;
typedef
unsigned
char
UCHAR
;
...
...
@@ -65,4 +56,7 @@ typedef int32_t LONG;
#define FALSE 0
#endif
void
EnterCriticalSection
(
void
);
void
ExitCriticalSection
(
void
);
#endif
components/net/freemodbus-v1.6.0/port/portevent.c
浏览文件 @
15129278
/*
* FreeModbus Libary:
STM32
Port
* FreeModbus Libary:
RT-Thread
Port
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* This library is free software; you can redistribute it and/or
...
...
@@ -24,35 +24,45 @@
#include "mbport.h"
/* ----------------------- Variables ----------------------------------------*/
static
eMBEventType
eQueuedEvent
;
static
BOOL
xEventInQueue
;
static
struct
rt_event
xSlaveOsEvent
;
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortEventInit
(
void
)
{
xEventInQueue
=
FALSE
;
rt_event_init
(
&
xSlaveOsEvent
,
"slave event"
,
RT_IPC_FLAG_PRIO
)
;
return
TRUE
;
}
BOOL
xMBPortEventPost
(
eMBEventType
eEvent
)
{
xEventInQueue
=
TRUE
;
eQueuedEvent
=
eEvent
;
rt_event_send
(
&
xSlaveOsEvent
,
eEvent
);
return
TRUE
;
}
BOOL
xMBPortEventGet
(
eMBEventType
*
eEvent
)
{
BOOL
xEventHappened
=
FALSE
;
if
(
xEventInQueue
)
rt_uint32_t
recvedEvent
;
/* waiting forever OS event */
rt_event_recv
(
&
xSlaveOsEvent
,
EV_READY
|
EV_FRAME_RECEIVED
|
EV_EXECUTE
|
EV_FRAME_SENT
,
RT_EVENT_FLAG_OR
|
RT_EVENT_FLAG_CLEAR
,
RT_WAITING_FOREVER
,
&
recvedEvent
);
switch
(
recvedEvent
)
{
*
eEvent
=
eQueuedEvent
;
xEventInQueue
=
FALSE
;
xEventHappened
=
TRUE
;
case
EV_READY
:
*
eEvent
=
EV_READY
;
break
;
case
EV_FRAME_RECEIVED
:
*
eEvent
=
EV_FRAME_RECEIVED
;
break
;
case
EV_EXECUTE
:
*
eEvent
=
EV_EXECUTE
;
break
;
case
EV_FRAME_SENT
:
*
eEvent
=
EV_FRAME_SENT
;
break
;
}
return
xEventHappened
;
return
TRUE
;
}
components/net/freemodbus-v1.6.0/port/portevent_m.c
浏览文件 @
15129278
/*
* FreeModbus Libary:
STM32
Port
* FreeModbus Libary:
RT-Thread
Port
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* This library is free software; you can redistribute it and/or
...
...
@@ -21,41 +21,219 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mb_m.h"
#include "mbport.h"
#include "port.h"
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
/* ----------------------- Defines ------------------------------------------*/
/* ----------------------- Variables ----------------------------------------*/
static
eMBMasterEventType
eMasterQueuedEvent
;
static
BOOL
xMasterEventInQueue
;
static
struct
rt_semaphore
xMasterRunRes
;
static
struct
rt_event
xMasterOsEvent
;
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBMasterPortEventInit
(
void
)
{
xMasterEventInQueue
=
FALSE
;
rt_event_init
(
&
xMasterOsEvent
,
"master event"
,
RT_IPC_FLAG_PRIO
)
;
return
TRUE
;
}
BOOL
xMBMasterPortEventPost
(
eMBMasterEventType
eEvent
)
{
xMasterEventInQueue
=
TRUE
;
eMasterQueuedEvent
=
eEvent
;
rt_event_send
(
&
xMasterOsEvent
,
eEvent
);
return
TRUE
;
}
BOOL
xMBMasterPortEventGet
(
eMBMasterEventType
*
eEvent
)
{
BOOL
xEventHappened
=
FALSE
;
rt_uint32_t
recvedEvent
;
/* waiting forever OS event */
rt_event_recv
(
&
xMasterOsEvent
,
EV_MASTER_READY
|
EV_MASTER_FRAME_RECEIVED
|
EV_MASTER_EXECUTE
|
EV_MASTER_FRAME_SENT
|
EV_MASTER_ERROR_PROCESS
,
RT_EVENT_FLAG_OR
|
RT_EVENT_FLAG_CLEAR
,
RT_WAITING_FOREVER
,
&
recvedEvent
);
/* the enum type couldn't convert to int type */
switch
(
recvedEvent
)
{
case
EV_MASTER_READY
:
*
eEvent
=
EV_MASTER_READY
;
break
;
case
EV_MASTER_FRAME_RECEIVED
:
*
eEvent
=
EV_MASTER_FRAME_RECEIVED
;
break
;
case
EV_MASTER_EXECUTE
:
*
eEvent
=
EV_MASTER_EXECUTE
;
break
;
case
EV_MASTER_FRAME_SENT
:
*
eEvent
=
EV_MASTER_FRAME_SENT
;
break
;
case
EV_MASTER_ERROR_PROCESS
:
*
eEvent
=
EV_MASTER_ERROR_PROCESS
;
break
;
}
return
TRUE
;
}
/**
* This function is initialize the OS resource for modbus master.
* Note:The resource is define by OS.If you not use OS this function can be empty.
*
*/
void
vMBMasterOsResInit
(
void
)
{
rt_sem_init
(
&
xMasterRunRes
,
"master res"
,
0x01
,
RT_IPC_FLAG_PRIO
);
}
/**
* This function is take Mobus Master running resource.
* Note:The resource is define by Operating System.If you not use OS this function can be just return TRUE.
*
* @param lTimeOut the waiting time.
*
* @return resource taked result
*/
BOOL
xMBMasterRunResTake
(
LONG
lTimeOut
)
{
/*If waiting time is -1 .It will wait forever */
return
rt_sem_take
(
&
xMasterRunRes
,
lTimeOut
)
?
FALSE
:
TRUE
;
}
/**
* This function is release Mobus Master running resource.
* Note:The resource is define by Operating System.If you not use OS this function can be empty.
*
*/
void
vMBMasterRunResRelease
(
void
)
{
/* release resource */
rt_sem_release
(
&
xMasterRunRes
);
}
/**
* This is modbus master respond timeout error process callback function.
* @note There functions will block modbus master poll while execute OS waiting.
* So,for real-time of system.Do not execute too much waiting process.
*
* @param ucDestAddress destination salve address
* @param pucPDUData PDU buffer data
* @param ucPDULength PDU buffer length
*
*/
void
vMBMasterErrorCBRespondTimeout
(
UCHAR
ucDestAddress
,
const
UCHAR
*
pucPDUData
,
USHORT
ucPDULength
)
{
/**
* @note This code is use OS's event mechanism for modbus master protocol stack.
* If you don't use OS, you can change it.
*/
rt_event_send
(
&
xMasterOsEvent
,
EV_MASTER_ERROR_RESPOND_TIMEOUT
);
/* You can add your code under here. */
if
(
xMasterEventInQueue
)
}
/**
* This is modbus master receive data error process callback function.
* @note There functions will block modbus master poll while execute OS waiting.
* So,for real-time of system.Do not execute too much waiting process.
*
* @param ucDestAddress destination salve address
* @param pucPDUData PDU buffer data
* @param ucPDULength PDU buffer length
*
*/
void
vMBMasterErrorCBReceiveData
(
UCHAR
ucDestAddress
,
const
UCHAR
*
pucPDUData
,
USHORT
ucPDULength
)
{
/**
* @note This code is use OS's event mechanism for modbus master protocol stack.
* If you don't use OS, you can change it.
*/
rt_event_send
(
&
xMasterOsEvent
,
EV_MASTER_ERROR_RECEIVE_DATA
);
/* You can add your code under here. */
}
/**
* This is modbus master execute function error process callback function.
* @note There functions will block modbus master poll while execute OS waiting.
* So,for real-time of system.Do not execute too much waiting process.
*
* @param ucDestAddress destination salve address
* @param pucPDUData PDU buffer data
* @param ucPDULength PDU buffer length
*
*/
void
vMBMasterErrorCBExecuteFunction
(
UCHAR
ucDestAddress
,
const
UCHAR
*
pucPDUData
,
USHORT
ucPDULength
)
{
/**
* @note This code is use OS's event mechanism for modbus master protocol stack.
* If you don't use OS, you can change it.
*/
rt_event_send
(
&
xMasterOsEvent
,
EV_MASTER_ERROR_EXECUTE_FUNCTION
);
/* You can add your code under here. */
}
/**
* This is modbus master request process success callback function.
* @note There functions will block modbus master poll while execute OS waiting.
* So,for real-time of system.Do not execute too much waiting process.
*
*/
void
vMBMasterCBRequestScuuess
(
void
)
{
/**
* @note This code is use OS's event mechanism for modbus master protocol stack.
* If you don't use OS, you can change it.
*/
rt_event_send
(
&
xMasterOsEvent
,
EV_MASTER_PROCESS_SUCESS
);
/* You can add your code under here. */
}
/**
* This function is wait for modbus master request finish and return result.
* Waiting result include request process success, request respond timeout,
* receive data error and execute function error.You can use the above callback function.
* @note If you are use OS, you can use OS's event mechanism. Otherwise you have to run
* much user custom delay for waiting.
*
* @return request error code
*/
eMBMasterReqErrCode
eMBMasterWaitRequestFinish
(
void
)
{
eMBMasterReqErrCode
eErrStatus
=
MB_MRE_NO_ERR
;
rt_uint32_t
recvedEvent
;
/* waiting for OS event */
rt_event_recv
(
&
xMasterOsEvent
,
EV_MASTER_PROCESS_SUCESS
|
EV_MASTER_ERROR_RESPOND_TIMEOUT
|
EV_MASTER_ERROR_RECEIVE_DATA
|
EV_MASTER_ERROR_EXECUTE_FUNCTION
,
RT_EVENT_FLAG_OR
|
RT_EVENT_FLAG_CLEAR
,
RT_WAITING_FOREVER
,
&
recvedEvent
);
switch
(
recvedEvent
)
{
*
eEvent
=
eMasterQueuedEvent
;
xMasterEventInQueue
=
FALSE
;
xEventHappened
=
TRUE
;
case
EV_MASTER_PROCESS_SUCESS
:
break
;
case
EV_MASTER_ERROR_RESPOND_TIMEOUT
:
{
eErrStatus
=
MB_MRE_TIMEDOUT
;
break
;
}
case
EV_MASTER_ERROR_RECEIVE_DATA
:
{
eErrStatus
=
MB_MRE_REV_DATA
;
break
;
}
case
EV_MASTER_ERROR_EXECUTE_FUNCTION
:
{
eErrStatus
=
MB_MRE_EXE_FUN
;
break
;
}
}
return
xEventHappened
;
return
eErrStatus
;
}
#endif
components/net/freemodbus-v1.6.0/port/portserial.c
浏览文件 @
15129278
/*
* FreeModbus Libary:
STM32
Port
* FreeModbus Libary:
RT-Thread
Port
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* This library is free software; you can redistribute it and/or
...
...
@@ -24,122 +24,148 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
#include "rtdevice.h"
#include "board.h"
/* ----------------------- Static variables ---------------------------------*/
ALIGN
(
RT_ALIGN_SIZE
)
/* software simulation serial transmit IRQ handler thread stack */
static
rt_uint8_t
serial_soft_trans_irq_stack
[
512
];
/* software simulation serial transmit IRQ handler thread */
static
struct
rt_thread
thread_serial_soft_trans_irq
;
/* serial event */
static
struct
rt_event
event_serial
;
/* modbus slave serial device */
static
rt_serial_t
*
serial
;
/* ----------------------- Defines ------------------------------------------*/
/* serial transmit event */
#define EVENT_SERIAL_TRANS_START (1<<0)
/* ----------------------- static functions ---------------------------------*/
static
void
prvvUARTTxReadyISR
(
void
);
static
void
prvvUARTRxISR
(
void
);
static
rt_err_t
serial_rx_ind
(
rt_device_t
dev
,
rt_size_t
size
);
static
void
serial_soft_trans_irq
(
void
*
parameter
);
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortSerialInit
(
UCHAR
ucPORT
,
ULONG
ulBaudRate
,
UCHAR
ucDataBits
,
eMBParity
eParity
)
{
/**
* set 485 mode receive and transmit control IO
* @note MODBUS_SLAVE_RT_CONTROL_PIN_INDEX need be defined by user
*/
rt_pin_mode
(
MODBUS_SLAVE_RT_CONTROL_PIN_INDEX
,
PIN_MODE_OUTPUT
);
/* set serial name */
if
(
ucPORT
==
1
)
{
#if defined(RT_USING_UART1) || defined(RT_USING_REMAP_UART1)
extern
struct
rt_serial_device
serial1
;
serial
=
&
serial1
;
#endif
}
else
if
(
ucPORT
==
2
)
{
#if defined(RT_USING_UART2)
extern
struct
rt_serial_device
serial2
;
serial
=
&
serial2
;
#endif
}
else
if
(
ucPORT
==
3
)
{
#if defined(RT_USING_UART3)
extern
struct
rt_serial_device
serial3
;
serial
=
&
serial3
;
#endif
}
/* set serial configure parameter */
serial
->
config
.
baud_rate
=
ulBaudRate
;
serial
->
config
.
stop_bits
=
STOP_BITS_1
;
switch
(
eParity
){
case
MB_PAR_NONE
:
{
serial
->
config
.
data_bits
=
DATA_BITS_8
;
serial
->
config
.
parity
=
PARITY_NONE
;
break
;
}
case
MB_PAR_ODD
:
{
serial
->
config
.
data_bits
=
DATA_BITS_9
;
serial
->
config
.
parity
=
PARITY_ODD
;
break
;
}
case
MB_PAR_EVEN
:
{
serial
->
config
.
data_bits
=
DATA_BITS_9
;
serial
->
config
.
parity
=
PARITY_EVEN
;
break
;
}
}
/* set serial configure */
serial
->
ops
->
configure
(
serial
,
&
(
serial
->
config
));
/* open serial device */
if
(
!
serial
->
parent
.
open
(
&
serial
->
parent
,
RT_DEVICE_OFLAG_RDWR
|
RT_DEVICE_FLAG_INT_RX
))
{
serial
->
parent
.
rx_indicate
=
serial_rx_ind
;
}
else
{
return
FALSE
;
}
/* software initialize */
rt_thread_init
(
&
thread_serial_soft_trans_irq
,
"slave trans"
,
serial_soft_trans_irq
,
RT_NULL
,
serial_soft_trans_irq_stack
,
sizeof
(
serial_soft_trans_irq_stack
),
10
,
5
);
rt_thread_startup
(
&
thread_serial_soft_trans_irq
);
rt_event_init
(
&
event_serial
,
"slave event"
,
RT_IPC_FLAG_PRIO
);
return
TRUE
;
}
void
vMBPortSerialEnable
(
BOOL
xRxEnable
,
BOOL
xTxEnable
)
{
if
(
xRxEnable
)
{
SLAVE_RS485_RECEIVE_MODE
;
USART_ITConfig
(
USART1
,
USART_IT_RXNE
,
ENABLE
);
}
else
{
SLAVE_RS485_SEND_MODE
;
USART_ITConfig
(
USART1
,
USART_IT_RXNE
,
DISABLE
);
}
if
(
xTxEnable
)
{
USART_ITConfig
(
USART1
,
USART_IT_TXE
,
ENABLE
);
}
else
{
USART_ITConfig
(
USART1
,
USART_IT_TXE
,
DISABLE
);
}
rt_uint32_t
recved_event
;
if
(
xRxEnable
)
{
/* enable RX interrupt */
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_SET_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_RX
);
/* switch 485 to receive mode */
rt_pin_write
(
MODBUS_SLAVE_RT_CONTROL_PIN_INDEX
,
PIN_LOW
);
}
else
{
/* switch 485 to transmit mode */
rt_pin_write
(
MODBUS_SLAVE_RT_CONTROL_PIN_INDEX
,
PIN_HIGH
);
/* disable RX interrupt */
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_CLR_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_RX
);
}
if
(
xTxEnable
)
{
/* start serial transmit */
rt_event_send
(
&
event_serial
,
EVENT_SERIAL_TRANS_START
);
}
else
{
/* stop serial transmit */
rt_event_recv
(
&
event_serial
,
EVENT_SERIAL_TRANS_START
,
RT_EVENT_FLAG_OR
|
RT_EVENT_FLAG_CLEAR
,
0
,
&
recved_event
);
}
}
void
vMBPortClose
(
void
)
{
USART_ITConfig
(
USART1
,
USART_IT_TXE
|
USART_IT_RXNE
,
DISABLE
);
USART_Cmd
(
USART1
,
DISABLE
);
}
//默认一个从机 串口1 波特率可设置 奇偶检验可设置
BOOL
xMBPortSerialInit
(
UCHAR
ucPORT
,
ULONG
ulBaudRate
,
UCHAR
ucDataBits
,
eMBParity
eParity
)
{
GPIO_InitTypeDef
GPIO_InitStructure
;
USART_InitTypeDef
USART_InitStructure
;
NVIC_InitTypeDef
NVIC_InitStructure
;
//======================时钟初始化=======================================
RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_GPIOA
|
RCC_APB2Periph_GPIOB
|
RCC_APB2Periph_USART1
,
ENABLE
);
//======================IO初始化=======================================
//USART1_TX
GPIO_InitStructure
.
GPIO_Speed
=
GPIO_Speed_50MHz
;
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_AF_PP
;
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_9
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStructure
);
//USART1_RX
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_IN_FLOATING
;
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_10
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStructure
);
//配置485发送和接收模式
// TODO 暂时先写B13 等之后组网测试时再修改
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_Out_PP
;
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_13
;
GPIO_Init
(
GPIOB
,
&
GPIO_InitStructure
);
//======================串口初始化=======================================
USART_InitStructure
.
USART_BaudRate
=
ulBaudRate
;
//设置校验模式
switch
(
eParity
)
{
case
MB_PAR_NONE
:
//无校验
USART_InitStructure
.
USART_Parity
=
USART_Parity_No
;
USART_InitStructure
.
USART_WordLength
=
USART_WordLength_8b
;
break
;
case
MB_PAR_ODD
:
//奇校验
USART_InitStructure
.
USART_Parity
=
USART_Parity_Odd
;
USART_InitStructure
.
USART_WordLength
=
USART_WordLength_9b
;
break
;
case
MB_PAR_EVEN
:
//偶校验
USART_InitStructure
.
USART_Parity
=
USART_Parity_Even
;
USART_InitStructure
.
USART_WordLength
=
USART_WordLength_9b
;
break
;
default:
return
FALSE
;
}
USART_InitStructure
.
USART_StopBits
=
USART_StopBits_1
;
USART_InitStructure
.
USART_HardwareFlowControl
=
USART_HardwareFlowControl_None
;
USART_InitStructure
.
USART_Mode
=
USART_Mode_Rx
|
USART_Mode_Tx
;
if
(
ucPORT
!=
1
)
return
FALSE
;
ENTER_CRITICAL_SECTION
();
//关全局中断
USART_Init
(
USART1
,
&
USART_InitStructure
);
USART_ITConfig
(
USART1
,
USART_IT_RXNE
,
ENABLE
);
USART_Cmd
(
USART1
,
ENABLE
);
//=====================中断初始化======================================
//设置NVIC优先级分组为Group2:0-3抢占式优先级,0-3的响应式优先级
NVIC_PriorityGroupConfig
(
NVIC_PriorityGroup_2
);
NVIC_InitStructure
.
NVIC_IRQChannel
=
USART1_IRQn
;
NVIC_InitStructure
.
NVIC_IRQChannelPreemptionPriority
=
0
;
NVIC_InitStructure
.
NVIC_IRQChannelSubPriority
=
1
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
EXIT_CRITICAL_SECTION
();
//开全局中断
return
TRUE
;
serial
->
parent
.
close
(
&
(
serial
->
parent
));
}
BOOL
xMBPortSerialPutByte
(
CHAR
ucByte
)
{
USART_SendData
(
USART1
,
ucByte
);
return
TRUE
;
serial
->
parent
.
write
(
&
(
serial
->
parent
),
0
,
&
ucByte
,
1
);
return
TRUE
;
}
BOOL
xMBPortSerialGetByte
(
CHAR
*
pucByte
)
{
*
pucByte
=
USART_ReceiveData
(
USART
1
);
return
TRUE
;
serial
->
parent
.
read
(
&
(
serial
->
parent
),
0
,
pucByte
,
1
);
return
TRUE
;
}
/*
...
...
@@ -151,7 +177,7 @@ BOOL xMBPortSerialGetByte(CHAR * pucByte)
*/
void
prvvUARTTxReadyISR
(
void
)
{
pxMBFrameCBTransmitterEmpty
();
pxMBFrameCBTransmitterEmpty
();
}
/*
...
...
@@ -162,28 +188,35 @@ void prvvUARTTxReadyISR(void)
*/
void
prvvUARTRxISR
(
void
)
{
pxMBFrameCBByteReceived
();
pxMBFrameCBByteReceived
();
}
/*******************************************************************************
* Function Name : USART1_IRQHandler
* Description : This function handles USART1 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void
USART1_IRQHandler
(
void
)
{
rt_interrupt_enter
();
//接收中断
if
(
USART_GetITStatus
(
USART1
,
USART_IT_RXNE
)
==
SET
)
{
USART_ClearITPendingBit
(
USART1
,
USART_IT_RXNE
);
prvvUARTRxISR
();
}
//发送中断
if
(
USART_GetITStatus
(
USART1
,
USART_IT_TXE
)
==
SET
)
{
prvvUARTTxReadyISR
();
}
rt_interrupt_leave
();
/**
* Software simulation serial transmit IRQ handler.
*
* @param parameter parameter
*/
static
void
serial_soft_trans_irq
(
void
*
parameter
)
{
rt_uint32_t
recved_event
;
while
(
1
)
{
/* waiting for serial transmit start */
rt_event_recv
(
&
event_serial
,
EVENT_SERIAL_TRANS_START
,
RT_EVENT_FLAG_OR
,
RT_WAITING_FOREVER
,
&
recved_event
);
/* execute modbus callback */
prvvUARTTxReadyISR
();
}
}
/**
* This function is serial receive callback function
*
* @param dev the device of serial
* @param size the data size that receive
*
* @return return RT_EOK
*/
static
rt_err_t
serial_rx_ind
(
rt_device_t
dev
,
rt_size_t
size
)
{
prvvUARTRxISR
();
return
RT_EOK
;
}
components/net/freemodbus-v1.6.0/port/portserial_m.c
浏览文件 @
15129278
/*
* FreeModbus Libary:
STM32
Port
* FreeModbus Libary:
RT-Thread
Port
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* This library is free software; you can redistribute it and/or
...
...
@@ -24,123 +24,149 @@
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
#include "rtdevice.h"
#include "board.h"
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
/* ----------------------- Static variables ---------------------------------*/
ALIGN
(
RT_ALIGN_SIZE
)
/* software simulation serial transmit IRQ handler thread stack */
static
rt_uint8_t
serial_soft_trans_irq_stack
[
512
];
/* software simulation serial transmit IRQ handler thread */
static
struct
rt_thread
thread_serial_soft_trans_irq
;
/* serial event */
static
struct
rt_event
event_serial
;
/* modbus slave serial device */
static
rt_serial_t
*
serial
;
/* ----------------------- Defines ------------------------------------------*/
/* serial transmit event */
#define EVENT_SERIAL_TRANS_START (1<<0)
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED
/* ----------------------- static functions ---------------------------------*/
static
void
prvvUARTTxReadyISR
(
void
);
static
void
prvvUARTRxISR
(
void
);
static
rt_err_t
serial_rx_ind
(
rt_device_t
dev
,
rt_size_t
size
);
static
void
serial_soft_trans_irq
(
void
*
parameter
);
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBMasterPortSerialInit
(
UCHAR
ucPORT
,
ULONG
ulBaudRate
,
UCHAR
ucDataBits
,
eMBParity
eParity
)
{
/**
* set 485 mode receive and transmit control IO
* @note MODBUS_MASTER_RT_CONTROL_PIN_INDEX need be defined by user
*/
rt_pin_mode
(
MODBUS_MASTER_RT_CONTROL_PIN_INDEX
,
PIN_MODE_OUTPUT
);
/* set serial name */
if
(
ucPORT
==
1
)
{
#if defined(RT_USING_UART1) || defined(RT_USING_REMAP_UART1)
extern
struct
rt_serial_device
serial1
;
serial
=
&
serial1
;
#endif
}
else
if
(
ucPORT
==
2
)
{
#if defined(RT_USING_UART2)
extern
struct
rt_serial_device
serial2
;
serial
=
&
serial2
;
#endif
}
else
if
(
ucPORT
==
3
)
{
#if defined(RT_USING_UART3)
extern
struct
rt_serial_device
serial3
;
serial
=
&
serial3
;
#endif
}
/* set serial configure parameter */
serial
->
config
.
baud_rate
=
ulBaudRate
;
serial
->
config
.
stop_bits
=
STOP_BITS_1
;
switch
(
eParity
){
case
MB_PAR_NONE
:
{
serial
->
config
.
data_bits
=
DATA_BITS_8
;
serial
->
config
.
parity
=
PARITY_NONE
;
break
;
}
case
MB_PAR_ODD
:
{
serial
->
config
.
data_bits
=
DATA_BITS_9
;
serial
->
config
.
parity
=
PARITY_ODD
;
break
;
}
case
MB_PAR_EVEN
:
{
serial
->
config
.
data_bits
=
DATA_BITS_9
;
serial
->
config
.
parity
=
PARITY_EVEN
;
break
;
}
}
/* set serial configure */
serial
->
ops
->
configure
(
serial
,
&
(
serial
->
config
));
/* open serial device */
if
(
!
serial
->
parent
.
open
(
&
serial
->
parent
,
RT_DEVICE_OFLAG_RDWR
|
RT_DEVICE_FLAG_INT_RX
))
{
serial
->
parent
.
rx_indicate
=
serial_rx_ind
;
}
else
{
return
FALSE
;
}
/* software initialize */
rt_thread_init
(
&
thread_serial_soft_trans_irq
,
"slave trans"
,
serial_soft_trans_irq
,
RT_NULL
,
serial_soft_trans_irq_stack
,
sizeof
(
serial_soft_trans_irq_stack
),
10
,
5
);
rt_thread_startup
(
&
thread_serial_soft_trans_irq
);
rt_event_init
(
&
event_serial
,
"slave event"
,
RT_IPC_FLAG_PRIO
);
return
TRUE
;
}
void
vMBMasterPortSerialEnable
(
BOOL
xRxEnable
,
BOOL
xTxEnable
)
{
if
(
xRxEnable
)
{
MASTER_RS485_RECEIVE_MODE
;
USART_ITConfig
(
USART2
,
USART_IT_RXNE
,
ENABLE
);
}
else
{
MASTER_RS485_SEND_MODE
;
USART_ITConfig
(
USART2
,
USART_IT_RXNE
,
DISABLE
);
}
if
(
xTxEnable
)
{
USART_ITConfig
(
USART2
,
USART_IT_TXE
,
ENABLE
);
}
else
{
USART_ITConfig
(
USART2
,
USART_IT_TXE
,
DISABLE
);
}
rt_uint32_t
recved_event
;
if
(
xRxEnable
)
{
/* enable RX interrupt */
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_SET_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_RX
);
/* switch 485 to receive mode */
rt_pin_write
(
MODBUS_MASTER_RT_CONTROL_PIN_INDEX
,
PIN_LOW
);
}
else
{
/* switch 485 to transmit mode */
rt_pin_write
(
MODBUS_MASTER_RT_CONTROL_PIN_INDEX
,
PIN_HIGH
);
/* disable RX interrupt */
serial
->
ops
->
control
(
serial
,
RT_DEVICE_CTRL_CLR_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_RX
);
}
if
(
xTxEnable
)
{
/* start serial transmit */
rt_event_send
(
&
event_serial
,
EVENT_SERIAL_TRANS_START
);
}
else
{
/* stop serial transmit */
rt_event_recv
(
&
event_serial
,
EVENT_SERIAL_TRANS_START
,
RT_EVENT_FLAG_OR
|
RT_EVENT_FLAG_CLEAR
,
0
,
&
recved_event
);
}
}
void
vMBMasterPortClose
(
void
)
{
USART_ITConfig
(
USART2
,
USART_IT_TXE
|
USART_IT_RXNE
,
DISABLE
);
USART_Cmd
(
USART2
,
DISABLE
);
}
//默认一个主机 串口2 波特率可设置 奇偶检验可设置
BOOL
xMBMasterPortSerialInit
(
UCHAR
ucPORT
,
ULONG
ulBaudRate
,
UCHAR
ucDataBits
,
eMBParity
eParity
)
{
GPIO_InitTypeDef
GPIO_InitStructure
;
USART_InitTypeDef
USART_InitStructure
;
NVIC_InitTypeDef
NVIC_InitStructure
;
//======================时钟初始化=======================================
RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_GPIOA
|
RCC_APB2Periph_GPIOB
,
ENABLE
);
RCC_APB1PeriphClockCmd
(
RCC_APB1Periph_USART2
,
ENABLE
);
//======================IO初始化=======================================
//USART2_TX
GPIO_InitStructure
.
GPIO_Speed
=
GPIO_Speed_50MHz
;
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_AF_PP
;
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_2
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStructure
);
//USART2_RX
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_IN_FLOATING
;
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_3
;
GPIO_Init
(
GPIOA
,
&
GPIO_InitStructure
);
//配置485发送和接收模式
// TODO 暂时先写B13 等之后组网测试时再修改
GPIO_InitStructure
.
GPIO_Mode
=
GPIO_Mode_Out_PP
;
GPIO_InitStructure
.
GPIO_Pin
=
GPIO_Pin_13
;
GPIO_Init
(
GPIOB
,
&
GPIO_InitStructure
);
//======================串口初始化=======================================
USART_InitStructure
.
USART_BaudRate
=
ulBaudRate
;
//设置校验模式
switch
(
eParity
)
{
case
MB_PAR_NONE
:
//无校验
USART_InitStructure
.
USART_Parity
=
USART_Parity_No
;
USART_InitStructure
.
USART_WordLength
=
USART_WordLength_8b
;
break
;
case
MB_PAR_ODD
:
//奇校验
USART_InitStructure
.
USART_Parity
=
USART_Parity_Odd
;
USART_InitStructure
.
USART_WordLength
=
USART_WordLength_9b
;
break
;
case
MB_PAR_EVEN
:
//偶校验
USART_InitStructure
.
USART_Parity
=
USART_Parity_Even
;
USART_InitStructure
.
USART_WordLength
=
USART_WordLength_9b
;
break
;
default:
return
FALSE
;
}
USART_InitStructure
.
USART_StopBits
=
USART_StopBits_1
;
USART_InitStructure
.
USART_HardwareFlowControl
=
USART_HardwareFlowControl_None
;
USART_InitStructure
.
USART_Mode
=
USART_Mode_Rx
|
USART_Mode_Tx
;
if
(
ucPORT
!=
2
)
return
FALSE
;
ENTER_CRITICAL_SECTION
();
//关全局中断
USART_Init
(
USART2
,
&
USART_InitStructure
);
USART_ITConfig
(
USART2
,
USART_IT_RXNE
,
ENABLE
);
USART_Cmd
(
USART2
,
ENABLE
);
//=====================中断初始化======================================
//设置NVIC优先级分组为Group2:0-3抢占式优先级,0-3的响应式优先级
NVIC_PriorityGroupConfig
(
NVIC_PriorityGroup_2
);
NVIC_InitStructure
.
NVIC_IRQChannel
=
USART2_IRQn
;
NVIC_InitStructure
.
NVIC_IRQChannelPreemptionPriority
=
0
;
NVIC_InitStructure
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
EXIT_CRITICAL_SECTION
();
//开全局中断
return
TRUE
;
serial
->
parent
.
close
(
&
(
serial
->
parent
));
}
BOOL
xMBMasterPortSerialPutByte
(
CHAR
ucByte
)
{
USART_SendData
(
USART2
,
ucByte
);
return
TRUE
;
serial
->
parent
.
write
(
&
(
serial
->
parent
),
0
,
&
ucByte
,
1
);
return
TRUE
;
}
BOOL
xMBMasterPortSerialGetByte
(
CHAR
*
pucByte
)
{
*
pucByte
=
USART_ReceiveData
(
USART2
);
return
TRUE
;
serial
->
parent
.
read
(
&
(
serial
->
parent
),
0
,
pucByte
,
1
);
return
TRUE
;
}
/*
...
...
@@ -152,7 +178,7 @@ BOOL xMBMasterPortSerialGetByte(CHAR * pucByte)
*/
void
prvvUARTTxReadyISR
(
void
)
{
pxMBMasterFrameCBTransmitterEmpty
();
pxMBMasterFrameCBTransmitterEmpty
();
}
/*
...
...
@@ -163,30 +189,37 @@ void prvvUARTTxReadyISR(void)
*/
void
prvvUARTRxISR
(
void
)
{
pxMBMasterFrameCBByteReceived
();
pxMBMasterFrameCBByteReceived
();
}
/*******************************************************************************
* Function Name : USART2_IRQHandler
* Description : This function handles USART2 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void
USART2_IRQHandler
(
void
)
{
rt_interrupt_enter
();
//接收中断
if
(
USART_GetITStatus
(
USART2
,
USART_IT_RXNE
)
==
SET
)
{
USART_ClearITPendingBit
(
USART2
,
USART_IT_RXNE
);
prvvUARTRxISR
();
}
//发送中断
if
(
USART_GetITStatus
(
USART2
,
USART_IT_TXE
)
==
SET
)
{
prvvUARTTxReadyISR
();
}
rt_interrupt_leave
();
/**
* Software simulation serial transmit IRQ handler.
*
* @param parameter parameter
*/
static
void
serial_soft_trans_irq
(
void
*
parameter
)
{
rt_uint32_t
recved_event
;
while
(
1
)
{
/* waiting for serial transmit start */
rt_event_recv
(
&
event_serial
,
EVENT_SERIAL_TRANS_START
,
RT_EVENT_FLAG_OR
,
RT_WAITING_FOREVER
,
&
recved_event
);
/* execute modbus callback */
prvvUARTTxReadyISR
();
}
}
/**
* This function is serial receive callback function
*
* @param dev the device of serial
* @param size the data size that receive
*
* @return return RT_EOK
*/
static
rt_err_t
serial_rx_ind
(
rt_device_t
dev
,
rt_size_t
size
)
{
prvvUARTRxISR
();
return
RT_EOK
;
}
#endif
components/net/freemodbus-v1.6.0/port/porttimer.c
浏览文件 @
15129278
/*
* FreeModbus Libary:
STM32
Port
* FreeModbus Libary:
RT-Thread
Port
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* This library is free software; you can redistribute it and/or
...
...
@@ -27,81 +27,37 @@
#include "mbport.h"
/* ----------------------- static functions ---------------------------------*/
static
struct
rt_timer
timer
;
static
void
prvvTIMERExpiredISR
(
void
);
static
void
timer_timeout_ind
(
void
*
parameter
);
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortTimersInit
(
USHORT
usTim1Timerout50us
)
{
uint16_t
PrescalerValue
=
0
;
TIM_TimeBaseInitTypeDef
TIM_TimeBaseStructure
;
NVIC_InitTypeDef
NVIC_InitStructure
;
//====================================时钟初始化===========================
//使能定时器3时钟
RCC_APB1PeriphClockCmd
(
RCC_APB1Periph_TIM3
,
ENABLE
);
//====================================定时器初始化===========================
//定时器时间基配置说明
//HCLK为72MHz,APB1经过2分频为36MHz
//TIM3的时钟倍频后为72MHz(硬件自动倍频,达到最大)
//TIM3的分频系数为3599,时间基频率为72 / (1 + Prescaler) = 20KHz,基准为50us
//TIM最大计数值为usTim1Timerout50u
PrescalerValue
=
(
uint16_t
)
(
SystemCoreClock
/
20000
)
-
1
;
//定时器1初始化
TIM_TimeBaseStructure
.
TIM_Period
=
(
uint16_t
)
usTim1Timerout50us
;
TIM_TimeBaseStructure
.
TIM_Prescaler
=
PrescalerValue
;
TIM_TimeBaseStructure
.
TIM_ClockDivision
=
0
;
TIM_TimeBaseStructure
.
TIM_CounterMode
=
TIM_CounterMode_Up
;
TIM_TimeBaseInit
(
TIM3
,
&
TIM_TimeBaseStructure
);
//预装载使能
TIM_ARRPreloadConfig
(
TIM3
,
ENABLE
);
//====================================中断初始化===========================
//设置NVIC优先级分组为Group2:0-3抢占式优先级,0-3的响应式优先级
NVIC_PriorityGroupConfig
(
NVIC_PriorityGroup_2
);
NVIC_InitStructure
.
NVIC_IRQChannel
=
TIM3_IRQn
;
NVIC_InitStructure
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStructure
.
NVIC_IRQChannelSubPriority
=
1
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
//清除溢出中断标志位
TIM_ClearITPendingBit
(
TIM3
,
TIM_IT_Update
);
//定时器3溢出中断关闭
TIM_ITConfig
(
TIM3
,
TIM_IT_Update
,
DISABLE
);
//定时器3禁能
TIM_Cmd
(
TIM3
,
DISABLE
);
return
TRUE
;
rt_timer_init
(
&
timer
,
"slave timer"
,
timer_timeout_ind
,
/* bind timeout callback function */
RT_NULL
,
(
50
*
usTim1Timerout50us
)
/
(
1000
*
1000
/
RT_TICK_PER_SECOND
),
RT_TIMER_FLAG_ONE_SHOT
);
/* one shot */
return
TRUE
;
}
void
vMBPortTimersEnable
()
{
TIM_ClearITPendingBit
(
TIM3
,
TIM_IT_Update
);
TIM_ITConfig
(
TIM3
,
TIM_IT_Update
,
ENABLE
);
TIM_SetCounter
(
TIM3
,
0
);
TIM_Cmd
(
TIM3
,
ENABLE
);
rt_timer_start
(
&
timer
);
}
void
vMBPortTimersDisable
()
{
TIM_ClearITPendingBit
(
TIM3
,
TIM_IT_Update
);
TIM_ITConfig
(
TIM3
,
TIM_IT_Update
,
DISABLE
);
TIM_SetCounter
(
TIM3
,
0
);
TIM_Cmd
(
TIM3
,
DISABLE
);
rt_timer_stop
(
&
timer
);
}
void
prvvTIMERExpiredISR
(
void
)
{
(
void
)
pxMBPortCBTimerExpired
();
(
void
)
pxMBPortCBTimerExpired
();
}
void
TIM3_IRQHandler
(
void
)
static
void
timer_timeout_ind
(
void
*
parameter
)
{
rt_interrupt_enter
();
if
(
TIM_GetITStatus
(
TIM3
,
TIM_IT_Update
)
!=
RESET
)
{
TIM_ClearFlag
(
TIM3
,
TIM_FLAG_Update
);
//清中断标记
TIM_ClearITPendingBit
(
TIM3
,
TIM_IT_Update
);
//清除定时器T3溢出中断标志位
prvvTIMERExpiredISR
();
}
rt_interrupt_leave
();
prvvTIMERExpiredISR
();
}
components/net/freemodbus-v1.6.0/port/porttimer_m.c
浏览文件 @
15129278
/*
* FreeModbus Libary:
STM32
Port
* FreeModbus Libary:
RT-Thread
Port
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* This library is free software; you can redistribute it and/or
...
...
@@ -27,10 +27,12 @@
#include "mb_m.h"
#include "mbport.h"
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED
> 0
/* ----------------------- Variables ----------------------------------------*/
static
USHORT
usT35TimeOut50us
;
static
USHORT
usPrescalerValue
=
0
;
static
struct
rt_timer
timer
;
static
void
prvvTIMERExpiredISR
(
void
);
static
void
timer_timeout_ind
(
void
*
parameter
);
/* ----------------------- static functions ---------------------------------*/
static
void
prvvTIMERExpiredISR
(
void
);
...
...
@@ -38,120 +40,68 @@ static void prvvTIMERExpiredISR(void);
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBMasterPortTimersInit
(
USHORT
usTimeOut50us
)
{
NVIC_InitTypeDef
NVIC_InitStructure
;
//====================================时钟初始化===========================
//使能定时器2时钟
RCC_APB1PeriphClockCmd
(
RCC_APB1Periph_TIM2
,
ENABLE
);
//====================================定时器初始化===========================
//定时器时间基配置说明
//HCLK为72MHz,APB1经过2分频为36MHz
//TIM2的时钟倍频后为72MHz(硬件自动倍频,达到最大)
//TIM2的分频系数为3599,时间基频率为72 / (1 + Prescaler) = 20KHz,基准为50us
//TIM最大计数值为usTim1Timerout50u
usPrescalerValue
=
(
uint16_t
)
(
SystemCoreClock
/
20000
)
-
1
;
//保存T35定时器计数值
usT35TimeOut50us
=
usTimeOut50us
;
//预装载使能
TIM_ARRPreloadConfig
(
TIM2
,
ENABLE
);
//====================================中断初始化===========================
//设置NVIC优先级分组为Group2:0-3抢占式优先级,0-3的响应式优先级
NVIC_PriorityGroupConfig
(
NVIC_PriorityGroup_2
);
NVIC_InitStructure
.
NVIC_IRQChannel
=
TIM2_IRQn
;
NVIC_InitStructure
.
NVIC_IRQChannelPreemptionPriority
=
1
;
NVIC_InitStructure
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
//清除溢出中断标志位
TIM_ClearITPendingBit
(
TIM2
,
TIM_IT_Update
);
//定时器3溢出中断关闭
TIM_ITConfig
(
TIM2
,
TIM_IT_Update
,
DISABLE
);
//定时器3禁能
TIM_Cmd
(
TIM2
,
DISABLE
);
return
TRUE
;
/* backup T35 ticks */
usT35TimeOut50us
=
usTimeOut50us
;
rt_timer_init
(
&
timer
,
"master timer"
,
timer_timeout_ind
,
/* bind timeout callback function */
RT_NULL
,
(
50
*
usT35TimeOut50us
)
/
(
1000
*
1000
/
RT_TICK_PER_SECOND
),
RT_TIMER_FLAG_ONE_SHOT
);
/* one shot */
return
TRUE
;
}
void
vMBMasterPortTimersT35Enable
()
{
TIM_TimeBaseInitTypeDef
TIM_TimeBaseStructure
;
rt_tick_t
timer_tick
=
(
50
*
usT35TimeOut50us
)
/
(
1000
*
1000
/
RT_TICK_PER_SECOND
);
/* Set current timer mode,
don't change it.*/
vMBMasterSetCurTimerMode
(
MB_TMODE_T35
);
/* Set current timer mode,
don't change it.*/
vMBMasterSetCurTimerMode
(
MB_TMODE_T35
);
TIM_TimeBaseStructure
.
TIM_Prescaler
=
usPrescalerValue
;
TIM_TimeBaseStructure
.
TIM_ClockDivision
=
0
;
TIM_TimeBaseStructure
.
TIM_CounterMode
=
TIM_CounterMode_Up
;
TIM_TimeBaseStructure
.
TIM_Period
=
(
uint16_t
)
usT35TimeOut50us
;
TIM_TimeBaseInit
(
TIM2
,
&
TIM_TimeBaseStructure
);
rt_timer_control
(
&
timer
,
RT_TIMER_CTRL_SET_TIME
,
&
timer_tick
);
TIM_ClearITPendingBit
(
TIM2
,
TIM_IT_Update
);
TIM_ITConfig
(
TIM2
,
TIM_IT_Update
,
ENABLE
);
TIM_SetCounter
(
TIM2
,
0
);
TIM_Cmd
(
TIM2
,
ENABLE
);
rt_timer_start
(
&
timer
);
}
void
vMBMasterPortTimersConvertDelayEnable
()
{
TIM_TimeBaseInitTypeDef
TIM_TimeBaseStructure
;
rt_tick_t
timer_tick
=
MB_MASTER_DELAY_MS_CONVERT
*
RT_TICK_PER_SECOND
/
1000
;
/* Set current timer mode,
don't change it.*/
vMBMasterSetCurTimerMode
(
MB_TMODE_CONVERT_DELAY
);
/* Set current timer mode,
don't change it.*/
vMBMasterSetCurTimerMode
(
MB_TMODE_CONVERT_DELAY
);
TIM_TimeBaseStructure
.
TIM_Prescaler
=
usPrescalerValue
;
TIM_TimeBaseStructure
.
TIM_ClockDivision
=
0
;
TIM_TimeBaseStructure
.
TIM_CounterMode
=
TIM_CounterMode_Up
;
TIM_TimeBaseStructure
.
TIM_Period
=
(
uint16_t
)(
MB_MASTER_DELAY_MS_CONVERT
*
1000
/
50
);
TIM_TimeBaseInit
(
TIM2
,
&
TIM_TimeBaseStructure
);
rt_timer_control
(
&
timer
,
RT_TIMER_CTRL_SET_TIME
,
&
timer_tick
);
TIM_ClearITPendingBit
(
TIM2
,
TIM_IT_Update
);
TIM_ITConfig
(
TIM2
,
TIM_IT_Update
,
ENABLE
);
TIM_SetCounter
(
TIM2
,
0
);
TIM_Cmd
(
TIM2
,
ENABLE
);
rt_timer_start
(
&
timer
);
}
void
vMBMasterPortTimersRespondTimeoutEnable
()
{
TIM_TimeBaseInitTypeDef
TIM_TimeBaseStructure
;
rt_tick_t
timer_tick
=
MB_MASTER_TIMEOUT_MS_RESPOND
*
RT_TICK_PER_SECOND
/
1000
;
/* Set current timer mode,
don't change it.*/
vMBMasterSetCurTimerMode
(
MB_TMODE_RESPOND_TIMEOUT
);
/* Set current timer mode,
don't change it.*/
vMBMasterSetCurTimerMode
(
MB_TMODE_RESPOND_TIMEOUT
);
TIM_TimeBaseStructure
.
TIM_Prescaler
=
usPrescalerValue
;
TIM_TimeBaseStructure
.
TIM_ClockDivision
=
0
;
TIM_TimeBaseStructure
.
TIM_CounterMode
=
TIM_CounterMode_Up
;
TIM_TimeBaseStructure
.
TIM_Period
=
(
uint16_t
)(
MB_MASTER_TIMEOUT_MS_RESPOND
*
1000
/
50
);
TIM_TimeBaseInit
(
TIM2
,
&
TIM_TimeBaseStructure
);
rt_timer_control
(
&
timer
,
RT_TIMER_CTRL_SET_TIME
,
&
timer_tick
);
TIM_ClearITPendingBit
(
TIM2
,
TIM_IT_Update
);
TIM_ITConfig
(
TIM2
,
TIM_IT_Update
,
ENABLE
);
TIM_SetCounter
(
TIM2
,
0
);
TIM_Cmd
(
TIM2
,
ENABLE
);
rt_timer_start
(
&
timer
);
}
void
vMBMasterPortTimersDisable
()
{
TIM_ClearITPendingBit
(
TIM2
,
TIM_IT_Update
);
TIM_ITConfig
(
TIM2
,
TIM_IT_Update
,
DISABLE
);
TIM_SetCounter
(
TIM2
,
0
);
TIM_Cmd
(
TIM2
,
DISABLE
);
rt_timer_stop
(
&
timer
);
}
void
prvvTIMERExpiredISR
(
void
)
{
(
void
)
pxMBMasterPortCBTimerExpired
();
(
void
)
pxMBMasterPortCBTimerExpired
();
}
void
TIM2_IRQHandler
(
void
)
static
void
timer_timeout_ind
(
void
*
parameter
)
{
rt_interrupt_enter
();
if
(
TIM_GetITStatus
(
TIM2
,
TIM_IT_Update
)
!=
RESET
)
{
TIM_ClearFlag
(
TIM2
,
TIM_FLAG_Update
);
//清中断标记
TIM_ClearITPendingBit
(
TIM2
,
TIM_IT_Update
);
//清除定时器TIM2溢出中断标志位
prvvTIMERExpiredISR
();
}
rt_interrupt_leave
();
prvvTIMERExpiredISR
();
}
#endif
components/net/freemodbus-v1.6.0/port/user_mb_app.c
浏览文件 @
15129278
此差异已折叠。
点击以展开。
components/net/freemodbus-v1.6.0/port/user_mb_app.h
浏览文件 @
15129278
#ifndef
USER_APP
#ifndef
USER_APP
#define USER_APP
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
...
...
@@ -8,47 +8,39 @@
#include "mbutils.h"
/* -----------------------Slave Defines -------------------------------------*/
#define S_DISCRETE_INPUT_START
1
#define S_DISCRETE_INPUT_START
0
#define S_DISCRETE_INPUT_NDISCRETES 16
#define S_COIL_START
1
#define S_COIL_START
0
#define S_COIL_NCOILS 64
#define S_REG_INPUT_START
1
#define S_REG_INPUT_START
0
#define S_REG_INPUT_NREGS 100
#define S_REG_HOLDING_START
1
#define S_REG_HOLDING_START
0
#define S_REG_HOLDING_NREGS 100
//从机模式:在保持寄存器中,各个地址对应的功能定义
#define S_HD_RESERVE 0 //保留
#define S_HD_CPU_USAGE_MAJOR 1 //当前CPU利用率的整数位
#define S_HD_CPU_USAGE_MINOR 2 //当前CPU利用率的小数位
//从机模式:在输入寄存器中,各个地址对应的功能定义
#define S_IN_RESERVE 0 //保留
//从机模式:在线圈中,各个地址对应的功能定义
#define S_CO_RESERVE 2 //保留
//从机模式:在离散输入中,各个地址对应的功能定义
#define S_DI_RESERVE 1 //保留
/* salve mode: holding register's all address */
#define S_HD_RESERVE 0
/* salve mode: input register's all address */
#define S_IN_RESERVE 0
/* salve mode: coil's all address */
#define S_CO_RESERVE 0
/* salve mode: discrete's all address */
#define S_DI_RESERVE 0
/* -----------------------Master Defines -------------------------------------*/
#define M_DISCRETE_INPUT_START
1
#define M_DISCRETE_INPUT_START
0
#define M_DISCRETE_INPUT_NDISCRETES 16
#define M_COIL_START
1
#define M_COIL_START
0
#define M_COIL_NCOILS 64
#define M_REG_INPUT_START
1
#define M_REG_INPUT_START
0
#define M_REG_INPUT_NREGS 100
#define M_REG_HOLDING_START
1
#define M_REG_HOLDING_START
0
#define M_REG_HOLDING_NREGS 100
//主机模式:在保持寄存器中,各个地址对应的功能定义
#define M_HD_RESERVE 0 //保留
//主机模式:在输入寄存器中,各个地址对应的功能定义
#define M_IN_RESERVE 0 //保留
//主机模式:在线圈中,各个地址对应的功能定义
#define M_CO_RESERVE 2 //保留
//主机模式:在离散输入中,各个地址对应的功能定义
#define M_DI_RESERVE 1 //保留
/* master mode: holding register's all address */
#define M_HD_RESERVE 0
/* master mode: input register's all address */
#define M_IN_RESERVE 0
/* master mode: coil's all address */
#define M_CO_RESERVE 0
/* master mode: discrete's all address */
#define M_DI_RESERVE 0
#endif
components/net/freemodbus-v1.6.0/port/user_mb_app_m.c
0 → 100644
浏览文件 @
15129278
/*
* FreeModbus Libary: user callback functions and buffer define in master mode
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* File: $Id: user_mb_app_m.c,v 1.60 2013/11/23 11:49:05 Armink $
*/
#include "user_mb_app.h"
/*-----------------------Master mode use these variables----------------------*/
#if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
//Master mode:DiscreteInputs variables
USHORT
usMDiscInStart
=
M_DISCRETE_INPUT_START
;
#if M_DISCRETE_INPUT_NDISCRETES%8
UCHAR
ucMDiscInBuf
[
MB_MASTER_TOTAL_SLAVE_NUM
][
M_DISCRETE_INPUT_NDISCRETES
/
8
+
1
];
#else
UCHAR
ucMDiscInBuf
[
MB_MASTER_TOTAL_SLAVE_NUM
][
M_DISCRETE_INPUT_NDISCRETES
/
8
];
#endif
//Master mode:Coils variables
USHORT
usMCoilStart
=
M_COIL_START
;
#if M_COIL_NCOILS%8
UCHAR
ucMCoilBuf
[
MB_MASTER_TOTAL_SLAVE_NUM
][
M_COIL_NCOILS
/
8
+
1
];
#else
UCHAR
ucMCoilBuf
[
MB_MASTER_TOTAL_SLAVE_NUM
][
M_COIL_NCOILS
/
8
];
#endif
//Master mode:InputRegister variables
USHORT
usMRegInStart
=
M_REG_INPUT_START
;
USHORT
usMRegInBuf
[
MB_MASTER_TOTAL_SLAVE_NUM
][
M_REG_INPUT_NREGS
];
//Master mode:HoldingRegister variables
USHORT
usMRegHoldStart
=
M_REG_HOLDING_START
;
USHORT
usMRegHoldBuf
[
MB_MASTER_TOTAL_SLAVE_NUM
][
M_REG_HOLDING_NREGS
];
/**
* Modbus master input register callback function.
*
* @param pucRegBuffer input register buffer
* @param usAddress input register address
* @param usNRegs input register number
*
* @return result
*/
eMBErrorCode
eMBMasterRegInputCB
(
UCHAR
*
pucRegBuffer
,
USHORT
usAddress
,
USHORT
usNRegs
)
{
eMBErrorCode
eStatus
=
MB_ENOERR
;
USHORT
iRegIndex
;
USHORT
*
pusRegInputBuf
;
USHORT
REG_INPUT_START
;
USHORT
REG_INPUT_NREGS
;
USHORT
usRegInStart
;
pusRegInputBuf
=
usMRegInBuf
[
ucMBMasterGetDestAddress
()
-
1
];
REG_INPUT_START
=
M_REG_INPUT_START
;
REG_INPUT_NREGS
=
M_REG_INPUT_NREGS
;
usRegInStart
=
usMRegInStart
;
/* it already plus one in modbus function method. */
usAddress
--
;
if
((
usAddress
>=
REG_INPUT_START
)
&&
(
usAddress
+
usNRegs
<=
REG_INPUT_START
+
REG_INPUT_NREGS
))
{
iRegIndex
=
usAddress
-
usRegInStart
;
while
(
usNRegs
>
0
)
{
pusRegInputBuf
[
iRegIndex
]
=
*
pucRegBuffer
++
<<
8
;
pusRegInputBuf
[
iRegIndex
]
|=
*
pucRegBuffer
++
;
iRegIndex
++
;
usNRegs
--
;
}
}
else
{
eStatus
=
MB_ENOREG
;
}
return
eStatus
;
}
/**
* Modbus master holding register callback function.
*
* @param pucRegBuffer holding register buffer
* @param usAddress holding register address
* @param usNRegs holding register number
* @param eMode read or write
*
* @return result
*/
eMBErrorCode
eMBMasterRegHoldingCB
(
UCHAR
*
pucRegBuffer
,
USHORT
usAddress
,
USHORT
usNRegs
,
eMBRegisterMode
eMode
)
{
eMBErrorCode
eStatus
=
MB_ENOERR
;
USHORT
iRegIndex
;
USHORT
*
pusRegHoldingBuf
;
USHORT
REG_HOLDING_START
;
USHORT
REG_HOLDING_NREGS
;
USHORT
usRegHoldStart
;
pusRegHoldingBuf
=
usMRegHoldBuf
[
ucMBMasterGetDestAddress
()
-
1
];
REG_HOLDING_START
=
M_REG_HOLDING_START
;
REG_HOLDING_NREGS
=
M_REG_HOLDING_NREGS
;
usRegHoldStart
=
usMRegHoldStart
;
/* if mode is read, the master will write the received date to buffer. */
eMode
=
MB_REG_WRITE
;
/* it already plus one in modbus function method. */
usAddress
--
;
if
((
usAddress
>=
REG_HOLDING_START
)
&&
(
usAddress
+
usNRegs
<=
REG_HOLDING_START
+
REG_HOLDING_NREGS
))
{
iRegIndex
=
usAddress
-
usRegHoldStart
;
switch
(
eMode
)
{
/* read current register values from the protocol stack. */
case
MB_REG_READ
:
while
(
usNRegs
>
0
)
{
*
pucRegBuffer
++
=
(
UCHAR
)
(
pusRegHoldingBuf
[
iRegIndex
]
>>
8
);
*
pucRegBuffer
++
=
(
UCHAR
)
(
pusRegHoldingBuf
[
iRegIndex
]
&
0xFF
);
iRegIndex
++
;
usNRegs
--
;
}
break
;
/* write current register values with new values from the protocol stack. */
case
MB_REG_WRITE
:
while
(
usNRegs
>
0
)
{
pusRegHoldingBuf
[
iRegIndex
]
=
*
pucRegBuffer
++
<<
8
;
pusRegHoldingBuf
[
iRegIndex
]
|=
*
pucRegBuffer
++
;
iRegIndex
++
;
usNRegs
--
;
}
break
;
}
}
else
{
eStatus
=
MB_ENOREG
;
}
return
eStatus
;
}
/**
* Modbus master coils callback function.
*
* @param pucRegBuffer coils buffer
* @param usAddress coils address
* @param usNCoils coils number
* @param eMode read or write
*
* @return result
*/
eMBErrorCode
eMBMasterRegCoilsCB
(
UCHAR
*
pucRegBuffer
,
USHORT
usAddress
,
USHORT
usNCoils
,
eMBRegisterMode
eMode
)
{
eMBErrorCode
eStatus
=
MB_ENOERR
;
USHORT
iRegIndex
,
iRegBitIndex
,
iNReg
;
UCHAR
*
pucCoilBuf
;
USHORT
COIL_START
;
USHORT
COIL_NCOILS
;
USHORT
usCoilStart
;
iNReg
=
usNCoils
/
8
+
1
;
pucCoilBuf
=
ucMCoilBuf
[
ucMBMasterGetDestAddress
()
-
1
];
COIL_START
=
M_COIL_START
;
COIL_NCOILS
=
M_COIL_NCOILS
;
usCoilStart
=
usMCoilStart
;
/* if mode is read,the master will write the received date to buffer. */
eMode
=
MB_REG_WRITE
;
/* it already plus one in modbus function method. */
usAddress
--
;
if
((
usAddress
>=
COIL_START
)
&&
(
usAddress
+
usNCoils
<=
COIL_START
+
COIL_NCOILS
))
{
iRegIndex
=
(
USHORT
)
(
usAddress
-
usCoilStart
)
/
8
;
iRegBitIndex
=
(
USHORT
)
(
usAddress
-
usCoilStart
)
%
8
;
switch
(
eMode
)
{
/* read current coil values from the protocol stack. */
case
MB_REG_READ
:
while
(
iNReg
>
0
)
{
*
pucRegBuffer
++
=
xMBUtilGetBits
(
&
pucCoilBuf
[
iRegIndex
++
],
iRegBitIndex
,
8
);
iNReg
--
;
}
pucRegBuffer
--
;
/* last coils */
usNCoils
=
usNCoils
%
8
;
/* filling zero to high bit */
*
pucRegBuffer
=
*
pucRegBuffer
<<
(
8
-
usNCoils
);
*
pucRegBuffer
=
*
pucRegBuffer
>>
(
8
-
usNCoils
);
break
;
/* write current coil values with new values from the protocol stack. */
case
MB_REG_WRITE
:
while
(
iNReg
>
1
)
{
xMBUtilSetBits
(
&
pucCoilBuf
[
iRegIndex
++
],
iRegBitIndex
,
8
,
*
pucRegBuffer
++
);
iNReg
--
;
}
/* last coils */
usNCoils
=
usNCoils
%
8
;
/* xMBUtilSetBits has bug when ucNBits is zero */
if
(
usNCoils
!=
0
)
{
xMBUtilSetBits
(
&
pucCoilBuf
[
iRegIndex
++
],
iRegBitIndex
,
usNCoils
,
*
pucRegBuffer
++
);
}
break
;
}
}
else
{
eStatus
=
MB_ENOREG
;
}
return
eStatus
;
}
/**
* Modbus master discrete callback function.
*
* @param pucRegBuffer discrete buffer
* @param usAddress discrete address
* @param usNDiscrete discrete number
*
* @return result
*/
eMBErrorCode
eMBMasterRegDiscreteCB
(
UCHAR
*
pucRegBuffer
,
USHORT
usAddress
,
USHORT
usNDiscrete
)
{
eMBErrorCode
eStatus
=
MB_ENOERR
;
USHORT
iRegIndex
,
iRegBitIndex
,
iNReg
;
UCHAR
*
pucDiscreteInputBuf
;
USHORT
DISCRETE_INPUT_START
;
USHORT
DISCRETE_INPUT_NDISCRETES
;
USHORT
usDiscreteInputStart
;
iNReg
=
usNDiscrete
/
8
+
1
;
pucDiscreteInputBuf
=
ucMDiscInBuf
[
ucMBMasterGetDestAddress
()
-
1
];
DISCRETE_INPUT_START
=
M_DISCRETE_INPUT_START
;
DISCRETE_INPUT_NDISCRETES
=
M_DISCRETE_INPUT_NDISCRETES
;
usDiscreteInputStart
=
usMDiscInStart
;
/* it already plus one in modbus function method. */
usAddress
--
;
if
((
usAddress
>=
DISCRETE_INPUT_START
)
&&
(
usAddress
+
usNDiscrete
<=
DISCRETE_INPUT_START
+
DISCRETE_INPUT_NDISCRETES
))
{
iRegIndex
=
(
USHORT
)
(
usAddress
-
usDiscreteInputStart
)
/
8
;
iRegBitIndex
=
(
USHORT
)
(
usAddress
-
usDiscreteInputStart
)
%
8
;
/* write current discrete values with new values from the protocol stack. */
while
(
iNReg
>
1
)
{
xMBUtilSetBits
(
&
pucDiscreteInputBuf
[
iRegIndex
++
],
iRegBitIndex
,
8
,
*
pucRegBuffer
++
);
iNReg
--
;
}
/* last discrete */
usNDiscrete
=
usNDiscrete
%
8
;
/* xMBUtilSetBits has bug when ucNBits is zero */
if
(
usNDiscrete
!=
0
)
{
xMBUtilSetBits
(
&
pucDiscreteInputBuf
[
iRegIndex
++
],
iRegBitIndex
,
usNDiscrete
,
*
pucRegBuffer
++
);
}
}
else
{
eStatus
=
MB_ENOREG
;
}
return
eStatus
;
}
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录