嵌入式安防监控项目——实现真实数据的上传

目录

一、相关驱动开发

二、A9主框架

三、脚本及数据上传实验


https://www.yuque.com/uh1h8r/dqrma0/tx0fq08mw1ar1sor?singleDoc# 《常见问题》

上个笔记的相关问题

一、相关驱动开发

     /* mpu6050六轴传感器 */
    i2c@138B0000 {
    /*    #address-cells = <1>;
        #size-cells = <0>;
        samsung,i2c-sda-delay = <100>;
        samsung,i2c-max-bus-freq = <20000>;*/

        pinctrl-0 = <&i2c5_bus>;
        pinctrl-names = "default";
        status = "okay";
        
        mpu6050@0x68{
            compatible = "invensense,mpu6050";
            reg = <0x68>;
        };
    };

 

 LED和蜂鸣器没用设备树直接操作的寄存器

 驱动主要就是这四个

buildmodule.sh是一个编译加拷贝的脚本

#!/bin/bash

echo "*****************************************************"
echo "just to compile the module int the current directory!"
echo "*****************************************************"

echo $PWD

for file in $PWD/*
do
    if [ -d "$file" ]
    then
        echo "$file is directory"
        cd $file 
        make clean
        make
        cp *.ko  *_test ../
        make clean
        cd -
    elif [ -f "$file" ]
    then
        echo "$file is file"
    fi
done

echo "*******************************************************"
echo "***********  compile the module over! *****************"
echo "*Do you want to mv to the file system directory y/n?*"
echo "*******************************************************"

read yourchoice

case $yourchoice in
    "y"|"yes"|"Y"|"YES")
        echo "moving,wait a moment,please"
        sleep 1
        sudo mv *.ko *_test ~/nfs_rootfs/drv/ 
        echo "moved,you are lazy,haha!"
        ;;
    "n"|"no"|"N"|"NO")
        echo "maybe you need to copy it by hand."
        ;;
    *)
        echo "I get $var,maybe your input is wrong !"
        echo "There is no chance,you need to do it manually !"
        ;;
esac
# --- end of case ---""""""""""

每个文件夹下都是对应的驱动程序,通过配套的MAkefile来编译

这是adc的驱动

#include <linux/module.h>  
#include <linux/device.h>  
#include <linux/platform_device.h>  
#include <linux/interrupt.h>  
#include <linux/fs.h>  
#include <linux/wait.h>  
#include <linux/sched.h>  
#include <asm/uaccess.h>  
#include <asm/io.h>  
#include <linux/of.h>
#include <linux/device.h>

static wait_queue_head_t wq;  

unsigned int major = 0;
struct class  *cls = NULL;
struct device *dev = NULL;


static int have_data = 0;  
static int fs4412_adc;  
static struct resource *res1;  
static struct resource *res2;  
static void *fs4412_adc_base;  
  
 #define  ADCCON    0x0000  
 #define  ADCDLY    0x0008  
 #define  ADCDAT    0x000C  
 #define  CLRINTADC  0x0018  
 #define  ADCMUX    0x001C


int flags = 1;
//#define flags 1 

#define DEBUG_PRINTK(msg,DEBUG_FLAG) \
    do{ \
        if(!!DEBUG_FLAG) { \
            printk("---->%s--->%d\n",__func__,__LINE__);\
            printk(msg);\
		}\
    }while(0)

static  irqreturn_t fs4412_adc_handler(int irqno, void *dev)  
{  
    have_data = 1;   //��������
  
   printk("--->%s--->%d.\n",__func__,__LINE__);
    /*���ж�*/  
    writel(0x12,fs4412_adc_base + CLRINTADC);  
    wake_up_interruptible(&wq);  
    return IRQ_HANDLED;  
}  
static int fs4412_adc_open (struct inode *inod, struct file *filep)  
{  
  	DEBUG_PRINTK("fs4412_adc_open",flags);
    return 0;  
}  

static ssize_t fs4412_adc_read(struct file *filep, char __user *buf, size_t len, loff_t *pos)  
{  
    writel(0x3,fs4412_adc_base + ADCMUX);  
    writel(1<<0 | 1<<14 | 0X1<<16 | 0XFF<<6 ,fs4412_adc_base + ADCCON );  
  
    wait_event_interruptible(wq, have_data == 1);  
  
    /*read data ������& 0xfff,�������ݳ��� */  
    fs4412_adc = readl(fs4412_adc_base+ADCDAT) & 0xfff;  

   //�����㲻�������㣬�ӽ����ݿ�����Ӧ�ò�
    if(copy_to_user(buf,&fs4412_adc,sizeof(int))) 
        return -EFAULT;  
    have_data = 0;  
	
    return len;  
}  


static  int fs4412_adc_release(struct inode *inode, struct file *filep)  
{  
	DEBUG_PRINTK("fs4412_adc_release",flags);
    return 0;  
}  

static struct file_operations  fs4412_adc_ops ={  
    .open    = fs4412_adc_open,  
    .release = fs4412_adc_release,  
    .read    = fs4412_adc_read,  
};  
  
  
static int fs4412_adc_probe(struct platform_device *pdev)  
{  
    printk("--->%s--->%d.\n",__func__,__LINE__);
  
    res1 = platform_get_resource(pdev,IORESOURCE_IRQ, 0);  
    res2 = platform_get_resource(pdev,IORESOURCE_MEM, 0);   

	fs4412_adc_base = ioremap(res2->start,res2->end - res2->start);   
	printk("res2->start,res2->end - res2->start :%#x.\n",res2->end - res2->start);
	
    request_irq(res1->start,fs4412_adc_handler,IRQF_DISABLED,"adc1",NULL); 
	printk("res1->start :%d.\n",res1->start);

	major = register_chrdev(0, "adc", &fs4412_adc_ops);  
	if(major <= 0){
		printk("register_chrdev failed.\n");
		return -1;
	}
	printk(KERN_INFO "major :%d.\n",major);

	cls = class_create(THIS_MODULE, "myadc");
	if(cls == NULL){
		printk("class_create failed");
		return -1;
	}

	dev = device_create(cls, NULL, MKDEV(major, 0),NULL, "fsadc%d",0);
	if(dev == NULL){
		printk("device_create failed.\n");
		return -1;
	}

    init_waitqueue_head(&wq);  
      
    return 0;  
}  
static int fs4412_adc_remove(struct platform_device *pdev)  
{  
    free_irq(res1->start,NULL);  
    free_irq(res2->start,NULL);    
    unregister_chrdev( major, "adc");  
    return 0;  
}  
  
static struct of_device_id myof_match_table[]=  {  
    {.compatible = "fs4412,adc" },  
};  
  
static struct platform_driver fs4412_adc_driver=  {  
    .probe = fs4412_adc_probe,  
    .remove = fs4412_adc_remove,  
    .driver ={  
        .name = "adc_demo",  
        .of_match_table = of_match_ptr(myof_match_table),  
    },  
};  
  
static int fs4412_adc_init(void)  
{  
    printk("--->%s--->%d.\n",__func__,__LINE__);
    return platform_driver_register(&fs4412_adc_driver);  
}  
static void fs4412_adc_exit(void)  
{  
	//printk("--->%s--->%d.\n",__func__,__LINE__);
    platform_driver_unregister(&fs4412_adc_driver);  
    return;  
}  
MODULE_LICENSE("GPL");  
module_init(fs4412_adc_init);  
module_exit(fs4412_adc_exit);  

这是蜂鸣器驱动

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/io.h>
#include <asm/uaccess.h>
#include <asm/ioctl.h>


unsigned int major = 0;
const char * modulename="pwmbeeper";
dev_t devnum = 0;
struct class  *cls = NULL;
struct device *dev = NULL;

#define GPD0CON       0x114000a0  
#define TIMER_BASE    0x139D0000             
#define TCFG0         0x0000                 
#define TCFG1         0x0004                              
#define TCON          0x0008               
#define TCNTB0        0x000C            
#define TCMPB0        0x0010


static unsigned int *gpd0con;  
static void *timer_base;  

typedef struct beep_desc{
	int beep;    //2 3 4 5
	int beep_state;  //0 or 1
	int tcnt;  //占空比
	int tcmp;  //调节占空比
}beep_desc_t;

#define mytype 'f'
#define BEEP_ON 	_IOW(mytype,0,beep_desc_t)
#define BEEP_OFF 	_IOW(mytype,1,beep_desc_t)
#define BEEP_FREQ 	_IOW(mytype,2,beep_desc_t)


char kbuf[] = {'1','2','3','4'};


void fs4412_beep_on(void)  
{
	writel (readl(timer_base +TCON ) | (0x1 <<0),timer_base +TCON ); 
}

void fs4412_beep_off(void)  
{
	writel (readl(timer_base +TCON ) | (~(1 << 0)),timer_base +TCON ); 
}

static void beep_freq(int beep_tcnt,int beep_tcmp)  
{  
	//tcnt决定了周期  tcnt 取值范围:
    writel (beep_tcnt, timer_base +TCNTB0  );  //计数值 100次
    //tcmp设置占空比  50 / 100 = 50%   综述:占空比 = tcmp / tcnt;  //决定声音的大小
    writel (beep_tcmp, timer_base +TCMPB0 );  //比较值 50次 
}  


int demo_open(struct inode *inode, struct file *filp)
{
	printk("--->%s--->%d.\n",__FUNCTION__,__LINE__);
	//fs4412_beep_on();
	return 0;
}

int demo_release(struct inode *inode, struct file *filp)
{
	printk("--->%s--->%d.\n",__FUNCTION__,__LINE__);
	fs4412_beep_off();
	return 0;
}

ssize_t demo_read(struct file *filp, char __user *usrbuf, size_t size, 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)
{
	beep_desc_t *beeper = (beep_desc_t *)args;
	printk("---->%s--->%d\n",__func__,__LINE__);

    switch(cmd)  
    {  
        case BEEP_ON:  
            fs4412_beep_on();  
            break;  
        case BEEP_OFF:  
            fs4412_beep_off();  
            break;  
        case BEEP_FREQ:  
            beep_freq(beeper->tcnt,beeper->tcmp);  
            break;  
        default :  
            return -EINVAL;  
    }  
	
	return 0;
}


const struct file_operations  fops={
	.open = demo_open,
	.read = demo_read,
	.write = demo_write,
	.unlocked_ioctl = demo_ioctl,
	.release = demo_release,
};

