introduction
In this article, an application program of LED lamp is written in C language, and the driver program of LED lamp developed in the article "HDF-based LED Driver Development" (1) and (2) is tested.
In addition, when writing applications for LED lights, we will use many APIs provided by the HDF framework. In order to facilitate the usage of these APIs, it is recommended that you open the article "API of HDF Driver Framework" (1) , (2) , (3) while reading this article . The APIs used in this article are collected in these articles. Of course, you can also directly read the source code and official documentation of these APIs.
This article refers to some tutorials of the BearPi-HM_Micro_Small development board.
https://gitee.com/bearpi/bearpi-hm_micro_small
Before reading this article, make sure you have read "Hello_World of BearPi-HM_Micro_Small" .
1. Write the source program
First, applications/BearPi/BearPi-HM_Micro/samples/dandelion
create a new folder under the path: my_led_app
.
Then, create a new file in the folder my_led_app
: my_led_app.c
, and then we write the source program in this file.
This application has no GUI, and can only be run in the form of command line: ./my_led 参数
, the command parameter has three values: 0, 1, 2, which control LED off, on, and state switching respectively.
In the source program my_led_app.c
, in addition to some header files and macro definitions, it mainly includes the following two functions:
function | describe |
---|---|
int main(int argc, char **argv) | application's main function |
static int LedWriteRead(struct HdfIoService *serv, uint8_t sendData, uint8_t *recvData) | Send data to the driver, and receive the driver's response. |
1.1 Header file, macro definition
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include "hdf_log.h"
#include "hdf_sbuf.h"
#include "hdf_io_service_if.h"
#define LED_WRITE_READ 1 //应用程序下发给LED驱动的命令字。1:写;0:读。
#define LED_SERVICE "hdf_led" //LED驱动对外提供的服务的名称,与驱动配置中的名称一致。
1.2 Main function
int main(int argc, char **argv)
{
int i;
// 打印输出在终端中输入的命令行
for (i=0; i < argc; i++)
{
printf("\r\nArgument %d is %s.\r\n", i, argv[i]);
}
// 获取驱动提供的服务
struct HdfIoService *serv = HdfIoServiceBind(LED_SERVICE);
if (serv == NULL)
{
printf("fail to get service %s!\r\n", LED_SERVICE);
return HDF_FAILURE;
}
// 向驱动发送LED的控制数据,从驱动接收LED当前的状态
uint8_t replyData = 0;
LedWriteRead(serv, atoi(argv[1]), &replyData);
printf("\r\nGet reply is: %d\r\n", replyData);
// 回收资源
HdfIoServiceRecycle(serv);
// 退出程序
printf("exit");
return HDF_SUCCESS;
}
In main
the function, the interface functions provided by HDF are used: HdfIoServiceBind
, HdfIoServiceRecycle
, and structure HdfIoService
.
1.3 LedWriteRead function
LedWriteRead
main
The function is called in the main function to exchange data with the driver in kernel mode. The first parameter serv
: a pointer to the driver service object ( HdfIoService
structure); the second parameter sendData
: the data sent to the driver; the third parameter recvData
: a pointer to a variable, which is used to store the data received from the driver function response data.
static int LedWriteRead(struct HdfIoService *serv, uint8_t sendData, uint8_t *recvData)
{
int ret = HDF_SUCCESS;
// 创建一个缓冲区,用于向驱动发送数据
struct HdfSBuf *data = HdfSBufObtainDefaultSize();
if (data == NULL)
{
printf("fail to obtain sbuf data!\r\n");
return HDF_FAILURE;
}
// 创建一个缓冲区,用于从驱动接收响应
struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
if (reply == NULL)
{
printf("fail to obtain sbuf reply!\r\n");
ret = HDF_DEV_ERR_NO_MEMORY;
goto out;
}
// 把要下发给驱动的数据写入缓冲区
if (!HdfSbufWriteUint8(data, sendData))
{
printf("fail to write sbuf!\r\n");
ret = HDF_FAILURE;
goto out;
}
// 调用应用态的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;
}
// 从缓冲区中读取驱动的响应数据
if (!HdfSbufReadUint8(reply, recvData))
{
printf("fail to get service call reply!\r\n");
ret = HDF_ERR_INVALID_OBJECT;
goto out;
}
out:
// 回收缓冲区
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
In main
the function, the interface functions provided by HDF are used: HdfSBufObtainDefaultSize
, HdfSbufWriteUint8
, HdfSbufReadUint8
, HdfSBufRecycle
, and the structure HdfSBuf
, HdfIoService
.
2. Write/modify the compilation script
my_led_app
1. Create a new file under the folder : BUILD.gn
, and write the compilation script of the source program in this file my_led_app.c
:
import("//build/lite/config/component/lite_component.gni")
HDF_FRAMEWORKS = "//drivers/framework"
executable("my_led_exe") {
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",
]
}
executable("my_led_exe")
Used to declare a named my_led_exe
target of type executable
, instructing the compile build subsystem to my_led_app.c
compile the source code into my_led
an executable file named .
output_name
Used to specify the name of the compiled executable.
sources
In the list are the source code files required for compiling and building.
include_dirs
In the list are the paths to the header files referenced in the source files.
deps
In the list are other libraries that need to be relied upon when compiling and building.
2. Modify dandelion
the compilation script file under the folder: BUILD.gn
.
import("//build/lite/config/component/lite_component.gni")
lite_component("dandelion_app") {
features = [
"hello_world:hello_world_exe",
"my_led_app:my_led_app",
]
}
lite_component
It is build/lite/config/component/lite_component.gni
a template defined in , which is used to my_led_exe
incorporate the target named above into my_led_app
the compile and build target named.
3. Compile and burn
Refer to the fifth and sixth parts of "Hello_World of BearPi-HM_Micro_Small" .
4. Test
After the system starts up, execute the following commands in sequence on the serial port terminal:
./bin/my_led 1
./bin/my_led 0
./bin/my_led 2
The LEDs on the BearPi-HM_Micro_Small development board will be controlled to turn on, turn off, and switch states respectively. The output and output of the serial port terminal are shown in the figure below: