Little bear Pie: use openharmory3 0 turns on the LED

Abstract: as a representative and complete development, this case can be divided into three parts: code file planning, LED lamp driving development and LED lighting business development.

This article is shared from Huawei cloud community< Use openharmory3 on Micro bear pie 0 lit LED(1)LED driver development >, author: shenlongju city.

Project overview

As a representative and complete development, this case can be divided into three parts: code file planning, LED lamp driving development and LED lighting business development.

1, LED Driver Development

1.1. Determine directory structure

1.1.1. According to the HDF framework, which takes the component-based driver model as the core design idea, the HDF framework puts a class of device drivers in the same host. Developers can also develop and deploy the driver functions hierarchically and independently, supporting one driver for multiple node s. The HDF driver model is shown in the following figure

1.1.2. Catalogue of this case

Yes/ Create a new led directory under the device/st/drivers path to store the driver source code files.

Yes/ device/st/bearpi_ hm_ micro/liteos_ a/hdf_ Create a new led folder under the config path and create a driver configuration file_ config. hcs

1.2.LED driver implementation

1.2.1. The driver implementation includes the driver business code and driver entry registration, which is displayed in LED Add the following code to the C file

#include "hdf_device_desc.h" 
#include "hdf_log.h"         
#include "device_resource_if.h"
#include "osal_io.h"
#include "osal.h"
#include "osal_mem.h"
#include "gpio_if.h"

#define HDF_LOG_TAG led_driver / / print the label contained in the log. If it is not defined, the default HDF is used_ Tag tag
#define LED_WRITE_READ 1 / / read / write operation code 1

enum LedOps {
    LED_OFF,
    LED_ON,  
    LED_TOGGLE,
};

struct Stm32Mp1ILed {
    uint32_t gpioNum;
};
static struct Stm32Mp1ILed g_Stm32Mp1ILed;
uint8_t status = 0;
// Dispatch is used to process messages sent from user status
int32_t LedDriverDispatch(struct HdfDeviceIoClient *client, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
{
    uint8_t contrl;
    HDF_LOGE("Led driver dispatch");
    if (client == NULL || client->device == NULL)
    {
        HDF_LOGE("Led driver device is NULL");
        return HDF_ERR_INVALID_OBJECT;
    }

    switch (cmdCode)
    {
    /* Received led from user status_ WRITE_ Read command */
    case LED_WRITE_READ:
        /* Read the data in data and assign it to contrl */
        HdfSbufReadUint8(data,&contrl);                  
        switch (contrl)
        {
        /* turn on the light */
        case LED_ON:                                            
            GpioWrite(g_Stm32Mp1ILed.gpioNum, GPIO_VAL_LOW);
            status = 1;
            break;
        /* Turn off the lights */
        case LED_OFF:                                           
            GpioWrite(g_Stm32Mp1ILed.gpioNum, GPIO_VAL_HIGH);
            status = 0;
            break;
        /* State flip */
        case LED_TOGGLE:
            if(status == 0)
            {
                GpioWrite(g_Stm32Mp1ILed.gpioNum, GPIO_VAL_LOW);
                status = 1;
            }
            else
            {
                GpioWrite(g_Stm32Mp1ILed.gpioNum, GPIO_VAL_HIGH);
                status = 0;
            }                                        
            break;
        default:
            break;
        }
        /* Write the status value of the LED into reply, which can be brought to the user program */
        if (!HdfSbufWriteInt32(reply, status))                
        {
            HDF_LOGE("replay is fail");
            return HDF_FAILURE;
        }
        break;
    default:
        break;
    }
    return HDF_SUCCESS;
}

// Read driver private configuration
static int32_t Stm32LedReadDrs(struct Stm32Mp1ILed *led, const struct DeviceResourceNode *node)
{
    int32_t ret;
    struct DeviceResourceIface *drsOps = NULL;

    drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
    if (drsOps == NULL || drsOps->GetUint32 == NULL) {
        HDF_LOGE("%s: invalid drs ops!", __func__);
        return HDF_FAILURE;
    }
    /* Read led Led in HCS_ gpio_ Value of num */
    ret = drsOps->GetUint32(node, "led_gpio_num", &led->gpioNum, 0); 
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: read led gpio num fail!", __func__);
        return ret;
    }
    return HDF_SUCCESS;
}