void fs4412_beep_init(void)
{
	gpd0con = ioremap(GPD0CON,4);
	timer_base = ioremap(TIMER_BASE,4);
	
	//一级分频:PCLK/(249 + 1) = 100MHZ/250 = 400000 
	//PWM.TCFG0 = 199;
	writel ((readl(gpd0con)&~(0xf<<0)) | (0x2<<0),gpd0con); // GPD0_0 : TOUT_0 
    writel ((readl(timer_base +TCFG0  )&~(0xff<<0)) | (0Xf9 <<0),timer_base +TCFG0); //设置默认值0XF9 = 249分频
    writel ((readl(timer_base +TCFG1 )&~(0xf<<0)) | (0x2<<0),timer_base +TCFG1 );  //4分频 

	
    //调整后的PWM波形 100000 / (tcnt)100 = 1000hz (20 - 20000)hz 周期1ms //设置频率 -声音的高低
	//tcnt决定了周期  tcnt 取值范围:
    writel (100, timer_base +TCNTB0  );  //计数值 100次
    //tcmp设置占空比  50 / 100 = 50%   综述:占空比 = tcmp / tcnt;  //决定声音的大小
    writel (80, timer_base +TCMPB0 );  //比较值 50次 
    
	writel (readl(timer_base +TCON ) | (0x1 <<3),timer_base +TCON ); //设置自动重装载
	writel (readl(timer_base +TCON ) | (0x1 <<1),timer_base +TCON );  //设置手动重装
	writel (readl(timer_base +TCON ) & (~(1 << 1)),timer_base +TCON );//清除手动记载

}

static int __init  demo_init(void)
{
	printk("--->%s--->%d.\n",__FUNCTION__,__LINE__);

	major = register_chrdev(0, modulename, &fops);
	if(major <= 0){
		printk("register_chrdev failed.\n");
		return -1;
	}
	devnum = MKDEV(major, 0);
	printk(KERN_INFO "major :%d.\n",major);

	cls = class_create(THIS_MODULE, "fsbeeper");
	if(cls == NULL){
		printk("class_create failed");
		return -1;
	}

	dev = device_create(cls, NULL, devnum,NULL, "fsbeeper%d",0);
	if(dev == NULL){
		printk("device_create failed.\n");
		return -1;
	}
	fs4412_beep_init();

	return 0;
}


void fs4412_beep_unioremap(void)
{
	iounmap(gpd0con);
	iounmap(timer_base);
}


static void __exit  demo_exit(void)
{
	printk("--->%s--->%d.\n",__FUNCTION__,__LINE__);

	fs4412_beep_unioremap();
	
	device_destroy(cls,devnum);
	class_destroy(cls);
	unregister_chrdev(major, modulename);
	
}

module_init(demo_init);
module_exit(demo_exit);
MODULE_LICENSE("GPL");

这是LED驱动

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <linux/device.h>
#include <linux/io.h>
#include "chrdev.h"

unsigned int major = 0;  //动态加载
//unsigned int major = 500;

const char * name = "demoname";

char kbuf[4] = {1,2,3,4};
int numlen = ARRAY_SIZE(kbuf);

struct class * cls;
struct device * dev;


#define GPX2CON 0x11000C40
#define GPX2_7DAT 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;

int demo_open(struct inode *inode, struct file *filp)
{
	printk("-----%s-----%d.\n",__FUNCTION__,__LINE__);

	return 0;
}

int demo_close(struct inode *inode, struct file *filp)
{
	printk("-----%s-----%d.\n",__FUNCTION__,__LINE__);

	return 0;
}

ssize_t demo_read(struct file *filp, char __user * usrbuf, size_t size, loff_t *offset)
{
	int rbytes;
	printk("-----%s-----%d.\n",__FUNCTION__,__LINE__);

	rbytes = copy_to_user(usrbuf, kbuf, 4);
	if(rbytes > 0){
		printk("copy failed bytes :%d.\n",rbytes);
	}
	printk("copy success bytes :%d.\n",rbytes);
	
	return 0;

}

ssize_t demo_write(struct file *filp, const char __user *usrbuf, size_t size, loff_t *offset)
{
	int i = 0;
	int wbytes ;
	printk("-----%s-----%d.\n",__FUNCTION__,__LINE__);
	
	wbytes = copy_from_user(kbuf, usrbuf,4);
	if(wbytes > 0){
		printk("copy failed bytes :%d.\n",wbytes);
	}
	for(i = 0;i < 4;i ++){
		printk("buf[%d] :%d.\n",i,kbuf[i]);
	}

	printk("copy success bytes :%d.\n",wbytes);	

	return 0;
}

long demo_ioctl(struct file *filp, unsigned int  cmd, unsigned long  args)
{	
	int lednum = 0;
	led_desc_t *led = (led_desc_t *)args;
	printk("-----%s-----%d.\n",__FUNCTION__,__LINE__);

	switch (cmd){
	case FSLEDON:  
		lednum = led->which;
		if(lednum == 2){
			printk("fsled %d on.\n",lednum);
			writel((readl(gpx2dat_vir) | 0x1 << 7),gpx2dat_vir);
			//控制硬件
		}else if(lednum == 3){
			writel(readl(gpx1dat_vir) | (0x1 << 0),gpx1dat_vir);
			printk("fsled %d on.\n",lednum);
		}else if(lednum == 4){
			writel(readl(gpf3dat_vir) | (0x1 << 4),gpf3dat_vir);
			printk("fsled %d on.\n",lednum);
		}else if(lednum == 5){
			writel(readl(gpf3dat_vir) | (0x1 << 5),gpf3dat_vir);
			printk("fsled %d on.\n",lednum);
		}
		break;
	case FSLEDOFF:
		lednum = led->which;
		if(lednum == 2){
			writel((readl(gpx2dat_vir) & ~(0x1 << 7)),gpx2dat_vir);
			printk("fsled %d off.\n",lednum);
		}else if(lednum == 3){
			writel(readl(gpx1dat_vir)&~(0x1 << 0),gpx1dat_vir);
			printk("fsled %d off.\n",lednum);
		}else if(lednum == 4){
			writel(readl(gpf3dat_vir)&~(0x1 << 4),gpf3dat_vir);
			printk("fsled %d off.\n",lednum);
		}else if(lednum == 5){
			writel(readl(gpf3dat_vir)&~(0x1 << 5),gpf3dat_vir);
			printk("fsled %d off.\n",lednum);
		}
		break;
	default:
		printk("default :....\n");
		break;
	}

	return 0;
}

