上篇文章:i.MX9352——介绍一款多核异构开发板,介绍了OK-MX9352开发板的基础硬件功能。
本篇来使用OK-MX9352开发板,通过Web界面进行点灯测试,最终的效果如下:
在进行代码编写之前,先在Ubuntu虚拟机上把这个板子的交叉编译环境配置好。
将压缩包(OKMX93-linux-sdk.tar.bz2.00和OKMX93-linux-sdk.tar.bz2.01)拷贝到自己的Ubuntu虚拟机中。
sdk_md5sum.txt是对应的md5信息,也拷贝一下。使用md5sum指令确认压缩包的md5信息是否正确,以验证压缩包是否完整。
xxpcb@ubuntuTest:~/myTest/ok-mx93/sourcecode$ md5sum OKMX93-linux-sdk.tar.bz2.0*
8ce38d0ab6cc754b2c0d9c232e1d0a4e OKMX93-linux-sdk.tar.bz2.00
7733d956ae8121699fb25b94e61dde3f OKMX93-linux-sdk.tar.bz2.01
然后使用如下指令解压:
sudo cat OKMX93-linux-sdk.tar.bz2.0* | sudo tar xj
解压需要一些时间,解压后如下:
再新建一个文件夹,将解压后SDK源码中tools中的fsl-imx-xwayland-glibc-x86_64-meta-toolchain-qt6-armv8a-imx93-11x11-lpddr4x-evk-toolchain-5.15-kirkstone.sh拷贝到自己的文件夹中,然后执行该脚本进行交叉编译工具链的安装。
安装过程如下:
安装信息的第一行要选择SDK的安装目录,回车默认即可,接着再输入Y确认,然后是输入自己虚拟机的用户密码,就开始安装了。
看到打印SDK has been successfully set up and is ready to be used表示安装成功。
最后的信息是说明如何设置编译环境:每次打开一个新的shell进行交叉编译时,需要使用如下指令进行环境变量的设置:
. /opt/fsl-imx-xwayland/5.15-kirkstone/environment-setup-armv8a-poky-linux
设置好之后,可以使用**$CC -v**显示gcc版本确认环境变量是否设置成功,如下:
hello.c
#include
int main()
{
printf("hello ok-mx93\n");
return 0;
}
Makefile
TARGET=hello
OBJS=hello.o
CFLAGS+=-c -Wall -g
$(TARGET):$(OBJS)
$(CC) $^ -o $@
%.o:%.c
$(CC) $^ $(CFLAGS) -o $@
clean:
$(RM) *.o $(TARGET) -r
执行make编译
也可以执行使用指令进行编译:
$CC hello.c -o hello
然后将编译的可执行文件复制到板子中,可以使用ssh命令:
scp hello [email protected]:/home/mytest
复制成功之后可在板子上运行,查看打印结果
嵌入式开发板,Web页面点灯的基本原理是:在开发板上配置Web服务器,然后在指定的文件位置,放置如html等类型的网页文件,然后板子连网,用电脑的浏览器输入板子的IP地址,连接到开发板的Web服务,实现开发板中网页内容的展示。
对于网页中内容或操作按钮等功能,要与开发板进行数据交互,通常使用CGI(Common Gateway Interface,公共网关接口)的方式进行编程。
OK-MX9352开发板中已经配置了lighttpd这个Web服务器,为了便于自己测试,可以修改其配置文件
/etc/lighttpd/lighttpd.conf
比如我这里把存放Web页面的默认位置更改为了/www/pages
另外,对应cgi的配置,还需要增加227行这句,否则cgi执行可能不能正常运行
这里使用html语言设计一个LED的控制界面。
OK-MX9352开发板上有两个可以控制的LED,一个位于核心板上,另一个位于底板上,在设置html时,可以使用select功能实现一个下拉选项,选择要控制的LED。
另外,LED也有多种控制模式,如基础的开关模式(设置开,或关),心跳灯模式,定时器模式(设置亮的时间和灭的时间),也使用下拉选项的方式。
选择不同的控制模式后,为了能动态展示不同模式下的操作功能,比如开关模式下需要显示开和关的按钮,心跳灯模式则不需要额外的配置,定时器模式则需要两个输入框来设置亮的时间和灭的时间。这里使用script功能,来实现此功能,通过读取网页中当前LED模式的值,来进行对应控件的显示或隐藏。
完整的html代码如下,led.html:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>led controltitle>
head>
<body background="background.png"
style="background-repeat:no-repeat;
background-size:100% 100%;
background-attachment: fixed;">
<center><br><br><br><br>
<h1 align="center">基于飞凌OK-MX9352的web控制LED灯h1>
<form action="led.cgi" method="get">
<p align="center">LED选择:
<select name="led_id">
<option value="LED0" selected>核心板LEDoption>
<option value="LED1">底板LEDoption>
select>p>
<p align="center">模式选择:
<select name="led_mode" onclick="select_event(this.options[this.selectedIndex].value);">
<option value="ONOFF" selected>开关模式option>
<option value="HEARTBEAT">心跳灯模式option>
<option value="TIMER">定时器灯模式option>
select>p>
<p align="center" id = "id_led_time_on" >亮时间:<input type="text" value=500 name="led_time_on"/>p>
<p align="center" id = "id_led_time_off" >灭时间:<input type="text" value=500 name="led_time_off"/>p>
<p align="center" id = "id_led_onoff">LED开关:
<input type="radio" name="led_val" value="ON" checked>开
<input type="radio" name="led_val" value="OFF">关
p><br><br>
<p align="center">
<input type="submit" value="确认"/>
<input type="reset" value="返回"/>
p>
form>
center>
<script>
document.getElementById("id_led_time_on").style.display = "none";
document.getElementById("id_led_time_off").style.display = "none";
script>
<script>
function select_event(value)
{
document.getElementById("id_led_onoff").style.display = "none";
document.getElementById("id_led_time_on").style.display = "none";
document.getElementById("id_led_time_off").style.display = "none";
if (value === "ONOFF")
{
document.getElementById("id_led_onoff").style.display = "";
}
else if (value === "TIMER")
{
document.getElementById("id_led_time_on").style.display = "";
document.getElementById("id_led_time_off").style.display = "";
}
}
script>
body>
html>
可以先使用浏览器直接打开这个html文件查看效果,实际效果如下:
CGI是Web服务器主机提供信息服务的标准接口。
通过CGI接口,Web服务器可以获取网页客户端提交的信息,转交给服务器端的CGI程序进行处理,最后返回结果给客户端。
CGI程序可以使用多种语言来实现,对于嵌入式开发,那就用熟悉的C语言来编写吧。
编写CGI程序,需要用到CGI的库,下载地址:https://github.com/boutell/cgic,只需要用到cgic.c和cgic.h这两个文件。
本次测试的LED点灯功能,CGI程序需要实现的,就是获取网页上的用户操作信息,然后控制板子上的LED进行对应模式的亮灭,完整的代码实现如下,led.c:
#include "cgic.h"
#include
#include
// cgic程序以cgiMain作为入口点, cgic的函数库会自动把cgiMain连接到相应的main()上去
int cgiMain()
{
char led_id[10];
char led_mode[10];
char led_val[10];
int led_time_on;
int led_time_off;
cgiFormString("led_id", led_id, 10);
cgiFormString("led_mode", led_mode, 10);
cgiFormString("led_val", led_val, 10);
cgiFormInteger("led_time_on", &led_time_on, -1);
cgiFormInteger("led_time_off", &led_time_off, -1);
// 设定输出的内容格式 这里我们要输出HTML
cgiHeaderContentType("text/html;charset=\"UTF-8\"");
fprintf(cgiOut,"LED Web Control ");
fprintf(cgiOut,"" );
fprintf(cgiOut,"
");
fprintf(cgiOut,"
");
fprintf(cgiOut,"
");
fprintf(cgiOut,"OK-MX93开发板从Web页面收到数据:
");
fprintf(cgiOut,"led_id: %s", led_id);
fprintf(cgiOut,"
");
fprintf(cgiOut,"led_mode: %s", led_mode);
fprintf(cgiOut,"
");
fprintf(cgiOut,"
");
fprintf(cgiOut,"led_val: %s", led_val);
fprintf(cgiOut,"
");
fprintf(cgiOut,"led_time_on: %d", led_time_on);
fprintf(cgiOut,"
");
fprintf(cgiOut,"led_time_off: %d", led_time_off);
fprintf(cgiOut,"
");
int ret = 0;
if (0==strncmp("ONOFF",led_mode,10))
{
if (0==strncmp("ON",led_val,10))
{
if (0==strncmp("LED0",led_id,10))
{
ret |= system("echo none > /sys/class/leds/heartbeat/trigger");
ret |= system("echo 1 > /sys/class/leds/heartbeat/brightness");
}
else if (0==strncmp("LED1",led_id,10))
{
ret |= system("echo none > /sys/class/leds/led1/trigger");
ret |= system("echo 1 > /sys/class/leds/led1/brightness");
}
}
else if (0==strncmp("OFF",led_val,10))
{
if (0==strncmp("LED0",led_id,10))
{
ret |= system("echo none > /sys/class/leds/heartbeat/trigger");
ret |= system("echo 0 > /sys/class/leds/heartbeat/brightness");
}
else if (0==strncmp("LED1",led_id,10))
{
ret |= system("echo none > /sys/class/leds/led1/trigger");
ret |= system("echo 0 > /sys/class/leds/led1/brightness");
}
}
}
else if (0==strncmp("HEARTBEAT",led_mode,10))
{
if (0==strncmp("LED0",led_id,10))
{
ret |= system("echo heartbeat > /sys/class/leds/heartbeat/trigger");
}
else if (0==strncmp("LED1",led_id,10))
{
ret |= system("echo heartbeat > /sys/class/leds/led1/trigger");
}
}
else if (0==strncmp("TIMER",led_mode,10))
{
char tmp1[256];
char tmp2[256];
if (0==strncmp("LED0",led_id,10))
{
ret |= system("echo timer > /sys/class/leds/heartbeat/trigger");
sprintf(tmp1, "echo %d > /sys/class/leds/heartbeat/delay_on", led_time_on);
sprintf(tmp2, "echo %d > /sys/class/leds/heartbeat/delay_off", led_time_off);
ret |= system(tmp1);
ret |= system(tmp2);
}
else if (0==strncmp("LED1",led_id,10))
{
ret |= system("echo timer > /sys/class/leds/led1/trigger");
sprintf(tmp1, "echo %d > /sys/class/leds/led1/delay_on", led_time_on);
sprintf(tmp2, "echo %d > /sys/class/leds/led1/delay_off", led_time_off);
ret |= system(tmp1);
ret |= system(tmp2);
}
}
fprintf(cgiOut,"
");
fprintf(cgiOut,"执行结果: %s", ret == 0 ? "成功" : "失败");
fprintf(cgiOut,"
");
fprintf(cgiOut,"
");
fprintf(cgiOut,"");
fprintf(cgiOut,"");
return 0;
}
此cgi程序的执行效果实测如下:
在Ubuntu中对cgi程序进行交叉编译。
每次打开一个bash窗口进行交叉编译时,都要先执行一次交叉编译环境的生效:
. /opt/fsl-imx-xwayland/5.15-kirkstone/environment-setup-armv8a-poky-linux
然后使用gcc指令编译即可,编译的后缀为.cgi
$CC led.c cgic.c -o led.cgi
然后将led.cgi和led.html以及html用到的背景图片拷贝到开发板中,可以新建一个led目录单独存放,如下:
root@ok-mx93:/etc/lighttpd# cd /www/pages/led/
root@ok-mx93:/www/pages/led#
root@ok-mx93:/www/pages/led# ls
background.png led.cgi led.html
root@ok-mx93:/www/pages/led#
OK-MX9352开发板开机自动启动Web服务,复制完之后,在电脑的浏览器中,输入板子ip以及对应目录的html文件目录即可,如我的是:
192.168.5.115/led/led.html
本篇介绍了在OK-MX9352开发板上,通过Web服务,实现网页上LED控制界面来控制板子上LED进行不同模式的亮灭。
文章首先介绍了在Ubuntu虚拟机中,进行OK-MX9352的C/C++交叉编译环境配置,然后介绍了Web点灯功能的代码实现,通过html设置页面,通过CGI程序实现网页指令的接收和板子上LED的控制,最后进行代码编译和实际测试。