未验证 提交 20f21ccc 编写于 作者: O openharmony_ci 提交者: Gitee

!6026 【OpenHarmony开源贡献者计划2022】【中文】驱动Watchdog 驱动相关格式及表达问题

Merge pull request !6026 from king_he/0628-c
# Watchdog<a name="ZH-CN_TOPIC_0000001206372825"></a> # Watchdog
## 概述
## 概述<a name="section14918241977"></a>
看门狗(Watchdog),又叫看门狗计时器(Watchdog timer),是一种硬件的计时设备。当系统主程序发生错误导致未及时清除看门狗计时器的计时值时,看门狗计时器就会对系统发出复位信号,使系统从悬停状态恢复到正常运作状态。
看门狗(Watchdog),又叫看门狗计时器(Watchdog Timer),是一种硬件的计时设备,当系统的主程序发生某些错误时,导致未及时清除看门狗计时器的计时值,这时看门狗计时器就会对系统发出复位信号,使系统从悬停状态恢复到正常运作状态。
## 接口说明<a name="section1180575010271"></a> ## 接口说明
**表 1** 看门狗 API接口功能介绍 **表1** 看门狗API接口功能介绍
<a name="table1731550155318"></a> | 接口 | 接口描述 |
<table><thead align="left"><tr id="row4419501537"><th class="cellrowborder" valign="top" width="26.619999999999997%" id="mcps1.2.4.1.1"><p id="p641050105320"><a name="p641050105320"></a><a name="p641050105320"></a>功能分类</p> | -------- | -------- |
</th> | WatchdogOpen | 打开看门狗 |
<th class="cellrowborder" valign="top" width="32.800000000000004%" id="mcps1.2.4.1.2"><p id="p54150165315"><a name="p54150165315"></a><a name="p54150165315"></a>接口名</p> | WatchdogClose | 关闭看门狗 |
</th> | WatchdogStart | 启动看门狗 |
<th class="cellrowborder" valign="top" width="40.58%" id="mcps1.2.4.1.3"><p id="p941150145313"><a name="p941150145313"></a><a name="p941150145313"></a>描述</p> | WatchdogStop | 停止看门狗 |
</th> | WatchdogSetTimeout | 设置看门狗超时时间 |
</tr> | WatchdogGetTimeout | 获取看门狗超时时间 |
</thead> | WatchdogGetStatus | 获取看门狗状态 |
<tbody><tr id="row837081981712"><td class="cellrowborder" rowspan="2" valign="top" width="26.619999999999997%" headers="mcps1.2.4.1.1 "><p id="p681292481718"><a name="p681292481718"></a><a name="p681292481718"></a>打开/关闭看门狗</p> | WatchdogFeed | 清除看门狗定时器(喂狗) |
</td>
<td class="cellrowborder" valign="top" width="32.800000000000004%" headers="mcps1.2.4.1.2 "><p id="p183701419141710"><a name="p183701419141710"></a><a name="p183701419141710"></a>WatchdogOpen</p> > ![](../public_sys-resources/icon-note.gif) **说明:**<br>
</td> > 本文涉及的看门狗的所有接口,仅限内核态使用,不支持在用户态使用。
<td class="cellrowborder" valign="top" width="40.58%" headers="mcps1.2.4.1.3 "><p id="p17370161911710"><a name="p17370161911710"></a><a name="p17370161911710"></a>打开看门狗设备</p>
</td>
</tr> ## 使用指导
<tr id="row5610415171719"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p661171510173"><a name="p661171510173"></a><a name="p661171510173"></a>WatchdogClose</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p11611715161713"><a name="p11611715161713"></a><a name="p11611715161713"></a>关闭看门狗设备</p> ### 使用流程
</td>
</tr> 使用看门狗的一般流程如下图所示。
<tr id="row337105133315"><td class="cellrowborder" rowspan="2" valign="top" width="26.619999999999997%" headers="mcps1.2.4.1.1 "><p id="p07631557153319"><a name="p07631557153319"></a><a name="p07631557153319"></a>启动/停止看门狗</p>
</td> **图1** 看门狗使用流程图
<td class="cellrowborder" valign="top" width="32.800000000000004%" headers="mcps1.2.4.1.2 "><p id="p163765113337"><a name="p163765113337"></a><a name="p163765113337"></a>WatchdogStart</p>
</td> ![image](figures/看门狗使用流程图.png "看门狗使用流程图")
<td class="cellrowborder" valign="top" width="40.58%" headers="mcps1.2.4.1.3 "><p id="p18376517332"><a name="p18376517332"></a><a name="p18376517332"></a>启动看门狗</p>
</td>
</tr> ### 打开看门狗设备
<tr id="row18399184610337"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1740010461335"><a name="p1740010461335"></a><a name="p1740010461335"></a>WatchdogStop</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p19400194633318"><a name="p19400194633318"></a><a name="p19400194633318"></a>停止看门狗</p>
</td>
</tr>
<tr id="row34145016535"><td class="cellrowborder" rowspan="2" valign="top" width="26.619999999999997%" headers="mcps1.2.4.1.1 "><p id="p229610227124"><a name="p229610227124"></a><a name="p229610227124"></a>设置/获取超时时间</p>
</td>
<td class="cellrowborder" valign="top" width="32.800000000000004%" headers="mcps1.2.4.1.2 "><p id="p8296182221219"><a name="p8296182221219"></a><a name="p8296182221219"></a>WatchdogSetTimeout</p>
</td>
<td class="cellrowborder" valign="top" width="40.58%" headers="mcps1.2.4.1.3 "><p id="p16297172213125"><a name="p16297172213125"></a><a name="p16297172213125"></a>设置看门狗超时时间</p>
</td>
</tr>
<tr id="row11585016539"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1095722493616"><a name="p1095722493616"></a><a name="p1095722493616"></a>WatchdogGetTimeout</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p15297162215122"><a name="p15297162215122"></a><a name="p15297162215122"></a>获取看门狗超时时间</p>
</td>
</tr>
<tr id="row105701653185811"><td class="cellrowborder" valign="top" width="26.619999999999997%" headers="mcps1.2.4.1.1 "><p id="p2571145325819"><a name="p2571145325819"></a><a name="p2571145325819"></a>获取看门狗状态</p>
</td>
<td class="cellrowborder" valign="top" width="32.800000000000004%" headers="mcps1.2.4.1.2 "><p id="p175711953195814"><a name="p175711953195814"></a><a name="p175711953195814"></a>WatchdogGetStatus</p>
</td>
<td class="cellrowborder" valign="top" width="40.58%" headers="mcps1.2.4.1.3 "><p id="p331961319210"><a name="p331961319210"></a><a name="p331961319210"></a>获取看门狗状态</p>
</td>
</tr>
<tr id="row1028182217215"><td class="cellrowborder" valign="top" width="26.619999999999997%" headers="mcps1.2.4.1.1 "><p id="p182818227214"><a name="p182818227214"></a><a name="p182818227214"></a>清除看门狗定时器</p>
</td>
<td class="cellrowborder" valign="top" width="32.800000000000004%" headers="mcps1.2.4.1.2 "><p id="p17281223219"><a name="p17281223219"></a><a name="p17281223219"></a>WatchdogFeed</p>
</td>
<td class="cellrowborder" valign="top" width="40.58%" headers="mcps1.2.4.1.3 "><p id="p62815221125"><a name="p62815221125"></a><a name="p62815221125"></a>清除看门狗定时器(喂狗)</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **说明:**
>本文涉及看门狗的所有接口,仅限内核态使用,不支持在用户态使用。
## 使用指导<a name="section10103184312813"></a>
### 使用流程<a name="section10181195910815"></a>
使用看门狗的一般流程如[图1](#fig430533913392)所示。
**图 1** 看门狗使用流程图<a name="fig430533913392"></a>
![](figures/看门狗使用流程图.png "看门狗使用流程图")
### 打开看门狗设备<a name="section66089201107"></a>
在操作看门狗之前,需要使用WatchdogOpen打开一个看门狗设备,一个系统可能有多个看门狗,通过ID号来打开指定的看门狗设备: 在操作看门狗之前,需要使用WatchdogOpen打开一个看门狗设备,一个系统可能有多个看门狗,通过ID号来打开指定的看门狗设备:
DevHandle WatchdogOpen\(int16\_t wdtId\); DevHandle WatchdogOpen(int16_t wdtId);
**表 2** WatchdogOpen参数和返回值描述 **表2** WatchdogOpen参数和返回值描述
<a name="table1413702552814"></a> | **参数** | **参数描述** |
<table><thead align="left"><tr id="row131371325142819"><th class="cellrowborder" valign="top" width="44.99%" id="mcps1.2.3.1.1"><p id="p191372254283"><a name="p191372254283"></a><a name="p191372254283"></a><strong id="b1913716253285"><a name="b1913716253285"></a><a name="b1913716253285"></a>参数</strong></p> | -------- | -------- |
</th> | wdtId | 看门狗设备号 |
<th class="cellrowborder" valign="top" width="55.010000000000005%" id="mcps1.2.3.1.2"><p id="p113819255284"><a name="p113819255284"></a><a name="p113819255284"></a><strong id="b151381725172812"><a name="b151381725172812"></a><a name="b151381725172812"></a>参数描述</strong></p> | **返回值** | **返回值描述** |
</th> | NULL | 打开失败 |
</tr> | DevHandle类型指针 | 看门狗设备句柄 |
</thead>
<tbody><tr id="row813812259282"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p101381625162813"><a name="p101381625162813"></a><a name="p101381625162813"></a>wdtId</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p191381425142813"><a name="p191381425142813"></a><a name="p191381425142813"></a>看门狗设备号</p>
</td>
</tr>
<tr id="row2138202515281"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p141387252287"><a name="p141387252287"></a><a name="p141387252287"></a><strong id="b11381325172810"><a name="b11381325172810"></a><a name="b11381325172810"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p12138192512281"><a name="p12138192512281"></a><a name="p12138192512281"></a><strong id="b81380254286"><a name="b81380254286"></a><a name="b81380254286"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row9138182519287"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p5138102532814"><a name="p5138102532814"></a><a name="p5138102532814"></a>NULL</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p3138192512815"><a name="p3138192512815"></a><a name="p3138192512815"></a>打开失败</p>
</td>
</tr>
<tr id="row15138192518283"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p1850115512916"><a name="p1850115512916"></a><a name="p1850115512916"></a>DevHandle类型指针</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p16138122512817"><a name="p16138122512817"></a><a name="p16138122512817"></a>看门狗设备句柄</p>
</td>
</tr>
</tbody>
</table>
``` ```
DevHandle handle = NULL; DevHandle handle = NULL;
...@@ -131,46 +62,21 @@ if (handle == NULL) { ...@@ -131,46 +62,21 @@ if (handle == NULL) {
} }
``` ```
### 获取看门狗状态<a name="section786624341011"></a>
### 获取看门狗状态
int32\_t WatchdogGetStatus\(DevHandle handle, int32\_t \*status\);
int32_t WatchdogGetStatus(DevHandle handle, int32_t *status);
**表 3** WatchdogGetStatus参数和返回值描述
**表3** WatchdogGetStatus参数和返回值描述
<a name="table1018490043"></a>
<table><thead align="left"><tr id="row31848013417"><th class="cellrowborder" valign="top" width="44.99%" id="mcps1.2.3.1.1"><p id="p1415816132411"><a name="p1415816132411"></a><a name="p1415816132411"></a><strong id="b129796117337"><a name="b129796117337"></a><a name="b129796117337"></a>参数</strong></p> | **参数** | **参数描述** |
</th> | -------- | -------- |
<th class="cellrowborder" valign="top" width="55.010000000000005%" id="mcps1.2.3.1.2"><p id="p11158111316410"><a name="p11158111316410"></a><a name="p11158111316410"></a><strong id="b1699118123314"><a name="b1699118123314"></a><a name="b1699118123314"></a>参数描述</strong></p> | handle | 看门狗设备句柄 |
</th> | status | 获取到的看门狗状态的指针 |
</tr> | **返回值** | **返回值描述** |
</thead> | 0 | 获取成功 |
<tbody><tr id="row3264122711222"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p15264727182211"><a name="p15264727182211"></a><a name="p15264727182211"></a>handle</p> | 负数 | 获取失败 |
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p2026452772210"><a name="p2026452772210"></a><a name="p2026452772210"></a>看门狗设备句柄</p>
</td>
</tr>
<tr id="row928111518418"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p4282955412"><a name="p4282955412"></a><a name="p4282955412"></a>status</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p7282752412"><a name="p7282752412"></a><a name="p7282752412"></a>获取到的启动状态指针</p>
</td>
</tr>
<tr id="row17393154515328"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p8158313248"><a name="p8158313248"></a><a name="p8158313248"></a><strong id="b18542051332"><a name="b18542051332"></a><a name="b18542051332"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p161591413741"><a name="p161591413741"></a><a name="p161591413741"></a><strong id="b45520523313"><a name="b45520523313"></a><a name="b45520523313"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row339324593215"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p103191916578"><a name="p103191916578"></a><a name="p103191916578"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p1231981611712"><a name="p1231981611712"></a><a name="p1231981611712"></a>获取成功</p>
</td>
</tr>
<tr id="row15393184519323"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p531916166716"><a name="p531916166716"></a><a name="p531916166716"></a>负数</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p93191161174"><a name="p93191161174"></a><a name="p93191161174"></a>获取失败</p>
</td>
</tr>
</tbody>
</table>
``` ```
int32_t ret; int32_t ret;
...@@ -183,46 +89,21 @@ if (ret != 0) { ...@@ -183,46 +89,21 @@ if (ret != 0) {
} }
``` ```
### 设置超时时间<a name="section182386137111"></a>
### 设置超时时间
int32\_t WatchdogSetTimeout\(DevHandle \*handle, uint32\_t seconds\);
int32_t WatchdogSetTimeout(DevHandle *handle, uint32_t seconds);
**表 4** WatchdogSetTimeout参数和返回值描述
**表4** WatchdogSetTimeout参数和返回值描述
<a name="table9159112182210"></a>
<table><thead align="left"><tr id="row1216012212212"><th class="cellrowborder" valign="top" width="44.99%" id="mcps1.2.3.1.1"><p id="p1416017262215"><a name="p1416017262215"></a><a name="p1416017262215"></a><strong id="b181604212216"><a name="b181604212216"></a><a name="b181604212216"></a>参数</strong></p> | **参数** | **参数描述** |
</th> | -------- | -------- |
<th class="cellrowborder" valign="top" width="55.010000000000005%" id="mcps1.2.3.1.2"><p id="p16160182192213"><a name="p16160182192213"></a><a name="p16160182192213"></a><strong id="b16160142162216"><a name="b16160142162216"></a><a name="b16160142162216"></a>参数描述</strong></p> | handle | 看门狗设备句柄 |
</th> | seconds | 超时时间,单位为秒 |
</tr> | **返回值** | **返回值描述** |
</thead> | 0 | 设置成功 |
<tbody><tr id="row199536232314"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p17685481236"><a name="p17685481236"></a><a name="p17685481236"></a>handle</p> | 负数 | 设置失败 |
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p196852811232"><a name="p196852811232"></a><a name="p196852811232"></a>看门狗设备句柄</p>
</td>
</tr>
<tr id="row141601729228"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p191601126226"><a name="p191601126226"></a><a name="p191601126226"></a>seconds</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p5160172182214"><a name="p5160172182214"></a><a name="p5160172182214"></a>超时时间,单位为秒</p>
</td>
</tr>
<tr id="row18160192172212"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p101601123222"><a name="p101601123222"></a><a name="p101601123222"></a><strong id="b516062172215"><a name="b516062172215"></a><a name="b516062172215"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p17160192182212"><a name="p17160192182212"></a><a name="p17160192182212"></a><strong id="b141601022227"><a name="b141601022227"></a><a name="b141601022227"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row171600202220"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p121601226224"><a name="p121601226224"></a><a name="p121601226224"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p151607218222"><a name="p151607218222"></a><a name="p151607218222"></a>设置成功</p>
</td>
</tr>
<tr id="row916012252211"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p19160026224"><a name="p19160026224"></a><a name="p19160026224"></a>负数</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p816092142210"><a name="p816092142210"></a><a name="p816092142210"></a>设置失败</p>
</td>
</tr>
</tbody>
</table>
``` ```
int32_t ret; int32_t ret;
...@@ -235,46 +116,21 @@ if (ret != 0) { ...@@ -235,46 +116,21 @@ if (ret != 0) {
} }
``` ```
### 获取超时时间<a name="section1883310371114"></a>
### 获取超时时间
int32\_t WatchdogGetTimeout\(DevHandle \*handle, uint32\_t \*seconds\);
int32_t WatchdogGetTimeout(DevHandle *handle, uint32_t *seconds);
**表 5** WatchdogGetTimeout参数和返回值描述
**表5** WatchdogGetTimeout参数和返回值描述
<a name="table10147164819233"></a>
<table><thead align="left"><tr id="row14147848142313"><th class="cellrowborder" valign="top" width="44.99%" id="mcps1.2.3.1.1"><p id="p4147124892316"><a name="p4147124892316"></a><a name="p4147124892316"></a><strong id="b214784813238"><a name="b214784813238"></a><a name="b214784813238"></a>参数</strong></p> | **参数** | **参数描述** |
</th> | -------- | -------- |
<th class="cellrowborder" valign="top" width="55.010000000000005%" id="mcps1.2.3.1.2"><p id="p12147144817232"><a name="p12147144817232"></a><a name="p12147144817232"></a><strong id="b51476482234"><a name="b51476482234"></a><a name="b51476482234"></a>参数描述</strong></p> | handle | 看门狗设备句柄 |
</th> | seconds | 接收超时时间的指针,单位为秒 |
</tr> | **返回值** | **返回值描述** |
</thead> | 0 | 获取成功 |
<tbody><tr id="row8147124819230"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p21471248142313"><a name="p21471248142313"></a><a name="p21471248142313"></a>handle</p> | 负数 | 获取失败 |
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p12147134815233"><a name="p12147134815233"></a><a name="p12147134815233"></a>看门狗设备句柄</p>
</td>
</tr>
<tr id="row514754818232"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p1614713484235"><a name="p1614713484235"></a><a name="p1614713484235"></a>seconds</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p71478484238"><a name="p71478484238"></a><a name="p71478484238"></a>接收超时时间的指针,单位为秒</p>
</td>
</tr>
<tr id="row214784814239"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p5147848152314"><a name="p5147848152314"></a><a name="p5147848152314"></a><strong id="b17147124822310"><a name="b17147124822310"></a><a name="b17147124822310"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p914724811236"><a name="p914724811236"></a><a name="p914724811236"></a><strong id="b614704813231"><a name="b614704813231"></a><a name="b614704813231"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row714744892312"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p1014764832315"><a name="p1014764832315"></a><a name="p1014764832315"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p1314824872310"><a name="p1314824872310"></a><a name="p1314824872310"></a>获取成功</p>
</td>
</tr>
<tr id="row1514884815230"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p10148114822319"><a name="p10148114822319"></a><a name="p10148114822319"></a>负数</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p1314864822311"><a name="p1314864822311"></a><a name="p1314864822311"></a>获取失败</p>
</td>
</tr>
</tbody>
</table>
``` ```
int32_t ret; int32_t ret;
...@@ -287,41 +143,20 @@ if (ret != 0) { ...@@ -287,41 +143,20 @@ if (ret != 0) {
} }
``` ```
### 启动看门狗<a name="section82501405123"></a>
### 启动看门狗
int32\_t WatchdogStart\(DevHandle handle\);
int32_t WatchdogStart(DevHandle handle);
**表 6** WatchdogStart参数和返回值描述
**表6** WatchdogStart参数和返回值描述
<a name="table529165182515"></a>
<table><thead align="left"><tr id="row92915122513"><th class="cellrowborder" valign="top" width="44.99%" id="mcps1.2.3.1.1"><p id="p5292582517"><a name="p5292582517"></a><a name="p5292582517"></a><strong id="b12293510259"><a name="b12293510259"></a><a name="b12293510259"></a>参数</strong></p> | **参数** | **参数描述** |
</th> | -------- | -------- |
<th class="cellrowborder" valign="top" width="55.010000000000005%" id="mcps1.2.3.1.2"><p id="p929554258"><a name="p929554258"></a><a name="p929554258"></a><strong id="b82913542514"><a name="b82913542514"></a><a name="b82913542514"></a>参数描述</strong></p> | handle | 看门狗设备句柄 |
</th> | **返回值** | **返回值描述** |
</tr> | 0 | 启动成功 |
</thead> | 负数 | 启动失败 |
<tbody><tr id="row629852250"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p22975122515"><a name="p22975122515"></a><a name="p22975122515"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p7290515256"><a name="p7290515256"></a><a name="p7290515256"></a>看门狗设备句柄</p>
</td>
</tr>
<tr id="row183035162514"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p8302511255"><a name="p8302511255"></a><a name="p8302511255"></a><strong id="b183018513251"><a name="b183018513251"></a><a name="b183018513251"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p16307522515"><a name="p16307522515"></a><a name="p16307522515"></a><strong id="b23010542510"><a name="b23010542510"></a><a name="b23010542510"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row12305552510"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p1730175132513"><a name="p1730175132513"></a><a name="p1730175132513"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p630754259"><a name="p630754259"></a><a name="p630754259"></a>启动成功</p>
</td>
</tr>
<tr id="row4306516252"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p15304502515"><a name="p15304502515"></a><a name="p15304502515"></a>负数</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p0301559254"><a name="p0301559254"></a><a name="p0301559254"></a>启动失败</p>
</td>
</tr>
</tbody>
</table>
``` ```
int32_t ret; int32_t ret;
...@@ -333,41 +168,20 @@ if (ret != 0) { ...@@ -333,41 +168,20 @@ if (ret != 0) {
} }
``` ```
### 喂狗<a name="section3547530101211"></a>
### 喂狗
int32\_t WatchdogFeed\(DevHandle handle\);
int32_t WatchdogFeed(DevHandle handle);
**表 7** WatchdogFeed参数和返回值描述
**表7** WatchdogFeed参数和返回值描述
<a name="table091163515394"></a>
<table><thead align="left"><tr id="row891133515393"><th class="cellrowborder" valign="top" width="44.99%" id="mcps1.2.3.1.1"><p id="p1911143513918"><a name="p1911143513918"></a><a name="p1911143513918"></a><strong id="b1791193553911"><a name="b1791193553911"></a><a name="b1791193553911"></a>参数</strong></p> | **参数** | **参数描述** |
</th> | -------- | -------- |
<th class="cellrowborder" valign="top" width="55.010000000000005%" id="mcps1.2.3.1.2"><p id="p1191173553917"><a name="p1191173553917"></a><a name="p1191173553917"></a><strong id="b4911835183910"><a name="b4911835183910"></a><a name="b4911835183910"></a>参数描述</strong></p> | handle | 看门狗设备句柄 |
</th> | **返回值** | **返回值描述** |
</tr> | 0 | 喂狗成功 |
</thead> | 负数 | 喂狗失败 |
<tbody><tr id="row189111635143918"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p189111435173917"><a name="p189111435173917"></a><a name="p189111435173917"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p11911143511397"><a name="p11911143511397"></a><a name="p11911143511397"></a>看门狗设备句柄</p>
</td>
</tr>
<tr id="row15911835173916"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p7911123516396"><a name="p7911123516396"></a><a name="p7911123516396"></a><strong id="b59112352394"><a name="b59112352394"></a><a name="b59112352394"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p169118356399"><a name="p169118356399"></a><a name="p169118356399"></a><strong id="b1091193593910"><a name="b1091193593910"></a><a name="b1091193593910"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row189119352393"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p1391113513917"><a name="p1391113513917"></a><a name="p1391113513917"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p149111435143911"><a name="p149111435143911"></a><a name="p149111435143911"></a>喂狗成功</p>
</td>
</tr>
<tr id="row5911123520392"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p49111335143920"><a name="p49111335143920"></a><a name="p49111335143920"></a>负数</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p1891216356391"><a name="p1891216356391"></a><a name="p1891216356391"></a>喂狗失败</p>
</td>
</tr>
</tbody>
</table>
``` ```
int32_t ret; int32_t ret;
...@@ -379,41 +193,20 @@ if (ret != 0) { ...@@ -379,41 +193,20 @@ if (ret != 0) {
} }
``` ```
### 停止看门狗<a name="section944595841217"></a>
### 停止看门狗
int32\_t WatchdogStop\(DevHandle handle\);
int32_t WatchdogStop(DevHandle handle);
**表 8** WatchdogStop参数和返回值描述
**表8** WatchdogStop参数和返回值描述
<a name="table1286810515254"></a>
<table><thead align="left"><tr id="row28687517259"><th class="cellrowborder" valign="top" width="44.99%" id="mcps1.2.3.1.1"><p id="p6868185120254"><a name="p6868185120254"></a><a name="p6868185120254"></a><strong id="b986815142510"><a name="b986815142510"></a><a name="b986815142510"></a>参数</strong></p> | **参数** | **参数描述** |
</th> | -------- | -------- |
<th class="cellrowborder" valign="top" width="55.010000000000005%" id="mcps1.2.3.1.2"><p id="p15868185114252"><a name="p15868185114252"></a><a name="p15868185114252"></a><strong id="b148681451142517"><a name="b148681451142517"></a><a name="b148681451142517"></a>参数描述</strong></p> | handle | 看门狗设备句柄 |
</th> | **返回值** | **返回值描述** |
</tr> | 0 | 停止成功 |
</thead> | 负数 | 停止失败 |
<tbody><tr id="row1868165114256"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p6869105115256"><a name="p6869105115256"></a><a name="p6869105115256"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p19869951202513"><a name="p19869951202513"></a><a name="p19869951202513"></a>看门狗设备句柄</p>
</td>
</tr>
<tr id="row68696510259"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p2869165114256"><a name="p2869165114256"></a><a name="p2869165114256"></a><strong id="b386935117258"><a name="b386935117258"></a><a name="b386935117258"></a>返回值</strong></p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p158691551142517"><a name="p158691551142517"></a><a name="p158691551142517"></a><strong id="b78691751152513"><a name="b78691751152513"></a><a name="b78691751152513"></a>返回值描述</strong></p>
</td>
</tr>
<tr id="row9869851192516"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p686916516252"><a name="p686916516252"></a><a name="p686916516252"></a>0</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p7869115192510"><a name="p7869115192510"></a><a name="p7869115192510"></a>停止成功</p>
</td>
</tr>
<tr id="row15869951122519"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p486925112518"><a name="p486925112518"></a><a name="p486925112518"></a>负数</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p086945172518"><a name="p086945172518"></a><a name="p086945172518"></a>停止失败</p>
</td>
</tr>
</tbody>
</table>
``` ```
int32_t ret; int32_t ret;
...@@ -425,45 +218,38 @@ if (ret != 0) { ...@@ -425,45 +218,38 @@ if (ret != 0) {
} }
``` ```
### 关闭看门狗设备<a name="section96561824121311"></a>
### 关闭看门狗设备
当操作完毕时,使用WatchdogClose关闭打开的设备句柄: 当操作完毕时,使用WatchdogClose关闭打开的设备句柄:
void WatchdogClose\(DevHandle handle\); void WatchdogClose(DevHandle handle);
**表 9** WatchdogClose参数和返回值描述 **表9** WatchdogClose参数和返回值描述
<a name="table1017315185320"></a> | **参数** | **参数描述** |
<table><thead align="left"><tr id="row417314182327"><th class="cellrowborder" valign="top" width="44.99%" id="mcps1.2.3.1.1"><p id="p117310184320"><a name="p117310184320"></a><a name="p117310184320"></a><strong id="b141734185327"><a name="b141734185327"></a><a name="b141734185327"></a>参数</strong></p> | -------- | -------- |
</th> | handle | 看门狗设备句柄 |
<th class="cellrowborder" valign="top" width="55.010000000000005%" id="mcps1.2.3.1.2"><p id="p7173191812324"><a name="p7173191812324"></a><a name="p7173191812324"></a><strong id="b2017318188327"><a name="b2017318188327"></a><a name="b2017318188327"></a>参数描述</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row1617331823211"><td class="cellrowborder" valign="top" width="44.99%" headers="mcps1.2.3.1.1 "><p id="p17173191811326"><a name="p17173191811326"></a><a name="p17173191811326"></a>handle</p>
</td>
<td class="cellrowborder" valign="top" width="55.010000000000005%" headers="mcps1.2.3.1.2 "><p id="p538814308323"><a name="p538814308323"></a><a name="p538814308323"></a>看门狗设备句柄</p>
</td>
</tr>
</tbody>
</table>
``` ```
/* 关闭看门狗 */ /* 关闭看门狗 */
ret = WatchdogClose(handle); ret = WatchdogClose(handle);
``` ```
## 使用实例<a name="section1724514523135"></a>
## 使用实例
本例程提供看门狗的完整使用流程。 本例程提供看门狗的完整使用流程。
在本例程中,我们打开一个看门狗设备,设置超时时间并启动计时: 在本例程中,我们打开一个看门狗设备,设置超时时间并启动计时:
- 首先定期喂狗,即按时清除看门狗定时器,确保系统不会因定时器超时而复位。 - 首先定期喂狗,即按时清除看门狗定时器,确保系统不会因定时器超时而复位。
- 接着再停止喂狗,观察定时器到期后系统是否发生复位行为。
示例如下: - 接着再停止喂狗,观察定时器到期后系统是否发生复位行为。
示例如下:
``` ```
#include "watchdog_if.h" #include "watchdog_if.h"
#include "hdf_log.h" #include "hdf_log.h"
...@@ -483,7 +269,7 @@ static int32_t TestCaseWatchdog(void) ...@@ -483,7 +269,7 @@ static int32_t TestCaseWatchdog(void)
/* 打开0号看门狗设备 */ /* 打开0号看门狗设备 */
handle = WatchdogOpen(0); handle = WatchdogOpen(0);
if (handle == NULL) { if (handle == NULL) {
HDF_LOGE("Open watchdog fail!"); HDF_LOGE("Open watchdog failed!");
return -1; return -1;
} }
...@@ -507,14 +293,14 @@ static int32_t TestCaseWatchdog(void) ...@@ -507,14 +293,14 @@ static int32_t TestCaseWatchdog(void)
/* 启动看门狗,开始计时 */ /* 启动看门狗,开始计时 */
ret = WatchdogStart(handle); ret = WatchdogStart(handle);
if (ret != HDF_SUCCESS) { if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: satrt fail! ret:%d\n", __func__, ret); HDF_LOGE("%s: start fail! ret:%d\n", __func__, ret);
WatchdogClose(handle); WatchdogClose(handle);
return ret; return ret;
} }
/* 每隔1S喂狗一次 */ /* 每隔1S喂狗一次 */
for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) {
HDF_LOGE("%s: feeding watchdog %d times... \n", __func__, i); HDF_LOGI("%s: feeding watchdog %d times... \n", __func__, i);
ret = WatchdogFeed(handle); ret = WatchdogFeed(handle);
if (ret != HDF_SUCCESS) { if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: feed dog fail! ret:%d\n", __func__, ret); HDF_LOGE("%s: feed dog fail! ret:%d\n", __func__, ret);
...@@ -524,18 +310,17 @@ static int32_t TestCaseWatchdog(void) ...@@ -524,18 +310,17 @@ static int32_t TestCaseWatchdog(void)
OsalSleep(1); OsalSleep(1);
} }
/* 由于喂狗间隔小于超时时间,系统不会发生复位,此日志可以正常打印 */ /* 由于喂狗间隔小于超时时间,系统不会发生复位,此日志可以正常打印 */
HDF_LOGE("%s: no reset ... feeding test OK!!!\n", __func__); HDF_LOGI("%s: no reset ... feeding test OK!!!\n", __func__);
/* 接下来持续不喂狗,使得看门狗计时器超时 */ /* 接下来持续不喂狗,使得看门狗计时器超时 */
for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) { for (i = 0; i < WATCHDOG_TEST_FEED_TIME; i++) {
HDF_LOGE("%s: watiting dog back %d times... \n", __func__, i); HDF_LOGI("%s: waiting dog buck %d times... \n", __func__, i);
OsalSleep(1); OsalSleep(1);
} }
/* 当不喂狗时间到达之前设定的超时时间的时候,系统会发生复位,理论上观察不到此日志的打印 */ /* 当不喂狗时间到达之前设定的超时时间的时候,系统会发生复位,理论上观察不到此日志的打印 */
HDF_LOGE("%s: dog hasn't back!!! \n", __func__, i); HDF_LOGI("%s: dog hasn't back!!! \n", __func__, i);
WatchdogClose(handle); WatchdogClose(handle);
return -1; return -1;
} }
``` ```
\ No newline at end of file
# WatchDog<a name="ZH-CN_TOPIC_0000001176922470"></a> # Watchdog
## 概述<a name="section1315827527160117"></a> ## 概述
看门狗(Watchdog),又叫看门狗计时器(Watchdog timer),是一种硬件的计时设备在HDF框架中,Watchdog接口适配模式采用独立服务模式,在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。 看门狗(Watchdog),又叫看门狗计时器(Watchdog timer),是一种硬件的计时设备在HDF框架中,Watchdog接口适配模式采用独立服务模式,在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,增加内存占用。
**图 1** Watchdog独立服务模式结构图<a name="fig61584136211"></a> **图1** Watchdog独立服务模式结构图
![](figures/独立服务模式结构图.png "Watchdog独立服务模式结构图")
## 接口说明<a name="section752964871810"></a> ![image](figures/独立服务模式结构图.png "Watchdog独立服务模式结构图")
## 接口说明
WatchdogMethod定义: WatchdogMethod定义:
``` ```
struct WatchdogMethod { struct WatchdogMethod {
int32_t (*getStatus)(struct WatchdogCntlr *wdt, int32_t *status); int32_t (*getStatus)(struct WatchdogCntlr *wdt, int32_t *status);
...@@ -20,342 +23,238 @@ struct WatchdogMethod { ...@@ -20,342 +23,238 @@ struct WatchdogMethod {
int32_t (*start)(struct WatchdogCntlr *wdt); int32_t (*start)(struct WatchdogCntlr *wdt);
int32_t (*stop)(struct WatchdogCntlr *wdt); int32_t (*stop)(struct WatchdogCntlr *wdt);
int32_t (*feed)(struct WatchdogCntlr *wdt); int32_t (*feed)(struct WatchdogCntlr *wdt);
int32_t (*getPriv)(struct WatchdogCntlr *wdt); //【可选】如果WatchdogCntlr 中的priv成员存在,则按需实例化 int32_t (*getPriv)(struct WatchdogCntlr *wdt); // 【可选】如果WatchdogCntlr中的priv成员存在,则按需实例化
void (*releasePriv)(struct WatchdogCntlr *wdt);//【可选】 void (*releasePriv)(struct WatchdogCntlr *wdt);// 【可选】
}; };
``` ```
**表 1** WatchdogMethod成员的回调函数功能说明 **表1** WatchdogMethod成员的回调函数功能说明
<a name="table1370451732"></a> | 成员函数 | 入参 | 出参 | 返回值 | 功能 |
<table><thead align="left"><tr id="row370511435"><th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.1"><p id="p170681939"><a name="p170681939"></a><a name="p170681939"></a>成员函数</p> | -------- | -------- | -------- | -------- | -------- |
</th> | getStatus | wdt:结构体指针,核心层WDG控制器 | status:&nbsp;int32_t指针,表示狗的状态(打开或关闭) | HDF_STATUS相关状态 | 获取看门狗所处的状态 |
<th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.2"><p id="p870641434"><a name="p870641434"></a><a name="p870641434"></a>入参</p> | start | wdt:结构体指针,核心层WDG控制器 | 无 | HDF_STATUS相关状态 | 打开开门狗 |
</th> | stop | wdt:结构体指针,核心层WDG控制器 | 无 | HDF_STATUS相关状态 | 关闭开门狗 |
<th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.3"><p id="p27061011739"><a name="p27061011739"></a><a name="p27061011739"></a>出参</p> | setTimeout | wdt:结构体指针,核心层WDG控制器 | seconds:&nbsp;uint32_t,时间传入值; | 无 | HDF_STATUS相关状态 | 设置超时时间值,单位秒,需要保证看门狗实际运行的时间符合该值 |
</th> | getTimeout | wdt:结构体指针,核心层WDG控制器 | seconds:&nbsp;uint32_t,传出的时间值 | HDF_STATUS相关状态 | 回读设置的超时时间值 |
<th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.4"><p id="p10707618315"><a name="p10707618315"></a><a name="p10707618315"></a>返回值</p> | feed | wdt:结构体指针,核心层WDG控制器 | 无 | HDF_STATUS相关状态 | 喂狗 |
</th>
<th class="cellrowborder" valign="top" width="20%" id="mcps1.2.6.1.5"><p id="p37071516316"><a name="p37071516316"></a><a name="p37071516316"></a>功能</p>
</th> ## 开发步骤
</tr>
</thead>
<tbody><tr id="row18707191835"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p970720118311"><a name="p970720118311"></a><a name="p970720118311"></a>getStatus</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p124968261413"><a name="p124968261413"></a><a name="p124968261413"></a>wdt: 结构体指针,核心层WDG控制器;</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="p17071515316"><a name="p17071515316"></a><a name="p17071515316"></a>status: int32_t指针,表示狗的状态(打开或关闭);</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="p5707319312"><a name="p5707319312"></a><a name="p5707319312"></a>HDF_STATUS相关状态</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p2707511312"><a name="p2707511312"></a><a name="p2707511312"></a>获取看门狗所处的状态</p>
</td>
</tr>
<tr id="row27071911538"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p370701533"><a name="p370701533"></a><a name="p370701533"></a>start</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p117071316317"><a name="p117071316317"></a><a name="p117071316317"></a>wdt: 结构体指针,核心层WDG控制器;</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="p127071411735"><a name="p127071411735"></a><a name="p127071411735"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="p19707111331"><a name="p19707111331"></a><a name="p19707111331"></a>HDF_STATUS相关状态</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p170811111319"><a name="p170811111319"></a><a name="p170811111319"></a>打开开门狗</p>
</td>
</tr>
<tr id="row17708191130"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p11708113315"><a name="p11708113315"></a><a name="p11708113315"></a>stop</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p870841138"><a name="p870841138"></a><a name="p870841138"></a>wdt: 结构体指针,核心层WDG控制器;</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="p770841533"><a name="p770841533"></a><a name="p770841533"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="p18708115313"><a name="p18708115313"></a><a name="p18708115313"></a>HDF_STATUS相关状态</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p3708121738"><a name="p3708121738"></a><a name="p3708121738"></a>关闭开门狗</p>
</td>
</tr>
<tr id="row107081818310"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p10708181136"><a name="p10708181136"></a><a name="p10708181136"></a>setTimeout</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p1870801834"><a name="p1870801834"></a><a name="p1870801834"></a>wdt: 结构体指针,核心层WDG控制器;seconds: uint32_t,时间传入值;</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="p77081011731"><a name="p77081011731"></a><a name="p77081011731"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="p470871436"><a name="p470871436"></a><a name="p470871436"></a>HDF_STATUS相关状态</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p57091717315"><a name="p57091717315"></a><a name="p57091717315"></a>设置超时时间值,单位秒,需要保证看门狗实际运行的时间符合该值</p>
</td>
</tr>
<tr id="row3709911938"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p2070911932"><a name="p2070911932"></a><a name="p2070911932"></a>getTimeout</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p47091711732"><a name="p47091711732"></a><a name="p47091711732"></a>wdt: 结构体指针,核心层WDG控制器;</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="p57091411632"><a name="p57091411632"></a><a name="p57091411632"></a>seconds: uint32_t,传出的时间值</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="p1470941838"><a name="p1470941838"></a><a name="p1470941838"></a>HDF_STATUS相关状态</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p17091511139"><a name="p17091511139"></a><a name="p17091511139"></a>回读设置的超时时间值</p>
</td>
</tr>
<tr id="row1770919112319"><td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.1 "><p id="p1270913116313"><a name="p1270913116313"></a><a name="p1270913116313"></a>feed</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.2 "><p id="p570971736"><a name="p570971736"></a><a name="p570971736"></a>wdt: 结构体指针,核心层WDG控制器;</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.3 "><p id="p67091517315"><a name="p67091517315"></a><a name="p67091517315"></a></p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.4 "><p id="p1670915111312"><a name="p1670915111312"></a><a name="p1670915111312"></a>HDF_STATUS相关状态</p>
</td>
<td class="cellrowborder" valign="top" width="20%" headers="mcps1.2.6.1.5 "><p id="p10709818316"><a name="p10709818316"></a><a name="p10709818316"></a>喂狗</p>
</td>
</tr>
</tbody>
</table>
## 开发步骤<a name="section477974542160117"></a>
Watchdog模块适配HDF框架的三个环节是配置属性文件,实例化驱动入口,以及实例化核心层接口函数。 Watchdog模块适配HDF框架的三个环节是配置属性文件,实例化驱动入口,以及实例化核心层接口函数。
1. **实例化驱动入口:** 1. **实例化驱动入口:**
- 实例化HdfDriverEntry结构体成员。 - 实例化HdfDriverEntry结构体成员。
- 调用HDF\_INIT将HdfDriverEntry实例化对象注册到HDF框架中。 - 调用HDF_INIT将HdfDriverEntry实例化对象注册到HDF框架中。
2. **配置属性文件:** 2. **配置属性文件:**
- 在device\_info.hcs文件中添加deviceNode描述。 - 在device_info.hcs文件中添加deviceNode描述。
- 【可选】添加watchdog\_config.hcs器件属性文件。 - 【可选】添加watchdog_config.hcs器件属性文件。
3. **实例化Watchdog控制器对象:** 3. **实例化Watchdog控制器对象:**
- 初始化WatchdogCntlr成员。 - 初始化WatchdogCntlr成员。
- 实例化WatchdogCntlr成员WatchdogMethod。 - 实例化WatchdogCntlr成员WatchdogMethod。
> ![](../public_sys-resources/icon-note.gif) **说明:**<br>
>![](../public_sys-resources/icon-note.gif) **说明:** > 实例化WatchdogCntlr成员WatchdogMethod,其定义和成员说明见[接口说明](#接口说明)。
>实例化WatchdogCntlr成员WatchdogMethod,其定义和成员说明见[接口说明](#section752964871810)。
4. **驱动调试:**
【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的信息反馈,超时时间设置的成功与否等。
4. **驱动调试:**
【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的信息反馈,超时时间设置的成功与否等。 ## 开发实例
下方将以watchdog_hi35xx.c为示例,展示需要厂商提供哪些内容来完整实现设备功能。
## 开发实例<a name="section1832270347160117"></a>
1. 驱动开发首先需要实例化驱动入口,驱动入口必须为HdfDriverEntry(在 hdf_device_desc.h 中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。
下方将以watchdog\_hi35xx.c为示例,展示需要厂商提供哪些内容来完整实现设备功能。 一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。
1. 驱动开发首先需要实例化驱动入口,驱动入口必须为HdfDriverEntry(在 hdf\_device\_desc.h 中定义)类型的全局变量,且moduleName要和device\_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。 Watchdog驱动入口参考:
一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 ```
struct HdfDriverEntry g_watchdogDriverEntry = {
Watchdog驱动入口参考: .moduleVersion = 1,
.Bind = Hi35xxWatchdogBind, // 见Bind参考
``` .Init = Hi35xxWatchdogInit, // 见Init参考
struct HdfDriverEntry g_watchdogDriverEntry = { .Release = Hi35xxWatchdogRelease, // 见Release参考
.moduleVersion = 1, .moduleName = "HDF_PLATFORM_WATCHDOG",// 【必要且与HCS文件中里面的moduleName匹配】
.Bind = Hi35xxWatchdogBind, //见Bind参考 };
.Init = Hi35xxWatchdogInit, //见Init参考 HDF_INIT(g_watchdogDriverEntry);// 调用HDF_INIT将驱动入口注册到HDF框架中
.Release = Hi35xxWatchdogRelease, //见Release参考 ```
.moduleName = "HDF_PLATFORM_WATCHDOG",//【必要且与HCS文件中里面的moduleName匹配】
}; 2. 完成驱动入口注册之后,下一步请在device_info.hcs文件中添加deviceNode信息,并在 watchdog_config.hcs 中配置器件属性。deviceNode信息与驱动入口注册相关,器件属性值与核心层WatchdogCntlr 成员的默认值或限制范围有密切关系。
HDF_INIT(g_watchdogDriverEntry);//调用HDF_INIT将驱动入口注册到HDF框架中 本例只有一个Watchdog控制器,如有多个器件信息,则需要在device_info文件增加deviceNode信息,以及在watchdog_config文件中增加对应的器件属性。
``` - device_info.hcs 配置参考:
2. 完成驱动入口注册之后,下一步请在device\_info.hcs文件中添加deviceNode信息,并在 watchdog\_config.hcs 中配置器件属性。deviceNode信息与驱动入口注册相关,器件属性值与核心层WatchdogCntlr 成员的默认值或限制范围有密切关系。
```
本例只有一个Watchdog控制器,如有多个器件信息,则需要在device\_info文件增加deviceNode信息,以及在watchdog\_config文件中增加对应的器件属性。 root {
device_info {
- device\_info.hcs 配置参考。 match_attr = "hdf_manager";
device_watchdog :: device { // 设备节点
``` device0 :: deviceNode { // 驱动的DeviceNode节点
root { policy = 1; // policy字段是驱动服务发布的策略,如果需要面向用户态,则为2
device_info { priority = 20; // 驱动启动优先级
match_attr = "hdf_manager"; permission = 0644; // 驱动创建设备节点权限
device_watchdog :: device { // 设备节点 moduleName = "HDF_PLATFORM_WATCHDOG";
device0 :: deviceNode { // 驱动的DeviceNode节点 // 【必要】驱动名称,该字段的值必须和驱动入口结构的moduleName值一致
policy = 1; // policy字段是驱动服务发布的策略,如果需要面向用户态,则为2 serviceName = "HDF_PLATFORM_WATCHDOG_0";
priority = 20; // 驱动启动优先级 // 【必要且唯一】驱动对外发布服务的名称
permission = 0644; // 驱动创建设备节点权限 deviceMatchAttr = "hisilicon_hi35xx_watchdog_0";
moduleName = "HDF_PLATFORM_WATCHDOG"; // 【必要】驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等
// 【必要】驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 }
serviceName = "HDF_PLATFORM_WATCHDOG_0"; }
// 【必要且唯一】驱动对外发布服务的名称 }
deviceMatchAttr = "hisilicon_hi35xx_watchdog_0"; }
// 【必要】驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等 ```
}
} - watchdog_config.hcs 配置参考:
}
}
``` ```
root {
- watchdog\_config.hcs 配置参考。 platform {
template watchdog_controller {// 【必要】模板配置,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省
``` id = 0;
root { match_attr = "";
platform { regBase = 0x12050000; // 【必要】地址映射需要
template watchdog_controller {//【必要】模板配置,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省 regStep = 0x1000; // 【必要】地址映射需要
id = 0; }
match_attr = ""; controller_0x12050000 :: watchdog_controller {// 【必要】是作为设备驱动私有数据匹配的关键字
regBase = 0x12050000; //【必要】地址映射需要 match_attr = "hisilicon_hi35xx_watchdog_0"; // 【必要】必须和device_info.hcs中的deviceMatchAttr值一致
regStep = 0x1000; //【必要】地址映射需要 }
} // 存在多个 watchdog 时【必须】添加,否则不用
controller_0x12050000 :: watchdog_controller {//【必要】是作为设备驱动私有数据匹配的关键字 ...
match_attr = "hisilicon_hi35xx_watchdog_0"; //【必要】必须和device_info.hcs中的deviceMatchAttr值一致 }
} }
//存在多个 watchdog 时【必须】添加,否则不用 ```
...
} 3. 完成驱动入口注册之后,最后一步就是以核心层WatchdogCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化WatchdogCntlr成员WatchdogMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。
} - 自定义结构体参考。
```
从驱动的角度看,自定义结构体是参数和数据的载体,而且watchdog_config.hcs文件中的数值会被HDF读入通过DeviceResourceIface来初始化结构体成员,其中一些重要数值也会传递给核心层WatchdogCntlr对象,例如索引、管脚数等。
3. 完成驱动入口注册之后,最后一步就是以核心层WatchdogCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化WatchdogCntlr成员WatchdogMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。
- 自定义结构体参考。
```
从驱动的角度看,自定义结构体是参数和数据的载体,而且watchdog\_config.hcs文件中的数值会被HDF读入通过DeviceResourceIface来初始化结构体成员,其中一些重要数值也会传递给核心层WatchdogCntlr对象,例如索引、管脚数等。 struct Hi35xxWatchdog {
struct WatchdogCntlr wdt; // 【必要】是链接上下层的载体,具体描述见下面
``` OsalSpinlock lock;
struct Hi35xxWatchdog { volatile unsigned char *regBase;// 【必要】地址映射需要
struct WatchdogCntlr wdt; //【必要】是链接上下层的载体,具体描述见下面 uint32_t phyBase; // 【必要】地址映射需要
OsalSpinlock lock; uint32_t regStep; // 【必要】地址映射需要
volatile unsigned char *regBase;//【必要】地址映射需要 };
uint32_t phyBase; //【必要】地址映射需要 // WatchdogCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值
uint32_t regStep; //【必要】地址映射需要 struct WatchdogCntlr {
}; struct IDeviceIoService service;// 驱动服务
//WatchdogCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值 struct HdfDeviceObject *device; // 驱动设备
struct WatchdogCntlr { OsalSpinlock lock; // 此变量在HDF核心层被调用来实现自旋锁功能
struct IDeviceIoService service;//驱动服务 struct WatchdogMethod *ops; // 接口回调函数
struct HdfDeviceObject *device; //驱动设备 int16_t wdtId; // WDG设备的识别id
OsalSpinlock lock; //此变量在HDF核心层被调用来实现自旋锁功能 void *priv; // 存储指针
struct WatchdogMethod *ops; //接口回调函数 };
int16_t wdtId; //WDG设备的识别id ```
void *priv; //存储指针 - WatchdogCntlr成员回调函数结构体WatchdogMethod的实例化,其他成员在Init和Bind函数中初始化。
};
```
- WatchdogCntlr成员回调函数结构体WatchdogMethod的实例化,其他成员在Init和Bind函数中初始化。
```
static struct WatchdogMethod g_method = {
.getStatus = Hi35xxWatchdogGetStatus,
.start = Hi35xxWatchdogStart,
.stop = Hi35xxWatchdogStop,
.setTimeout = Hi35xxWatchdogSetTimeout,
.getTimeout = Hi35xxWatchdogGetTimeout,
.feed = Hi35xxWatchdogFeed,
};
```
- Init函数和Bind函数参考
入参:
HdfDeviceObject :HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。
返回值:
HDF\_STATUS相关状态 (下表为部分展示,如需使用其他状态,可见//drivers/framework/include/utils/hdf\_base.h中HDF\_STATUS 定义)。
**表 2** Init函数和Bind函数入参和返回值
<a name="table86931033998"></a>
<table><thead align="left"><tr id="row10694203319911"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p1669433319918"><a name="p1669433319918"></a><a name="p1669433319918"></a>状态(值)</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p06945331911"><a name="p06945331911"></a><a name="p06945331911"></a>问题描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row869417338918"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p96941433391"><a name="p96941433391"></a><a name="p96941433391"></a>HDF_ERR_INVALID_OBJECT</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p4694333395"><a name="p4694333395"></a><a name="p4694333395"></a>找不到 WDG 设备</p>
</td>
</tr>
<tr id="row136941833091"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p66941336920"><a name="p66941336920"></a><a name="p66941336920"></a>HDF_ERR_MALLOC_FAIL</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1694133395"><a name="p1694133395"></a><a name="p1694133395"></a>内存分配失败</p>
</td>
</tr>
<tr id="row469443317913"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p116951933293"><a name="p116951933293"></a><a name="p116951933293"></a>HDF_ERR_IO</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p969511331918"><a name="p969511331918"></a><a name="p969511331918"></a>I/O 错误</p>
</td>
</tr>
<tr id="row369533318911"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p669511331891"><a name="p669511331891"></a><a name="p669511331891"></a>HDF_SUCCESS</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p136951233699"><a name="p136951233699"></a><a name="p136951233699"></a>初始化成功</p>
</td>
</tr>
<tr id="row17695633596"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p1469583314910"><a name="p1469583314910"></a><a name="p1469583314910"></a>HDF_FAILURE</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p10695193311919"><a name="p10695193311919"></a><a name="p10695193311919"></a>初始化失败</p>
</td>
</tr>
</tbody>
</table>
函数说明:
初始化自定义结构体对象,初始化WatchdogCntlr成员,调用核心层WatchdogCntlrAdd函数。
```
//一般而言,Init函数需要根据入参(HdfDeviceObject对象)的属性值初始化Hi35xxWatchdog结构体的成员,
//但本例中是在bind函数中实现的
static int32_t Hi35xxWatchdogInit(struct HdfDeviceObject *device)
{
(void)device;
return HDF_SUCCESS;
}
static int32_t Hi35xxWatchdogBind(struct HdfDeviceObject *device) ```
{ static struct WatchdogMethod g_method = {
int32_t ret; .getStatus = Hi35xxWatchdogGetStatus,
struct Hi35xxWatchdog *hwdt = NULL; .start = Hi35xxWatchdogStart,
... .stop = Hi35xxWatchdogStop,
hwdt = (struct Hi35xxWatchdog *)OsalMemCalloc(sizeof(*hwdt));//Hi35xxWatchdog 结构体的内存申请 .setTimeout = Hi35xxWatchdogSetTimeout,
... .getTimeout = Hi35xxWatchdogGetTimeout,
hwdt->regBase = OsalIoRemap(hwdt->phyBase, hwdt->regStep); //地址映射 .feed = Hi35xxWatchdogFeed,
... };
hwdt->wdt.priv = (void *)device->property;//【可选】此处是将设备属性的内容赋值给priv成员,但后续没有调用 priv 成员, ```
// 如果需要用到priv成员,需要额外实例化WatchdogMethod的getPriv和releasePriv成员函数
hwdt->wdt.ops = &g_method; //【必要】将实例化后的对象赋值给ops成员,就可以实现顶层调用WatchdogMethod成员函数 - Init函数和Bind函数参考:
hwdt->wdt.device = device; //【必要】这是为了方便HdfDeviceObject与WatchdogcCntlr相互转化
ret = WatchdogCntlrAdd(&hwdt->wdt); //【必要】调用此函数初始化核心层结构体,返回成功信号后驱动才完全接入平台核心层
if (ret != HDF_SUCCESS) { //不成功的话,需要释放Init函数申请的资源
OsalIoUnmap((void *)hwdt->regBase);
OsalMemFree(hwdt);
return ret;
}
return HDF_SUCCESS;
}
```
- Release函数参考
入参:
HdfDeviceObject :HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。
返回值:
无。
函数说明:
该函数需要在驱动入口结构体中赋值给Release,当HDF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源。该函数中需包含释放内存和删除控制器等操作。所有强制转换获取相应对象的操作前提是在Init函数中具备对应赋值的操作。
```
static void Hi35xxWatchdogRelease(struct HdfDeviceObject *device)
{
struct WatchdogCntlr *wdt = NULL;
struct Hi35xxWatchdog *hwdt = NULL;
...
wdt = WatchdogCntlrFromDevice(device);//这里会通过service成员将HdfDeviceObject转化为WatchdogCntlr
//return (device == NULL) ? NULL : (struct WatchdogCntlr *)device->service;
if (wdt == NULL) {
return;
}
WatchdogCntlrRemove(wdt); //核心层函数,实际执行wdt->device->service = NULL以及cntlr->lock的释放
hwdt = (struct Hi35xxWatchdog *)wdt; //这里将WatchdogCntlr转化为HimciHost
if (hwdt->regBase != NULL) { //解除地址映射
OsalIoUnmap((void *)hwdt->regBase);
hwdt->regBase = NULL;
}
OsalMemFree(hwdt); //释放厂商自定义对象占用的内存
}
```
入参:
HdfDeviceObject :HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。
返回值:
HDF_STATUS相关状态 (下表为部分展示,如需使用其他状态,可见// drivers/framework/include/utils/hdf_base.h中HDF_STATUS 定义)。
**表2** Init函数和Bind函数入参和返回值
| 状态(值) | 问题描述 |
| -------- | -------- |
| HDF_ERR_INVALID_OBJECT | 找不到&nbsp;WDG&nbsp;设备 |
| HDF_ERR_MALLOC_FAIL | 内存分配失败 |
| HDF_ERR_IO | I/O&nbsp;错误 |
| HDF_SUCCESS | 初始化成功 |
| HDF_FAILURE | 初始化失败 |
函数说明:
初始化自定义结构体对象,初始化WatchdogCntlr成员,调用核心层WatchdogCntlrAdd函数。
```
// 一般而言,Init函数需要根据入参(HdfDeviceObject对象)的属性值初始化Hi35xxWatchdog结构体的成员,
// 但本例中是在bind函数中实现的
static int32_t Hi35xxWatchdogInit(struct HdfDeviceObject *device)
{
(void)device;
return HDF_SUCCESS;
}
static int32_t Hi35xxWatchdogBind(struct HdfDeviceObject *device)
{
int32_t ret;
struct Hi35xxWatchdog *hwdt = NULL;
...
hwdt = (struct Hi35xxWatchdog *)OsalMemCalloc(sizeof(*hwdt));// Hi35xxWatchdog 结构体的内存申请
...
hwdt->regBase = OsalIoRemap(hwdt->phyBase, hwdt->regStep); // 地址映射
...
hwdt->wdt.priv = (void *)device->property;// 【可选】此处是将设备属性的内容赋值给priv成员,但后续没有调用 priv 成员,
// 如果需要用到priv成员,需要额外实例化WatchdogMethod的getPriv和releasePriv成员函数
hwdt->wdt.ops = &g_method; // 【必要】将实例化后的对象赋值给ops成员,就可以实现顶层调用WatchdogMethod成员函数
hwdt->wdt.device = device; // 【必要】这是为了方便HdfDeviceObject与WatchdogcCntlr相互转化
ret = WatchdogCntlrAdd(&hwdt->wdt); // 【必要】调用此函数初始化核心层结构体,返回成功信号后驱动才完全接入平台核心层
if (ret != HDF_SUCCESS) { // 不成功的话,需要释放Init函数申请的资源
OsalIoUnmap((void *)hwdt->regBase);
OsalMemFree(hwdt);
return ret;
}
return HDF_SUCCESS;
}
```
- Release函数参考:
入参:
HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。
返回值:
无。
函数说明:
该函数需要在驱动入口结构体中赋值给Release,当HDF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源。该函数中需包含释放内存和删除控制器等操作。所有强制转换获取相应对象的操作前提是在Init函数中具备对应赋值的操作。
```
static void Hi35xxWatchdogRelease(struct HdfDeviceObject *device)
{
struct WatchdogCntlr *wdt = NULL;
struct Hi35xxWatchdog *hwdt = NULL;
...
wdt = WatchdogCntlrFromDevice(device);// 这里会通过service成员将HdfDeviceObject转化为WatchdogCntlr
// return (device == NULL) ? NULL : (struct WatchdogCntlr *)device->service;
if (wdt == NULL) {
return;
}
WatchdogCntlrRemove(wdt); // 核心层函数,实际执行wdt->device->service = NULL以及cntlr->lock的释放
hwdt = (struct Hi35xxWatchdog *)wdt; // 这里将WatchdogCntlr转化为HimciHost
if (hwdt->regBase != NULL) { // 解除地址映射
OsalIoUnmap((void *)hwdt->regBase);
hwdt->regBase = NULL;
}
OsalMemFree(hwdt); // 释放厂商自定义对象占用的内存
}
```
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册