Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Mr_Pangza
rt-thread
提交
91d866d8
R
rt-thread
项目概览
Mr_Pangza
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
2
Star
1
Fork
1
代码
文件
提交
分支
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,发现更多精彩内容 >>
提交
91d866d8
编写于
7月 06, 2015
作者:
B
BernardXiong
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[DeviceDrivers] Use mutex to lock can_open/close
上级
14885688
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
250 addition
and
362 deletion
+250
-362
components/drivers/can/can.c
components/drivers/can/can.c
+82
-196
components/drivers/include/drivers/can.h
components/drivers/include/drivers/can.h
+168
-166
未找到文件。
components/drivers/can/can.c
浏览文件 @
91d866d8
...
...
@@ -3,20 +3,33 @@
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2015, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
* 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
* 2015-05-14 aubrcool@qq.com first version
* 2015-07-06 Bernard code cleanup
.
* 2015-07-06 Bernard code cleanup
and remove RT_CAN_USING_LED;
*/
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#define CAN_LOCK(can) rt_mutex_take(&(can->lock), RT_WAITING_FOREVER)
#define CAN_UNLOCK(can) rt_mutex_release(&(can->lock))
static
rt_err_t
rt_can_init
(
struct
rt_device
*
dev
)
{
rt_err_t
result
=
RT_EOK
;
...
...
@@ -54,7 +67,6 @@ rt_inline int _can_int_rx(struct rt_can_device *can, struct rt_can_msg *data, in
while
(
msgs
)
{
rt_base_t
level
;
rt_int32_t
hdr
;
struct
rt_can_msg_list
*
listmsg
=
RT_NULL
;
/* disable interrupt */
...
...
@@ -75,6 +87,7 @@ rt_inline int _can_int_rx(struct rt_can_device *can, struct rt_can_msg *data, in
}
else
if
(
hdr
==
-
1
)
#endif
/*RT_CAN_USING_HDR*/
{
if
(
!
rt_list_isempty
(
&
rx_fifo
->
uselist
))
{
listmsg
=
rt_list_entry
(
rx_fifo
->
uselist
.
next
,
struct
rt_can_msg_list
,
list
);
...
...
@@ -86,7 +99,7 @@ rt_inline int _can_int_rx(struct rt_can_device *can, struct rt_can_msg *data, in
listmsg
->
owner
->
msgs
--
;
}
listmsg
->
owner
=
RT_NULL
;
#endif
#endif
/*RT_CAN_USING_HDR*/
}
else
{
...
...
@@ -94,17 +107,20 @@ rt_inline int _can_int_rx(struct rt_can_device *can, struct rt_can_msg *data, in
rt_hw_interrupt_enable
(
level
);
break
;
}
}
/* enable interrupt */
rt_hw_interrupt_enable
(
level
);
if
(
listmsg
!=
RT_NULL
)
{
rt_memcpy
(
data
,
&
listmsg
->
data
,
sizeof
(
struct
rt_can_msg
));
level
=
rt_hw_interrupt_disable
();
rt_list_insert_before
(
&
rx_fifo
->
freelist
,
&
listmsg
->
list
);
rx_fifo
->
freenumbers
++
;
RT_ASSERT
(
rx_fifo
->
freenumbers
<=
can
->
config
.
msgboxsz
);
rt_hw_interrupt_enable
(
level
);
listmsg
=
RT_NULL
;
}
else
...
...
@@ -146,20 +162,23 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
else
{
rt_hw_interrupt_enable
(
level
);
rt_completion_wait
(
&
(
tx_fifo
->
completion
),
RT_WAITING_FOREVER
);
continue
;
}
rt_hw_interrupt_enable
(
level
);
no
=
((
rt_uint32_t
)
tx_tosnd
-
(
rt_uint32_t
)
tx_fifo
->
buffer
)
/
sizeof
(
struct
rt_can_sndbxinx_list
);
tx_tosnd
->
result
=
RT_CAN_
_SND_RESUTL
_WAIT
;
if
(
can
->
ops
->
sendmsg
(
can
,
data
,
no
)
)
tx_tosnd
->
result
=
RT_CAN_
SND_RESULT
_WAIT
;
if
(
can
->
ops
->
sendmsg
(
can
,
data
,
no
)
!=
RT_EOK
)
{
/* send failed. */
level
=
rt_hw_interrupt_disable
();
rt_list_insert_after
(
&
tx_fifo
->
freelist
,
&
tx_tosnd
->
list
);
rt_hw_interrupt_enable
(
level
);
continue
;
}
can
->
status
.
sndchange
=
1
;
rt_completion_wait
(
&
(
tx_tosnd
->
completion
),
RT_WAITING_FOREVER
);
...
...
@@ -172,11 +191,12 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
rt_list_insert_before
(
&
tx_fifo
->
freelist
,
&
tx_tosnd
->
list
);
rt_hw_interrupt_enable
(
level
);
if
(
result
==
RT_CAN_
_SND_RESUTL
_OK
)
if
(
result
==
RT_CAN_
SND_RESULT
_OK
)
{
level
=
rt_hw_interrupt_disable
();
can
->
status
.
sndpkg
++
;
rt_hw_interrupt_enable
(
level
);
data
++
;
msgs
-=
sizeof
(
struct
rt_can_msg
);
if
(
!
msgs
)
break
;
...
...
@@ -192,13 +212,9 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
level
=
rt_hw_interrupt_disable
();
if
(
rt_list_isempty
(
&
tx_fifo
->
freelist
))
{
rt_hw_interrupt_enable
(
level
);
rt_completion_done
(
&
(
tx_fifo
->
completion
));
}
else
{
rt_hw_interrupt_enable
(
level
);
}
rt_hw_interrupt_enable
(
level
);
}
return
(
size
-
msgs
);
...
...
@@ -226,16 +242,17 @@ rt_inline int _can_int_tx_priv(struct rt_can_device *can, const struct rt_can_ms
}
level
=
rt_hw_interrupt_disable
();
if
((
tx_fifo
->
buffer
[
no
].
result
!=
RT_CAN_
_SND_RESUTL
_OK
))
if
((
tx_fifo
->
buffer
[
no
].
result
!=
RT_CAN_
SND_RESULT
_OK
))
{
rt_hw_interrupt_enable
(
level
);
rt_completion_wait
(
&
(
tx_fifo
->
buffer
[
no
].
completion
),
RT_WAITING_FOREVER
);
continue
;
}
tx_fifo
->
buffer
[
no
].
result
=
RT_CAN_
_SND_RESUTL
_WAIT
;
tx_fifo
->
buffer
[
no
].
result
=
RT_CAN_
SND_RESULT
_WAIT
;
rt_hw_interrupt_enable
(
level
);
if
(
can
->
ops
->
sendmsg
(
can
,
data
,
no
)
!=
RT_EOK
)
if
(
can
->
ops
->
sendmsg
(
can
,
data
,
no
)
!=
RT_EOK
)
{
continue
;
}
...
...
@@ -243,7 +260,7 @@ rt_inline int _can_int_tx_priv(struct rt_can_device *can, const struct rt_can_ms
rt_completion_wait
(
&
(
tx_fifo
->
buffer
[
no
].
completion
),
RT_WAITING_FOREVER
);
result
=
tx_fifo
->
buffer
[
no
].
result
;
if
(
result
==
RT_CAN_
_SND_RESUTL
_OK
)
if
(
result
==
RT_CAN_
SND_RESULT
_OK
)
{
level
=
rt_hw_interrupt_disable
();
can
->
status
.
sndpkg
++
;
...
...
@@ -271,19 +288,21 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
RT_ASSERT
(
dev
!=
RT_NULL
);
can
=
(
struct
rt_can_device
*
)
dev
;
CAN_LOCK
(
can
);
/* get open flags */
dev
->
open_flag
=
oflag
&
0xff
;
rt_enter_critical
();
if
(
can
->
can_rx
==
RT_NULL
)
{
if
(
oflag
&
RT_DEVICE_FLAG_INT_RX
)
{
int
i
=
0
;
int
i
=
0
;
struct
rt_can_rx_fifo
*
rx_fifo
;
rx_fifo
=
(
struct
rt_can_rx_fifo
*
)
rt_malloc
(
sizeof
(
struct
rt_can_rx_fifo
)
+
can
->
config
.
msgboxsz
*
sizeof
(
struct
rt_can_msg_list
));
RT_ASSERT
(
rx_fifo
!=
RT_NULL
);
rx_fifo
->
buffer
=
(
struct
rt_can_msg_list
*
)(
rx_fifo
+
1
);
rt_memset
(
rx_fifo
->
buffer
,
0
,
can
->
config
.
msgboxsz
*
sizeof
(
struct
rt_can_msg_list
));
rt_list_init
(
&
rx_fifo
->
freelist
);
...
...
@@ -298,7 +317,6 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
#endif
}
can
->
can_rx
=
rx_fifo
;
rt_exit_critical
();
dev
->
open_flag
|=
RT_DEVICE_FLAG_INT_RX
;
/* configure low level device */
...
...
@@ -307,15 +325,9 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
else
{
can
->
can_rx
=
RT_NULL
;
rt_exit_critical
();
}
}
else
{
rt_exit_critical
();
}
rt_enter_critical
();
if
(
can
->
can_tx
==
RT_NULL
)
{
if
(
oflag
&
RT_DEVICE_FLAG_INT_TX
)
...
...
@@ -326,6 +338,7 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
tx_fifo
=
(
struct
rt_can_tx_fifo
*
)
rt_malloc
(
sizeof
(
struct
rt_can_tx_fifo
)
+
can
->
config
.
sndboxnumber
*
sizeof
(
struct
rt_can_sndbxinx_list
));
RT_ASSERT
(
tx_fifo
!=
RT_NULL
);
tx_fifo
->
buffer
=
(
struct
rt_can_sndbxinx_list
*
)(
tx_fifo
+
1
);
rt_memset
(
tx_fifo
->
buffer
,
0
,
can
->
config
.
sndboxnumber
*
sizeof
(
struct
rt_can_sndbxinx_list
));
...
...
@@ -334,11 +347,11 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
{
rt_list_insert_before
(
&
tx_fifo
->
freelist
,
&
tx_fifo
->
buffer
[
i
].
list
);
rt_completion_init
(
&
(
tx_fifo
->
buffer
[
i
].
completion
));
tx_fifo
->
buffer
[
i
].
result
=
RT_CAN_
_SND_RESUTL
_OK
;
tx_fifo
->
buffer
[
i
].
result
=
RT_CAN_
SND_RESULT
_OK
;
}
rt_completion_init
(
&
(
tx_fifo
->
completion
));
can
->
can_tx
=
tx_fifo
;
rt_exit_critical
();
dev
->
open_flag
|=
RT_DEVICE_FLAG_INT_TX
;
/* configure low level device */
can
->
ops
->
control
(
can
,
RT_DEVICE_CTRL_SET_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_TX
);
...
...
@@ -346,25 +359,17 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
else
{
can
->
can_tx
=
RT_NULL
;
rt_exit_critical
();
}
}
else
{
rt_exit_critical
();
}
can
->
ops
->
control
(
can
,
RT_DEVICE_CTRL_SET_INT
,
(
void
*
)
RT_DEVICE_CAN_INT_ERR
);
#ifdef RT_CAN_USING_HDR
rt_enter_critical
();
if
(
can
->
hdr
==
RT_NULL
)
{
int
i
=
0
;
struct
rt_can_hdr
*
phdr
;
/* exit critical region for malloc a header. */
rt_exit_critical
();
phdr
=
(
struct
rt_can_hdr
*
)
rt_malloc
(
can
->
config
.
maxhdr
*
sizeof
(
struct
rt_can_hdr
));
RT_ASSERT
(
phdr
!=
RT_NULL
);
rt_memset
(
phdr
,
0
,
can
->
config
.
maxhdr
*
sizeof
(
struct
rt_can_hdr
));
...
...
@@ -373,45 +378,18 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
rt_list_init
(
&
phdr
[
i
].
list
);
}
rt_enter_critical
();
can
->
hdr
=
phdr
;
rt_exit_critical
();
}
else
{
rt_exit_critical
();
}
#endif
rt_enter_critical
();
if
(
!
can
->
timerinitflag
)
{
can
->
timerinitflag
=
1
;
rt_exit_critical
();
#ifdef RT_CAN_USING_LED
if
(
can
->
config
.
rcvled
!=
RT_NULL
)
{
rt_pin_mode
(
can
->
config
.
rcvled
->
pin
,
can
->
config
.
rcvled
->
mode
);
rt_pin_write
(
can
->
config
.
rcvled
->
pin
,
can
->
config
.
rcvled
->
init
);
}
if
(
can
->
config
.
sndled
!=
RT_NULL
)
{
rt_pin_mode
(
can
->
config
.
sndled
->
pin
,
can
->
config
.
sndled
->
mode
);
rt_pin_write
(
can
->
config
.
sndled
->
pin
,
can
->
config
.
sndled
->
init
);
}
if
(
can
->
config
.
errled
!=
RT_NULL
)
{
rt_pin_mode
(
can
->
config
.
errled
->
pin
,
can
->
config
.
errled
->
mode
);
rt_pin_write
(
can
->
config
.
errled
->
pin
,
can
->
config
.
errled
->
init
);
}
#endif
rt_timer_start
(
&
can
->
timer
);
}
else
{
rt_exit_critical
();
}
CAN_UNLOCK
(
can
);
return
RT_EOK
;
}
...
...
@@ -423,48 +401,33 @@ static rt_err_t rt_can_close(struct rt_device *dev)
RT_ASSERT
(
dev
!=
RT_NULL
);
can
=
(
struct
rt_can_device
*
)
dev
;
CAN_LOCK
(
can
);
/* this device has more reference count */
if
(
dev
->
ref_count
>
1
)
return
RT_EOK
;
if
(
dev
->
ref_count
>
1
)
{
CAN_UNLOCK
(
can
);
return
RT_EOK
;
}
rt_enter_critical
();
if
(
can
->
timerinitflag
)
{
can
->
timerinitflag
=
0
;
rt_exit_critical
();
rt_timer_stop
(
&
can
->
timer
);
#ifdef RT_CAN_USING_LED
rt_pin_write
(
can
->
config
.
rcvled
->
pin
,
can
->
config
.
rcvled
->
init
);
rt_pin_write
(
can
->
config
.
rcvled
->
pin
,
can
->
config
.
sndled
->
init
);
rt_pin_write
(
can
->
config
.
rcvled
->
pin
,
can
->
config
.
errled
->
init
);
#endif
}
else
{
rt_exit_critical
();
}
rt_enter_critical
();
can
->
status_indicate
.
ind
=
RT_NULL
;
can
->
status_indicate
.
args
=
RT_NULL
;
rt_exit_critical
();
#ifdef RT_CAN_USING_HDR
rt_enter_critical
();
if
(
can
->
hdr
!=
RT_NULL
)
{
struct
rt_can_hdr
*
hdr
;
hdr
=
can
->
hdr
;
rt_free
(
can
->
hdr
);
can
->
hdr
=
RT_NULL
;
rt_exit_critical
();
rt_free
(
hdr
);
}
else
{
rt_exit_critical
();
}
#endif
if
(
dev
->
open_flag
&
RT_DEVICE_FLAG_INT_RX
)
{
struct
rt_can_rx_fifo
*
rx_fifo
;
...
...
@@ -475,8 +438,9 @@ static rt_err_t rt_can_close(struct rt_device *dev)
rt_free
(
rx_fifo
);
dev
->
open_flag
&=
~
RT_DEVICE_FLAG_INT_RX
;
/* configure low level device */
can
->
ops
->
control
(
can
,
RT_DEVICE_CTRL_CLR_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_
T
X
);
can
->
ops
->
control
(
can
,
RT_DEVICE_CTRL_CLR_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_
R
X
);
}
if
(
dev
->
open_flag
&
RT_DEVICE_FLAG_INT_TX
)
{
struct
rt_can_tx_fifo
*
tx_fifo
;
...
...
@@ -489,7 +453,11 @@ static rt_err_t rt_can_close(struct rt_device *dev)
/* configure low level device */
can
->
ops
->
control
(
can
,
RT_DEVICE_CTRL_CLR_INT
,
(
void
*
)
RT_DEVICE_FLAG_INT_TX
);
}
can
->
ops
->
control
(
can
,
RT_DEVICE_CTRL_CLR_INT
,
(
void
*
)
RT_DEVICE_CAN_INT_ERR
);
CAN_UNLOCK
(
can
);
return
RT_EOK
;
}
...
...
@@ -505,7 +473,7 @@ static rt_size_t rt_can_read(struct rt_device *dev,
can
=
(
struct
rt_can_device
*
)
dev
;
if
(
dev
->
open_flag
&
RT_DEVICE_FLAG_INT_RX
)
if
(
(
dev
->
open_flag
&
RT_DEVICE_FLAG_INT_RX
)
&&
(
dev
->
ref_count
>
0
)
)
{
return
_can_int_rx
(
can
,
buffer
,
size
);
}
...
...
@@ -525,7 +493,7 @@ static rt_size_t rt_can_write(struct rt_device *dev,
can
=
(
struct
rt_can_device
*
)
dev
;
if
(
dev
->
open_flag
&
RT_DEVICE_FLAG_INT_TX
)
if
(
(
dev
->
open_flag
&
RT_DEVICE_FLAG_INT_TX
)
&&
(
dev
->
ref_count
>
0
)
)
{
if
(
can
->
config
.
privmode
)
{
...
...
@@ -573,10 +541,8 @@ static rt_err_t rt_can_control(struct rt_device *dev,
rt_base_t
level
;
struct
rt_can_tx_fifo
*
tx_fifo
;
if
(
res
=
can
->
ops
->
control
(
can
,
cmd
,
args
)
!=
RT_EOK
)
{
return
res
;
}
res
=
can
->
ops
->
control
(
can
,
cmd
,
args
);
if
(
res
!=
RT_EOK
)
return
res
;
tx_fifo
=
(
struct
rt_can_tx_fifo
*
)
can
->
can_tx
;
if
(
can
->
config
.
privmode
)
...
...
@@ -595,7 +561,7 @@ static rt_err_t rt_can_control(struct rt_device *dev,
for
(
i
=
0
;
i
<
can
->
config
.
sndboxnumber
;
i
++
)
{
level
=
rt_hw_interrupt_disable
();
if
(
tx_fifo
->
buffer
[
i
].
result
==
RT_CAN_
_SND_RESUTL
_OK
)
if
(
tx_fifo
->
buffer
[
i
].
result
==
RT_CAN_
SND_RESULT
_OK
)
{
rt_list_insert_before
(
&
tx_fifo
->
freelist
,
&
tx_fifo
->
buffer
[
i
].
list
);
}
...
...
@@ -605,10 +571,12 @@ static rt_err_t rt_can_control(struct rt_device *dev,
return
RT_EOK
;
}
break
;
case
RT_CAN_CMD_SET_STATUS_IND
:
can
->
status_indicate
.
ind
=
((
rt_can_status_ind_type_t
)
args
)
->
ind
;
can
->
status_indicate
.
args
=
((
rt_can_status_ind_type_t
)
args
)
->
args
;
break
;
#ifdef RT_CAN_USING_HDR
case
RT_CAN_CMD_SET_FILTER
:
res
=
can
->
ops
->
control
(
can
,
cmd
,
args
);
...
...
@@ -636,8 +604,8 @@ static rt_err_t rt_can_control(struct rt_device *dev,
pitem
++
;
continue
;
}
level
=
rt_hw_interrupt_disable
();
level
=
rt_hw_interrupt_disable
();
if
(
!
can
->
hdr
[
pitem
->
hdr
].
connected
)
{
rt_memcpy
(
&
can
->
hdr
[
pitem
->
hdr
].
filter
,
pitem
,
...
...
@@ -647,6 +615,7 @@ static rt_err_t rt_can_control(struct rt_device *dev,
rt_list_init
(
&
can
->
hdr
[
pitem
->
hdr
].
list
);
}
rt_hw_interrupt_enable
(
level
);
count
--
;
pitem
++
;
}
...
...
@@ -682,6 +651,7 @@ static rt_err_t rt_can_control(struct rt_device *dev,
}
break
;
#endif
/*RT_CAN_USING_HDR*/
default
:
/* control device */
if
(
can
->
ops
->
control
!=
RT_NULL
)
...
...
@@ -699,105 +669,14 @@ static rt_err_t rt_can_control(struct rt_device *dev,
*/
static
void
cantimeout
(
void
*
arg
)
{
#ifdef RT_CAN_USING_LED
rt_uint32_t
ledonflag
=
0
;
#endif
/*RT_CAN_USING_LED*/
rt_can_t
can
=
(
rt_can_t
)
arg
;
rt_device_control
((
rt_device_t
)
can
,
RT_CAN_CMD_GET_STATUS
,
(
void
*
)
&
can
->
status
);
if
(
can
->
timerinitflag
==
1
)
{
#ifdef RT_CAN_USING_LED
ledonflag
=
1
;
#endif
/*RT_CAN_USING_LED*/
can
->
timerinitflag
=
0xFF
;
}
#ifdef RT_CAN_USING_LED
if
(
can
->
config
.
rcvled
!=
RT_NULL
&&
can
->
config
.
sndled
==
RT_NULL
)
{
if
(
ledonflag
==
1
)
{
rt_pin_write
(
can
->
config
.
rcvled
->
pin
,
can
->
config
.
rcvled
->
init
?
0
:
1
);
}
else
{
if
(
can
->
status
.
rcvchange
==
1
||
can
->
status
.
sndchange
==
1
)
{
can
->
status
.
rcvchange
=
0
;
can
->
status
.
sndchange
=
0
;
rt_pin_write
(
can
->
config
.
rcvled
->
pin
,
rt_pin_read
(
can
->
config
.
rcvled
->
pin
)
?
0
:
1
);
}
else
{
rt_pin_write
(
can
->
config
.
rcvled
->
pin
,
can
->
config
.
rcvled
->
init
);
}
}
}
else
if
(
can
->
config
.
rcvled
!=
RT_NULL
&&
can
->
config
.
sndled
!=
RT_NULL
)
{
if
(
ledonflag
==
1
)
{
rt_pin_write
(
can
->
config
.
rcvled
->
pin
,
can
->
config
.
rcvled
->
init
?
0
:
1
);
rt_pin_write
(
can
->
config
.
sndled
->
pin
,
can
->
config
.
sndled
->
init
?
0
:
1
);
}
else
{
if
(
can
->
status
.
rcvchange
==
1
)
{
can
->
status
.
rcvchange
=
0
;
rt_pin_write
(
can
->
config
.
rcvled
->
pin
,
rt_pin_read
(
can
->
config
.
rcvled
->
pin
)
?
0
:
1
);
}
else
{
rt_pin_write
(
can
->
config
.
rcvled
->
pin
,
can
->
config
.
rcvled
->
init
);
}
if
(
can
->
status
.
sndchange
==
1
)
{
can
->
status
.
sndchange
=
0
;
rt_pin_write
(
can
->
config
.
sndled
->
pin
,
rt_pin_read
(
can
->
config
.
sndled
->
pin
)
?
0
:
1
);
}
else
{
rt_pin_write
(
can
->
config
.
sndled
->
pin
,
can
->
config
.
sndled
->
init
);
}
}
}
else
if
(
can
->
config
.
rcvled
==
RT_NULL
&&
can
->
config
.
sndled
!=
RT_NULL
)
{
if
(
ledonflag
==
1
)
{
rt_pin_write
(
can
->
config
.
sndled
->
pin
,
can
->
config
.
sndled
->
init
?
0
:
1
);
}
else
{
if
(
can
->
status
.
rcvchange
==
1
||
can
->
status
.
sndchange
==
1
)
{
can
->
status
.
rcvchange
=
0
;
can
->
status
.
sndchange
=
0
;
rt_pin_write
(
can
->
config
.
sndled
->
pin
,
rt_pin_read
(
can
->
config
.
sndled
->
pin
)
?
0
:
1
);
}
else
{
rt_pin_write
(
can
->
config
.
sndled
->
pin
,
can
->
config
.
sndled
->
init
);
}
}
}
if
(
ledonflag
==
1
)
{
rt_pin_write
(
can
->
config
.
errled
->
pin
,
can
->
config
.
errled
->
init
?
0
:
1
);
}
else
{
if
(
can
->
status
.
errcode
)
{
rt_pin_write
(
can
->
config
.
errled
->
pin
,
can
->
config
.
errled
->
init
?
0
:
1
);
}
else
{
rt_pin_write
(
can
->
config
.
errled
->
pin
,
can
->
config
.
errled
->
init
);
}
}
#endif
if
(
can
->
status_indicate
.
ind
!=
RT_NULL
)
{
can
->
status_indicate
.
ind
(
can
,
can
->
status_indicate
.
args
);
...
...
@@ -825,6 +704,8 @@ rt_err_t rt_hw_can_register(struct rt_can_device *can,
#endif
can
->
can_rx
=
RT_NULL
;
can
->
can_tx
=
RT_NULL
;
rt_mutex_init
(
&
(
can
->
lock
),
"can"
,
RT_IPC_FLAG_PRIO
);
device
->
init
=
rt_can_init
;
device
->
open
=
rt_can_open
;
device
->
close
=
rt_can_close
;
...
...
@@ -838,7 +719,8 @@ rt_err_t rt_hw_can_register(struct rt_can_device *can,
rt_memset
(
&
can
->
status
,
0
,
sizeof
(
can
->
status
));
device
->
user_data
=
data
;
can
->
timerinitflag
=
0
;
can
->
timerinitflag
=
0
;
rt_timer_init
(
&
can
->
timer
,
name
,
cantimeout
,
...
...
@@ -954,6 +836,7 @@ void rt_hw_can_isr(struct rt_can_device *can, int event)
}
else
#endif
{
if
(
can
->
parent
.
rx_indicate
!=
RT_NULL
)
{
rt_size_t
rx_length
;
...
...
@@ -965,6 +848,7 @@ void rt_hw_can_isr(struct rt_can_device *can, int event)
can
->
parent
.
rx_indicate
(
&
can
->
parent
,
rx_length
);
}
}
break
;
}
...
...
@@ -976,13 +860,14 @@ void rt_hw_can_isr(struct rt_can_device *can, int event)
no
=
event
>>
8
;
tx_fifo
=
(
struct
rt_can_tx_fifo
*
)
can
->
can_tx
;
RT_ASSERT
(
tx_fifo
!=
RT_NULL
);
if
((
event
&
0xff
)
==
RT_CAN_EVENT_TX_DONE
)
{
tx_fifo
->
buffer
[
no
].
result
=
RT_CAN_
_SND_RESUTL
_OK
;
tx_fifo
->
buffer
[
no
].
result
=
RT_CAN_
SND_RESULT
_OK
;
}
else
{
tx_fifo
->
buffer
[
no
].
result
=
RT_CAN_
_SND_RESUTL
_ERR
;
tx_fifo
->
buffer
[
no
].
result
=
RT_CAN_
SND_RESULT
_ERR
;
}
rt_completion_done
(
&
(
tx_fifo
->
buffer
[
no
].
completion
));
break
;
...
...
@@ -1055,3 +940,4 @@ int cmd_canstat(int argc, void **argv)
}
FINSH_FUNCTION_EXPORT_ALIAS
(
cmd_canstat
,
__cmd_canstat
,
Stat
Can
Device
Status
.);
#endif
components/drivers/include/drivers/can.h
浏览文件 @
91d866d8
...
...
@@ -3,80 +3,76 @@
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2015, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
* 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
* 2015-05-14 aubrcool@qq.com first version
* Date Author Notes
* 2015-05-14 aubrcool@qq.com first version
* 2015-07-06 Bernard remove RT_CAN_USING_LED.
*/
#ifndef CAN_H_
#define CAN_H_
#include <rtthread.h>
#ifndef RT_CANMSG_BOX_SZ
#define RT_CANMSG_BOX_SZ 16
#define RT_CANMSG_BOX_SZ
16
#endif
#ifndef RT_CANSND_BOX_NUM
#define RT_CANSND_BOX_NUM 1
#define RT_CANSND_BOX_NUM
1
#endif
enum
CANBAUD
{
CAN1MBaud
=
0
,
// 1 MBit/sec
CAN800kBaud
,
// 800 kBit/sec
CAN500kBaud
,
// 500 kBit/sec
CAN250kBaud
,
// 250 kBit/sec
CAN125kBaud
,
// 125 kBit/sec
CAN100kBaud
,
// 100 kBit/sec
CAN50kBaud
,
// 50 kBit/sec
CAN20kBaud
,
// 20 kBit/sec
CAN10kBaud
// 10 kBit/sec
CAN1MBaud
=
0
,
/* 1 MBit/sec */
CAN800kBaud
,
/* 800 kBit/sec */
CAN500kBaud
,
/* 500 kBit/sec */
CAN250kBaud
,
/* 250 kBit/sec */
CAN125kBaud
,
/* 125 kBit/sec */
CAN100kBaud
,
/* 100 kBit/sec */
CAN50kBaud
,
/* 50 kBit/sec */
CAN20kBaud
,
/* 20 kBit/sec */
CAN10kBaud
/* 10 kBit/sec */
};
#define RT_CAN_MODE_NORMAL 0
#define RT_CAN_MODE_LISEN 1
#define RT_CAN_MODE_LOOPBACK 2
#define RT_CAN_MODE_LOOPBACKANLISEN 3
#define RT_CAN_MODE_PRIV 0x01
#define RT_CAN_MODE_NOPRIV 0x00
#define RT_CAN_MODE_NORMAL 0
#define RT_CAN_MODE_LISEN 1
#define RT_CAN_MODE_LOOPBACK 2
#define RT_CAN_MODE_LOOPBACKANLISEN 3
#ifdef RT_CAN_USING_LED
struct
rt_can_led
{
rt_uint32_t
pin
,
mode
,
init
;
struct
rt_timer
*
timer
;
const
char
*
timer_name
;
};
#endif
/*RT_CAN_USING_LED*/
#define RT_CAN_MODE_PRIV 0x01
#define RT_CAN_MODE_NOPRIV 0x00
struct
rt_can_filter_item
{
rt_uint32_t
id
:
29
;
rt_uint32_t
ide
:
1
;
rt_uint32_t
rtr
:
1
;
rt_uint32_t
mode
:
1
;
rt_uint32_t
mask
;
rt_int32_t
hdr
;
rt_uint32_t
id
:
29
;
rt_uint32_t
ide
:
1
;
rt_uint32_t
rtr
:
1
;
rt_uint32_t
mode
:
1
;
rt_uint32_t
mask
;
rt_int32_t
hdr
;
#ifdef RT_CAN_USING_HDR
rt_err_t
(
*
ind
)(
rt_device_t
dev
,
void
*
args
,
rt_int32_t
hdr
,
rt_size_t
size
);
void
*
args
;
rt_err_t
(
*
ind
)(
rt_device_t
dev
,
void
*
args
,
rt_int32_t
hdr
,
rt_size_t
size
);
void
*
args
;
#endif
/*RT_CAN_USING_HDR*/
};
#ifdef RT_CAN_USING_HDR
#define RT_CAN_FILTER_ITEM_INIT(id,ide,rtr,mode,mask,ind,args) \
{\
id,\
ide,\
rtr,\
mode,\
mask,\
-1,\
ind,\
args,\
}
{(id), (ide), (rtr), (mode), (mask), -1, (ind), (args)}
#define RT_CAN_FILTER_STD_INIT(id,ind,args) \
RT_CAN_FILTER_ITEM_INIT(id,0,0,0,0xFFFFFFFF,ind,args)
#define RT_CAN_FILTER_EXT_INIT(id,ind,args) \
...
...
@@ -90,15 +86,9 @@ struct rt_can_filter_item
#define RT_CAN_EXT_RMT_DATA_FILTER_INIT(id,ind,args) \
RT_CAN_FILTER_ITEM_INIT(id,1,0,1,0xFFFFFFFF,ind,args)
#else
#define RT_CAN_FILTER_ITEM_INIT(id,ide,rtr,mode,mask) \
{\
id,\
ide,\
rtr,\
mode,\
mask,\
-1,\
}
{(id), (ide), (rtr), (mode), (mask), -1, }
#define RT_CAN_FILTER_STD_INIT(id) \
RT_CAN_FILTER_ITEM_INIT(id,0,0,0,0xFFFFFFFF)
#define RT_CAN_FILTER_EXT_INIT(id) \
...
...
@@ -115,26 +105,22 @@ struct rt_can_filter_item
struct
rt_can_filter_config
{
rt_uint32_t
count
;
rt_uint32_t
actived
;
struct
rt_can_filter_item
*
items
;
rt_uint32_t
count
;
rt_uint32_t
actived
;
struct
rt_can_filter_item
*
items
;
};
struct
can_configure
{
rt_uint32_t
baud_rate
;
rt_uint32_t
msgboxsz
;
rt_uint32_t
sndboxnumber
;
rt_uint32_t
mode
:
8
;
rt_uint32_t
privmode
:
8
;
rt_uint32_t
reserved
:
16
;
#ifdef RT_CAN_USING_LED
const
struct
rt_can_led
*
rcvled
;
const
struct
rt_can_led
*
sndled
;
const
struct
rt_can_led
*
errled
;
#endif
/*RT_CAN_USING_LED*/
rt_uint32_t
ticks
;
rt_uint32_t
baud_rate
;
rt_uint32_t
msgboxsz
;
rt_uint32_t
sndboxnumber
;
rt_uint32_t
mode
:
8
;
rt_uint32_t
privmode
:
8
;
rt_uint32_t
reserved
:
16
;
rt_uint32_t
ticks
;
#ifdef RT_CAN_USING_HDR
rt_uint32_t
maxhdr
;
rt_uint32_t
maxhdr
;
#endif
};
...
...
@@ -147,80 +133,88 @@ struct can_configure
};
struct
rt_can_ops
;
#define RT_CAN_CMD_SET_FILTER 0x13
#define RT_CAN_CMD_SET_BAUD 0x14
#define RT_CAN_CMD_SET_MODE 0x15
#define RT_CAN_CMD_SET_PRIV 0x16
#define RT_CAN_CMD_GET_STATUS 0x17
#define RT_CAN_CMD_SET_STATUS_IND 0x18
#define RT_CAN_CMD_SET_FILTER
0x13
#define RT_CAN_CMD_SET_BAUD
0x14
#define RT_CAN_CMD_SET_MODE
0x15
#define RT_CAN_CMD_SET_PRIV
0x16
#define RT_CAN_CMD_GET_STATUS
0x17
#define RT_CAN_CMD_SET_STATUS_IND
0x18
#define RT_DEVICE_CAN_INT_ERR 0x1000
#define RT_DEVICE_CAN_INT_ERR
0x1000
enum
RT_CAN_STATUS_MODE
{
NORMAL
=
0
,
ERRWARNING
=
1
,
ERRPASSIVE
=
2
,
BUSOFF
=
4
,
NORMAL
=
0
,
ERRWARNING
=
1
,
ERRPASSIVE
=
2
,
BUSOFF
=
4
,
};
enum
RT_CAN_BUS_ERR
{
RT_CAN_BUS_NO_ERR
=
0
,
RT_CAN_BUS_BIT_PAD_ERR
=
1
,
RT_CAN_BUS_FORMAT_ERR
=
2
,
RT_CAN_BUS_ACK_ERR
=
3
,
RT_CAN_BUS_IMPLICIT_BIT_ERR
=
4
,
RT_CAN_BUS_EXPLICIT_BIT_ERR
=
5
,
RT_CAN_BUS_CRC_ERR
=
6
,
RT_CAN_BUS_NO_ERR
=
0
,
RT_CAN_BUS_BIT_PAD_ERR
=
1
,
RT_CAN_BUS_FORMAT_ERR
=
2
,
RT_CAN_BUS_ACK_ERR
=
3
,
RT_CAN_BUS_IMPLICIT_BIT_ERR
=
4
,
RT_CAN_BUS_EXPLICIT_BIT_ERR
=
5
,
RT_CAN_BUS_CRC_ERR
=
6
,
};
struct
rt_can_status
{
rt_uint32_t
rcverrcnt
;
rt_uint32_t
snderrcnt
;
rt_uint32_t
errcode
;
rt_uint32_t
rcvpkg
;
rt_uint32_t
dropedrcvpkg
;
rt_uint32_t
sndpkg
;
rt_uint32_t
dropedsndpkg
;
rt_uint32_t
bitpaderrcnt
;
rt_uint32_t
formaterrcnt
;
rt_uint32_t
ackerrcnt
;
rt_uint32_t
biterrcnt
;
rt_uint32_t
crcerrcnt
;
rt_uint32_t
rcvchange
;
rt_uint32_t
sndchange
;
rt_uint32_t
lasterrtype
;
rt_uint32_t
rcverrcnt
;
rt_uint32_t
snderrcnt
;
rt_uint32_t
errcode
;
rt_uint32_t
rcvpkg
;
rt_uint32_t
dropedrcvpkg
;
rt_uint32_t
sndpkg
;
rt_uint32_t
dropedsndpkg
;
rt_uint32_t
bitpaderrcnt
;
rt_uint32_t
formaterrcnt
;
rt_uint32_t
ackerrcnt
;
rt_uint32_t
biterrcnt
;
rt_uint32_t
crcerrcnt
;
rt_uint32_t
rcvchange
;
rt_uint32_t
sndchange
;
rt_uint32_t
lasterrtype
;
};
#ifdef RT_CAN_USING_HDR
struct
rt_can_hdr
{
rt_uint32_t
connected
;
rt_uint32_t
msgs
;
struct
rt_can_filter_item
filter
;
struct
rt_list_node
list
;
struct
rt_can_hdr
{
rt_uint32_t
connected
;
rt_uint32_t
msgs
;
struct
rt_can_filter_item
filter
;
struct
rt_list_node
list
;
};
#endif
struct
rt_can_device
;
typedef
rt_err_t
(
*
rt_canstatus_ind
)(
struct
rt_can_device
*
,
void
*
);
typedef
rt_err_t
(
*
rt_canstatus_ind
)(
struct
rt_can_device
*
,
void
*
);
typedef
struct
rt_can_status_ind_type
{
rt_canstatus_ind
ind
;
void
*
args
;
void
*
args
;
}
*
rt_can_status_ind_type_t
;
struct
rt_can_device
{
struct
rt_device
parent
;
const
struct
rt_can_ops
*
ops
;
struct
can_configure
config
;
struct
rt_can_status
status
;
rt_uint32_t
timerinitflag
;
struct
rt_timer
timer
;
struct
rt_can_status_ind_type
status_indicate
;
struct
rt_device
parent
;
const
struct
rt_can_ops
*
ops
;
struct
can_configure
config
;
struct
rt_can_status
status
;
rt_uint32_t
timerinitflag
;
struct
rt_timer
timer
;
struct
rt_can_status_ind_type
status_indicate
;
#ifdef RT_CAN_USING_HDR
struct
rt_can_hdr
*
hdr
;
struct
rt_can_hdr
*
hdr
;
#endif
void
*
can_rx
;
void
*
can_tx
;
struct
rt_mutex
lock
;
void
*
can_rx
;
void
*
can_tx
;
};
typedef
struct
rt_can_device
*
rt_can_t
;
...
...
@@ -229,68 +223,76 @@ typedef struct rt_can_device *rt_can_t;
#define RT_CAN_DTR 0
#define RT_CAN_RTR 1
typedef
struct
rt_can_status
*
rt_can_status_t
;
typedef
struct
rt_can_status
*
rt_can_status_t
;
struct
rt_can_msg
{
rt_uint32_t
id
:
29
;
rt_uint32_t
ide
:
1
;
rt_uint32_t
rtr
:
1
;
rt_uint32_t
rsv
:
1
;
rt_uint32_t
len
:
8
;
rt_uint32_t
priv
:
8
;
rt_uint32_t
hdr
:
8
;
rt_uint32_t
reserved
:
8
;
rt_uint8_t
data
[
8
];
rt_uint32_t
id
:
29
;
rt_uint32_t
ide
:
1
;
rt_uint32_t
rtr
:
1
;
rt_uint32_t
rsv
:
1
;
rt_uint32_t
len
:
8
;
rt_uint32_t
priv
:
8
;
rt_uint32_t
hdr
:
8
;
rt_uint32_t
reserved
:
8
;
rt_uint8_t
data
[
8
];
};
typedef
struct
rt_can_msg
*
rt_can_msg_t
;
struct
rt_can_msg_list
{
struct
rt_list_node
list
;
typedef
struct
rt_can_msg
*
rt_can_msg_t
;
struct
rt_can_msg_list
{
struct
rt_list_node
list
;
#ifdef RT_CAN_USING_HDR
struct
rt_list_node
hdrlist
;
struct
rt_can_hdr
*
owner
;
struct
rt_list_node
hdrlist
;
struct
rt_can_hdr
*
owner
;
#endif
struct
rt_can_msg
data
;
struct
rt_can_msg
data
;
};
struct
rt_can_rx_fifo
{
/* software fifo */
struct
rt_can_msg_list
*
buffer
;
rt_uint32_t
freenumbers
;
struct
rt_list_node
freelist
;
struct
rt_list_node
uselist
;
/* software fifo */
struct
rt_can_msg_list
*
buffer
;
rt_uint32_t
freenumbers
;
struct
rt_list_node
freelist
;
struct
rt_list_node
uselist
;
};
#define RT_CAN_
_SND_RESUTL_OK
0
#define RT_CAN_
_SND_RESUTL_ERR
1
#define RT_CAN_
_SND_RESUTL_WAIT
2
#define RT_CAN_
SND_RESULT_OK
0
#define RT_CAN_
SND_RESULT_ERR
1
#define RT_CAN_
SND_RESULT_WAIT
2
#define RT_CAN_EVENT_RX_IND
0x01
/* Rx indication */
#define RT_CAN_EVENT_TX_DONE
0x02
/* Tx complete */
#define RT_CAN_EVENT_TX_FAIL
0x03
/* Tx complete */
#define RT_CAN_EVENT_RX_TIMEOUT
0x05
/* Rx timeout */
#define RT_CAN_EVENT_RXOF_IND
0x06
/* Rx overflow */
#define RT_CAN_EVENT_RX_IND 0x01
/* Rx indication */
#define RT_CAN_EVENT_TX_DONE 0x02
/* Tx complete */
#define RT_CAN_EVENT_TX_FAIL 0x03
/* Tx complete */
#define RT_CAN_EVENT_RX_TIMEOUT 0x05
/* Rx timeout */
#define RT_CAN_EVENT_RXOF_IND 0x06
/* Rx overflow */
struct
rt_can_sndbxinx_list
{
struct
rt_list_node
list
;
struct
rt_completion
completion
;
rt_uint32_t
result
;
struct
rt_can_sndbxinx_list
{
struct
rt_list_node
list
;
struct
rt_completion
completion
;
rt_uint32_t
result
;
};
struct
rt_can_tx_fifo
{
struct
rt_can_sndbxinx_list
*
buffer
;
struct
rt_completion
completion
;
struct
rt_list_node
freelist
;
struct
rt_can_sndbxinx_list
*
buffer
;
struct
rt_completion
completion
;
struct
rt_list_node
freelist
;
};
struct
rt_can_ops
{
rt_err_t
(
*
configure
)(
struct
rt_can_device
*
can
,
struct
can_configure
*
cfg
);
rt_err_t
(
*
control
)(
struct
rt_can_device
*
can
,
int
cmd
,
void
*
arg
);
int
(
*
sendmsg
)(
struct
rt_can_device
*
can
,
const
void
*
buf
,
rt_uint32_t
boxno
);
int
(
*
recvmsg
)(
struct
rt_can_device
*
can
,
void
*
buf
,
rt_uint32_t
boxno
);
rt_err_t
(
*
configure
)(
struct
rt_can_device
*
can
,
struct
can_configure
*
cfg
);
rt_err_t
(
*
control
)(
struct
rt_can_device
*
can
,
int
cmd
,
void
*
arg
);
int
(
*
sendmsg
)(
struct
rt_can_device
*
can
,
const
void
*
buf
,
rt_uint32_t
boxno
);
int
(
*
recvmsg
)(
struct
rt_can_device
*
can
,
void
*
buf
,
rt_uint32_t
boxno
);
};
rt_err_t
rt_hw_can_register
(
struct
rt_can_device
*
can
,
const
char
*
name
,
const
struct
rt_can_ops
*
ops
,
void
*
data
);
const
char
*
name
,
const
struct
rt_can_ops
*
ops
,
void
*
data
);
void
rt_hw_can_isr
(
struct
rt_can_device
*
can
,
int
event
);
#endif
/*_CAN_H*/
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录