//Drive the service capabilities provided externally and bind the relevant service interfaces to the HDF framework
int32_t HdfLedDriverBind(struct HdfDeviceObject *deviceObject)
{
    if (deviceObject == NULL)
    {
        HDF_LOGE("Led driver bind failed!");
        return HDF_ERR_INVALID_OBJECT;
    }
    static struct IDeviceIoService ledDriver = {
        .Dispatch = LedDriverDispatch,
    };
    deviceObject->service = (struct IDeviceIoService *)(&ledDriver);
    HDF_LOGD("Led driver bind success");
    return HDF_SUCCESS;
}

// Interface that drives the initial of its own business
int32_t HdfLedDriverInit(struct HdfDeviceObject *device)
{
    struct Stm32Mp1ILed *led = &g_Stm32Mp1ILed;
    int32_t ret;

    if (device == NULL || device->property == NULL) {
        HDF_LOGE("%s: device or property NULL!", __func__);
        return HDF_ERR_INVALID_OBJECT;
    }
    /* Read hcs private attribute value */
    ret = Stm32LedReadDrs(led, device->property);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: get led device resource fail:%d", __func__, ret);
        return ret;
    }
    /* Configure GPIO pin as output */
    ret = GpioSetDir(led->gpioNum, GPIO_DIR_OUT);
    if (ret != 0)
    {
        HDF_LOGE("GpioSerDir: failed, ret %d\n", ret);
        return ret;
    }
    HDF_LOGD("Led driver Init success");
    return HDF_SUCCESS;
}

// Interface driving resource release
void HdfLedDriverRelease(struct HdfDeviceObject *deviceObject)
{
    if (deviceObject == NULL)
    {
        HDF_LOGE("Led driver release failed!");
        return;
    }
    HDF_LOGD("Led driver release success");
    return;
}

// The object defining the driver entry must be a global variable of type HdfDriverEntry (defined in hdf_device_desc.h)
struct HdfDriverEntry g_ledDriverEntry = {
    .moduleVersion = 1,
    .moduleName = "HDF_LED",
    .Bind = HdfLedDriverBind,
    .Init = HdfLedDriverInit,
    .Release = HdfLedDriverRelease,
};

// Call HDF_INIT registers the driver entry into the HDF framework
HDF_INIT(g_ledDriverEntry);

1.2.2. Compile script file

In LED / build Add the following code to the GN file to add led C compiled into hdf_led

import("//drivers/adapter/khdf/liteos/hdf.gni")
hdf_driver("hdf_led") {
    sources = [
    "led.c",
    ]
}

At / device / St / Drivers / build Add the following code to the GN file to hdf_led compiled into the kernel, "led" is a new content

1.3. Drive configuration

HDF uses HCS as the configuration description source code. The driver configuration includes two parts: the driver device description defined by the HDF framework and the private configuration information of the driver.

The information required by the HDF framework to load the driver comes from the driver device description defined by the HDF framework. Therefore, the driver developed based on the HDF framework must be in the device defined by the HDF framework_ info. Add the corresponding device description in the HCS configuration file, so we need to add it in device \ St \ bearpi_ hm_ micro\liteos_ a\hdf_ config\device_ info\device_ info. Add LED device description to HCS

device_led :: device {             // led device node
    device0 :: deviceNode {        // led driven DeviceNode node
        policy = 2;                // The policy field is the policy of driving service publishing, which is described in detail in the chapter of driving service management
        priority = 10;             // Drive startup priority (0-200). The higher the value, the lower the priority. It is recommended to configure 100 by default. If the priority is the same, the loading order of device s is not guaranteed
        preload = 1;               // Drive on demand fields
        permission = 0777;         // Driver create device node permission
        moduleName = "HDF_LED";    // Driver name. The value of this field must be consistent with the moduleName value of the driver entry structure
        serviceName = "hdf_led";   // The name of the driver publishing service must be unique
        deviceMatchAttr = "st_stm32mp157_led"; // The keyword matching the driver private data must match the keyword in the driver private data configuration table_ Equal attr values
    }
}  