const struct file_operations fops = {
	.open = demo_open,
	.release = demo_close,
	.read = demo_read,
	.write = demo_write,
	.unlocked_ioctl = demo_ioctl,
};	


void gpio_led_ioremap(void)
{
	gpx2con_vir = ioremap(GPX2CON, 4);
	gpx2dat_vir = gpx2con_vir +4;

	gpx1con_vir = ioremap(GPX1CON,4);
	gpx1dat_vir = gpx1con_vir + 4;
	
	gpf3con_vir = ioremap(GPF3CON,4);
	gpf3dat_vir = gpf3con_vir + 4;
	
	writel((readl(gpx2dat_vir) | 0x0 << 7),gpx2dat_vir);
	writel(( readl(gpx2con_vir) & (~(0xF << 28))) | 0x1 << 28,gpx2con_vir);
	
	writel((readl(gpx1con_vir) & ~(0XF<< 0))| (0x1 << 0),gpx1con_vir);
	writel((readl(gpf3con_vir) & ~(0XFF<< 16 ))| (0x11 << 16),gpf3con_vir);
}

void gpio_led_iounmap(void)
{
	iounmap(gpx2con_vir);
	iounmap(gpx1con_vir);
	iounmap(gpf3con_vir);
}


static int __init demo_init(void)
{	
	printk("-----%s-----%d.\n",__FUNCTION__,__LINE__);

	major = register_chrdev(0,  name, &fops);
	if(major <  0){
		printk("register_chrdev failed.\n");
	}
	printk("major :%d.\n",major);

	cls = class_create(THIS_MODULE, "chardev");
	if(cls == NULL){
		goto err0;
	}
	dev = device_create(cls,NULL,MKDEV(major, 0),NULL, "fsled%d",0);
	if(dev == NULL){
		printk("device_create failed.\n");
		goto err0;
	}

	//硬件操作
	gpio_led_ioremap();

	return 0;	
	
err0:
	unregister_chrdev(major, name);
	return -1;
}

