quickstart-lite-steps-hi3516-program.md 20.5 KB
Newer Older
D
duangavin123 已提交
1
# 驱动开发示例<a name="ZH-CN_TOPIC_0000001174350613"></a>
W
wenjun 已提交
2

[
[yang] 已提交
3
-   [驱动程序介绍](#s8efc1952ebfe4d1ea717182e108c29bb)
D
duangavin123 已提交
4
-   [编译和烧录](#section660016185110)
M
mamingshuai 已提交
5
-   [镜像运行](#section333215226219)
[
[yang] 已提交
6 7
-   [下一步学习](#section9712145420182)

W
wenjun 已提交
8 9 10 11
本节指导开发者在单板上运行第一个驱动程序,其中包括驱动程序介绍、编译、烧写、运行等步骤。

## 驱动程序介绍<a name="s8efc1952ebfe4d1ea717182e108c29bb"></a>

M
mamingshuai 已提交
12
下面基于HDF框架,提供一个简单的UART(Universal Asynchronous Receiver/Transmitter)平台驱动开发样例,包含配置文件的添加,驱动代码的实现以及用户态程序和驱动交互的流程。驱动程序源码位于vendor/huawei/hdf/sample目录
W
wenjun 已提交
13 14 15

1.  添加配置。

N
NEEN 已提交
16
    在HDF框架的驱动配置文件(例如device/hisilicon/hi3516dv300/sdk\_liteos/config/uart/uart\_config.hcs)中添加该驱动的配置信息,如下所示:
W
wenjun 已提交
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

    ```
    root {
        platform {
            uart_sample {
                num = 5;            // UART设备编号
                base = 0x120a0000;  // UART 寄存器基地址
                irqNum = 38;
                baudrate = 115200;
                uartClk = 24000000;
                wlen = 0x60;
                parity = 0;
                stopBit = 0;
                match_attr = "sample_uart_5";
            }
        }
    }
    ```

N
NEEN 已提交
36
    在HDF框架的设备配置文件(例如vendor/hisilicon/ipcamera\_hi3516dv300\_liteos/config/device\_info/device\_info.hcs)中添加该驱动的设备节点信息,如下所示:
W
wenjun 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

    ```
    root {
        device_info {
            platform :: host {
                hostName = "platform_host";
                priority = 50;
                device_uart :: device {
                    device5 :: deviceNode {
                        policy = 2;
                        priority = 10;
                        permission = 0660;
                        moduleName = "UART_SAMPLE";
                        serviceName = "HDF_PLATFORM_UART_5";
                        deviceMatchAttr = "sample_uart_5";
                    }
                }
            }
        }
    }
    ```

D
duangavin123 已提交
59
    >![](../public_sys-resources/icon-note.gif) **说明:** 
W
wenjun 已提交
60 61 62 63 64 65 66 67
    >配置文件与UART驱动示例的源码在同一个路径,需要手动添加到Hi3516DV300单板路径下。

2.  注册UART驱动入口。

    基于HDF框架注册UART驱动的入口HdfDriverEntry,代码如下:

    ```
    // 绑定UART驱动接口到HDF框架
N
NEEN 已提交
68
    static int32_t SampleUartDriverBind(struct HdfDeviceObject *device)
W
wenjun 已提交
69
    {
N
NEEN 已提交
70 71
        struct UartHost *uartHost = NULL;
    
W
wenjun 已提交
72 73 74 75
        if (device == NULL) {
            return HDF_ERR_INVALID_OBJECT;
        }
        HDF_LOGI("Enter %s:", __func__);
N
NEEN 已提交
76 77 78 79 80 81 82 83
    
        uartHost = UartHostCreate(device);
        if (uartHost == NULL) {
            HDF_LOGE("%s: UartHostCreate failed", __func__);
            return HDF_FAILURE;
        }
        uartHost->service.Dispatch = SampleDispatch;
        return HDF_SUCCESS;
W
wenjun 已提交
84 85 86
    }
     
    // 从UART驱动的HCS中获取配置信息
N
NEEN 已提交
87
    static uint32_t GetUartDeviceResource(
W
wenjun 已提交
88 89 90 91 92 93 94 95 96
        struct UartDevice *device, const struct DeviceResourceNode *resourceNode)
    {
        struct UartResource *resource = &device->resource;
        struct DeviceResourceIface *dri = NULL;
        dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
        if (dri == NULL || dri->GetUint32 == NULL) {
            HDF_LOGE("DeviceResourceIface is invalid");
            return HDF_FAILURE;
        }
N
NEEN 已提交
97
    
W
wenjun 已提交
98 99 100 101 102 103 104 105
        if (dri->GetUint32(resourceNode, "num", &resource->num, 0) != HDF_SUCCESS) {
            HDF_LOGE("uart config read num fail");
            return HDF_FAILURE;
        }
        if (dri->GetUint32(resourceNode, "base", &resource->base, 0) != HDF_SUCCESS) {
            HDF_LOGE("uart config read base fail");
            return HDF_FAILURE;
        }
N
NEEN 已提交
106
        resource->physBase = (unsigned long)OsalIoRemap(resource->base, 0x48);
W
wenjun 已提交
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
        if (resource->physBase == 0) {
            HDF_LOGE("uart config fail to remap physBase");
            return HDF_FAILURE;
        }
        if (dri->GetUint32(resourceNode, "irqNum", &resource->irqNum, 0) != HDF_SUCCESS) {
            HDF_LOGE("uart config read irqNum fail");
            return HDF_FAILURE;
        }
        if (dri->GetUint32(resourceNode, "baudrate", &resource->baudrate, 0) != HDF_SUCCESS) {
            HDF_LOGE("uart config read baudrate fail");
            return HDF_FAILURE;
        }
        if (dri->GetUint32(resourceNode, "wlen", &resource->wlen, 0) != HDF_SUCCESS) {
            HDF_LOGE("uart config read wlen fail");
            return HDF_FAILURE;
        }
        if (dri->GetUint32(resourceNode, "parity", &resource->parity, 0) != HDF_SUCCESS) {
            HDF_LOGE("uart config read parity fail");
            return HDF_FAILURE;
        }
        if (dri->GetUint32(resourceNode, "stopBit", &resource->stopBit, 0) != HDF_SUCCESS) {
            HDF_LOGE("uart config read stopBit fail");
            return HDF_FAILURE;
        }
        if (dri->GetUint32(resourceNode, "uartClk", &resource->uartClk, 0) != HDF_SUCCESS) {
            HDF_LOGE("uart config read uartClk fail");
            return HDF_FAILURE;
        }
        return HDF_SUCCESS;
    }
     
    // 将UART驱动的配置和接口附加到HDF驱动框架
N
NEEN 已提交
139
    static int32_t AttachUartDevice(struct UartHost *host, struct HdfDeviceObject *device)
W
wenjun 已提交
140 141 142 143 144 145 146
    {
        int32_t ret;
        struct UartDevice *uartDevice = NULL;
        if (device->property == NULL) {
            HDF_LOGE("%s: property is NULL", __func__);
            return HDF_FAILURE;
        }
N
NEEN 已提交
147
        uartDevice = (struct UartDevice *)OsalMemCalloc(sizeof(struct UartDevice));
W
wenjun 已提交
148 149 150 151
        if (uartDevice == NULL) {
            HDF_LOGE("%s: OsalMemCalloc uartDevice error", __func__);
            return HDF_ERR_MALLOC_FAIL;
        }
N
NEEN 已提交
152
        ret = GetUartDeviceResource(uartDevice, device->property);
W
wenjun 已提交
153
        if (ret != HDF_SUCCESS) {
N
NEEN 已提交
154
            (void)OsalMemFree(uartDevice);
W
wenjun 已提交
155 156 157 158
            return HDF_FAILURE;
        }
        host->num = uartDevice->resource.num;
        host->priv = uartDevice;
N
NEEN 已提交
159 160
        AddUartDevice(host);
        return InitUartDevice(uartDevice);
W
wenjun 已提交
161 162 163
    }
     
    // 初始化UART驱动
N
NEEN 已提交
164
    static int32_t SampleUartDriverInit(struct HdfDeviceObject *device)
W
wenjun 已提交
165 166 167
    {
        int32_t ret;
        struct UartHost *host = NULL;
N
NEEN 已提交
168
    
W
wenjun 已提交
169 170 171 172 173 174 175 176 177 178
        if (device == NULL) {
            HDF_LOGE("%s: device is NULL", __func__);
            return HDF_ERR_INVALID_OBJECT;
        }
        HDF_LOGI("Enter %s:", __func__);
        host = UartHostFromDevice(device);
        if (host == NULL) {
            HDF_LOGE("%s: host is NULL", __func__);
            return HDF_FAILURE;
        }
N
NEEN 已提交
179
        ret = AttachUartDevice(host, device);
W
wenjun 已提交
180 181 182 183
        if (ret != HDF_SUCCESS) {
            HDF_LOGE("%s: attach error", __func__);
            return HDF_FAILURE;
        }
N
NEEN 已提交
184
        host->method = &g_sampleUartHostMethod;
W
wenjun 已提交
185 186 187
        return ret;
    }
     
N
NEEN 已提交
188
    static void DeinitUartDevice(struct UartDevice *device)
W
wenjun 已提交
189
    {
N
NEEN 已提交
190
        struct UartRegisterMap *regMap = (struct UartRegisterMap *)device->resource.physBase;
W
wenjun 已提交
191 192 193 194
        /* wait for uart enter idle. */
        while (UartPl011IsBusy(regMap));
        UartPl011ResetRegisters(regMap);
        uart_clk_cfg(0, false);
N
NEEN 已提交
195
        OsalIoUnmap((void *)device->resource.physBase);
W
wenjun 已提交
196 197 198 199
        device->state = UART_DEVICE_UNINITIALIZED;
    }
     
    // 解绑并释放UART驱动
N
NEEN 已提交
200
    static void DetachUartDevice(struct UartHost *host)
W
wenjun 已提交
201 202
    {
        struct UartDevice *uartDevice = NULL;
N
NEEN 已提交
203
    
W
wenjun 已提交
204 205 206 207 208
        if (host->priv == NULL) {
            HDF_LOGE("%s: invalid parameter", __func__);
            return;
        }
        uartDevice = host->priv;
N
NEEN 已提交
209 210
        DeinitUartDevice(uartDevice);
        (void)OsalMemFree(uartDevice);
W
wenjun 已提交
211 212 213 214
        host->priv = NULL;
    }
     
    // 释放UART驱动
N
NEEN 已提交
215
    static void SampleUartDriverRelease(struct HdfDeviceObject *device)
W
wenjun 已提交
216 217 218
    {
        struct UartHost *host = NULL;
        HDF_LOGI("Enter %s:", __func__);
N
NEEN 已提交
219
    
W
wenjun 已提交
220
        if (device == NULL) {
N
NEEN 已提交
221
            HDF_LOGE("%s: device is NULL", __func__);
W
wenjun 已提交
222 223 224 225
            return;
        }
        host = UartHostFromDevice(device);
        if (host == NULL) {
N
NEEN 已提交
226
            HDF_LOGE("%s: host is NULL", __func__);
W
wenjun 已提交
227 228 229
            return;
        }
        if (host->priv != NULL) {
N
NEEN 已提交
230
            DetachUartDevice(host);
W
wenjun 已提交
231 232 233 234
        }
        UartHostDestroy(host);
    }
     
N
NEEN 已提交
235
    struct HdfDriverEntry g_sampleUartDriverEntry = {
W
wenjun 已提交
236 237
        .moduleVersion = 1,
        .moduleName = "UART_SAMPLE",
N
NEEN 已提交
238 239 240
        .Bind = SampleUartDriverBind,
        .Init = SampleUartDriverInit,
        .Release = SampleUartDriverRelease,
W
wenjun 已提交
241 242
    };
     
N
NEEN 已提交
243
    HDF_INIT(g_sampleUartDriverEntry);
W
wenjun 已提交
244 245 246 247 248 249 250
    ```

3.  注册UART驱动接口。

    HDF框架提供了UART驱动接口的模板方法UartHostMethod,实现UART驱动接口的代码如下:

    ```
N
NEEN 已提交
251
    static int32_t SampleUartHostInit(struct UartHost *host)
W
wenjun 已提交
252 253 254 255 256 257 258 259 260
    {
        HDF_LOGI("%s: Enter", __func__);
        if (host == NULL) {
            HDF_LOGE("%s: invalid parameter", __func__);
            return HDF_ERR_INVALID_PARAM;
        }
        return HDF_SUCCESS;
    }
    
N
NEEN 已提交
261
    static int32_t SampleUartHostDeinit(struct UartHost *host)
W
wenjun 已提交
262 263 264 265 266 267 268 269 270 271
    {
        HDF_LOGI("%s: Enter", __func__);
        if (host == NULL) {
            HDF_LOGE("%s: invalid parameter", __func__);
            return HDF_ERR_INVALID_PARAM;
        }
        return HDF_SUCCESS;
    }
    
    // 向UART中写入数据
N
NEEN 已提交
272
    static int32_t SampleUartHostWrite(struct UartHost *host, uint8_t *data, uint32_t size)
W
wenjun 已提交
273 274 275 276 277
    {
        HDF_LOGI("%s: Enter", __func__);
        uint32_t idx;
        struct UartRegisterMap *regMap = NULL;
        struct UartDevice *device = NULL;
N
NEEN 已提交
278
    
W
wenjun 已提交
279 280 281 282
        if (host == NULL || data == NULL || size == 0) {
            HDF_LOGE("%s: invalid parameter", __func__);
            return HDF_ERR_INVALID_PARAM;
        }
N
NEEN 已提交
283
        device = (struct UartDevice *)host->priv;
W
wenjun 已提交
284 285 286 287
        if (device == NULL) {
            HDF_LOGE("%s: device is NULL", __func__);
            return HDF_ERR_INVALID_PARAM;
        }
N
NEEN 已提交
288
        regMap = (struct UartRegisterMap *)device->resource.physBase;
W
wenjun 已提交
289 290 291 292 293 294 295
        for (idx = 0; idx < size; idx++) {
            UartPl011Write(regMap, data[idx]);
        }
        return HDF_SUCCESS;
    }
     
    // 设置UART的波特率
N
NEEN 已提交
296
    static int32_t SampleUartHostSetBaud(struct UartHost *host, uint32_t baudRate)
W
wenjun 已提交
297 298 299 300 301
    {
        HDF_LOGI("%s: Enter", __func__);
        struct UartDevice *device = NULL;
        struct UartRegisterMap *regMap = NULL;
        UartPl011Error err;
N
NEEN 已提交
302
    
W
wenjun 已提交
303 304 305 306
        if (host == NULL) {
            HDF_LOGE("%s: invalid parameter", __func__);
            return HDF_ERR_INVALID_PARAM;
        }
N
NEEN 已提交
307
        device = (struct UartDevice *)host->priv;
W
wenjun 已提交
308 309 310 311
        if (device == NULL) {
            HDF_LOGE("%s: device is NULL", __func__);
            return HDF_ERR_INVALID_PARAM;
        }
N
NEEN 已提交
312
        regMap = (struct UartRegisterMap *)device->resource.physBase;
W
wenjun 已提交
313 314 315 316 317 318 319 320 321 322 323 324 325 326
        if (device->state != UART_DEVICE_INITIALIZED) {
            return UART_PL011_ERR_NOT_INIT;
        }
        if (baudRate == 0) {
            return UART_PL011_ERR_INVALID_BAUD;
        }
        err = UartPl011SetBaudrate(regMap, device->uartClk, baudRate);
        if (err == UART_PL011_ERR_NONE) {
            device->baudrate = baudRate;
        }
        return err;
    }
     
    // 获取UART的波特率
N
NEEN 已提交
327
    static int32_t SampleUartHostGetBaud(struct UartHost *host, uint32_t *baudRate)
W
wenjun 已提交
328 329 330
    {
        HDF_LOGI("%s: Enter", __func__);
        struct UartDevice *device = NULL;
N
NEEN 已提交
331
    
W
wenjun 已提交
332 333 334 335
        if (host == NULL) {
            HDF_LOGE("%s: invalid parameter", __func__);
            return HDF_ERR_INVALID_PARAM;
        }
N
NEEN 已提交
336
        device = (struct UartDevice *)host->priv;
W
wenjun 已提交
337 338 339 340 341 342 343 344 345
        if (device == NULL) {
            HDF_LOGE("%s: device is NULL", __func__);
            return HDF_ERR_INVALID_PARAM;
        }
        *baudRate = device->baudrate;
        return HDF_SUCCESS;
    }
     
    // 在HdfUartSampleInit方法中绑定
N
NEEN 已提交
346 347 348
    struct UartHostMethod g_sampleUartHostMethod = {
        .Init = SampleUartHostInit,
        .Deinit = SampleUartHostDeinit,
W
wenjun 已提交
349
        .Read = NULL,
N
NEEN 已提交
350 351 352
        .Write = SampleUartHostWrite,
        .SetBaud = SampleUartHostSetBaud,
        .GetBaud = SampleUartHostGetBaud,
W
wenjun 已提交
353 354 355 356 357 358
        .SetAttribute = NULL,
        .GetAttribute = NULL,
        .SetTransMode = NULL,
    };
    ```

N
NEEN 已提交
359
    在device/hisilicon/drivers/lite.mk编译脚本中增加示例UART驱动模块,代码如下:
W
wenjun 已提交
360 361 362

    ```
    LITEOS_BASELIB += -lhdf_uart_sample
N
NEEN 已提交
363
    LIB_SUBDIRS    += $(LITEOS_SOURCE_ROOT)/vendor/huawei/hdf/sample/platform/uart
W
wenjun 已提交
364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
    ```

4.  用户程序和驱动交互代码。

    UART驱动成功初始化后,会创建/dev/uartdev-5设备节点,通过设备节点与UART驱动交互的代码如下:

    ```
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include "hdf_log.h"
    
    #define HDF_LOG_TAG "hello_uart"
    #define INFO_SIZE 16
    
    int main(void)
    {
        int ret;
        int fd;
        const char info[INFO_SIZE] = {" HELLO UART! "};
    
        fd = open("/dev/uartdev-5", O_RDWR);
        if (fd < 0) {
            HDF_LOGE("hello_uart uartdev-5 open failed %d", fd);
            return -1;
        }
        ret = write(fd, info, INFO_SIZE);
        if (ret != 0) {
            HDF_LOGE("hello_uart write uartdev-5 ret is %d", ret);
        }
        ret = close(fd);
        if (ret != 0) {
            HDF_LOGE("hello_uart uartdev-5 close failed %d", fd);
            return -1;
        }
        return ret;
    }
    ```

N
NEEN 已提交
403
    在build/lite/components/drivers.json驱动配置中hdf\_hi3516dv300\_liteos\_a组件下的targets中增加hello\_uart\_sample组件,代码如下:
W
wenjun 已提交
404 405 406

    ```
    {
N
NEEN 已提交
407
      "components": [
W
wenjun 已提交
408
        {
N
NEEN 已提交
409 410 411 412
          "component": "hdf_hi3516dv300_liteos_a",
          ...
          "targets": [
            "//vendor/huawei/hdf/sample/platform/uart:hello_uart_sample"
W
wenjun 已提交
413 414 415 416 417 418
          ]
        }
      ]
    }
    ```

D
duangavin123 已提交
419
    >![](../public_sys-resources/icon-note.gif) **说明:** 
W
wenjun 已提交
420 421 422 423
    >如上代码均为示例代码,完整代码可以在vendor/huawei/hdf/sample查看。
    >示例代码默认不参与编译,需要手动添加到编译脚本中。


D
duangavin123 已提交
424
## 编译和烧录<a name="section660016185110"></a>
W
wenjun 已提交
425

D
duangavin123 已提交
426
参考《运行Hello OHOS》进行编译和烧录:[编译](quickstart-lite-steps-hi3516-running.md#section1077671315253)[烧录](quickstart-lite-steps-hi3516-running.md#section1347011412201)
W
wenjun 已提交
427

M
mamingshuai 已提交
428
## 镜像运行<a name="section333215226219"></a>
W
wenjun 已提交
429 430 431

1.  连接串口。

D
duangavin123 已提交
432
    >![](../public_sys-resources/icon-notice.gif) **须知:** 
D
duangavin123 已提交
433
    >若无法连接串口,请参考[常见问题](quickstart-lite-steps-hi3516-faqs.md#section14871149155911)进行排查。
N
NEEN 已提交
434

D
duangavin123 已提交
435 436
    **图 1**  连接串口图<a name="fig124315964718"></a>  
    ![](figure/连接串口图-4.png "连接串口图-4")
W
wenjun 已提交
437

N
NEEN 已提交
438 439
    1.  单击**Monitor**打开串口。
    2.  连续输入回车直到串口显示"hisilicon"。
D
duangavin123 已提交
440
    3.  单板初次启动或修改启动参数,请进入[步骤2](quickstart-lite-steps-hi3516-running.md#l5b42e79a33ea4d35982b78a22913b0b1),否则进入[步骤3](quickstart-lite-steps-hi3516-running.md#ld26f18828aa44c36bfa36be150e60e49)。
W
wenjun 已提交
441 442 443

2.  (单板初次启动必选)修改U-boot的bootcmd及bootargs内容:该步骤为固化操作,若不修改参数只需执行一次。每次复位单板均会自动进入系统。

D
duangavin123 已提交
444
    >![](../public_sys-resources/icon-notice.gif) **须知:** 
N
NEEN 已提交
445
    >U-boot引导程序默认会有2秒的等待时间,用户可使用回车打断等待并显示"hisilicon",通过**reset**命令可再次启动系统。
W
wenjun 已提交
446

N
NEEN 已提交
447
    **表 1**  U-boot修改命令
W
wenjun 已提交
448

M
mamingshuai 已提交
449 450
    <a name="zh-cn_topic_0000001151888681_table1323441103813"></a>
    <table><thead align="left"><tr id="zh-cn_topic_0000001151888681_row1423410183818"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="zh-cn_topic_0000001151888681_p623461163818"><a name="zh-cn_topic_0000001151888681_p623461163818"></a><a name="zh-cn_topic_0000001151888681_p623461163818"></a>执行命令</p>
N
NEEN 已提交
451
    </th>
M
mamingshuai 已提交
452
    <th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="zh-cn_topic_0000001151888681_p42341014388"><a name="zh-cn_topic_0000001151888681_p42341014388"></a><a name="zh-cn_topic_0000001151888681_p42341014388"></a>命令解释</p>
W
wenjun 已提交
453
    </th>
N
NEEN 已提交
454 455
    </tr>
    </thead>
M
mamingshuai 已提交
456
    <tbody><tr id="zh-cn_topic_0000001151888681_row1623471113817"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001151888681_p102341719385"><a name="zh-cn_topic_0000001151888681_p102341719385"></a><a name="zh-cn_topic_0000001151888681_p102341719385"></a>setenv bootcmd "mmc read 0x0 0x80000000 0x800 0x4800; go 0x80000000";</p>
N
NEEN 已提交
457
    </td>
M
mamingshuai 已提交
458
    <td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="zh-cn_topic_0000001151888681_p92347120389"><a name="zh-cn_topic_0000001151888681_p92347120389"></a><a name="zh-cn_topic_0000001151888681_p92347120389"></a>读取FLASH起始地址为0x800(单位为512B,即1MB),大小为0x4800(单位为512B,即9MB)的内容到0x80000000的内存地址,该大小(9MB)与IDE中所填写OHOS_Image.bin文件大小<strong id="zh-cn_topic_0000001151888681_b15685648113111"><a name="zh-cn_topic_0000001151888681_b15685648113111"></a><a name="zh-cn_topic_0000001151888681_b15685648113111"></a>必须相同</strong>。</p>
W
wenjun 已提交
459 460
    </td>
    </tr>
M
mamingshuai 已提交
461
    <tr id="zh-cn_topic_0000001151888681_row12234912381"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001151888681_p172306219392"><a name="zh-cn_topic_0000001151888681_p172306219392"></a><a name="zh-cn_topic_0000001151888681_p172306219392"></a>setenv bootargs "console=ttyAMA0,115200n8 root=emmc fstype=vfat rootaddr=10M rootsize=20M rw";</p>
N
NEEN 已提交
462
    </td>
M
mamingshuai 已提交
463 464
    <td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="zh-cn_topic_0000001151888681_p13489329396"><a name="zh-cn_topic_0000001151888681_p13489329396"></a><a name="zh-cn_topic_0000001151888681_p13489329396"></a>表示设置启动参数,输出模式为串口输出,波特率为115200,数据位8,rootfs挂载于emmc器件,文件系统类型为vfat,</p>
    <p id="zh-cn_topic_0000001151888681_p12481832163913"><a name="zh-cn_topic_0000001151888681_p12481832163913"></a><a name="zh-cn_topic_0000001151888681_p12481832163913"></a>“rootaddr=10M rootsize=20M rw”处对应填入rootfs.img的烧写起始位置与长度,此处与IDE中新增rootfs.img文件时所填大小<strong id="zh-cn_topic_0000001151888681_b24816327398"><a name="zh-cn_topic_0000001151888681_b24816327398"></a><a name="zh-cn_topic_0000001151888681_b24816327398"></a>必须相同</strong>。</p>
N
NEEN 已提交
465 466
    </td>
    </tr>
M
mamingshuai 已提交
467
    <tr id="zh-cn_topic_0000001151888681_row18234161153820"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001151888681_p823417118386"><a name="zh-cn_topic_0000001151888681_p823417118386"></a><a name="zh-cn_topic_0000001151888681_p823417118386"></a>saveenv</p>
N
NEEN 已提交
468
    </td>
M
mamingshuai 已提交
469
    <td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="zh-cn_topic_0000001151888681_p32341616389"><a name="zh-cn_topic_0000001151888681_p32341616389"></a><a name="zh-cn_topic_0000001151888681_p32341616389"></a>表示保存当前配置。</p>
N
NEEN 已提交
470 471
    </td>
    </tr>
M
mamingshuai 已提交
472
    <tr id="zh-cn_topic_0000001151888681_row192345113811"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="zh-cn_topic_0000001151888681_p7235111183819"><a name="zh-cn_topic_0000001151888681_p7235111183819"></a><a name="zh-cn_topic_0000001151888681_p7235111183819"></a>reset</p>
N
NEEN 已提交
473
    </td>
M
mamingshuai 已提交
474
    <td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="zh-cn_topic_0000001151888681_p123781411114016"><a name="zh-cn_topic_0000001151888681_p123781411114016"></a><a name="zh-cn_topic_0000001151888681_p123781411114016"></a>表示复位单板。</p>
W
wenjun 已提交
475 476 477 478 479
    </td>
    </tr>
    </tbody>
    </table>

D
duangavin123 已提交
480
    >![](../public_sys-resources/icon-notice.gif) **须知:** 
N
NEEN 已提交
481 482
    >**“go 0x80000000”**为可选指令,默认配置已将该指令固化在启动参数中,单板复位后可自动启动。若想切换为手动启动,可在U-boot启动倒数阶段使用"回车"打断自动启动。

W
wenjun 已提交
483 484
3.  输入**“reset”**指令并回车,重启单板,启动成功如下图,输入回车串口显示OHOS字样。

D
duangavin123 已提交
485 486
    **图 2**  系统启动图<a name="fig14618415485"></a>  
    ![](figure/系统启动图-5.png "系统启动图-5")
W
wenjun 已提交
487

N
NEEN 已提交
488
4.  根目录下,在命令行输入指令“**./bin/hello\_uart**”执行写入的demo程序,显示成功结果如下所示。
W
wenjun 已提交
489 490 491 492 493 494 495 496 497

    ```
    OHOS # ./bin/hello_uart
    OHOS #  HELLO UART!
    ```


## 下一步学习<a name="section9712145420182"></a>

D
duangavin123 已提交
498
恭喜,您已完成Hi3516 快速上手!建议您下一步进入[带屏摄像头产品开发](../guide/device-camera.md)的学习 。
W
wenjun 已提交
499