当前位置:网站首页>LED的C语言应用程序
LED的C语言应用程序
2022-08-04 19:36:00 【随遇而安的dandelion】
引言
在本文中,用C语言编写一个LED灯的应用程序,对文章《基于HDF的LED驱动程序开发》(1)、(2)中开发的LED灯的驱动程序进行测试。
另外,在编写LED灯的应用程序时,我们会用到很多由HDF框架提供的API。为了便于查阅这这些API的用法,建议大家在阅读本文的同时,打开文章《HDF驱动框架的API》(1)、(2)、(3)。在这几篇文章中汇集了本文所用到的API。当然,你也可以直接去阅读这些API的源码和官方说明文档。
本文参考了小熊派BearPi-HM_Micro_Small开发板的部分教程。
https://gitee.com/bearpi/bearpi-hm_micro_small
在阅读本文之前,确保已阅读了《小熊派BearPi-HM_Micro_Small之Hello_World》。
一、编写源程序
首先,在路径applications/BearPi/BearPi-HM_Micro/samples/dandelion下新建一个文件夹:my_led_app。
然后,在文件夹my_led_app中新建一个文件:my_led_app.c,接下来我们在这个文件中编写源程序。
这个应用程序没有用户图形界面,只能以命令行的形式运行:./my_led 参数 ,命令参数有三种取值:0、1、2,分别控制LED关闭、打开和状态切换。
在源程序my_led_app.c中,除了一些头文件和宏定义之外,主要包括以下两个函数:
| 函数 | 描述 |
|---|---|
| int main(int argc, char **argv) | 应用程序的主函数 |
| static int LedWriteRead(struct HdfIoService *serv, uint8_t sendData, uint8_t *recvData) | 向驱动程序发送数据,然后接收驱动程序的响应。 |
1.1 头文件、宏定义
#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 主函数
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;
}
在main函数中,使用到了HDF提供的接口函数:HdfIoServiceBind、HdfIoServiceRecycle,以及结构体HdfIoService。
1.3 LedWriteRead函数
LedWriteRead函数在主函数main中被调用,用于与内核态的驱动程序交换数据。第1个参数serv:指向驱动服务对象(HdfIoService结构体)的指针;第2个参数sendData:向驱动程序下发的数据;第3个参数recvData:指向一个变量的指针,该变量用于存放从驱动函数收到的应答数据。
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;
}
在main函数中,使用到了HDF提供的接口函数:HdfSBufObtainDefaultSize、HdfSbufWriteUint8、HdfSbufReadUint8、HdfSBufRecycle,以及结构体HdfSBuf、HdfIoService。
二、编写/修改编译脚本
1、在文件夹my_led_app下新建一个文件:BUILD.gn,在这个文件中编写源程序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")用于声明一个名为my_led_exe的、类型为executable的目标(target),指示编译构建子系统将源码my_led_app.c编译成名为my_led的可执行文件。
output_name用于指定编译生成的可执行文件的名称。
sources列表中是编译构建所需要的源码文件。
include_dirs列表中是源码文件中引用的头文件的路径。
deps列表中是编译构建时需要依赖的其他库。
2、修改文件夹dandelion下的编译脚本文件: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是在build/lite/config/component/lite_component.gni中定义的一个template,用于将上面那个名为my_led_exe的target纳入到名为my_led_app的编译构建目标里面。
三、编译、烧写
参考《小熊派BearPi-HM_Micro_Small之Hello_World》第五、六部分。
四、测试
待系统启动完毕后,在串口终端中依次执行以下命令:
./bin/my_led 1
./bin/my_led 0
./bin/my_led 2
将分别控制小熊派BearPi-HM_Micro_Small开发板上的LED点亮、熄灭、状态切换,串口终端终端输出入下图所示:

边栏推荐
猜你喜欢

Yuanguo chain game system development

TritonVM——基于Recursive STARK的虚拟机

getBoundingClientRect

我的四周年创作纪念日

Exploration and Practice of Database Governance

ELECTRA:Pre-training Text Encoders as Discriminators Rather Than Generators

正畸MIA微种植体支抗技术中国10周年交流会在沈举办

基于YOLOV5行人跌倒检测实验

Query the published version records of the APP Store

译文推荐|Apache Pulsar 隔离系列(四):单集群隔离策略
随机推荐
PG网络传输安全SSL介绍及使用示例
ELECTRA:Pre-training Text Encoders as Discriminators Rather Than Generators
Industrial CCD and CMOS camera
Ant Group's time series database CeresDB is officially open source
TritonVM——基于Recursive STARK的虚拟机
【HCIP】MPLS WPN 实验
SQL Server 遇到报错解决办法--更新中
Orthodontic MIA micro-implant anchorage technology China 10th anniversary exchange meeting was held in Shenyang
基于YOLOV5行人跌倒检测实验
visual studio 与 visual studio code
VQ Realization of Wavelet Extraction Features
【着色器实现Glitch单项故障闪烁效果(与Television效果不同)_Shader效果第十四篇】
零基础做出高端堆叠极环图
c sqlite...
我的四周年创作纪念日
入门:人脸专集1 | 级联卷积神经网络用于人脸检测(文末福利)
密码学系列之:PEM和PKCS7,PKCS8,PKCS12
华为企业组网实例:VRRP+MSTP典型组网配置
JS手写JSON.stringify() (面试)
用“绿色计算“技术推动算力可持续发展