static void __exit demo_exit(void)
{
	printk("-----%s-----%d.\n",__FUNCTION__,__LINE__);

	gpio_led_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");//GPL

 下面是mpu6050驱动

#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 <linux/of.h>
#include <linux/slab.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/workqueue.h>
#include <linux/platform_device.h>
#include<linux/ioport.h>
#include <linux/timer.h>
#include <linux/i2c.h>
#include <asm/delay.h>
#include "common.h"
#include "mpu6050.h"


#define GPBCON 0x11400040
void __iomem *gpbcon_vir;

unsigned int  major ;
struct class *cls;
struct device *dev;


char kbuf[] = {'1','2','3','4'};

struct i2c_client *mpu_client;

char  mpu6050_read(char regaddr)
{
	char txbuf[1] = {regaddr};
	char rxbuf[1] = {0};
	
	struct i2c_msg  msgs[2] = {
		{mpu_client->addr,0,1,txbuf},
		{mpu_client->addr,1,1,rxbuf}
	};

	i2c_transfer(mpu_client->adapter,msgs,2);

	return rxbuf[0];
}

int  mpu6050_write(char reg,char val)
{
	char  txbuf[] ={reg,val};
	
	struct i2c_msg  msgs[] = {
		{mpu_client->addr,0,2,txbuf},
	};

	i2c_transfer(mpu_client->adapter,msgs,1);

	return  0;
}

int mpu6050_gpio_init(void)
{
    mpu6050_write(MPU_PWR_MGMT1_REG, 0x80);//复位MPU6050  
    udelay(2000);
    mpu6050_write(MPU_PWR_MGMT1_REG, 0x0);//唤醒MPU6050    
    	mpu6050_write(MPU_GYRO_CFG_REG, 0xF8);//陀螺仪传感器,±2000dps  
    mpu6050_write(MPU_ACCEL_CFG_REG, 0x19);//加速度传感器 2g

//	mpu6050_write(MPU_GYRO_CFG_REG, (0x3 << 3));//陀螺仪传感器,±2000dps  
//   mpu6050_write(MPU_ACCEL_CFG_REG, (0x0 << 3));//加速度传感器 2g

    //mpu6050_write(MPU_ACCEL_CFG_REG, 0x01);//唤醒MPU6050    
   
	mpu6050_write(MPU_SAMPLE_RATE_REG, 0x07);//设置采æ ·率50Hz       
    mpu6050_write(MPU_CFG_REG, 0x06);//唤醒MPU6050    
	
#if 1
    printk("who am i:0x%x\n", mpu6050_read(0x75)); 
#endif 
		
	return 0;
}


int mpu6050_open(struct inode *inode, struct file *filp)
{
	//硬件的初始化工作--收发数据的初始化
	printk("---->%s--->%d\n",__func__,__LINE__);
	return 0;
}

ssize_t dev_mpu6050_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 dev_mpu6050_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 mpu6050_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
{
	struct mpu6050_data data;

//	printk("---->%s--->%d\n",__func__,__LINE__);
	
	switch(cmd)
	{
		case MPU6050_GYRO:
			data.gyro.x =  mpu6050_read(MPU_GYRO_XOUTL_REG);	
			data.gyro.x |= mpu6050_read(MPU_GYRO_XOUTH_REG) << 8;	
			
			data.gyro.x =  mpu6050_read(MPU_GYRO_YOUTL_REG);	
			data.gyro.x |= mpu6050_read(MPU_GYRO_YOUTH_REG) << 8;	
			
			data.gyro.x =  mpu6050_read(MPU_GYRO_ZOUTL_REG);	
			data.gyro.x |= mpu6050_read(MPU_GYRO_ZOUTH_REG) << 8;	
			break;

		case MPU6050_ACCEL:
			data.accel.x =  mpu6050_read(MPU_ACCEL_XOUTL_REG);
			data.accel.x |= mpu6050_read(MPU_ACCEL_XOUTH_REG) << 8;
			
			data.accel.y =  mpu6050_read(MPU_ACCEL_YOUTL_REG);
			data.accel.y |= mpu6050_read(MPU_ACCEL_YOUTH_REG) << 8;
			
			data.accel.z =  mpu6050_read(MPU_ACCEL_ZOUTL_REG);
			data.accel.z |= mpu6050_read(MPU_ACCEL_ZOUTH_REG) << 8;
			break;

		case MPU6050_TEMP:
			data.temp = mpu6050_read(MPU_TEMP_OUTL_REG);
			data.temp |= mpu6050_read(MPU_TEMP_OUTH_REG) << 8;

			break;
		default:
			printk("sorry, cmd wrong !\n");
	}

	if (copy_to_user((void *)args, &data, sizeof(data)))  
		return -EFAULT;  

	return 0;
}

int mpu6050_close(struct inode *inode, struct file *filp)
{
	printk("---->%s--->%d\n",__func__,__LINE__);
	return 0;
}

const struct file_operations mpu6050_fops = {
	.owner = THIS_MODULE,
	.open  = mpu6050_open,
	.read  = dev_mpu6050_read,
	.write = dev_mpu6050_write,
	.unlocked_ioctl = mpu6050_ioctl,
	.release = mpu6050_close,
};


int mpu6050_probe(struct i2c_client *client, struct i2c_device_id *devid)
{
	printk("---->%s--->%d\n",__func__,__LINE__);
	mpu_client = client;
	
	printk("MPU6050 probe name.....%s\n",devid->name);
	printk("MPU6050 probe addr.....%#x\n",client->addr);
	
	major = register_chrdev(0,"mpu6050",&mpu6050_fops); 
	if(major <= 0){
		printk("register_chrdev failed!\n");
	}
	printk("register_chrdev success .major: %d\n",major);
	
	cls = class_create(THIS_MODULE,"mpu6050");
	if(cls == NULL){
		printk("class_create failed!\n");
	}

	dev = device_create(cls, NULL,MKDEV(major,0),NULL,"fsmpu60500");
	if(dev == NULL){	
		printk("device_create failed!\n");
	}

//	printk("mpu_6050 read who am i :0x%#x\n",mpu6050_read(0x75));
	
	mpu6050_gpio_init();

	return 0;
}

int mpu6050_remove(struct i2c_client *mpu_6050)
{
	printk("---->%s--->%d\n",__func__,__LINE__);
	return 0;
}

struct i2c_device_id mpu6050_id_table[] = {
	{},
	{},
};

struct of_device_id  mpu6050_device_id[] = {
	{.compatible = "invensense,mpu6050"},
	{},
};

struct i2c_driver mpu6050={
	.driver={
		.name = "mpu6050",
		.of_match_table = of_match_ptr(mpu6050_device_id),
	},
	.probe = mpu6050_probe,
	.remove = mpu6050_remove,
	.id_table =mpu6050_id_table,
	
};


static int __init mpu6050_init(void)
{
	printk("---->%s--->%d\n",__func__,__LINE__);

	if(i2c_add_driver(&mpu6050)){
		printk("driver_register failed\n");
		return -1;
	}
	return 0;
}


static void __exit mpu6050_exit(void)
{
//	printk("---->%s--->%d\n",__func__,__LINE__);
//	iounmap(gpbcon_vir);
	device_destroy(cls,MKDEV(major,0));
	class_destroy(cls);
	unregister_chrdev(major,"mpu6050");
	i2c_del_driver(&mpu6050);
}


module_init(mpu6050_init);
module_exit(mpu6050_exit);

MODULE_LICENSE("GPL");




#if 0

测试结果:

[root@fengjunhui ]:~$ insmod mpu6050.ko 
[ 1361.710000] ---->mpu6050_init--->240
[ 1361.710000] ---->mpu6050_probe--->180
[ 1361.715000] MPU6050 probe name.....(null)
[ 1361.720000] MPU6050 probe addr.....0x68
[ 1361.720000] register_chrdev success .major: 253
[ 1361.745000] who am i:0x68
[root@fengjunhui ]:~$ ./app
[ 4315.375000] ---->mpu6050_open--->87
open device succe[ 4315.585000] ---->dev_mpu6050_read--->94
[ 4315.590000] ---->dev_mpu6050_write--->107
[ 4315.595000] copy_from_user usrbuf:9
ss! fd: 3
usrbuf[2] : 3
----------------------------------accel-------------------
accel data: x = 001848, y = 065432, z = 015538
***********************************gyro*******************
gyro data: x = 000005, y = 000000, z = 000002
===================================temp===================
temp data: z = 063159
----------------------------------accel-------------------
accel data: x = 001860, y = 065430, z = 015514
***********************************gyro*******************
gyro data: x = 000005, y = 000000, z = 000002
===================================temp===================
temp data: z = 063159
----------------------------------accel-------------------
accel data: x = 001844, y = 065422, z = 015518
***********************************gyro*******************
gyro data: x = 000005, y = 000000, z = 000002
===================================temp===================
temp data: z = 063160
----------------------------------accel-------------------
accel data: x = 001856, y = 065422, z = 015508
***********************************gyro*******************
gyro data: x = 000005, y = 000000, z = 000002
===================================temp===================
temp data: z = 063156
----------------------------------accel-------------------
accel data: x = 001858, y = 065424, z = 015484
^C[ 4319.900000] ---->mpu6050_close--->165

[root@fengjunhui ]:~$ rmmod mpu6050
[ 4425.180000] ---->mpu6050_exit--->253
[ 4425.185000] ---->mpu6050_remove--->211


#endif 

export ARCH=arm
export CROSS_COMPILE=arm-none-linux-gnueabi-

#KERNELDIR :=/lib/modules/$(shell uname -r)/build
KERNELDIR :=/home/book/Linux_4412/kernel/linux-3.14
PWD  :=$(shell pwd)

obj-m += fsmpu6050.o  

all:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
    arm-none-linux-gnueabi-gcc test.c -o mpu6050_test

install:
    cp  mpu6050_test *.ko ~/nfs_rootfs/drv/
clean:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) clean
    rm -rf mpu6050_test

