目录
一、html控制LED
二、模拟数据上传到html
一、html控制LED
简单来说就是html给boa服务器发了一个控制指令信息,然后boa转发给cgi进程,cgi通过消息队列和主进程通信。主进程再去启动LED子线程。
这是老师给的工程。
以前学32都有这工具那工具来管理,现在就是自己建文件夹,然后写makefile来管理
先来看看makefile
KERNELDIR :=/home/book/Linux_4412/kernel/linux-3.14
PWD :=$(shell pwd)CROSS_COMPILE=arm-none-linux-gnueabi-
#CROSS_COMPILE=
CC=$(CROSS_COMPILE)gcc
CP=cpARM_DRVDIR=~/nfs_rootfs/drv/
NFS_BOA_WWWDIR=~/nfs_rootfs/boa/www/
NFS_BOA_CGIDIR=~/nfs_rootfs/boa/cgi-bin/obj-m +=demo.o
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
$(CC) -o cgi_led.cgi -static cgi_led.c
mv *.o *.mod.c *.order *.symvers objinstall:
sudo cp demo.ko $(ARM_DRVDIR)
sudo cp *.mp3 *.jpg led.html $(NFS_BOA_WWWDIR)
sudo cp cgi_led.cgi $(NFS_BOA_CGIDIR)clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
rm -rf cgi_led.cgi
主要就是调用内核的makefile来编译我们的驱动程序,然后编译我们的LED的C文件生成cgi。
为了方便加上clean和install命令
/*************************************************************************
# FileName : test.c
# Author : fengjunhui
# Email : 18883765905@163.com
# Created : 2017年07月03日 星期一 15时48分02秒
************************************************************************/
#include<stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/limits.h>
#include <errno.h>
#include "chardev.h"
#define LED_DEVICE "/dev/chrdev0"
#define MAX_BUFFER_SIZE PIPE_BUF
int main(int argc, const char *argv[])
{
int i = 0,j = 3;
int nread;
int led_control,led_state;
int led_fd,fifo_fd;
led_desc_t led;
char *data;
led_fd = open(LED_DEVICE,O_RDWR);
if(led_fd < 0){
printf("open failed !\n");
}
printf("open device success! led_fd: %d\n",led_fd);
printf("Content-type: text/html;charset=utf-8\n\n");
printf("<html>\n");
printf("<head><title>cgi control led web</title></head>\n");
printf("<body>\n");
printf("<p>led is setted successful! you can watch the led's change</p>\n");
//printf("<p><a herf=http://192.168.1.100/led.html>go back</a></p>\n");
printf("<a href=\"/led.html\">go back led control page </a>");
printf("</body>\n");
data = getenv("QUERY_STRING"); //getenv()读取环境变量的当前值的函数
if(sscanf(data,"led_control=%d&led_state=%d",&led_control,&led_state)!=2)
{ //利用sscnaf()函数的特点将环境变量分别提取出led_control和led_state这两个值
printf("<p>please input right");
printf("</p>");
}
printf("<p>led_control = %d,led_state = %d</p>", led_control, led_state);
if(led_control < 2 || led_control > 5) {
printf("<p>Please input 2<=led_control<=5!");
printf("</p>");
}
if(led_state>1) {
printf("<p>Please input 0<=led_state<=1!");
printf("</p>");
}
led.led_num = led_control;
led.led_state = led_state;
if(led.led_state == 0){
ioctl(led_fd,FS_LED_OFF,&led);
}else if(led.led_state == 1){
ioctl(led_fd,FS_LED_ON,&led);
}else if(led.led_state == 2){
while(j --){
for(i = 2; i <= 5; i ++ ){
led.led_num = i;
led.led_state = 0;
ioctl(led_fd,FS_LED_OFF,&led);
usleep(500000);
led.led_state = 1;
ioctl(led_fd,FS_LED_ON,&led);
usleep(500000);
}
}
}
close(led_fd);
printf("</html>\n");
return 0;
}
这是老师再17年写的老代码了,主要就是接收html的指令然后发给A9主进程,但是由于这只是个测试所以没用主进程,直接再这个cgi进程中操作LED了。
昨天发烧没看清,录视频讲错了。
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include "chardev.h"
const char *name = "chrdev";
unsigned int major ;
struct class *cls;
struct device *dev;
#define GPX2CON 0x11000c40
#define GPX2DAT 0x11000c44
#define GPX1CON 0x11000c20
#define GPX1DAT 0x11000c24
#define GPF3CON 0x114001e0
#define GPF3DAT 0x114001e4
void __iomem * gpx2con_vir;
void __iomem * gpx2dat_vir;
void __iomem * gpx1con_vir;
void __iomem * gpx1dat_vir;
void __iomem * gpf3con_vir;
void __iomem * gpf3dat_vir;
char kbuf[] = {'1','2','3','4'};
loff_t demo_llseek(struct file *filp, loff_t offset, int cnt)
{
printk("---->%s--->%d\n",__func__,__LINE__);
return 0;
}
ssize_t demo_read(struct file *filp, char __user *usrbuf, size_t count, loff_t *offset)
{
int bytes = 0;
printk("---->%s--->%d\n",__func__,__LINE__);
bytes = copy_to_user(usrbuf,kbuf,4);
if(bytes > 0){
printk("copy_to_user failed!\n");
}
return 0;
}
ssize_t demo_write(struct file *filp, const char __user *usrbuf, size_t size, loff_t *offset)
{
int bytes = 0;
printk("---->%s--->%d\n",__func__,__LINE__);
bytes = copy_from_user(kbuf,usrbuf,4);
if(bytes > 0){
printk("copy_from_user failed\n");
return -1;
}
printk("copy_from_user usrbuf:%c\n",kbuf[0]);
return 0;
}
long demo_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
{
int i;
led_desc_t *led = (led_desc_t *)args;
printk("---->%s--->%d\n",__func__,__LINE__);
switch(cmd){
case FS_LED_ON:
i = led->led_num;
printk("i= %d\n",i);
if(i == 2){
writel(readl(gpx2dat_vir) | (0x1 << 7),gpx2dat_vir);
}
else if(i == 3){
writel(readl(gpx1dat_vir) | (0x1 << 0),gpx1dat_vir);
}else if(i == 4){
writel(readl(gpf3dat_vir) | (0x1 << 4),gpf3dat_vir);
}else if(i == 5){
writel(readl(gpf3dat_vir) | (0x1 << 5),gpf3dat_vir);
}
printk("FS_LED_ON. \n");
break;
case FS_LED_OFF:
i = led->led_num;
printk("i= %d\n",i);
if(i == 2){
writel(readl(gpx2dat_vir)&~(0x1 << 7),gpx2dat_vir);
}else if(i == 3){
writel(readl(gpx1dat_vir)&~(0x1 << 0),gpx1dat_vir);
}else if(i == 4){
writel(readl(gpf3dat_vir)&~(0x1 << 4),gpf3dat_vir);
}else if(i == 5){
writel(readl(gpf3dat_vir)&~(0x1 << 5),gpf3dat_vir);
}
printk("FS_LED_OFF. \n");
break;
default:
printk("default :....\n");
break;
}
return 0;
}
int demo_open(struct inode *inode, struct file *filp)
{
//硬件的初始化工作--收发数据的初始化
printk("---->%s--->%d\n",__func__,__LINE__);
return 0;
}
int demo_close(struct inode *inode, struct file *filp)
{
printk("---->%s--->%d\n",__func__,__LINE__);
return 0;
}
const struct file_operations fops = {
.open=demo_open,
.llseek=demo_llseek,
.read=demo_read,
.write=demo_write,
.unlocked_ioctl=demo_ioctl,
.release=demo_close,
};
void gpio_ioremap(void)
{
gpx2con_vir = ioremap(GPX2CON,8);
gpx2dat_vir = gpx2con_vir + 4;
gpx1con_vir = ioremap(GPX1CON,8);
gpx1dat_vir = gpx1con_vir + 4;
gpf3con_vir = ioremap(GPF3CON,8);
gpf3dat_vir = gpf3con_vir + 4;
writel((readl(gpx2con_vir) & ~(0XF<< 28))| (0x1 << 28),gpx2con_vir);
writel((readl(gpx1con_vir) & ~(0XF<< 0))| (0x1 << 0),gpx1con_vir);
writel((readl(gpf3con_vir) & ~(0XF<< 16 ))| (0x1 << 16),gpf3con_vir);
writel((readl(gpf3con_vir) & ~(0XF<< 20 ))| (0x1 << 20),gpf3con_vir);
}
static int __init demo_init(void)
{
printk("---->%s--->%d\n",__func__,__LINE__);
major = register_chrdev(0,name,&fops);
if(major <= 0){
printk("register_chrdev failed!\n");
}
printk("register_chrdev success .major: %d\n",major);
cls = class_create(THIS_MODULE,name);
if(cls == NULL){
printk("class_create failed!\n");
}
dev = device_create(cls, NULL,MKDEV(major,0),NULL,"chrdev0");
if(dev == NULL){
printk("device_create failed!\n");
}
gpio_ioremap();
return 0;
}
void viraddr_iounmap(void)
{
iounmap(gpx2con_vir);
iounmap(gpx1con_vir);
iounmap(gpf3con_vir);
}
static void __exit demo_exit(void)
{
printk("---->%s--->%d\n",__func__,__LINE__);
viraddr_iounmap();
device_destroy(cls,MKDEV(major,0));
class_destroy(cls);
unregister_chrdev(major,name);
}
module_init(demo_init);
module_exit(demo_exit);
MODULE_LICENSE("GPL");
这就是一个LED的驱动程序
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>web控制A9开发板led</title>
</head>
<body background="./makeru-desktop.jpg">
<br/>
<embed src="./meiyanfang.mp3" autostart="true" loop="true" hidden="true">
<h1 align="center">基于Cortex-A9的web控制LED灯</h1>
<!--新建一个表单,动作链接到开发板的/cgi-bin/cgi_led.cgi,采用的方法为GET-->
<form action="/cgi-bin/cgi_led.cgi" method="get">
<p align="center">Web端的led的控制测试</p>
<p align="center">请输入需要控制的led:<input type="text" name="led_control"/></p>
<p align="center">请输入LED控制命令 :<input type="text" name="led_state"/></p>
<h2 align="center"> (0熄灭-1点亮-2流水)</h2>
<p align="center"><input type="submit" value="sure"/>
<input type="reset" value="back"/>
</p>
</form>
</body>
</html>
LED的前端程序,和搞web的差远了哈,这个不用精通会点就行,这部分工作以后公司有专人做的。
嵌入式安防监控项目——LED控制_哔哩哔哩_bilibili
二、模拟数据上传到html
#include "data_global.h"
#include "sem.h"
#define N 1024 //for share memory
extern int shmid;
extern int msgid;
extern int semid;
extern key_t shm_key;
extern key_t sem_key;
extern key_t key; //msg_key
extern pthread_mutex_t mutex_client_request,
mutex_refresh,
mutex_sqlite,
mutex_transfer,
mutex_analysis,
mutex_sms,
mutex_buzzer,
mutex_led,
mutex_camera;
extern pthread_cond_t cond_client_request,
cond_refresh,
cond_sqlite,
cond_transfer,
cond_analysis,
cond_sms,
cond_buzzer,
cond_led,
cond_camera;
extern struct env_info_client_addr sm_all_env_info;
struct shm_addr
{
char shm_status; //shm_status���Ե���home_id���������ֹ����ڴ�����
struct env_info_client_addr sm_all_env_info;
};
struct shm_addr *shm_buf;
int file_env_info_struct(struct env_info_client_addr *rt_status,int home_id);
void *pthread_refresh(void *arg)
{
//semaphore for access to resource limits
if((sem_key = ftok("/tmp",'i')) < 0){
perror("ftok failed .\n");
exit(-1);
}
semid = semget(sem_key,1,IPC_CREAT|IPC_EXCL|0666);
if(semid == -1) {
if(errno == EEXIST){
semid = semget(sem_key,1,0777);
}else{
perror("fail to semget");
exit(1);
}
}else{
init_sem (semid, 0, 1);
}
//share memory for env_info refresh config
if((shm_key = ftok("/tmp",'i')) < 0){
perror("ftok failed .\n");
exit(-1);
}
shmid = shmget(shm_key,N,IPC_CREAT|IPC_EXCL|0666);
if(shmid == -1) {
if(errno == EEXIST){
shmid = shmget(key,N,0777);
}else{
perror("fail to shmget");
exit(1);
}
}
//share memap
if((shm_buf = (struct shm_addr *)shmat(shmid,NULL,0)) == (void *)-1)
{
perror("fail to shmat");
exit(1);
}
printf("pthread_refresh ......>>>>>>>\n");
#if 1
bzero (shm_buf, sizeof (struct shm_addr));
while(1){
sem_p(semid,0);
shm_buf->shm_status = 1;
file_env_info_struct(&shm_buf->sm_all_env_info,shm_buf->shm_status);
sleep(1);
sem_v(semid,0);
}
#endif
}
int file_env_info_struct(struct env_info_client_addr *rt_status,int home_id)
{
int env_info_size = sizeof(struct env_info_client_addr);
printf("env_info_size = %d.\n",env_info_size);
rt_status->monitor_no[home_id].zigbee_info.temperature = 10.0;
rt_status->monitor_no[home_id].zigbee_info.tempMIN = 2.0;
rt_status->monitor_no[home_id].zigbee_info.tempMAX = 20.0;
rt_status->monitor_no[home_id].zigbee_info.humidity = 20.0;
rt_status->monitor_no[home_id].zigbee_info.humidityMIN = 10.0;
rt_status->monitor_no[home_id].zigbee_info.humidityMAX = 30.0;
rt_status->monitor_no[home_id].zigbee_info.reserved[0] = 0.01;
rt_status->monitor_no[home_id].zigbee_info.reserved[1] = -0.01;
rt_status->monitor_no[home_id].a9_info.adc = 9.0;
rt_status->monitor_no[home_id].a9_info.gyrox = -14.0;
rt_status->monitor_no[home_id].a9_info.gyroy = 20.0;
rt_status->monitor_no[home_id].a9_info.gyroz = 40.0;
rt_status->monitor_no[home_id].a9_info.aacx = 642.0;
rt_status->monitor_no[home_id].a9_info.aacy = -34.0;
rt_status->monitor_no[home_id].a9_info.aacz = 5002.0;
rt_status->monitor_no[home_id].a9_info.reserved[0] = 0.01;
rt_status->monitor_no[home_id].a9_info.reserved[1] = -0.01;
return 0;
}
这是A9刷新的线程程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <errno.h>
#include <sys/sem.h>
#include <unistd.h>
#include "sem.h"
#include "cgic.h"
#include "data_global.h"
#define N 32
#define MONITOR_NUM 1
char status[2][6] = {"Close", "Open"};
char fan_status[4][6] = {"Close", "One", "Two", "Three"};
struct shm_addr
{
char shm_status;
struct env_info_client_addr sm_all_env_info;
};
int cgiMain()
{
key_t key;
int shmid,semid;
struct shm_addr *shm_buf;
if((key = ftok("/tmp",'i')) <0)
{
perror("ftok");
exit(1);
}
printf("key = %x\n",key);
if((semid = semget(key, 1, 0666)) < 0)
{
perror("semget");
exit(1);
}
if((shmid = shmget(key, N, 0666 )) == -1)
{
perror("shmget");
exit(1);
}
if((shm_buf = (struct shm_addr*)shmat(shmid, NULL, 0)) == (void*)-1 )
{
perror("shmat");
exit(1);
}
sem_p(semid,0);
cgiHeaderContentType("text/html");
fprintf(cgiOut, "<head><meta http-equiv=\"refresh\" content=\"1\"><style><!--body{line-height:50%}--></style> </head>");
fprintf(cgiOut, "<HTML>\n");
fprintf(cgiOut, "<BODY bgcolor=\"#666666\">\n");
//fprintf(cgiOut, "<h1><font color=\"#FF0000\">HOME_ID #%d:</font></H2>\n ", shm_buf->shm_status);
if (shm_buf->shm_status == 1)
{
fprintf(cgiOut, "<script>function show(){var date =new Date(); var now = \"\"; now = date.getFullYear()+\"年\"; now = now + (date.getMonth()+1)+\"月\"; \ now = now + date.getDate()+\"日\"; now = now + date.getHours()+\"时\"; now = now + date.getMinutes()+\"分\";now = now + date.getSeconds()+\"秒\"; document.getElementById(\"nowDiv\").innerHTML = now; setTimeout(\"show()\",1000);} </script> \n ");
fprintf(cgiOut, "<h2><font face=\"Broadway\"><font color=\"#00FAF0\">Home1 Real-time Environment Info:</font></font></H2>\n ");
fprintf(cgiOut, "<h2 align=center><font color=\"#cc0033\"><body onload=\"show()\"> <div id=\"nowDiv\"></div></font></h2> \n ");
fprintf(cgiOut, "<h4>ZIGBEE数据显示部分</H4>\n ");
fprintf(cgiOut, "<h4>Temperature:\t%0.2f</H4>\n ", shm_buf->sm_all_env_info.monitor_no[shm_buf->shm_status].zigbee_info.temperature );
fprintf(cgiOut, "<h4>Humidity:\t%0.2f</H4>\n ", shm_buf->sm_all_env_info.monitor_no[shm_buf->shm_status].zigbee_info.humidity);
fprintf(cgiOut, "<h4>A9数据显示部分</H4>\n ");
fprintf(cgiOut, "<h4>Adc:\t%0.2f</H4>\n ", shm_buf->sm_all_env_info.monitor_no[shm_buf->shm_status].a9_info.adc);
fprintf(cgiOut, "<h4>GYROX:\t%d</H4>\n ", shm_buf->sm_all_env_info.monitor_no[shm_buf->shm_status].a9_info.gyrox);
fprintf(cgiOut, "<h4>GYROY:\t%d</H4>\n ", shm_buf->sm_all_env_info.monitor_no[shm_buf->shm_status].a9_info.gyroy);
fprintf(cgiOut, "<h4>GYROZ:\t%d</H4>\n ", shm_buf->sm_all_env_info.monitor_no[shm_buf->shm_status].a9_info.gyroz);
fprintf(cgiOut, "<h4>AACX :\t%d</H4>\n ", shm_buf->sm_all_env_info.monitor_no[shm_buf->shm_status].a9_info.aacx);
fprintf(cgiOut, "<h4>AACY :\t%d</H4>\n ", shm_buf->sm_all_env_info.monitor_no[shm_buf->shm_status].a9_info.aacy);
fprintf(cgiOut, "<h4>AACZ :\t%d</H4>\n ", shm_buf->sm_all_env_info.monitor_no[shm_buf->shm_status].a9_info.aacz);
fprintf(cgiOut, "<h4>A9-RESERVED[0]:\t%d</H4>\n ", shm_buf->sm_all_env_info.monitor_no[shm_buf->shm_status].a9_info.reserved[0]);
fprintf(cgiOut, "<h4>A9-RESERVED[1]:\t%d</H4>\n ", shm_buf->sm_all_env_info.monitor_no[shm_buf->shm_status].a9_info.reserved[1]);
fprintf(cgiOut, "<h4>STM32数据显示部分</H4>\n ");
fprintf(cgiOut, "<h4>......</H4>\n ");
}
else
{
fprintf(cgiOut, "<h2><font face=\"Broadway\"><font color=\"#FFFAF0\">Close!</font></font></H2>\n ");
}
// fprintf(cgiOut, "<h3>:</H3>\n ");
fprintf(cgiOut, "</BODY></HTML>\n");
sem_v (semid, 0);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <errno.h>
#include "cgic.h"
#include "data_global.h"
#define home_id 1
struct shm_addr
{
char shm_status; //shm_status可以等于home_id,用来区分共享内存数据
struct env_info_client_addr sm_all_env_info;
};
struct shm_addr *shm_buf;
#if 0
struct setEnv
{
int temMAX;
int temMIN;
int humMAX;
int humMIN;
int illMAX;
int illMIN;
};
#endif
int cgiMain()
{
key_t key;
char sto_no[2];
char buf[20];
struct shm_addr new;
int msgid;
struct msg msg_buf;
memset(&msg_buf,0,sizeof(msg_buf));
cgiFormString("store", sto_no, 2);
cgiFormString("temMAX", buf, 20);
new.sm_all_env_info.monitor_no[home_id].zigbee_info.tempMAX = atoi(buf);
cgiFormString("temMIN", buf, 20);
new.sm_all_env_info.monitor_no[home_id].zigbee_info.tempMIN = atoi(buf);
cgiFormString("humMAX", buf, 20);
new.sm_all_env_info.monitor_no[home_id].zigbee_info.humidityMAX = atoi(buf);
cgiFormString("humMIN", buf, 20);
new.sm_all_env_info.monitor_no[home_id].zigbee_info.humidityMIN = atoi(buf);
//cgiFormString("illMAX", buf, 20);
//new.illMAX = atoi (buf);
//cgiFormString("illMIN", buf, 20);
//new.illMIN = atoi (buf);
if((key = ftok("/tmp", 'g')) < 0)
{
perror("ftok");
exit(1);
}
if((msgid = msgget(key, 0666)) < 0)
{
perror("msgget");
exit(1);
}
memcpy (msg_buf.text+1, &new, 24);
msg_buf.type = 1L;
msg_buf.msgtype = 5L;
msg_buf.text[0] = sto_no[0];
msgsnd(msgid, &msg_buf,sizeof(msg_buf)-sizeof(long),0);
sto_no[0] -= 48;
cgiHeaderContentType("text/html\n\n");
fprintf(cgiOut, "<HTML><HEAD>\n");
fprintf(cgiOut, "<TITLE>My CGI</TITLE></HEAD>\n");
fprintf(cgiOut, "<BODY>");
fprintf(cgiOut, "<H2>send sucess</H2>");
//fprintf(cgiOut, "<a href='.html'>返回</a>");
fprintf(cgiOut, "<meta http-equiv=\"refresh\" content=\"1;url=../home%d.html\">", sto_no[0]);
fprintf(cgiOut, "</BODY>\n");
fprintf(cgiOut, "</HTML>\n");
return 0;
}
这俩是CGI相关的程序都是为了完成数据的刷新
录了讲解视频,后面发评论区