1.4. Private driver information configuration

If the driver has private configuration, you can add a driver configuration file to fill in some default configuration information of the driver. When loading the driver, the HDF framework will obtain and save the corresponding configuration information in the property in the HdfDeviceObject and pass it to the driver through Bind and Init, so we need to enter it in device \ St \ bearpi_ hm_ micro\liteos_ a\hdf_ config\LED\led_ config. Add LED private configuration description to HCS.

root {
    LedDriverConfig {
        led_gpio_num = 13;
        match_attr = "st_stm32mp157_led";   //The value of this field must be the same as device_ info. The deviceMatchAttr value in HCS is consistent
    }
}

1.5. Board level configuration entry file

After the configuration information is defined, you need to add the configuration file to the board level configuration entry file device\st\bearpi_hm_micro\liteos_a\hdf_config\hdf.hcs

#include "device_info/device_info.hcs"
#include "led/led_config.hcs"

2, Lighting LED service code

2.1. Create directory

When writing business, be sure to write it first/ applications/BearPi/BearPi-HM_ Create a new directory (or a set of directory structure) under the micro / samples path to store the business source code files

Add my in the samples folder_ led_ App folder and create a new build Gn and my_led_app.c two documents

2.2. Write business code

In my_ led_ app. Add the following business code to C

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include "hdf_sbuf.h"
#include "hdf_io_service_if.h"

#define LED_WRITE_READ 1
#define LED_SERVICE "hdf_led"

static int SendEvent(struct HdfIoService *serv, uint8_t eventData)
{
    int ret = 0;
    struct HdfSBuf *data = HdfSBufObtainDefaultSize();
    if (data == NULL)
    {
        printf("fail to obtain sbuf data!\r\n");
        return 1;
    }

    struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
    if (reply == NULL)
    {
        printf("fail to obtain sbuf reply!\r\n");
        ret = HDF_DEV_ERR_NO_MEMORY;
        goto out;
    }
    /* Write data */
    if (!HdfSbufWriteUint8(data, eventData))
    {
        printf("fail to write sbuf!\r\n");
        ret = HDF_FAILURE;
        goto out;
    }
    /* Send to driver via Dispatch */
    ret = serv->dispatcher->Dispatch(&serv->object, LED_WRITE_READ, data, reply);
    if (ret != HDF_SUCCESS)
    {
        printf("fail to send service call!\r\n");
        goto out;
    }

    int replyData = 0;
    /* Read the reply data of the driver */
    if (!HdfSbufReadInt32(reply, &replyData))
    {
        printf("fail to get service call reply!\r\n");
        ret = HDF_ERR_INVALID_OBJECT;
        goto out;
    }
    printf("\r\nGet reply is: %d\r\n", replyData);
out:
    HdfSBufRecycle(data);
    HdfSBufRecycle(reply);
    return ret;
}

int main(int argc, char **argv)
{
    int i;
 
    /* Get service */
    struct HdfIoService *serv = HdfIoServiceBind(LED_SERVICE);
    if (serv == NULL)
    {
        printf("fail to get service %s!\r\n", LED_SERVICE);
        return HDF_FAILURE;
    }

    for (i=0; i < argc; i++)
    {
        printf("\r\nArgument %d is %s.\r\n", i, argv[i]);
    }

    SendEvent(serv, atoi(argv[1]));

    HdfIoServiceRecycle(serv);
    printf("exit");

    return HDF_SUCCESS;
}

2.3. Write a build that will build the business code GN file

BUILD. The GN file consists of three parts (target, source file and header file path), which should be completed by the developer. With my_led_app, for example, needs to be created/ applications/BearPi/BearPi-HM_Micro/samples/my_led_app/BUILD.gn, and complete the following configuration

import("//build/lite/config/component/lite_component.gni")

HDF_FRAMEWORKS = "//drivers/framework"