拿mpu6050的makefile举例 

二、A9主框架

主要是数据上传这部分的程序

#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");
	bzero (shm_buf, sizeof (struct shm_addr));
	while(1){
		sem_p(semid,0); //P����
		shm_buf->shm_status = 1;
		int home_id = 1;
#if 1
		shm_buf->sm_all_env_info.monitor_no[home_id] = sm_all_env_info.monitor_no[home_id];  //��ʵ�����ϴ�
#else
		file_env_info_struct(&shm_buf->sm_all_env_info,shm_buf->shm_status); //ģ�������ϴ�
#endif 
		sleep(1);
		sem_v(semid,0); //v����
		pthread_cond_signal(&cond_transfer);
	}


}



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;

	//����stm32���ֵ����ݡ�arduino���ݣ�

	return 0;
}
#include "data_global.h"
#include "common.h"
#include "mpu6050.h"
#include <strings.h>

//����ZigBee�����ݺͲɼ���A9ƽ̨�Ĵ���������
int adc_fd;
int mpu_fd;

extern pthread_cond_t cond_transfer;
extern pthread_mutex_t mutex_transfer;
extern struct env_info_client_addr  sm_all_env_info;

int file_env_info_a9_zigbee_debug(struct env_info_client_addr *rt_status,int home_id);
int file_env_info_a9_zigbee_stm32(struct env_info_client_addr *rt_status,int home_id);

int printf_sensor_info_debug(struct env_info_client_addr  *sm_all_env_info,int home_id);

void *pthread_transfer(void *arg)
{
	int home_id = 1;
	adc_fd = open(ADC_DEV,O_RDWR);
	mpu_fd = open(MPU6050_DEV,O_RDWR);
	if((adc_fd == -1) || (mpu_fd == -1)){
		printf("open adc or mpu device failed.\n");
	}
	while(1){
		pthread_mutex_lock(&mutex_transfer);
		pthread_cond_wait(&cond_transfer,&mutex_transfer);
		printf("pthread_analysis and tranfer.\n");
#if 1
		file_env_info_a9_zigbee_stm32(&sm_all_env_info,home_id);
#else	
		file_env_info_a9_zigbee_debug(&sm_all_env_info,home_id);
#endif
		pthread_mutex_unlock(&mutex_transfer);
		sleep(1);
	}
	close(adc_fd);
	close(mpu_fd);
}




int file_env_info_a9_zigbee_debug(struct env_info_client_addr *rt_status,int home_id)
{
	static int temp = 0;
	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;

	temp ++;
	rt_status->monitor_no[home_id].a9_info.adc  = temp;
	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;
		
	printf_sensor_info_debug(rt_status,home_id);

	//����stm32���ֵ����ݡ�arduino���ݣ�
	
	return 0;
}


#if 0
int	get_sensor_data_from_a9(struct makeru_a9_info* a9_sensor_data)
{
	int adc_sensor_data;
	struct mpu6050_data data;

	/*get adc sensor data*/
	read(adc_fd,&adc_sensor_data,4); 
	printf("adc value :%0.2fV.\n",(1.8*adc_sensor_data)/4096);  

	/* get mpu6050 sensor data*/
	ioctl(mpu_fd,MPU6050_GYRO,&data);
	printf("gyro data: x = %05d, y = %05d, z = %05d\n", data.gyro.x,data.gyro.y,data.gyro.z);
	ioctl(mpu_fd,MPU6050_ACCEL,&data);
	printf("accel data: x = %05d, y = %05d, z = %05d\n", data.accel.x,data.accel.y,data.accel.z);

	/*Ԥ���䣬�е��˷ѿռ䣬���ҿ����Ż�һ��*/
	a9_sensor_data->adc = (1.8 * adc_sensor_data)/4096 * 100; //����δint32,Ӧ����float,�Ŵ�100��������С��λ
	a9_sensor_data->gyrox = data.gyro.x;
	a9_sensor_data->gyroy = data.gyro.y;
	a9_sensor_data->gyroz = data.gyro.z;
	a9_sensor_data->aacx  = data.accel.x;
	a9_sensor_data->aacy  = data.accel.y;
	a9_sensor_data->aacz  = data.accel.z;

	return 0;
}
#endif 


