Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
nix61
rt-thread
提交
59f0f669
R
rt-thread
项目概览
nix61
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
1
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,发现更多精彩内容 >>
提交
59f0f669
编写于
8月 19, 2013
作者:
B
Bernard Xiong
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #144 from grissiom/portal-device
Portal device
上级
a8f9f85f
6e676e77
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
282 addition
and
1 deletion
+282
-1
components/drivers/include/rtdevice.h
components/drivers/include/rtdevice.h
+28
-0
components/drivers/src/pipe.c
components/drivers/src/pipe.c
+1
-1
components/drivers/src/portal.c
components/drivers/src/portal.c
+251
-0
include/rtdef.h
include/rtdef.h
+2
-0
未找到文件。
components/drivers/include/rtdevice.h
浏览文件 @
59f0f669
...
...
@@ -73,6 +73,14 @@ struct rt_ringbuffer
rt_int16_t
buffer_size
;
};
/* portal device */
struct
rt_portal_device
{
struct
rt_device
parent
;
struct
rt_device
*
write_dev
;
struct
rt_device
*
read_dev
;
};
/* pipe device */
#define PIPE_DEVICE(device) ((struct rt_pipe_device*)(device))
enum
rt_pipe_flag
...
...
@@ -101,6 +109,9 @@ struct rt_pipe_device
/* suspended list */
rt_list_t
suspended_read_list
;
rt_list_t
suspended_write_list
;
struct
rt_portal_device
*
write_portal
;
struct
rt_portal_device
*
read_portal
;
};
#define RT_DATAQUEUE_EVENT_UNKNOWN 0x00
...
...
@@ -224,6 +235,23 @@ rt_err_t rt_pipe_create(const char *name, enum rt_pipe_flag flag, rt_size_t size
void
rt_pipe_destroy
(
struct
rt_pipe_device
*
pipe
);
#endif
/**
* Portal for DeviceDriver
*/
rt_err_t
rt_portal_init
(
struct
rt_portal_device
*
portal
,
const
char
*
portal_name
,
const
char
*
write_dev
,
const
char
*
read_dev
);
rt_err_t
rt_portal_detach
(
struct
rt_portal_device
*
portal
);
#ifdef RT_USING_HEAP
rt_err_t
rt_portal_create
(
const
char
*
name
,
const
char
*
write_dev
,
const
char
*
read_dev
);
void
rt_portal_destroy
(
struct
rt_portal_device
*
portal
);
#endif
/**
* DataQueue for DeviceDriver
*/
...
...
components/drivers/src/pipe.c
浏览文件 @
59f0f669
...
...
@@ -224,7 +224,7 @@ rt_err_t rt_pipe_init(struct rt_pipe_device *pipe,
pipe
->
flag
=
flag
;
/* create pipe */
pipe
->
parent
.
type
=
RT_Device_Class_
Char
;
pipe
->
parent
.
type
=
RT_Device_Class_
Pipe
;
pipe
->
parent
.
init
=
RT_NULL
;
pipe
->
parent
.
open
=
RT_NULL
;
pipe
->
parent
.
close
=
RT_NULL
;
...
...
components/drivers/src/portal.c
0 → 100644
浏览文件 @
59f0f669
/*
* File : portal.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2013, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2013-08-19 Grissiom initial version
*/
#include <rtthread.h>
#include <rtdevice.h>
#define PT_WRITE_DEV(pt) (((struct rt_portal_device*)pt)->write_dev)
#define PT_READ_DEV(pt) (((struct rt_portal_device*)pt)->read_dev)
static
rt_err_t
_portal_init
(
rt_device_t
dev
)
{
rt_err_t
err
;
struct
rt_portal_device
*
portal
;
RT_ASSERT
(
dev
);
portal
=
(
struct
rt_portal_device
*
)
dev
;
err
=
rt_device_init
(
portal
->
write_dev
);
if
(
err
!=
RT_EOK
)
return
err
;
err
=
rt_device_init
(
portal
->
read_dev
);
return
err
;
}
static
rt_err_t
_portal_open
(
rt_device_t
dev
,
rt_uint16_t
oflag
)
{
rt_err_t
err
;
struct
rt_portal_device
*
portal
;
RT_ASSERT
(
dev
);
portal
=
(
struct
rt_portal_device
*
)
dev
;
if
(
oflag
&
RT_DEVICE_OFLAG_RDONLY
)
{
err
=
rt_device_open
(
portal
->
read_dev
,
RT_DEVICE_OFLAG_RDONLY
);
if
(
err
!=
RT_EOK
)
return
err
;
}
if
(
oflag
&
RT_DEVICE_OFLAG_WRONLY
)
{
err
=
rt_device_open
(
portal
->
write_dev
,
RT_DEVICE_OFLAG_WRONLY
);
if
(
err
!=
RT_EOK
)
return
err
;
}
return
RT_EOK
;
}
static
rt_err_t
_portal_close
(
rt_device_t
dev
)
{
struct
rt_portal_device
*
portal
;
RT_ASSERT
(
dev
);
portal
=
(
struct
rt_portal_device
*
)
dev
;
rt_device_close
(
portal
->
write_dev
);
rt_device_close
(
portal
->
read_dev
);
return
RT_EOK
;
}
static
rt_size_t
_portal_read
(
rt_device_t
dev
,
rt_off_t
pos
,
void
*
buffer
,
rt_size_t
size
)
{
return
rt_device_read
(
PT_READ_DEV
(
dev
),
pos
,
buffer
,
size
);
}
static
rt_size_t
_portal_write
(
rt_device_t
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
)
{
return
rt_device_write
(
PT_WRITE_DEV
(
dev
),
pos
,
buffer
,
size
);
}
static
rt_err_t
_portal_rx_indicate
(
rt_device_t
dev
,
rt_size_t
size
)
{
struct
rt_pipe_device
*
pipe
;
RT_ASSERT
(
dev
&&
dev
->
type
==
RT_Device_Class_Pipe
);
pipe
=
(
struct
rt_pipe_device
*
)
dev
;
if
(
pipe
->
read_portal
->
parent
.
rx_indicate
)
return
pipe
->
read_portal
->
parent
.
rx_indicate
(
dev
,
size
);
return
-
RT_ENOSYS
;
}
static
rt_err_t
_portal_tx_complete
(
rt_device_t
dev
,
void
*
buf
)
{
struct
rt_pipe_device
*
pipe
;
RT_ASSERT
(
dev
&&
dev
->
type
==
RT_Device_Class_Pipe
);
pipe
=
(
struct
rt_pipe_device
*
)
dev
;
if
(
pipe
->
write_portal
->
parent
.
tx_complete
)
return
pipe
->
write_portal
->
parent
.
tx_complete
(
dev
,
buf
);
return
-
RT_ENOSYS
;
}
/**
* This function will initialize a portal device and put it under control of
* resource management.
*
* Portal is a device that connect devices
*
* Currently, you can only connect pipes in portal. Pipes are unidirectional.
* But with portal, you can construct a bidirectional device with two pipes.
* The inner connection is just like this:
*
* portal0 portal1
* read || || write
* <--<---||<---<---||<---<-- (pipe0)
* || ||
* -->--->||--->--->||--->--> (pipe1)
* write || || read
*
* You will always construct two portals on two pipes, say, "portal0" and
* "portal1". Data written into "portal0" can be retrieved in "portal1" and
* vice versa. `rx_indicate` and `tx_complete` events are propagated
* accordingly.
*
* @param portal the portal device
* @param portal_name the name of the portal device
* @param write_dev the name of the pipe device that this portal write into
* @param read_dev the name of the pipe device that this portal read from
*
* @return the operation status, RT_EOK on successful. -RT_ENOSYS on one pipe
* device could not be found.
*/
rt_err_t
rt_portal_init
(
struct
rt_portal_device
*
portal
,
const
char
*
portal_name
,
const
char
*
write_dev
,
const
char
*
read_dev
)
{
rt_device_t
dev
;
RT_ASSERT
(
portal
);
portal
->
parent
.
type
=
RT_Device_Class_Portal
;
portal
->
parent
.
init
=
_portal_init
;
portal
->
parent
.
open
=
_portal_open
;
portal
->
parent
.
close
=
_portal_close
;
portal
->
parent
.
write
=
_portal_write
;
portal
->
parent
.
read
=
_portal_read
;
/* single control of the two devices makes no sense */
portal
->
parent
.
control
=
RT_NULL
;
dev
=
rt_device_find
(
write_dev
);
if
(
dev
==
RT_NULL
)
return
-
RT_ENOSYS
;
RT_ASSERT
(
dev
->
type
==
RT_Device_Class_Pipe
);
portal
->
write_dev
=
dev
;
rt_device_set_tx_complete
(
&
portal
->
parent
,
dev
->
tx_complete
);
rt_device_set_tx_complete
(
dev
,
_portal_tx_complete
);
((
struct
rt_pipe_device
*
)
dev
)
->
write_portal
=
portal
;
dev
=
rt_device_find
(
read_dev
);
if
(
dev
==
RT_NULL
)
{
rt_device_set_tx_complete
(
dev
,
portal
->
parent
.
tx_complete
);
return
-
RT_ENOSYS
;
}
RT_ASSERT
(
dev
->
type
==
RT_Device_Class_Pipe
);
portal
->
read_dev
=
dev
;
rt_device_set_rx_indicate
(
&
portal
->
parent
,
dev
->
rx_indicate
);
rt_device_set_rx_indicate
(
dev
,
_portal_rx_indicate
);
((
struct
rt_pipe_device
*
)
dev
)
->
read_portal
=
portal
;
return
rt_device_register
(
&
(
portal
->
parent
),
portal_name
,
RT_DEVICE_FLAG_RDWR
);
}
RTM_EXPORT
(
rt_portal_init
);
/**
* This function will detach a portal device from resource management
*
* @param portal the portal device
*
* @return the operation status, RT_EOK on successful
*/
rt_err_t
rt_portal_detach
(
struct
rt_portal_device
*
portal
)
{
return
rt_device_unregister
(
&
portal
->
parent
);
}
RTM_EXPORT
(
rt_portal_detach
);
#ifdef RT_USING_HEAP
rt_err_t
rt_portal_create
(
const
char
*
name
,
const
char
*
write_dev
,
const
char
*
read_dev
)
{
struct
rt_portal_device
*
portal
;
portal
=
(
struct
rt_portal_device
*
)
rt_calloc
(
1
,
sizeof
(
*
portal
));
if
(
portal
==
RT_NULL
)
return
-
RT_ENOMEM
;
return
rt_portal_init
(
portal
,
name
,
write_dev
,
read_dev
);
}
RTM_EXPORT
(
rt_portal_create
);
void
rt_portal_destroy
(
struct
rt_portal_device
*
portal
)
{
if
(
portal
==
RT_NULL
)
return
;
rt_portal_detach
(
portal
);
rt_free
(
portal
);
return
;
}
RTM_EXPORT
(
rt_portal_destroy
);
#endif
/* RT_USING_HEAP */
include/rtdef.h
浏览文件 @
59f0f669
...
...
@@ -739,6 +739,8 @@ enum rt_device_class_type
RT_Device_Class_SPIDevice
,
/**< SPI device */
RT_Device_Class_SDIO
,
/**< SDIO bus device */
RT_Device_Class_PM
,
/**< PM pseudo device */
RT_Device_Class_Pipe
,
/**< Pipe device */
RT_Device_Class_Portal
,
/**< Portal device */
RT_Device_Class_Miscellaneous
,
/**< Miscellaneous device */
RT_Device_Class_Unknown
/**< unknown device */
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录