LV15-01-点亮LED-02-应用开发实例

本文主要是点亮LED——应用开发实例的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
PC端开发环境 Windows Windows11
Ubuntu Ubuntu20.04.6的64位版本(一开始使用的是16.04版本,后来进行了升级)
VMware® Workstation 17 Pro 17.0.0 build-20800274
终端软件 MobaXterm(Professional Edition v23.0 Build 5042 (license))
Win32DiskImager Win32DiskImager v1.0
Linux开发板环境 Linux开发板 正点原子 i.MX6ULL Linux 阿尔法开发板
uboot NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03)
linux内核 linux-4.15(NXP官方提供)
点击查看本文参考资料
分类 网址 说明
官方网站 https://www.arm.com/ ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档
https://www.nxp.com.cn/ NXP官方网站
https://www.nxpic.org.cn/NXP 官方社区
https://u-boot.readthedocs.io/en/latest/u-boot官网
https://www.kernel.org/linux内核官网
点击查看相关文件下载
分类 网址 说明
NXP https://github.com/nxp-imx NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库
https://elixir.bootlin.com/linux/latest/source 在线阅读linux kernel源码
nxp-imx/linux-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga NXP linux内核仓库tags中的rel_imx_4.1.15_2.1.0_ga
nxp-imx/uboot-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga NXP u-boot仓库tags中的rel_imx_4.1.15_2.1.0_ga
I.MX6ULL i.MX 6ULL Applications Processors for Industrial Products I.MX6ULL 芯片手册(datasheet,可以在线查看)
i.MX 6ULL Applications ProcessorReference Manual I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网)

一、代码实例

1. 代码编写

这一部分就是通过open、close、read、write、ioctl等函数来操作LED驱动,进而控制LED灯。代码可以看这里:LV15_LED_CTRL · 苏木/imx6ull-app-demo - 码云 - 开源中国 (gitee.com)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/** =====================================================
* Copyright © hk. 2022-2025. All rights reserved.
* File name : led_ctrl.c
* Author : 苏木
* Date : 2024-09-02
* Version :
* Description:
* ======================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define LED_TRIGGER "/sys/class/leds/sys-led/trigger"
#define LED_BRIGHTNESS "/sys/class/leds/sys-led/brightness"
#define USAGE() fprintf(stderr, "usage:\n" \
" %s <on|off>\n" \
" %s <trigger> <type>\n", argv[0], argv[0])

int main(int argc, char *argv[])
{
int fd1, fd2;

/* 校验传参 */
if (2 > argc)
{
USAGE();
exit(-1);
}

/* 打开文件 */
fd1 = open(LED_TRIGGER, O_RDWR);
if (0 > fd1)
{
perror("open error");
exit(-1);
}

fd2 = open(LED_BRIGHTNESS, O_RDWR);
if (0 > fd2)
{
perror("open error");
exit(-1);
}

/* 根据传参控制LED */
if (!strcmp(argv[1], "on"))
{
write(fd1, "none", 4); //先将触发模式设置为none
write(fd2, "1", 1); //点亮LED
}
else if (!strcmp(argv[1], "off"))
{
write(fd1, "none", 4); //先将触发模式设置为none
write(fd2, "0", 1); //LED灭
}
else if (!strcmp(argv[1], "trigger"))
{
if (3 != argc)
{
USAGE();
exit(-1);
}

if (0 > write(fd1, argv[2], strlen(argv[2])))
perror("write error");
}
else
USAGE();

exit(0);
}

程序中定义了两个宏, LED_TRIGGER 和 LED_BRIGHTNESS, 分别对应/sys/class/leds/sys-led/trigger 和/sys/class/leds/sys-led/brightness 属性文件,宏 USAGE()用于打印程序的使用方法;程序首先会调用 open()函数打开这两个属性文件,之后判断传入参数指向相应的动作,传入 “on” 表示点亮 LED,先调用 write() 将 “none”写入到 trigger 属性文件中,也就是设置为无触发,接着再向 brightness 属性文件中写入”1”点亮 LED;传入”off” 表示熄灭 LED,同样也是先调用 write()将”none”写入到 trigger 属性文件设置 LED 为无触发,接着再向brightness 属性文件中入”0”熄灭 LED;传入”trigger”表示设置 LED 的触发模式,则需要传入第二个参数,第二个参数表示需要设置的模式。

2. 编译

由于我们是在 ALPHA I.MX6U开发板上运行程序,所以需要 I.MX6U 平台对应的交叉编译工具来编译测试代码,这样编译得到的可执行文件才能在开发板上运行。 这里使用的交叉编译工具是:

1
2
3
4
5
sumu@sumu-virtual-machine:~/5imx6ull/imx6ull-app-demo$ arm-linux-gnueabihf-gcc --version
arm-linux-gnueabihf-gcc (Linaro GCC 4.9-2017.01) 4.9.4
Copyright © 2015 Free Software Foundation, Inc.
本程序是自由软件;请参看源代码的版权声明。本软件没有任何担保;
包括没有适销性和某一专用目的下的适用性担保。

然后编写Makefile文件,其实这里只有一个文件,不需要Makefile也行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
##============================================================================#
# Copyright © hk. 2022-2025. All rights reserved.
# File name: Makefile
# Author : 苏木
# Date : 2024-09-02
# Version :
# Description:
##============================================================================#
##
CROSS_COMPILE ?= arm-linux-gnueabihf-
TARGET ?= app_demo
NFS_APP_DEMO ?= ~/4nfs/app

OBJ_DIR ?= ./
CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld
OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump

CFLAGS := -Wall

INCDIRS := ./
SRCDIRS := ./

INCLUDE := $(patsubst %, -I %, $(INCDIRS))
CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))

SFILENDIR := $(notdir $(SFILES))
CFILENDIR := $(notdir $(CFILES))

COBJS := $(patsubst %, $(OBJ_DIR)%, $(CFILENDIR:.c=.o))
OBJS := $(COBJS)

VPATH := $(SRCDIRS)
.PHONY: clean

$(TARGET): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDE) $(OBJS) -o $@

$(COBJS) : $(OBJ_DIR)%.o : %.c
$(CC) $(CFLAGS) -c $(INCLUDE) $< -o $@

clean:
rm -rf $(TARGET) $(COBJS)

install:
@cp -vf $(TARGET) $(NFS_APP_DEMO)

uninstall:
@rm -rvf $(NFS_APP_DEMO)/$(TARGET)

我们执行make命令就会完成编译,生成可执行文件:

image-20240903074504297

我们使用file命令查看文件格式可以知道这是一个32位ARM架构下的可执行文件。

二、开发板测试

启动开发板进入 Linux 系统,将上小节编译得到的可执行文件 app_demo 拷贝到开发板根文件系统中,我是前面设置了NFS开发环境,直接挂在了ubuntu中的目录:

image-20240903074645817

可以执行以下命令来进行测试:

1
2
3
./testApp on     # 点亮 LED
./testApp off # 熄灭 LED
./testApp trigger heartbeat # 将 LED 触发模式设置为 heartbeat