int file_env_info_a9_zigbee_stm32(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.head[0]  = 'm';
	rt_status->monitor_no[home_id].zigbee_info.head[1]  = 's';
	rt_status->monitor_no[home_id].zigbee_info.head[2]  = 'm';
	rt_status->monitor_no[home_id].zigbee_info.head[3]  = 'z';
	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;

	//��ȡ����     
	int adc_sensor_data;
	struct mpu6050_data data;
	/*get adc sensor data*/
	read(adc_fd,&adc_sensor_data,4); /*�����������������Ǽ��������ˣ�ͬ־��Ҫע����......*/
	//printf("adc value :%0.2fV.\n",(1.8*adc_sensor_data)/4096);  
	rt_status->monitor_no[home_id].a9_info.adc    = (float)((1.8*adc_sensor_data)/4096);
	
	/* get mpu6050 sensor data*/
	ioctl(mpu_fd,MPU6050_GYRO,&data);
	//printf("gyro data: x = %d, y = %d, z = %d\n", data.gyro.x,data.gyro.y,data.gyro.z);
	ioctl(mpu_fd,MPU6050_ACCEL,&data);
	//printf("accel data: x = %d, y = %d, z = %d\n", data.accel.x,data.accel.y,data.accel.z);
	
	rt_status->monitor_no[home_id].a9_info.head[0]  = 'm';
	rt_status->monitor_no[home_id].a9_info.head[1]  = 's';
	rt_status->monitor_no[home_id].a9_info.head[2]  = 'm';
	rt_status->monitor_no[home_id].a9_info.head[3]  = 'a';

	rt_status->monitor_no[home_id].a9_info.gyrox  =  (short)data.gyro.x;
	rt_status->monitor_no[home_id].a9_info.gyroy  =  (short)data.gyro.y;
	rt_status->monitor_no[home_id].a9_info.gyroz  =  (short)data.gyro.z;

	rt_status->monitor_no[home_id].a9_info.aacx   =  (short)data.accel.x;
	rt_status->monitor_no[home_id].a9_info.aacy   =  (short)data.accel.y;
	rt_status->monitor_no[home_id].a9_info.aacz   =  (short)data.accel.z;
	rt_status->monitor_no[home_id].a9_info.reserved[0]  = 0.01;
	rt_status->monitor_no[home_id].a9_info.reserved[1]  = -0.01;

	//printf_sensor_info_debug(rt_status,home_id);
	
	//����stm32���ֵ����ݡ�arduino���ݣ�

	return 0;
}


int printf_sensor_info_debug(struct env_info_client_addr  *sm_all_env_info,int home_id)
{
	printf("a9_info.adc  : %f.\n",sm_all_env_info->monitor_no[home_id].a9_info.adc  );
	printf("a9_info.gyrox: %d.\n",sm_all_env_info->monitor_no[home_id].a9_info.gyrox);
	printf("a9_info.gyroy: %d.\n",sm_all_env_info->monitor_no[home_id].a9_info.gyroy);
	printf("a9_info.gyroz: %d.\n",sm_all_env_info->monitor_no[home_id].a9_info.gyroz);
	printf("a9_info.aacx : %d.\n",sm_all_env_info->monitor_no[home_id].a9_info.aacx );
	printf("a9_info.aacy : %d.\n",sm_all_env_info->monitor_no[home_id].a9_info.aacy );
	printf("a9_info.aacz : %d.\n",sm_all_env_info->monitor_no[home_id].a9_info.aacz );
	printf("a9_info.reserved[0]: %d.\n",sm_all_env_info->monitor_no[home_id].a9_info.reserved[0] );
	printf("a9_info.reserved[1]: %d.\n",sm_all_env_info->monitor_no[home_id].a9_info.reserved[1] );

	return 0;
}

三、脚本及数据上传实验

写一个插入模块的脚本

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/660.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

web实现太极八卦图、旋转动画、定位、角度、坐标、html、css、JavaScript、animation

文章目录前言1、html部分2、css部分3、JavaScript部分4、微信小程序演示前言 哈哈 1、html部分 <div class"great_ultimate_eight_diagrams_box"><div class"eight_diagrams_box"><div class"eight_diagrams"><div class&…

SpringBoot-实用开发篇

SpringBoot开发实用篇开发实用篇中因为牵扯到SpringBoot整合各种各样的技术&#xff0c;所以在整合每一个技术之前&#xff0c;都会做一个快速的普及&#xff0c;这样的话内容整个开发实用篇所包含的内容就会比较多。在学习的时候&#xff0c;如果对某一个技术不是很清楚&#…

硬刚ChatGPT!文心一言能否为百度止颓?中国版ChatGPT“狂飙”的机会在哪儿?

文章目录目录产品背景发展历程科技简介主要功能合作伙伴结语文心一言 &#xff08;英文名&#xff1a;ERNIE Bot&#xff09; *是百度基于文心大模型技术推出的生成式对话产品&#xff0c;被外界誉为“中国版ChatGPT”&#xff0c;将于2023年3月份面向公众开放。 [40] 百度在人…

python自动化办公(二)

上接python自动化办公&#xff08;一&#xff09; 文章目录文件和目录操作使用shutil库文件查找globfnmatchhashlib文件和目录操作 使用shutil库 shutil库也是Python标准库&#xff0c;它可以处理文件、文件夹、压缩包&#xff0c;能实现文件复制、移动、压缩、解压缩等功能。…

Vue基础23之路由第二节

Vue基础23路由路由的query参数src/router/index.jsDetail.vueHomeMessage.vue路由的query参数命名路由src/router/index.jsHomeMessage.vueApp.vue总结路由的params参数src/router/index.jsHomeMessage.vueDetail.vue总结路由 路由的query参数 src/router/index.js //该文件专…

