Skip to content

Commit

Permalink
feat: add 'timeSlice' support
Browse files Browse the repository at this point in the history
  • Loading branch information
wwhai committed Apr 18, 2023
1 parent 330d00f commit e2924d3
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 9 deletions.
41 changes: 35 additions & 6 deletions device/custom_protocol_device.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import (
serial "github.com/tarm/serial"
)

// 读出来的字节缓冲默认大小
const __DEFAULT_BUFFER_SIZE = 100

// 传输形式:
// `rawtcp`, `rawudp`, `rs485rawserial`, `rs485rawtcp`
// const rawtcp string = "rawtcp"
Expand Down Expand Up @@ -45,11 +48,13 @@ type _ProtocolArg struct {
type _Protocol struct {
Name string `json:"name" validate:"required"` // 名称
// 如果是静态的, 就取in参数; 如果是动态的, 则直接取第三个参数
Type int `json:"type" validate:"required" default:"1"` // 指令类型, 1 静态, 2动态
Type int `json:"type" validate:"required" default:"1"` // 指令类型, 1 静态, 2动态, 3 定时读, 4 定时读写
Description string `json:"description"` // 描述文本
RW int `json:"rw" validate:"required"` // 1:RO 2:WO 3:RW
BufferSize int `json:"bufferSize" validate:"required"` // 缓冲区大小
Timeout int `json:"timeout" validate:"required"` // 指令的等待时间, 在 Timeout 范围读 BufferSize 个字节, 否则就直接失败
// [Important!] 该参数用来配合定时协议使用, Type== 3、4 时生效
TimeSlice int `json:"timeSlice" validate:"required"` // 定时请求倒计时,单位毫秒,默认为0
//---------------------------------------------------------------------
// 下面都是校验算法相关配置:
// -- 例如对[Byte1,Byte2,Byte3,Byte4,Byte5,Byte6,Byte7]用XOR算法比对
Expand Down Expand Up @@ -235,7 +240,7 @@ func (mdev *CustomProtocolDevice) Start(cctx typex.CCTX) error {
mdev.errorCount++
continue
}
result := [100]byte{} // 全局buf, 默认是100字节, 应该能覆盖绝大多数报文了
result := [__DEFAULT_BUFFER_SIZE]byte{} // 全局buf, 默认是100字节, 应该能覆盖绝大多数报文了
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
if _, err2 := utils.ReadAtLeast(ctx, mdev.serialPort, result[:p.BufferSize],
p.BufferSize); err2 != nil {
Expand Down Expand Up @@ -328,7 +333,7 @@ func (mdev *CustomProtocolDevice) OnRead(cmd []byte, data []byte) (int, error) {
return 0, err1
}

result := [100]byte{} // 全局buf, 默认是100字节, 应该能覆盖绝大多数报文了
result := [__DEFAULT_BUFFER_SIZE]byte{} // 全局buf, 默认是100字节, 应该能覆盖绝大多数报文了
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
if _, err2 := utils.ReadAtLeast(ctx, mdev.serialPort, result[:p.BufferSize],
p.BufferSize); err2 != nil {
Expand Down Expand Up @@ -426,7 +431,7 @@ func (mdev *CustomProtocolDevice) OnWrite(cmd []byte, data []byte) (int, error)
return 0, err1
}

result := [100]byte{} // 全局buf, 默认是100字节, 应该能覆盖绝大多数报文了
result := [__DEFAULT_BUFFER_SIZE]byte{} // 全局buf, 默认是100字节, 应该能覆盖绝大多数报文了
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
if _, err2 := utils.ReadAtLeast(ctx, mdev.serialPort, result[:p.BufferSize],
p.BufferSize); err2 != nil {
Expand Down Expand Up @@ -527,7 +532,7 @@ func (mdev *CustomProtocolDevice) OnCtrl(cmd []byte, args []byte) ([]byte, error
return nil, err1
}

result := [100]byte{} // 全局buf, 默认是100字节, 应该能覆盖绝大多数报文了
result := [__DEFAULT_BUFFER_SIZE]byte{} // 全局buf, 默认是100字节, 应该能覆盖绝大多数报文了
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
if _, err2 := utils.ReadAtLeast(ctx, mdev.serialPort, result[:p.BufferSize],
p.BufferSize); err2 != nil {
Expand All @@ -548,8 +553,32 @@ func (mdev *CustomProtocolDevice) OnCtrl(cmd []byte, args []byte) ([]byte, error
bytes, _ := json.Marshal(dataMap)
return (bytes), nil
}
//------------------------------------------------------------------------------------------
// 基于时间片的轮询协议
//------------------------------------------------------------------------------------------
// 时间片只读
if p.Type == 3 {
glogger.GLogger.Debug("Time slice SliceReceive:", p.TimeSlice)
result := [__DEFAULT_BUFFER_SIZE]byte{}
count, err := utils.SliceReceive(context.Background(),
mdev.serialPort, result[:], time.Duration(p.TimeSlice))
return (result[:count]), err
}
// 时间片读写
if p.Type == 4 {
glogger.GLogger.Debug("Time slice SliceRequest:", string(args))
hexs, err := hex.DecodeString(string(args))
if err != nil {
glogger.GLogger.Error(err)
return nil, err
}
result := [__DEFAULT_BUFFER_SIZE]byte{}
count, err := utils.SliceRequest(context.Background(),
mdev.serialPort, hexs, result[:], time.Duration(p.TimeSlice))
return (result[:count]), err
}
}
return nil, errors.New("unknown write command:" + string(cmd))
return nil, errors.New("unknown ctrl command:" + string(cmd))
}

// 设备当前状态
Expand Down
4 changes: 2 additions & 2 deletions typex/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func (v Version) String() string {
}

var DefaultVersion = Version{
Version: `v0.4.4`,
ReleaseTime: "2023-04-17 09:41:25",
Version: `v0.4.4-hotfix`,
ReleaseTime: "2023-04-18 17:56:26",
}

2 changes: 1 addition & 1 deletion utils/banner.b
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
|
|*| Welcome to RULEX framework world <'_'>
|*| Version: v0.4.4-f62e88103bc9af9
|*| Version: v0.4.4-hotfix-330d00f9f5ea993
|*| Document: https://rulex.pages.dev
|
54 changes: 54 additions & 0 deletions utils/io_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"io"
"time"
)

// 直接把io包下面的同名函数抄过来了,加上了Context支持,主要解决读取超时问题
Expand Down Expand Up @@ -41,3 +42,56 @@ func ReadAtLeast(ctx context.Context, r io.Reader, buf []byte, min int) (n int,
}
return
}

/*
*
* 时间片读写请求
*
*/
func SliceRequest(ctx context.Context,
iio io.ReadWriter, writeBytes []byte, resultBuffer []byte,
td time.Duration) (int, error) {
_, errW := iio.Write(writeBytes)
if errW != nil {
return 0, errW
}
return SliceReceive(ctx, iio, resultBuffer, td)
}

/*
*
* 通过一个定时时间片读取
*
*/
func SliceReceive(ctx context.Context,
iio io.Reader, resultBuffer []byte, td time.Duration) (int, error) {
var peerCount int
sliceTimer := time.NewTimer(td)
sliceTimer.Stop()
for {
select {
case <-ctx.Done():
return peerCount, nil
default:
readCount, errR := iio.Read(resultBuffer[peerCount:])
if errR != nil {
return peerCount, errR
}
if readCount != 0 {
sliceTimer.Reset(td)
peerCount += readCount
}
}
}
}

/*
*
* 某个时间片期望最少收到字节数
*
*/
func SliceReceiveAtLeast(ctx context.Context,
iio io.Reader, resultBuffer []byte, td time.Duration, min int) (int, error) {
// 后期实现
return 0, nil
}

0 comments on commit e2924d3

Please sign in to comment.