Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
rt-thread
提交
537943ed
R
rt-thread
项目概览
BaiXuePrincess
/
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看板
提交
537943ed
编写于
1月 22, 2018
作者:
A
Aubr.Cool
提交者:
lymzzyh
1月 22, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[Components] driver usb vcom fix error for console (#1160)
* [Components] driver usb vcom fix error for console
上级
765df5b4
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
193 addition
and
77 deletion
+193
-77
components/drivers/usb/usbdevice/class/cdc_vcom.c
components/drivers/usb/usbdevice/class/cdc_vcom.c
+193
-77
未找到文件。
components/drivers/usb/usbdevice/class/cdc_vcom.c
浏览文件 @
537943ed
...
...
@@ -37,26 +37,41 @@
#ifdef RT_USB_DEVICE_CDC
#define TX_TIMEOUT 1000
#define CDC_RX_BUFSIZE
204
8
#define CDC_RX_BUFSIZE
12
8
#define CDC_MAX_PACKET_SIZE 64
#define VCOM_DEVICE "vcom"
#define VCOM_TASK_STK_SIZE 2048
#ifdef RT_VCOM_TASK_STK_SIZE
#define VCOM_TASK_STK_SIZE RT_VCOM_TASK_STK_SIZE
#else
/*!RT_VCOM_TASK_STK_SIZE*/
#define VCOM_TASK_STK_SIZE 512
#endif
/*RT_VCOM_TASK_STK_SIZE*/
//#define VCOM_TX_USE_DMA
#ifdef RT_VCOM_TX_USE_DMA
#define VCOM_TX_USE_DMA
#endif
/*RT_VCOM_TASK_STK_SIZE*/
#ifdef RT_VCOM_SERNO
#define _SER_NO RT_VCOM_SERNO
#else
/*!RT_VCOM_SERNO*/
#define _SER_NO "32021919830108"
#endif
/*RT_VCOM_SERNO*/
#ifdef RT_VCOM_SER_LEN
#define __SER_NO_LEN RT_VCOM_SER_LEN
#else
/*!RT_VCOM_SER_LEN*/
#define __SER_NO_LEN rt_strlen("32021919830108")
#endif
/*RT_VCOM_SER_LEN*/
ALIGN
(
RT_ALIGN_SIZE
)
static
rt_uint8_t
vcom_thread_stack
[
VCOM_TASK_STK_SIZE
];
static
struct
rt_thread
vcom_thread
;
#define VCOM_MQ_MSG_SZ 16
#define VCOM_MQ_MAX_MSG 4
/* internal of the message queue: every message is associated with a pointer,
* so in order to recveive VCOM_MQ_MAX_MSG messages, we have to allocate more
* than VCOM_MQ_MSG_SZ*VCOM_MQ_MAX_MSG memery. */
static
rt_uint8_t
vcom_tx_thread_mq_pool
[(
VCOM_MQ_MSG_SZ
+
sizeof
(
void
*
))
*
VCOM_MQ_MAX_MSG
];
static
struct
rt_messagequeue
vcom_tx_thread_mq
;
static
struct
ucdc_line_coding
line_coding
;
#define CDC_TX_BUFSIZE 1024
#define CDC_TX_HAS_DATE 0x01
struct
vcom
{
struct
rt_serial_device
serial
;
...
...
@@ -67,7 +82,10 @@ struct vcom
rt_bool_t
in_sending
;
struct
rt_completion
wait
;
rt_uint8_t
rx_rbp
[
CDC_RX_BUFSIZE
];
struct
rt_ringbuffer
rx_ringbuffer
;
struct
rt_ringbuffer
rx_ringbuffer
;
rt_uint8_t
tx_rbp
[
CDC_TX_BUFSIZE
];
struct
rt_ringbuffer
tx_ringbuffer
;
struct
rt_event
tx_event
;
};
struct
vcom_tx_msg
...
...
@@ -191,12 +209,17 @@ const static struct ucdc_data_descriptor _data_desc =
0x00
,
};
static
char
serno
[
_SER_NO_LEN
+
1
]
=
{
'\0'
,};
RT_WEAK
rt_err_t
vcom_get_stored_serno
(
char
*
serno
,
int
size
)
{
return
RT_ERROR
;
}
const
static
char
*
_ustring
[]
=
{
"Language"
,
"RT-Thread Team."
,
"RTT Virtual Serial"
,
"32021919830108"
,
serno
,
"Configuration"
,
"Interface"
,
};
...
...
@@ -233,7 +256,6 @@ static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size)
RT_ASSERT
(
func
!=
RT_NULL
);
RT_DEBUG_LOG
(
RT_DEBUG_USB
,
(
"_ep_in_handler %d
\n
"
,
size
));
rt_kprintf
(
"%s size = %d
\n
"
,
__func__
,
size
);
data
=
(
struct
vcom
*
)
func
->
user_data
;
if
((
size
!=
0
)
&&
(
size
%
CDC_MAX_PACKET_SIZE
==
0
))
{
...
...
@@ -286,7 +308,7 @@ static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size)
data
->
ep_out
->
request
.
buffer
=
data
->
ep_out
->
buffer
;
data
->
ep_out
->
request
.
size
=
EP_MAXPACKET
(
data
->
ep_out
);
data
->
ep_out
->
request
.
req_type
=
UIO_REQUEST_READ_BEST
;
data
->
ep_out
->
request
.
req_type
=
UIO_REQUEST_READ_BEST
;
rt_usbd_io_request
(
func
->
device
,
data
->
ep_out
,
&
data
->
ep_out
->
request
);
return
RT_EOK
;
...
...
@@ -442,7 +464,7 @@ static rt_err_t _function_enable(ufunction_t func)
data
->
ep_out
->
request
.
buffer
=
data
->
ep_out
->
buffer
;
data
->
ep_out
->
request
.
size
=
EP_MAXPACKET
(
data
->
ep_out
);
data
->
ep_out
->
request
.
req_type
=
UIO_REQUEST_READ_BEST
;
data
->
ep_out
->
request
.
req_type
=
UIO_REQUEST_READ_BEST
;
rt_usbd_io_request
(
func
->
device
,
data
->
ep_out
,
&
data
->
ep_out
->
request
);
return
RT_EOK
;
...
...
@@ -522,6 +544,14 @@ ufunction_t rt_usbd_function_cdc_create(udevice_t device)
/* parameter check */
RT_ASSERT
(
device
!=
RT_NULL
);
extern
rt_err_t
vcom_get_stored_serno
(
char
*
serno
,
int
size
);
rt_memset
(
serno
,
0
,
_SER_NO_LEN
+
1
);
if
(
vcom_get_stored_serno
(
serno
,
_SER_NO_LEN
)
!=
RT_EOK
)
{
rt_memset
(
serno
,
0
,
_SER_NO_LEN
+
1
);
rt_memcpy
(
serno
,
_SER_NO
,
rt_strlen
(
_SER_NO
));
}
/* set usb device string description */
rt_usbd_device_set_string
(
device
,
_ustring
);
...
...
@@ -636,113 +666,205 @@ static int _vcom_getc(struct rt_serial_device *serial)
return
result
;
}
#ifdef VCOM_TX_USE_DMA
static
rt_size_t
_vcom_tx
(
struct
rt_serial_device
*
serial
,
const
char
*
buf
,
rt_size_t
size
,
int
direction
)
static
rt_size_t
_vcom_tx
(
struct
rt_serial_device
*
serial
,
rt_uint8_t
*
buf
,
rt_size_t
size
,
int
direction
)
{
static
struct
vcom_tx_msg
msg
;
rt_uint32_t
level
;
struct
ufunction
*
func
;
struct
vcom
*
data
;
func
=
(
struct
ufunction
*
)
serial
->
parent
.
user_data
;
data
=
(
struct
vcom
*
)
func
->
user_data
;
rt_uint32_t
baksize
=
size
;
rt_size_t
ptr
=
0
;
int
empty
=
0
;
rt_uint8_t
crlf
[
2
]
=
{
'\r'
,
'\n'
,};
RT_ASSERT
(
serial
!=
RT_NULL
);
RT_ASSERT
(
buf
!=
RT_NULL
);
rt_kprintf
(
"%s
\n
"
,
__func__
);
msg
.
buf
=
buf
;
msg
.
serial
=
serial
;
msg
.
size
=
size
;
RT_DEBUG_LOG
(
RT_DEBUG_USB
,
(
"%s
\n
"
,
__func__
));
if
(
rt_mq_send
(
&
vcom_tx_thread_mq
,
(
void
*
)
&
msg
,
sizeof
(
struct
vcom_tx_msg
))
!=
RT_EOK
)
if
(
data
->
connected
)
{
rt_kprintf
(
"vcom send msg fail
\n
"
);
return
0
;
}
size
=
0
;
if
((
serial
->
parent
.
open_flag
&
RT_DEVICE_FLAG_STREAM
))
{
empty
=
0
;
while
(
ptr
<
baksize
)
{
while
(
ptr
<
baksize
&&
buf
[
ptr
]
!=
'\n'
)
{
ptr
++
;
}
if
(
ptr
<
baksize
)
{
level
=
rt_hw_interrupt_disable
();
size
+=
rt_ringbuffer_put_force
(
&
data
->
tx_ringbuffer
,
(
const
rt_uint8_t
*
)
&
buf
[
size
],
ptr
-
size
);
rt_hw_interrupt_enable
(
level
);
if
(
size
==
ptr
)
{
level
=
rt_hw_interrupt_disable
();
if
(
rt_ringbuffer_space_len
(
&
data
->
tx_ringbuffer
)
>=
2
)
{
rt_ringbuffer_put_force
(
&
data
->
tx_ringbuffer
,
crlf
,
2
);
size
++
;
}
rt_hw_interrupt_enable
(
level
);
}
else
{
empty
=
1
;
break
;
}
if
(
size
==
ptr
)
{
empty
=
1
;
break
;
}
ptr
++
;
}
else
{
break
;
}
}
}
if
(
size
<
baksize
&&
!
empty
)
{
level
=
rt_hw_interrupt_disable
();
size
+=
rt_ringbuffer_put_force
(
&
data
->
tx_ringbuffer
,
(
rt_uint8_t
*
)
&
buf
[
size
],
baksize
-
size
);
rt_hw_interrupt_enable
(
level
);
}
if
(
size
)
{
rt_event_send
(
&
data
->
tx_event
,
CDC_TX_HAS_DATE
);
}
}
return
size
;
}
#else
static
int
_vcom_putc
(
struct
rt_serial_device
*
serial
,
char
c
)
{
static
struct
vcom_tx_msg
msg
;
rt_uint32_t
level
;
struct
ufunction
*
func
;
struct
vcom
*
data
;
func
=
(
struct
ufunction
*
)
serial
->
parent
.
user_data
;
data
=
(
struct
vcom
*
)
func
->
user_data
;
RT_ASSERT
(
serial
!=
RT_NULL
);
msg
.
buf
=
(
void
*
)((
rt_uint32_t
)
c
);
msg
.
serial
=
serial
;
msg
.
size
=
1
;
if
(
rt_mq_send
(
&
vcom_tx_thread_mq
,
(
void
*
)
&
msg
,
sizeof
(
struct
vcom_tx_msg
))
!=
RT_EOK
)
if
(
data
->
connected
)
{
// rt_kprintf("vcom send msg fail\n");
return
-
1
;
if
(
c
==
'\n'
&&
(
serial
->
parent
.
open_flag
&
RT_DEVICE_FLAG_STREAM
))
{
level
=
rt_hw_interrupt_disable
();
rt_ringbuffer_putchar_force
(
&
data
->
tx_ringbuffer
,
'\r'
);
rt_hw_interrupt_enable
(
level
);
rt_event_send
(
&
data
->
tx_event
,
CDC_TX_HAS_DATE
);
}
level
=
rt_hw_interrupt_disable
();
rt_ringbuffer_putchar_force
(
&
data
->
tx_ringbuffer
,
c
);
rt_hw_interrupt_enable
(
level
);
rt_event_send
(
&
data
->
tx_event
,
CDC_TX_HAS_DATE
);
}
return
1
;
}
#endif
static
const
struct
rt_uart_ops
usb_vcom_ops
=
{
_vcom_configure
,
_vcom_control
,
#ifndef VCOM_TX_USE_DMA
_vcom_putc
,
_vcom_getc
,
RT_NULL
#else
RT_NULL
,
_vcom_getc
,
_vcom_tx
#endif
};
/* Vcom Tx Thread */
static
void
vcom_tx_thread_entry
(
void
*
parameter
)
{
struct
vcom_tx_msg
msg
;
rt_uint8_t
ch
;
rt_uint32_t
level
;
rt_uint32_t
res
;
struct
ufunction
*
func
=
(
struct
ufunction
*
)
parameter
;
struct
vcom
*
data
=
(
struct
vcom
*
)
func
->
user_data
;
rt_uint8_t
ch
[
64
];
while
(
1
)
{
if
(
rt_mq_recv
(
&
vcom_tx_thread_mq
,
(
void
*
)
&
msg
,
sizeof
(
struct
vcom_tx_msg
),
RT_WAITING_FOREVER
)
==
RT_EOK
)
if
(
(
rt_event_recv
(
&
data
->
tx_event
,
CDC_TX_HAS_DATE
,
RT_EVENT_FLAG_OR
|
RT_EVENT_FLAG_CLEAR
,
RT_WAITING_FOREVER
,
&
res
)
!=
RT_EOK
)
||
(
!
(
res
&
CDC_TX_HAS_DATE
))
)
{
struct
ufunction
*
func
;
struct
vcom
*
data
;
func
=
(
struct
ufunction
*
)
msg
.
serial
->
parent
.
user_data
;
data
=
(
struct
vcom
*
)
func
->
user_data
;
continue
;
}
if
(
!
res
&
CDC_TX_HAS_DATE
)
{
continue
;
}
while
(
rt_ringbuffer_data_len
(
&
data
->
tx_ringbuffer
))
{
level
=
rt_hw_interrupt_disable
();
res
=
rt_ringbuffer_get
(
&
data
->
tx_ringbuffer
,
ch
,
64
);
rt_hw_interrupt_enable
(
level
);
if
(
!
res
)
{
continue
;
}
if
(
!
data
->
connected
)
{
if
(
data
->
serial
.
parent
.
open_flag
&
#ifndef VCOM_TX_USE_DMA
RT_DEVICE_FLAG_INT_TX
#else
RT_DEVICE_FLAG_DMA_TX
#endif
)
{
/* drop msg */
#ifndef VCOM_TX_USE_DMA
rt_hw_serial_isr
(
&
data
->
serial
,
RT_SERIAL_EVENT_TX_DONE
);
rt_hw_serial_isr
(
&
data
->
serial
,
RT_SERIAL_EVENT_TX_DONE
);
#else
rt_hw_serial_isr
(
&
data
->
serial
,
RT_SERIAL_EVENT_TX_DMADONE
);
rt_hw_serial_isr
(
&
data
->
serial
,
RT_SERIAL_EVENT_TX_DMADONE
);
#endif
}
continue
;
}
rt_completion_init
(
&
data
->
wait
);
#ifndef VCOM_TX_USE_DMA
ch
=
(
rt_uint8_t
)((
rt_uint32_t
)
msg
.
buf
);
data
->
ep_in
->
request
.
buffer
=
(
rt_uint8_t
*
)
&
ch
;
#else
data
->
ep_in
->
request
.
buffer
=
(
rt_uint8_t
*
)
msg
.
buf
;
#endif
data
->
ep_in
->
request
.
size
=
msg
.
size
;
data
->
ep_in
->
request
.
buffer
=
ch
;
data
->
ep_in
->
request
.
size
=
res
;
data
->
ep_in
->
request
.
req_type
=
UIO_REQUEST_WRITE
;
rt_usbd_io_request
(
func
->
device
,
data
->
ep_in
,
&
data
->
ep_in
->
request
);
if
(
rt_completion_wait
(
&
data
->
wait
,
TX_TIMEOUT
)
!=
RT_EOK
)
{
rt_kprintf
(
"vcom tx timeout
\n
"
);
RT_DEBUG_LOG
(
RT_DEBUG_USB
,
(
"vcom tx timeout
\n
"
)
);
}
if
(
data
->
serial
.
parent
.
open_flag
&
#ifndef VCOM_TX_USE_DMA
rt_hw_serial_isr
(
&
data
->
serial
,
RT_SERIAL_EVENT_TX_DONE
);
RT_DEVICE_FLAG_INT_TX
#else
rt_hw_serial_isr
(
&
data
->
serial
,
RT_SERIAL_EVENT_TX_DMADONE
);
RT_DEVICE_FLAG_DMA_TX
#endif
)
{
#ifndef VCOM_TX_USE_DMA
rt_hw_serial_isr
(
&
data
->
serial
,
RT_SERIAL_EVENT_TX_DONE
);
#else
rt_hw_serial_isr
(
&
data
->
serial
,
RT_SERIAL_EVENT_TX_DMADONE
);
#endif
}
}
}
}
...
...
@@ -754,6 +876,9 @@ static void rt_usb_vcom_init(struct ufunction *func)
/* initialize ring buffer */
rt_ringbuffer_init
(
&
data
->
rx_ringbuffer
,
data
->
rx_rbp
,
CDC_RX_BUFSIZE
);
rt_ringbuffer_init
(
&
data
->
tx_ringbuffer
,
data
->
tx_rbp
,
CDC_TX_BUFSIZE
);
rt_event_init
(
&
data
->
tx_event
,
"vom"
,
RT_IPC_FLAG_FIFO
);
config
.
baud_rate
=
BAUD_RATE_115200
;
config
.
data_bits
=
DATA_BITS_8
;
...
...
@@ -776,20 +901,11 @@ static void rt_usb_vcom_init(struct ufunction *func)
#endif
func
);
/* create an vcom message queue */
rt_mq_init
(
&
vcom_tx_thread_mq
,
"vcomq"
,
vcom_tx_thread_mq_pool
,
VCOM_MQ_MSG_SZ
,
sizeof
(
vcom_tx_thread_mq_pool
),
RT_IPC_FLAG_FIFO
);
/* init usb device thread */
rt_thread_init
(
&
vcom_thread
,
"vcom"
,
vcom_tx_thread_entry
,
RT_NULL
,
vcom_tx_thread_entry
,
func
,
vcom_thread_stack
,
VCOM_TASK_STK_SIZE
,
8
,
20
);
16
,
20
);
result
=
rt_thread_startup
(
&
vcom_thread
);
RT_ASSERT
(
result
==
RT_EOK
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录