executable("led_lib") {
    output_name = "my_led"
    sources = [
        "my_led_app.c",
    ]

    include_dirs = [
    "$HDF_FRAMEWORKS/ability/sbuf/include",
    "$HDF_FRAMEWORKS/core/shared/include",
    "$HDF_FRAMEWORKS/core/host/include",
    "$HDF_FRAMEWORKS/core/master/include",
    "$HDF_FRAMEWORKS/include/core",
    "$HDF_FRAMEWORKS/include/utils",
    "$HDF_FRAMEWORKS/utils/include",
    "$HDF_FRAMEWORKS/include/osal",
    "//drivers/adapter/uhdf/posix/include",
    "//third_party/bounds_checking_function/include",
    "//base/hiviewdfx/hilog_lite/interfaces/native/innerkits",
    ]

    deps = [
        "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared",
        "//drivers/adapter/uhdf/manager:hdf_core",
        "//drivers/adapter/uhdf/posix:hdf_posix_osal",
    ]
}

lite_component("my_led_app") {
    features = [
        ":led_lib",
    ]
}
  1. First, import the gni component and transfer the source code to my_led_app.c compiled into led_lib library file
  2. The name of the output executable is determined by output_name is defined as my_led
  3. include_ Add my to dirs_ led_ app. C what needs to be used in it h header file path
  4. Add the dependent library to deps.
  5. Then turn the LED_ Package lib into lite_component, named my_led_app component.

2.4. Add new component

Modify the file build / LITE / components / applications JSON, add component my_sample configuration

{
        "component": "my_sample",
        "description": "my samples",
        "optional": "true",
        "dirs": [
            "applications/BearPi/BearPi-HM_Micro/samples/my_first_app",
            "applications/BearPi/BearPi-HM_Micro/samples/my_led_app"
        ],
        "targets": [
            "//applications/BearPi/BearPi-HM_Micro/samples/my_first_app:my_app",
            "//applications/BearPi/BearPi-HM_Micro/samples/my_led_app:my_led_app"
        ],
        "rom": "",
        "ram": "",
        "output": [],
        "adapted_kernel": [ "liteos_a" ],
        "features": [],
        "deps": {
        "components": [],
        "third_party": [ ]
        }
    },

2.5. Modify board configuration file

Modify the vendor / bearpi / bearpi file_ hm_ micro/config. JSON, add my_ Entries for the sample component

{
      "subsystem": "applications",
      "components": [
         { "component": "my_sample", "features":[] },
         { "component": "bearpi_sample_app", "features":[] },
         { "component": "bearpi_screensaver_app", "features":[] }
      ]
},

3, Compile

Execute hb set to set the development board under the root directory of the project. There is only one. Press enter

Execute compile command

hb build -t notest --tee -f

After the compilation is completed, the words "build success" appear on the screen, indicating that the compilation is successful.

After compiling, you can directly view the final compiled firmware. The specific path is: \ project \ bearpi HM_ micro_ small\out\bearpi-hm_ micro\bearpi-hm_ micro

Folder structure description

  • OHOS_Image.stm32: system image file
  • rootfs_vfat.img: root file system
  • userfs_vfat.img: user file system

Execute the following three instructions to copy the above three files to applications / bearpi / bearpi HM_ Micro/tools/download_ IMG / kernel / for subsequent burning systems

cp out/bearpi_hm_micro/bearpi_hm_micro/OHOS_Image.stm32 applications/BearPi/BearPi-HM_Micro/tools/download_img/kernel/
cp out/bearpi_hm_micro/bearpi_hm_micro/rootfs_vfat.img applications/BearPi/BearPi-HM_Micro/tools/download_img/kernel/
cp out/bearpi_hm_micro/bearpi_hm_micro/userfs_vfat.img applications/BearPi/BearPi-HM_Micro/tools/download_img/kernel/

4, Summary

So far, the complete project has been developed, and the next step is to burn and run.

For more learning content, please pay attention to IoT IOT community  , add Huawei cloud IoT assistant wechat (HWC IoT) and reply to "read" for more information.

 

Click follow to learn about Huawei's new cloud technology for the first time~

Keywords: IoT liteos

Added by weknowtheworld on Thu, 24 Feb 2022 06:02:01 +0200