业务代码

  1. .c文件编写业务代码
  2. BUILD.gn把业务代码打包成可执行文件,再把可执行文件打包成小组件
  3. applications.json将小组件打包成组件
  4. /vendor/../config.json编译构建组件

驱动的使用

业务代码

1.获取驱动
HdfIoServiceBind(驱动名称) #驱动对外发布服务的名称,在device_info.hcs里查询

  1. 申请内存
    HdfSBufObtainDefaultSize()申请发送数据data和接受数据reply的内存
    3.将业务代码的数据翻译成驱动代码的数据(翻译数据)
    HdfSbufWriteUint8(1,2)将参数二写入参数一,参数一将被步骤四带到驱动代码中
  2. 发送和接受驱动的数据
    serv->dispatcher->Dispatch(&serv->object,操作确认符, data, reply) 数据通过Dispatch发送接收数据
    *serv是第一步HdfIoServiceBind()的返回值
  3. 翻译驱动代码发来的数据(翻译数据)
    HdfSbufReadInt32(1, &2)将参数一(驱动在步骤四发送来的数据)写入参数二,参数二为业务代码可以查看的数据(参数二为地址)
  4. 释放申请的内存
    HdfSBufRecycle()将第二步申请的data和reply内存释放

驱动代码

新建代码:device\st\drivers\新建代码文件夹\驱动代码+BUILD.gn

  1. 将驱动入口注册到HDF框架中
    HDF_INIT(驱动入口的对象)
    驱动入口的对象必须为HdfDriverEntry类型的全局变量

    struct HdfDriverEntry g_ledDriverEntry = {
    .moduleVersion = 1,              //版本号
    .moduleName = "HDF_LED",         //驱动名称
    .Bind = HdfLedDriverBind,        //驱动对外提供的服务能力,将相关的服务接口绑定到HDF框架
    .Init = HdfLedDriverInit,        // 驱动自身业务初始的接口
    .Release = HdfLedDriverRelease,  // 驱动资源释放的接口
    };
  2. 在Dispatch中处理用户态发下来的消息
    LedDriverDispatch(struct HdfDeviceIoClient *client, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)对应参数为业务代码中的第四步
    1. 翻译业务代码带来的数据(翻译数据)
      HdfSbufReadUint8(data,&2);将data数据转换成驱动代码可以使用的数据,完成相应动作(参数二为地址)
    2. 将驱动代码的数据发送到业务代码(翻译数据)
      HdfSbufWriteInt32(reply,2)将参数2写入参数1的reply中,reply可被带至业务程序
      PS:==当需要翻译的数据为字符串时,用函数HdfSbufWriteString(1, 2);2=HdfSbufReadString(1)==
  1. 驱动的BUILD.gn把驱动代码编译成可执行文件
  2. 系统驱动的BUILD.gn中的依赖库添加入==驱动代码的所在文件夹==
    /device/st/drivers/BUILD.gn
  3. 驱动配置(LED灯为例子)
    1. 驱动设备描述
      device\st\bearpi_hm_micro\liteos_a\hdf_config\device_info\device_info.hcs
      device_led :: device {                  // 设备节点
      device0 :: deviceNode {             // 驱动的DeviceNode节点
      policy = 2;                     // policy字段是驱动服务发布的策略
      priority = 10;                 // 驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序
      preload = 1;                    // 驱动按需加载字段
      permission = 0777;              // 驱动创建设备节点权限
      moduleName = "HDF_LED";        // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致
      serviceName = "hdf_led";    // 驱动对外发布服务的名称,必须唯一,驱动代码将以此名字启用驱动
      deviceMatchAttr = "st_stm32mp157_led"; // 驱动私有数据名称
      }
      }  
    2. 驱动的私有配置信息
      驱动的私有(只有该驱动使用)配置可以添加一个配置文件,HDF框架在加载驱动的时候,会将对应的配置信息获取并保存在HdfDeviceObject 中的property里面,通过Bind和Init传递给驱动,在device\st\bearpi_hm_micro\liteos_a\hdf_config\led\led_config.hcs中添加有配置描述。
      root {
      LedDriverConfig {
      led_gpio_num = 13;
      match_attr = "st_stm32mp157_led";   
      //该字段的值必须和device_info.hcs中的deviceMatchAttr值一致,以便于该私有配置可以被调用
      }
      }

      配置信息定义之后,需要将该配置文件添加到板级配置入口文件device\st\bearpi_hm_micro\liteos_a\hdf_config\hdf.hcs,示例如下:

      #include "led/led_config.hcs"

GPIO口使用

GPIO口写入操作

==GPIO口一组16个,按顺序排列。==
例如当使用到GPIOA0时,IO口设置为16*0+0=0;当使用GPIOB1时,IO口设置为16*1+1=17
在驱动代码中添加以下代码:
``` C++
//位置:bearpi-hm_micro_small\drivers\framework\support\platform\src\gpio_if.c
#include "gpio_if.h"

/1/
//IO口设置函数
GpioSetDir(uint16_t gpio, uint16_t dir); //dir的值查询GPIO口模式设置
/2/
//GPIO口操作函数
GpioWrite(uint16_t gpio, uint16_t val);
GpioRead(uint16_t gpio, uint16_t *val);

IO口设置和操作函数的调用
``` C++
//IO口设置调用的函数
GpioCntlrSetDir(GpioGetCntlr(gpio), GpioToLocal(gpio), dir);    //调用函数
GpioCntlrSetDir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t dir);    //函数头
cntlr->ops->setDir(cntlr, local, dir);      //操作
//IO写入值
GpioCntlrWrite(GpioGetCntlr(gpio), GpioToLocal(gpio), val);      //调用函数
GpioCntlrWrite(struct GpioCntlr *cntlr, uint16_t local, uint16_t val); //函数头
cntlr->ops->write(cntlr, local, val);       //操作

GPIO口模式设置

``` C++
GpioSetDir(uint16_t gpio, uint16_t dir);
typedef enum {
E53_GPIO_Out_PullUp = 0,
E53_GPIO_Out_PullDown,
E53_GPIO_Out_PullNone,
E53_GPIO_Out_DrainUp,
E53_GPIO_Out_DrainDown,
E53_GPIO_In_Floating,
E53_GPIO_In_Up,
E53_GPIO_In_Down,
}E53_GPIO_Mode;



[想了解更多关于开源的内容,请访问:](https://ost.51cto.com/#bkwz)

[51CTO 开源基础软件社区](https://ost.51cto.com#bkwz)

https://ost.51cto.com/#bkwz