上篇文章,介紹了OK-MX9352開(kāi)發(fā)板的基礎(chǔ)硬件功能。
本篇來(lái)使用OK-MX9352開(kāi)發(fā)板,通過(guò)Web界面進(jìn)行點(diǎn)燈測(cè)試,最終的效果如下:
在進(jìn)行代碼編寫(xiě)之前,先在Ubuntu虛擬機(jī)上把這個(gè)板子的交叉編譯環(huán)境配置好。
1 交叉編譯環(huán)境配置
1.1 OKMX93 SDK源碼拷貝與解壓
將壓縮包(OKMX93-linux-sdk.tar.bz2.00和OKMX93-linux-sdk.tar.bz2.01)拷貝到自己的Ubuntu虛擬機(jī)中。
sdk_md5sum.txt是對(duì)應(yīng)的md5信息,也拷貝一下。使用md5sum指令確認(rèn)壓縮包的md5信息是否正確,以驗(yàn)證壓縮包是否完整。
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
解壓需要一些時(shí)間,解壓后如下:
1.2 交叉編譯工具鏈的安裝
再新建一個(gè)文件夾,將解壓后SDK源碼中tools中的fsl-imx-xwayland-glibc-x86_64-meta-toolchain-qt6-armv8a-imx93-11x11-lpddr4x-evk-toolchain-5.15-kirkstone.sh拷貝到自己的文件夾中,然后執(zhí)行該腳本進(jìn)行交叉編譯工具鏈的安裝。
安裝過(guò)程如下:
安裝信息的第一行要選擇SDK的安裝目錄,回車(chē)默認(rèn)即可,接著再輸入Y確認(rèn),然后是輸入自己虛擬機(jī)的用戶(hù)密碼,就開(kāi)始安裝了。
看到打印****SDK has been successfully set up and is ready to be used表示安裝成功。
最后的信息是說(shuō)明如何設(shè)置編譯環(huán)境:每次打開(kāi)一個(gè)新的shell進(jìn)行交叉編譯時(shí),需要使用如下指令進(jìn)行環(huán)境變量的設(shè)置:
. /opt/fsl-imx-xwayland/5.15-kirkstone/environment-setup-armv8a-poky-linux
設(shè)置好之后,可以使用 $CC -v顯示gcc版本確認(rèn)環(huán)境變量是否設(shè)置成功,如下:
1.3 helloword程序測(cè)試
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
執(zhí)行make編譯
也可以執(zhí)行使用指令進(jìn)行編譯:
$CC hello.c -o hello
然后將編譯的可執(zhí)行文件復(fù)制到板子中,可以使用ssh命令:
scp hello root@192.168.5.115:/home/mytest
復(fù)制成功之后可在板子上運(yùn)行,查看打印結(jié)果
2 Web頁(yè)面點(diǎn)燈代碼
嵌入式開(kāi)發(fā)板,Web頁(yè)面點(diǎn)燈的基本原理是:在開(kāi)發(fā)板上配置Web服務(wù)器,然后在指定的文件位置,放置如html等類(lèi)型的網(wǎng)頁(yè)文件,然后板子連網(wǎng),用電腦的瀏覽器輸入板子的IP地址,連接到開(kāi)發(fā)板的Web服務(wù),實(shí)現(xiàn)開(kāi)發(fā)板中網(wǎng)頁(yè)內(nèi)容的展示。
對(duì)于網(wǎng)頁(yè)中內(nèi)容或操作按鈕等功能,要與開(kāi)發(fā)板進(jìn)行數(shù)據(jù)交互,通常使用CGI(Common Gateway Interface,公共網(wǎng)關(guān)接口)的方式進(jìn)行編程。
2.1 lighttpd配置修改
OK-MX9352開(kāi)發(fā)板中已經(jīng)配置了lighttpd這個(gè)Web服務(wù)器,為了便于自己測(cè)試,可以修改其配置文件
/etc/lighttpd/lighttpd.conf
比如我這里把存放Web頁(yè)面的默認(rèn)位置更改為了/www/pages
另外,對(duì)應(yīng)cgi的配置,還需要增加227行這句,否則cgi執(zhí)行可能不能正常運(yùn)行
2.2 Web頁(yè)面設(shè)計(jì)
這里使用html語(yǔ)言設(shè)計(jì)一個(gè)LED的控制界面。
OK-MX9352開(kāi)發(fā)板上有兩個(gè)可以控制的LED,一個(gè)位于核心板上,另一個(gè)位于底板上,在設(shè)置html時(shí),可以使用select功能實(shí)現(xiàn)一個(gè)下拉選項(xiàng),選擇要控制的LED。
另外,LED也有多種控制模式,如基礎(chǔ)的開(kāi)關(guān)模式(設(shè)置開(kāi),或關(guān)),心跳燈模式,定時(shí)器模式(設(shè)置亮的時(shí)間和滅的時(shí)間),也使用下拉選項(xiàng)的方式。
選擇不同的控制模式后,為了能動(dòng)態(tài)展示不同模式下的操作功能,比如開(kāi)關(guān)模式下需要顯示開(kāi)和關(guān)的按鈕,心跳燈模式則不需要額外的配置,定時(shí)器模式則需要兩個(gè)輸入框來(lái)設(shè)置亮的時(shí)間和滅的時(shí)間。這里使用script功能,來(lái)實(shí)現(xiàn)此功能,通過(guò)讀取網(wǎng)頁(yè)中當(dāng)前LED模式的值,來(lái)進(jìn)行對(duì)應(yīng)控件的顯示或隱藏。
完整的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 control<span class="hljs-name"title>
<span class="hljs-name"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燈<span class="hljs-name"h1>
<form action="led.cgi" method="get">
<p align="center">LED選擇:
<select name="led_id">
<option value="LED0" selected>核心板LED<span class="hljs-name"option>
<option value="LED1">底板LED<span class="hljs-name"option>
<span class="hljs-name"select><span class="hljs-name"p>
<p align="center">模式選擇:
<select name="led_mode" onclick="select_event(this.options[this.selectedIndex].value);">
<option value="ONOFF" selected>開(kāi)關(guān)模式<span class="hljs-name"option>
<option value="HEARTBEAT">心跳燈模式<span class="hljs-name"option>
<option value="TIMER">定時(shí)器燈模式<span class="hljs-name"option>
<span class="hljs-name"select><span class="hljs-name"p>
<p align="center" id = "id_led_time_on" >亮?xí)r間:<input type="text" value=500 name="led_time_on"/><span class="hljs-name"p>
<p align="center" id = "id_led_time_off" >滅時(shí)間:<input type="text" value=500 name="led_time_off"/><span class="hljs-name"p>
<p align="center" id = "id_led_onoff">LED開(kāi)關(guān):
<input type="radio" name="led_val" value="ON" checked>開(kāi)
<input type="radio" name="led_val" value="OFF">關(guān)
<span class="hljs-name"p><br><br>
<p align="center">
<input type="submit" value="確認(rèn)"/>
<input type="reset" value="返回"/>
<span class="hljs-name"p>
<span class="hljs-name"form>
<span class="hljs-name"center>
?
<script>
document.getElementById("id_led_time_on").style.display = "none";
document.getElementById("id_led_time_off").style.display = "none";
<span class="hljs-name"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 = "";
}
}
class="hljs-name"script>
可以先使用瀏覽器直接打開(kāi)這個(gè)html文件查看效果,實(shí)際效果如下:
2.3 CGI程序設(shè)計(jì)
CGI是Web服務(wù)器主機(jī)提供信息服務(wù)的標(biāo)準(zhǔn)接口。
通過(guò)CGI接口,Web服務(wù)器可以獲取網(wǎng)頁(yè)客戶(hù)端提交的信息,轉(zhuǎn)交給服務(wù)器端的CGI程序進(jìn)行處理,最后返回結(jié)果給客戶(hù)端。
CGI程序可以使用多種語(yǔ)言來(lái)實(shí)現(xiàn),對(duì)于嵌入式開(kāi)發(fā),那就用熟悉的C語(yǔ)言來(lái)編寫(xiě)吧。
編寫(xiě)CGI程序,需要用到CGI的庫(kù),下載地址: https://github.com/boutell/cgic,只需要用到cgic.c和cgic.h這兩個(gè)文件。
本次測(cè)試的LED點(diǎn)燈功能,CGI程序需要實(shí)現(xiàn)的,就是獲取網(wǎng)頁(yè)上的用戶(hù)操作信息,然后控制板子上的LED進(jìn)行對(duì)應(yīng)模式的亮滅,完整的代碼實(shí)現(xiàn)如下,led.c:
#include "cgic.h"
#include
#include
?
// cgic程序以cgiMain作為入口點(diǎn), cgic的函數(shù)庫(kù)會(huì)自動(dòng)把cgiMain連接到相應(yīng)的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);
// 設(shè)定輸出的內(nèi)容格式 這里我們要輸出HTML
cgiHeaderContentType("text/html;charset=\"UTF-8\"");
fprintf(cgiOut,"LED Web Control");
fprintf(cgiOut,"");
fprintf(cgiOut,"
");
fprintf(cgiOut,"
");
fprintf(cgiOut,"
");
fprintf(cgiOut,"OK-MX93開(kāi)發(fā)板從Web頁(yè)面收到數(shù)據(jù):");
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,"執(zhí)行結(jié)果: %s", ret == 0 ? "成功" : "失敗");
fprintf(cgiOut,"
");
fprintf(cgiOut,"
");
fprintf(cgiOut,"返回");
fprintf(cgiOut,"");
?
return 0;
}
此cgi程序的執(zhí)行效果實(shí)測(cè)如下:
3 編譯與測(cè)試
在Ubuntu中對(duì)cgi程序進(jìn)行交叉編譯。
每次打開(kāi)一個(gè)bash窗口進(jìn)行交叉編譯時(shí),都要先執(zhí)行一次交叉編譯環(huán)境的生效:
. /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用到的背景圖片拷貝到開(kāi)發(fā)板中,可以新建一個(gè)led目錄單獨(dú)存放,如下:
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開(kāi)發(fā)板開(kāi)機(jī)自動(dòng)啟動(dòng)Web服務(wù),復(fù)制完之后,在電腦的瀏覽器中,輸入板子ip以及對(duì)應(yīng)目錄的html文件目錄即可,如我的是:
192.168.5.115/led/led.html
4 總結(jié)
本篇介紹了在OK-MX9352開(kāi)發(fā)板上,通過(guò)Web服務(wù),實(shí)現(xiàn)網(wǎng)頁(yè)上LED控制界面來(lái)控制板子上LED進(jìn)行不同模式的亮滅。
文章首先介紹了在Ubuntu虛擬機(jī)中,進(jìn)行OK-MX9352的C/C++交叉編譯環(huán)境配置,然后介紹了Web點(diǎn)燈功能的代碼實(shí)現(xiàn),通過(guò)html設(shè)置頁(yè)面,通過(guò)CGI程序?qū)崿F(xiàn)網(wǎng)頁(yè)指令的接收和板子上LED的控制,最后進(jìn)行代碼編譯和實(shí)際測(cè)試。
審核編輯:湯梓紅
-
嵌入式
+關(guān)注
關(guān)注
5059文章
18973瀏覽量
302029 -
Web
+關(guān)注
關(guān)注
2文章
1255瀏覽量
69292 -
Linux
+關(guān)注
關(guān)注
87文章
11207瀏覽量
208717 -
開(kāi)發(fā)板
+關(guān)注
關(guān)注
25文章
4896瀏覽量
97058 -
Ubuntu
+關(guān)注
關(guān)注
5文章
559瀏覽量
29503
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論