Gehpi的网络布局

Gehpi的网络布局1. 力引导布局2. 辅助布局布局是网络可视化中的重要概念&#xff0c;指将点和边通过某种策略进行排布&#xff0c;应尽可能满足以下4个原则&#xff1a; 节点均匀分布在有限的区域内避免边的交叉和弯曲保持边的长度一致整体布局能反映图内在的特性 Gephi的布局…

卷积神经网络

目录卷积神经网络概述神经网络原理卷积神经网络卷积层怎么控制输出数据&#xff1f;如何抓取特征池化层归一化层全连接层局部感受野权值共享多卷积核池化子采样多卷积层卷积神经网络的训练前向传播BackForward反向传播权值更新过程中的卷积网络结构层的排列规律层的尺寸设置规律…

web3:区块链共识机制系列-POS(Proof of Stake)股权证明算法

web3相关学习一并收录至该博客&#xff1a;web3学习博客目录大全 前情衔接&#xff1a;web3:区块链常见的几大共识机制及优缺点 目录前言算法公式与原理算法公式运作原理以Peer Coin为例缺陷优点缺点特点分类发展历程casper协议1.什么是无成本利益关系问题2.引入casper协议解决…

SpringBoot 动态操作定时任务(启动、停止、修改执行周期)增强版

前段时间编写了一篇博客SpringBoot 动态操作定时任务&#xff08;启动、停止、修改执行周期&#xff0c;该篇博客还是帮助了很多同学。 但是该篇博客中的方法有些不足的地方&#xff1a; 只能通过前端控制器controller手动注册任务。【具体的应该是我们提前配置好我们的任务&am…

selenium(4)-------自动化测试脚本(python)

webdriverAPI 一)定位元素的方式&#xff0c;必问 1.1)id来定位元素&#xff0c;前提是元素必须具有id属性&#xff0c;因为有的元素是没有id的 1.2)name&#xff0c;元素必须有name&#xff0c;并且必须全局唯一 1.3)tagname&#xff0c;元素是一定有的&#xff0c;但是必须全…

HTTP 缓存的工作原理

缓存是解决http1.1当中的性能问题主要手段。缓存可能存在于客户端浏览器上&#xff0c;也可以存在服务器上面&#xff0c;当使用过期缓存可能给用户展示的是错误的信息而导致一些bug。 HTTP 缓存&#xff1a;为当前请求复用前请求的响应 • 目标&#xff1a;减少时延&#xff1…

Python+Yolov8目标识别特征检测

Yolov8目标识别特征检测如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01;前言这篇博客针对<<Yolov8目标识别特征检测>>编写代码&#xff0c;代码整洁&#xff0c;规则&#xff0c;易读。 学习与应用推荐…

3分钟看完-丄-Python自动化测试【项目实战解析】经验分享

目录&#xff1a;导读 引言 自动化测试 背景 测试团队 测试体系发展 测试平台 自动化测试现状 现状一&#xff1a; 现状二&#xff1a; 现状三&#xff1a; 现状四&#xff1a; 现状五&#xff1a; 现状六&#xff1a; 失败的背景 失败的经历 失败总结 引言 内…

Java多线程系列--synchronized的原理

原文网址&#xff1a;Java多线程系列--synchronized的原理_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Java的synchronized的原理。 反编译出字节码 Test.java public class Test {private static Object LOCK new Object();public static int main(String[] args) {synchro…

动态矢量瓦片缓存库方案

目录 前言 二、实现步骤 1.将数据写入postgis数据库 2.将矢量瓦片数据写入缓存库 3.瓦片接口实现 4.瓦片局部更新接口实现 总结 前言 矢量瓦片作为webgis目前最优秀的数据格式&#xff0c;其主要特点就是解决了大批量数据在前端渲染时出现加载缓慢、卡顿的问题&#xff0…

LeetCode 112. 路径总和

LeetCode 112. 路径总和 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 叶…

Python笔记 -- 文件和异常

文章目录1、文件1.1、with关键字1.2、逐行读取1.3、写入模式1.4、多行写入2、异常2.1、try-except-else2.2、pass1、文件 1.1、with关键字 with关键字用于自动管理资源 使用with可以让python在合适的时候释放资源 python会将文本解读为字符串 # -*- encoding:utf-8 -*- # 如…

Linux操作系统基础的常用命令

1&#xff0c;Linux简介Linux是一种自由和开放源码的操作系统&#xff0c;存在着许多不同的Linux版本&#xff0c;但它们都使用了Linux内核。Linux可安装在各种计算机硬件设备中&#xff0c;比如手机、平板电脑、路由器、台式计算机。1.1Linux介绍Linux出现于1991年&#xff0c…

操作技巧 | 在Revit中借用CAD填充图案的方法

在建模过程中&#xff0c;有时需要达到多种填充效果&#xff0c;而CAD中大量的二维填充图案&#xff0c;便是最直接的资源之一。 使用 填充图案之前 使用 填充图案之后 其中要用到主要命令便是对表面填充图案的添加与编辑 简单效果 如下 模型填充与绘图填充 区别 模型填…

Java for循环嵌套for循环,你需要懂的代码性能优化技巧

前言 本篇分析的技巧点其实是比较常见的&#xff0c;但是最近的几次的代码评审还是发现有不少兄弟没注意到。 所以还是想拿出来说下。 正文 是个什么场景呢&#xff1f; 就是 for循环 里面还有 for循环&#xff0c; 然后做一些数据匹配、处理 这种场景。 我们结合实例代码来…
最新文章