当前位置: 首页 > news >正文

IIC总线式驱动开发(mpu6050)(二)

目录

六、I2C总线二级外设驱动开发方法

七、I2C总线二级外设驱动开发之名称匹配

1. i2c_register_board_info

2. i2c_new_device:明确二级外设地址的情况下可用

3. i2c_new_probed_device

八、I2C总线二级外设驱动开发之设备树匹配


六、I2C总线二级外设驱动开发方法

1. 查阅原理图以便得知二级外设挂在哪条I2C总线上、二级外设的身份标识(二级外设自身的地址)

2. 参照platform样式搭建二级外设驱动框架

3. 查询二级外设芯片手册以便得知驱动需要用到的寄存器地址

   注意:

(1) 此处寄存器是指二级外设内部的寄存器,每个寄存器在芯片手册里有个对应编号(也被称为地址),但不是内存地址,特别提醒此寄存器不是SOC芯片内部参与内存统一编址的寄存器,更不是ARM核-CPU的寄存器

(2)通过调用i2c_tranfer函数完成与相应寄存器的数据交互

4. 参照字符驱动完成其余代码编写

5. 创建对应的i2c_client对象

   linux-3.14\Documentation\i2c\instantiating-devices

   匹配方式:

   

   1. 名称匹配(id和name差不多)

   

   2. 设备树匹配

   

   3. ACPI匹配

   

      Advanced Configuration and Power Management Interface 高级配置和电源管理接口

      PC机平台采用的一种硬件配置接口

(咱们是arm平台这种方式用不了)

i2c二级外设驱动框架:

```c//其它struct file_operations函数实现原理同硬编驱动static int mpu6050_probe(struct i2c_client *pclt,const struct i2c_device_id *pid){//做硬编驱动模块入口函数的活}static int mpu6050_remove(struct i2c_client *pclt){//做硬编驱动模块出口函数的活}/*名称匹配时定义struct i2c_device_id数组*/static struct i2c_device_id mpu6050_ids ={{"mpu6050",0},//.....{}};/*设备树匹配时定义struct of_device_id数组*/static struct of_device_id mpu6050_dts ={{.compatible = "invensense,mpu6050"},//....{}};/*通过定义struct i2c_driver类型的全局变量来创建i2c_driver对象,同时对其主要成员进行初始化*/struct i2c_driver mpu6050_driver ={.driver = {.name = "mpu6050",.owner = THIS_MODULE,.of_match_table = mpu6050_dts,},.probe = mpu6050_probe,.remove = mpu6050_remove,.id_table = mpu6050_ids,};/*以下其实是个宏,展开后相当于实现了模块入口函数和模块出口函数*/module_i2c_driver(mpu6050_driver);MODULE_LICENSE("GPL");```

七、I2C总线二级外设驱动开发之名称匹配

这种匹配方式需要自己创建i2c_client对象

创建i2c_client对象有三种方式:

1. i2c_register_board_info

1.当开发板上电内核跑起来的时候,肯定是架构相关的程序首先运行,也就是mach-xxx.c

2. mach-xxx.c文件里首先会定义i2c_board_info的结构体数组,在mach-xxx.c的初始化函数里调用i2c_register_board_info函数把i2c_board_inifo链接进内核的i2c_board_list链表当中去

3.在驱动i2c目录下和开发板板对应的驱动文件i2c-xxx.c里,创建i2c_adapter对象

4.这种方式严重依赖平台,缺乏灵活性,基本会被遗弃

2. i2c_new_device:明确二级外设地址的情况下可用

   i2c二级外设client框架:

   ```c#include <linux/kernel.h>#include <linux/module.h>#include <linux/i2c.h>static struct i2c_board_info mpu6050_info ={I2C_BOARD_INFO("mpu6050",二级外设地址)  };static struct i2c_client *mpu6050_client;static int __init mpu6050_dev_init(void){struct i2c_adapter *padp = NULL;padp = i2c_get_adapter(i2c通道编号);mpu6050_client = i2c_new_device(padp,&mpu6050_info);i2c_put_adapter(padp);return 0;}module_init(mpu6050_dev_init);static void __exit mpu6050_dev_exit(void){i2c_unregister_device(mpu6050_client);}module_exit(mpu6050_dev_exit);MODULE_LICENSE("GPL");```

3. i2c_new_probed_device

   i2c二级外设client框架:不明确二级外设地址,但是知道是可能几个值之一的情况下可用



```c#include <linux/kernel.h>#include <linux/module.h>#include <linux/i2c.h>static const unsigned short addr_list[] ={0x68,//.....I2C_CLIENT_END};static struct i2c_client *mpu6050_client;static int __init mpu6050_dev_init(void){struct i2c_adapter *padp = NULL;struct i2c_board_info mpu6050_info = {""};strcpy(mpu6050_info.type,"mpu6050");padp = i2c_get_adapter(i2c通道编号);mpu6050_client = i2c_new_probed_device(padp,&mpu6050_info,addr_list,NULL);i2c_put_adapter(padp);if(mpu6050_client != NULL){return 0;}else{return -ENODEV;}}module_init(mpu6050_dev_init);static void __exit mpu6050_dev_exit(void){i2c_unregister_device(mpu6050_client);}module_exit(mpu6050_dev_exit);MODULE_LICENSE("GPL");```

 mpu6050_client.c

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>static struct i2c_board_info mpu6050_info = 
{I2C_BOARD_INFO("mpu6050",0x68)
};static struct i2c_client *gpmpu6050_client = NULL;static int __init mpu6050_client_init(void)
{struct i2c_adapter *padp = NULL;padp = i2c_get_adapter(5);gpmpu6050_client = i2c_new_device(padp,&mpu6050_info);i2c_put_adapter(padp);return 0;
}static void  mpu6050_client_exit(void)
{i2c_unregister_device(gpmpu6050_client);
}module_init(mpu6050_client_init);
module_exit(mpu6050_client_exit);
MODULE_LICENSE("GPL");

 mpu6050_drv.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/i2c.h>
#include <linux/cdev.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>#include "mpu6050.h"#define SMPLRT_DIV 0x19
#define CONFIG 0x1A
#define GYRO_CONFIG 0x1B
#define ACCEL_CONFIG 0x1C#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48#define PWR_MGMT_1  0x6Bint major = 11;
int minor = 0;
int mpu6050_num  = 1;struct mpu6050_dev
{struct cdev mydev;struct i2c_client *pclt;};struct mpu6050_dev *pgmydev = NULL;int mpu6050_read_byte(struct i2c_client *pclt,unsigned char reg)
{int ret = 0;char txbuf[1] = {reg};char rxbuf[1] = {0};struct i2c_msg msg[2] = {{pclt->addr,0,1,txbuf},{pclt->addr,I2C_M_RD,1,rxbuf}};ret = i2c_transfer(pclt->adapter,msg,ARRAY_SIZE(msg));if(ret < 0){printk("ret = %d,in mpu6050_read_byte\n",ret);return ret;}return rxbuf[0];
}int mpu6050_write_byte(struct i2c_client *pclt,unsigned char reg,unsigned char val)
{int ret = 0;char txbuf[2] = {reg,val};struct i2c_msg msg[1] = {{pclt->addr,0,2,txbuf},};ret = i2c_transfer(pclt->adapter,msg,ARRAY_SIZE(msg));if(ret < 0){printk("ret = %d,in mpu6050_write_byte\n",ret);return ret;}return 0;
}int mpu6050_open(struct inode *pnode,struct file *pfile)
{pfile->private_data =(void *) (container_of(pnode->i_cdev,struct mpu6050_dev,mydev));return 0;
}int mpu6050_close(struct inode *pnode,struct file *pfile)
{return 0;
}long mpu6050_ioctl(struct file *pfile,unsigned int cmd,unsigned long arg)
{struct mpu6050_dev *pmydev = (struct mpu6050_dev *)pfile->private_data;union mpu6050_data data;switch(cmd){case GET_ACCEL:data.accel.x = mpu6050_read_byte(pmydev->pclt,ACCEL_XOUT_L);data.accel.x |= mpu6050_read_byte(pmydev->pclt,ACCEL_XOUT_H) << 8;data.accel.y = mpu6050_read_byte(pmydev->pclt,ACCEL_YOUT_L);data.accel.y |= mpu6050_read_byte(pmydev->pclt,ACCEL_YOUT_H) << 8;data.accel.z = mpu6050_read_byte(pmydev->pclt,ACCEL_ZOUT_L);data.accel.z |= mpu6050_read_byte(pmydev->pclt,ACCEL_ZOUT_H) << 8;break;case GET_GYRO:data.gyro.x = mpu6050_read_byte(pmydev->pclt,GYRO_XOUT_L);data.gyro.x |= mpu6050_read_byte(pmydev->pclt,GYRO_XOUT_H) << 8;data.gyro.y = mpu6050_read_byte(pmydev->pclt,GYRO_YOUT_L);data.gyro.y |= mpu6050_read_byte(pmydev->pclt,GYRO_YOUT_H) << 8;data.gyro.z = mpu6050_read_byte(pmydev->pclt,GYRO_ZOUT_L);data.gyro.z |= mpu6050_read_byte(pmydev->pclt,GYRO_ZOUT_H) << 8;break;case GET_TEMP:data.temp = mpu6050_read_byte(pmydev->pclt,TEMP_OUT_L);data.temp |= mpu6050_read_byte(pmydev->pclt,TEMP_OUT_H) << 8;break;default:return -EINVAL;}if(copy_to_user((void *)arg,&data,sizeof(data))){return -EFAULT;}return sizeof(data);
}void init_mpu6050(struct i2c_client *pclt)
{mpu6050_write_byte(pclt,PWR_MGMT_1,0x00);mpu6050_write_byte(pclt,SMPLRT_DIV,0x07);mpu6050_write_byte(pclt,CONFIG,0x06);mpu6050_write_byte(pclt,GYRO_CONFIG,0xF8);mpu6050_write_byte(pclt,ACCEL_CONFIG,0x19);
}struct file_operations myops = {.owner = THIS_MODULE,.open = mpu6050_open,.release = mpu6050_close,.unlocked_ioctl = mpu6050_ioctl,
};static int mpu6050_probe(struct i2c_client *pclt,const struct i2c_device_id *pid)
{int ret = 0;dev_t devno = MKDEV(major,minor);/*申请设备号*/ret = register_chrdev_region(devno,mpu6050_num,"mpu6050");if(ret){ret = alloc_chrdev_region(&devno,minor,mpu6050_num,"mpu6050");if(ret){printk("get devno failed\n");return -1;}major = MAJOR(devno);//容易遗漏,注意}pgmydev = (struct mpu6050_dev *)kmalloc(sizeof(struct mpu6050_dev),GFP_KERNEL);if(NULL == pgmydev){unregister_chrdev_region(devno,mpu6050_num);printk("kmalloc failed\n");return -1;}memset(pgmydev,0,sizeof(struct mpu6050_dev));pgmydev->pclt = pclt;/*给struct cdev对象指定操作函数集*/	cdev_init(&pgmydev->mydev,&myops);/*将struct cdev对象添加到内核对应的数据结构里*/pgmydev->mydev.owner = THIS_MODULE;cdev_add(&pgmydev->mydev,devno,mpu6050_num);init_mpu6050(pgmydev->pclt);return 0;
}static int mpu6050_remove(struct i2c_client *pclt)
{dev_t devno = MKDEV(major,minor);cdev_del(&pgmydev->mydev);unregister_chrdev_region(devno,mpu6050_num);kfree(pgmydev);pgmydev = NULL;return 0;
}struct i2c_device_id mpu6050_ids[] = 
{{"mpu6050",0},{}
};struct i2c_driver mpu6050_driver = 
{.driver = {.name = "mpu6050",.owner = THIS_MODULE,},.probe = mpu6050_probe,.remove = mpu6050_remove,.id_table = mpu6050_ids,
};#if 0
int __init mpu6050_driver_init(void)
{i2c_add_driver(&mpu6050_driver);
}void __exit mpu6050_driver_exit(void)
{i2c_del_driver(&mpu6050_driver);
}
module_init(mpu6050_driver_init);
module_exit(mpu6050_driver_exit);
#else
module_i2c_driver(mpu6050_driver);
#endifMODULE_LICENSE("GPL");

#ifndef MPU_6050_H
#define MPU_6050_Hstruct accel_data
{unsigned short x;unsigned short y;unsigned short z;
};
struct gyro_data
{unsigned short x;unsigned short y;unsigned short z;
};union mpu6050_data
{struct accel_data accel;struct gyro_data gyro;unsigned short temp;
};#define MPU6050_MAGIC 'K'#define GET_ACCEL _IOR(MPU6050_MAGIC,0,union mpu6050_data)
#define GET_GYRO _IOR(MPU6050_MAGIC,1,union mpu6050_data)
#define GET_TEMP _IOR(MPU6050_MAGIC,2,union mpu6050_data)#endif

使用probed也行

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>static unsigned short mpu6050_addr_list[] = 
{0x68,0x69,I2C_CLIENT_END
};static struct i2c_client *gpmpu6050_client = NULL;static int __init mpu6050_client_init(void)
{struct i2c_adapter *padp = NULL;struct i2c_board_info mpu6050_info = {""};strcpy(mpu6050_info.type,"mpu6050");padp = i2c_get_adapter(5);gpmpu6050_client = i2c_new_probed_device(padp,&mpu6050_info,mpu6050_addr_list,NULL);i2c_put_adapter(padp);if(gpmpu6050_client != NULL){return 0;}else{return -ENODEV;}
}static void  mpu6050_client_exit(void)
{i2c_unregister_device(gpmpu6050_client);
}module_init(mpu6050_client_init);
module_exit(mpu6050_client_exit);
MODULE_LICENSE("GPL");

 测试用的APP

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>#include <stdio.h>#include "mpu6050.h"int main(int argc,char *argv[])
{int fd = -1;union mpu6050_data data;if(argc < 2){printf("The argument is too few\n");return 1;}fd = open(argv[1],O_RDONLY);if(fd < 0){printf("open %s failed \n",argv[1]);return 2;}while(1){sleep(2);ioctl(fd,GET_ACCEL,&data);printf("Accel-x=0x%x\n",data.accel.x);printf("Accel-y=0x%x\n",data.accel.y);printf("Accel-z=0x%x\n",data.accel.z);ioctl(fd,GET_GYRO,&data);printf("Gyro-x=0x%x\n",data.gyro.x);printf("Gyro-y=0x%x\n",data.gyro.y);printf("Gyro-z=0x%x\n",data.gyro.z);ioctl(fd,GET_TEMP,&data);printf("Temp=0x%x\n",data.temp);printf("\n");}close(fd);fd = -1;return 0;
}

八、I2C总线二级外设驱动开发之设备树匹配

 0x68是从设备号,interrupt是中断

IIC的实现和前面LED不太一样那个使用设备树匹配不需要ip   IIC需要有一个IP。

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/i2c.h>
#include <linux/cdev.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>#include "mpu6050.h"#define SMPLRT_DIV 0x19
#define CONFIG 0x1A
#define GYRO_CONFIG 0x1B
#define ACCEL_CONFIG 0x1C#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48#define PWR_MGMT_1  0x6Bint major = 11;
int minor = 0;
int mpu6050_num  = 1;struct mpu6050_dev
{struct cdev mydev;struct i2c_client *pclt;};struct mpu6050_dev *pgmydev = NULL;int mpu6050_read_byte(struct i2c_client *pclt,unsigned char reg)
{int ret = 0;char txbuf[1] = {reg};char rxbuf[1] = {0};struct i2c_msg msg[2] = {{pclt->addr,0,1,txbuf},{pclt->addr,I2C_M_RD,1,rxbuf}};ret = i2c_transfer(pclt->adapter,msg,ARRAY_SIZE(msg));if(ret < 0){printk("ret = %d,in mpu6050_read_byte\n",ret);return ret;}return rxbuf[0];
}int mpu6050_write_byte(struct i2c_client *pclt,unsigned char reg,unsigned char val)
{int ret = 0;char txbuf[2] = {reg,val};struct i2c_msg msg[1] = {{pclt->addr,0,2,txbuf},};ret = i2c_transfer(pclt->adapter,msg,ARRAY_SIZE(msg));if(ret < 0){printk("ret = %d,in mpu6050_write_byte\n",ret);return ret;}return 0;
}int mpu6050_open(struct inode *pnode,struct file *pfile)
{pfile->private_data =(void *) (container_of(pnode->i_cdev,struct mpu6050_dev,mydev));return 0;
}int mpu6050_close(struct inode *pnode,struct file *pfile)
{return 0;
}long mpu6050_ioctl(struct file *pfile,unsigned int cmd,unsigned long arg)
{struct mpu6050_dev *pmydev = (struct mpu6050_dev *)pfile->private_data;union mpu6050_data data;switch(cmd){case GET_ACCEL:data.accel.x = mpu6050_read_byte(pmydev->pclt,ACCEL_XOUT_L);data.accel.x |= mpu6050_read_byte(pmydev->pclt,ACCEL_XOUT_H) << 8;data.accel.y = mpu6050_read_byte(pmydev->pclt,ACCEL_YOUT_L);data.accel.y |= mpu6050_read_byte(pmydev->pclt,ACCEL_YOUT_H) << 8;data.accel.z = mpu6050_read_byte(pmydev->pclt,ACCEL_ZOUT_L);data.accel.z |= mpu6050_read_byte(pmydev->pclt,ACCEL_ZOUT_H) << 8;break;case GET_GYRO:data.gyro.x = mpu6050_read_byte(pmydev->pclt,GYRO_XOUT_L);data.gyro.x |= mpu6050_read_byte(pmydev->pclt,GYRO_XOUT_H) << 8;data.gyro.y = mpu6050_read_byte(pmydev->pclt,GYRO_YOUT_L);data.gyro.y |= mpu6050_read_byte(pmydev->pclt,GYRO_YOUT_H) << 8;data.gyro.z = mpu6050_read_byte(pmydev->pclt,GYRO_ZOUT_L);data.gyro.z |= mpu6050_read_byte(pmydev->pclt,GYRO_ZOUT_H) << 8;break;case GET_TEMP:data.temp = mpu6050_read_byte(pmydev->pclt,TEMP_OUT_L);data.temp |= mpu6050_read_byte(pmydev->pclt,TEMP_OUT_H) << 8;break;default:return -EINVAL;}if(copy_to_user((void *)arg,&data,sizeof(data))){return -EFAULT;}return sizeof(data);
}void init_mpu6050(struct i2c_client *pclt)
{mpu6050_write_byte(pclt,PWR_MGMT_1,0x00);mpu6050_write_byte(pclt,SMPLRT_DIV,0x07);mpu6050_write_byte(pclt,CONFIG,0x06);mpu6050_write_byte(pclt,GYRO_CONFIG,0xF8);mpu6050_write_byte(pclt,ACCEL_CONFIG,0x19);
}struct file_operations myops = {.owner = THIS_MODULE,.open = mpu6050_open,.release = mpu6050_close,.unlocked_ioctl = mpu6050_ioctl,
};static int mpu6050_probe(struct i2c_client *pclt,const struct i2c_device_id *pid)
{int ret = 0;dev_t devno = MKDEV(major,minor);/*申请设备号*/ret = register_chrdev_region(devno,mpu6050_num,"mpu6050");if(ret){ret = alloc_chrdev_region(&devno,minor,mpu6050_num,"mpu6050");if(ret){printk("get devno failed\n");return -1;}major = MAJOR(devno);//容易遗漏,注意}pgmydev = (struct mpu6050_dev *)kmalloc(sizeof(struct mpu6050_dev),GFP_KERNEL);if(NULL == pgmydev){unregister_chrdev_region(devno,mpu6050_num);printk("kmalloc failed\n");return -1;}memset(pgmydev,0,sizeof(struct mpu6050_dev));pgmydev->pclt = pclt;/*给struct cdev对象指定操作函数集*/	cdev_init(&pgmydev->mydev,&myops);/*将struct cdev对象添加到内核对应的数据结构里*/pgmydev->mydev.owner = THIS_MODULE;cdev_add(&pgmydev->mydev,devno,mpu6050_num);init_mpu6050(pgmydev->pclt);return 0;
}static int mpu6050_remove(struct i2c_client *pclt)
{dev_t devno = MKDEV(major,minor);cdev_del(&pgmydev->mydev);unregister_chrdev_region(devno,mpu6050_num);kfree(pgmydev);pgmydev = NULL;return 0;
}struct of_device_id mpu6050_dt[] = 
{{.compatible = "invensense,mpu6050"},{}
};struct i2c_device_id mpu6050_ids[] = 
{{"mpu6050",0},{}
};struct i2c_driver mpu6050_driver = 
{.driver = {.name = "mpu6050",.owner = THIS_MODULE,.of_match_table = mpu6050_dt,},.probe = mpu6050_probe,.remove = mpu6050_remove,.id_table = mpu6050_ids,
};#if 0
int __init mpu6050_driver_init(void)
{i2c_add_driver(&mpu6050_driver);
}void __exit mpu6050_driver_exit(void)
{i2c_del_driver(&mpu6050_driver);
}
module_init(mpu6050_driver_init);
module_exit(mpu6050_driver_exit);
#else
module_i2c_driver(mpu6050_driver);
#endifMODULE_LICENSE("GPL");

 测试程序和.h程序和上面一样。

相关文章:

IIC总线式驱动开发(mpu6050)(二)

目录 六、I2C总线二级外设驱动开发方法 七、I2C总线二级外设驱动开发之名称匹配 1. i2c_register_board_info 2. i2c_new_device&#xff1a;明确二级外设地址的情况下可用 3. i2c_new_probed_device 八、I2C总线二级外设驱动开发之设备树匹配 六、I2C总线二级外设驱动开…...

盘点一下那些远程办公的神仙公司

其实远程办公已经有50多年的历史了&#xff0c;这几年&#xff0c;这种工作方式越来越受到大家的喜欢&#xff0c;对于员工来说&#xff0c;工作效率可以大幅提高&#xff0c;节省下来的通勤时间和成本&#xff0c;有更多的时间花在工作上。可以更好的平衡工作与生活。对于公司…...

Spring Cloud Alibaba全家桶(四)——微服务调用组件Feign

前言 本文小新为大家带来 微服务调用组件Feign 的相关知识&#xff0c;具体内容包含什么是Feign&#xff0c;Spring Cloud Alibaba快速整合OpenFeign&#xff0c;Spring Cloud Feign的自定义配置及使用&#xff08;包括&#xff1a;日志配置、契约配置、自定义拦截器实现认证逻…...

安装pytorch

一、在anaconda中创建虚拟环境 打开Anaconda Prompt创建一个虚拟环境。比如要创建一个名字为pytorch的虚拟环境&#xff0c;可以如下输入。其中python3.7指定该虚拟环境的python版本号。 conda create -n pytorch python3.7 二、进入新创建的虚拟环境。 创建好虚拟环境后&a…...

自动化测试 Appium之Python运行环境搭建 Part2

环境部署 1、安装Android SDK 安装好后&#xff0c;配置ANDROID_HOME环境变量&#xff0c;设置为Android SDK安装路径(例中&#xff1a;D:\Program Files (x86)\Android\android-sdk) 2、安装其它SDK相关软件包 安装好Android SDK后&#xff0c;选择打开Android SDK Manager…...

LeetCode 2 - 两数相加

给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都不会以 0 开…...

用Python实现九九乘法表的几种方式,最简单只需一行代码

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 我们在学习Python的过程中需要不断的积累和练习&#xff0c;这样才能够走的更远&#xff0c; 今天一起来学习怎么用Python写九九乘法表~ 更多教程源码资料电子书: 点击此处跳转文末名片获取 第一种方法、for-for 代码&…...

入职外包三个月,我提桶跑路了

有一种打工人的羡慕&#xff0c;叫做“大厂”。 真是年少不知大厂香&#xff0c;错把青春插稻秧。 但是&#xff0c;在深圳有一群比大厂员工更庞大的群体&#xff0c;他们顶着大厂的“名”&#xff0c;做着大厂的工作&#xff0c;还可以享受大厂的伙食&#xff0c;却没有大厂…...

企业邮箱对企业有哪些好处以及便捷性

企业邮箱拥有更专业的办公功能&#xff0c;更适合职场使用。同时&#xff0c;使用企业邮箱还可以帮助企业“公私分明”。一方面保护了公司信息&#xff0c;另一方面也提高了工作效率。加上公司统一邮箱也有助于提升公司形象。使用企业邮箱除了收发邮件方便外&#xff0c;还可以…...

ConvNeXt V2实战:使用ConvNeXt V2实现图像分类任务(一)

文章目录摘要安装包安装timm安装 grad-cam数据增强Cutout和MixupEMA项目结构计算mean和std生成数据集关于不上分的问题摘要 论文&#xff1a;https://arxiv.org/pdf/2301.00808.pdf 论文翻译&#xff1a;https://wanghao.blog.csdn.net/article/details/128541957 官方源码&am…...

3.2 报错整理

报错1&#xff1a; 报错&#xff1a;RuntimeError: DataLoader worker (pid 93789) is killed by signal: Killed.原因&#xff1a;显存不够报错2&#xff1a; 报错&#xff1a;TqdmWarning: IProgress not found. Please update jupyter and ipywidgets.解决&#xff1a;pip i…...

从0开始学python -46

Python CGI编程 什么是CGI CGI 目前由NCSA维护&#xff0c;NCSA定义CGI如下&#xff1a; CGI(Common Gateway Interface),通用网关接口,它是一段程序,运行在服务器上如&#xff1a;HTTP服务器&#xff0c;提供同客户端HTML页面的接口。 网页浏览 为了更好的了解CGI是如何工作…...

JavaScript事件委托机制详解

一、什么是事件委托机制 事件委托机制就是&#xff1a;我们给元素添加click事件时不在该元素上添加&#xff0c;而是委托给某个公共的祖辈元素&#xff0c;告诉祖辈元素如果接收到了click事件&#xff0c;并且这个click事件是由该元素触发的&#xff0c;就执行祖辈元素上委托绑…...

【项目实战】MySQL中union和union all的相同点与不同点

一、union和union all的相同点 在MySQL中&#xff0c;Union和Union All都是用来合并两个或者多个查询结果集的关键字 二、union和union all的不同点 union复杂&#xff0c;union all简单 2.1 自动压缩&#xff0c;自动求并集、去重、排序操作 &#xff08;1&#xff09;unio…...

ChatGPT最牛应用,让它帮你更新网站新闻吧!

谁能想到&#xff0c;ChatGPT火了&#xff01;既能对话入流&#xff0c;又能写诗歌论文、出面试题、编代码&#xff0c;甚至还通过了谷歌面试拿到L3工程师offer&#xff0c;放在一年之前&#xff0c;没人相信这是当前AI能够达到的水平。ChatGPT自面世以来&#xff0c;凭借其极为…...

乌班图安装kvm并配置网络

乌班图22安装KVM 1.安装KVM sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager virtinstsudo adduser id -un libvirt sudo adduser id -un kvm sudo apt install virtinst qemu-efi sudo systemctl enable --now libvirtd sudo s…...

蓝库云|ERP系统在企业数字化转型中最常用的八大功能

ERP系统和与企业数字化转型 随着数字化发展的兴起&#xff0c;规划和管理已成为企业产生富有成效的成果的关键。许多企业采用了企业资源规划 (ERP) 等先进工具&#xff0c;使企业所有者能够以高效的方式规划和管理其资源和运营。 ERP系统负责整合业务的不同流程并向决策者提供…...

Pytorch学习笔记#1:拟合函数/梯度下降

学习自https://pytorch.org/tutorials/beginner/pytorch_with_examples.html 概念 Pytorch Tensor在概念上和Numpy的array一样是一个nnn维向量的。不过Tensor可以在GPU中进行计算&#xff0c;且可以跟踪计算图&#xff08;computational graph&#xff09;和梯度&#xff08;…...

挑战图像处理100问(24)——伽玛校正

伽马校正&#xff08;Gamma Correction&#xff09;是一种图像处理技术&#xff0c;用于校正显示设备的非线性响应。通过对图像进行伽马变换&#xff0c;可以将图像的亮度范围映射到显示设备的亮度范围内&#xff0c;从而提高图像的对比度和细节&#xff0c;改善图像的视觉效果…...

高级信息系统项目管理师(高项)软考论文评分标准(附历年高项论文题目汇总)

1、如果您想了解如何高分通过高级信息系统项目管理师&#xff08;高项&#xff09;你可以点击一下链接&#xff1a; 高级信息系统项目管理师&#xff08;高项&#xff09;高分通过经验分享_高项经验 2、如果您想了解更多的高级信息系统项目管理(高项 软考)原创论文&#xff0…...

MySQL实战记录篇2

事务&#xff1f; 1、事务的特性&#xff1a;原子性、一致性、隔离性、持久性 &#xff08;ACID&#xff09; 2、多事务同时执行的时候&#xff0c;可能会出现的问题&#xff1a;脏读、不可重复读、幻读 3、事务隔离级别&#xff1a;读未提交、读提交、可重复读、串行化 4、不…...

C++实现AVL树

目录 一、搜索二叉树 1.1 搜索二叉树概念 二、模拟实现二叉搜索树 2.1 框架 2.2 构造函数 2.2.1 构造函数 2.2.2 拷贝构造 2.2.3 赋值拷贝 2.3 插入函数 2.3.1 insert() 2.3.2 RcInsert() 递归实现 2.4 删除结点函数 2.4.1 Erase() 2.4.2 RcErase() 2.5 中序遍历…...

高并发语言erlang编程初步

初步 下载安装与初步使用 下载并安装&#xff0c;然后开始菜单中有对应的图标&#xff0c;打开就能进入erlang的命令行。当然也可以将其安装路径的bin文件夹加入环境变量&#xff0c;然后就可以在命令行中输入erl进入erlang了。 在erlang语言中&#xff0c;语句结束需要用.标…...

springboot 问题记录

部署到Tomcat中的时候&#xff0c;找不到需要部署的项目&#xff1b; project facets severt-name severt-class安装lombok.jar eclipse添加lombok插件后闪退打不开Clean 项目&#xff0c;project clean clean的作用检查插件部署项目Springboot修改端口号&#xff1a;applica…...

【PAT甲级题解记录】1034 Head of a Gang (30 分)

【PAT甲级题解记录】1034 Head of a Gang (30 分) 前言 Problem&#xff1a;1034 Head of a Gang (30 分) Tags&#xff1a;图的遍历 连通分量统计 DFS Difficulty&#xff1a;剧情模式 想流点汗 想流点血 死而无憾 Address&#xff1a;1034 Head of a Gang (30 分) 问题描述 …...

Python搭建一个steam钓鱼网站,只要免费领游戏,一钓一个准

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 我们日常上网的时候&#xff0c;总是会碰到一些盗号的网站&#xff0c;或者是别人发一些链接给你&#xff0c; 里面的内容是一些可以免费购物网站的优惠券、游戏官网上可以免费领取皮肤、打折的游戏。 这些盗号网站统一的目…...

maven 私服nexus安装与使用

一、下载nexus Sonatype公司的一款maven私服产品 1、官网下载地址&#xff1a;https://help.sonatype.com/repomanager3/product-information/download 2、csdn下载地址&#xff1a;https://download.csdn.net/download/u010197591/87522994 二、安装与配置 1、下载后解压如…...

详解数据结构中的顺序表的手动实现,顺序表功能接口【数据结构】

文章目录线性表顺序表接口实现尾插尾删头插头删指定位置插入指定位置删除练习线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列…...

【二】kubernetes操作

k8s卸载重置 名词解释 1、Namespace&#xff1a;名称用来隔离资源&#xff0c;不隔离网络 创建名称空间 一、命名空间namesapce 方式一&#xff1a;命令行创建 kubectl create ns hello删除名称空间 kubectl delete ns hello查询指定的名称空间 kubectl get pod -n kube-s…...

如何在 C++ 中调用 python 解析器来执行 python 代码(五)?

本节研究如何对 import 做白名单 目录 如何在 C 中调用 python 解析器来执行 python 代码&#xff08;一&#xff09;&#xff1f;如何在 C 中调用 python 解析器来执行 python 代码&#xff08;二&#xff09;&#xff1f;如何在 C 中调用 python 解析器来执行 python 代码&…...

济宁正德网站建设/软文营销怎么做

一、最普通的格式&#xff0c;简单的插入一个swfswfobject.embedSWF("test.swf", "fileID", "200", "120", "9.0.0", "expressInstall.swf");参数的地址依次是&#xff1a;1、swf文件的地址&#xff1b;2、用于装…...

建设网站前的市场分析包括哪些内容/全渠道营销

华硕USB-AC55无线网卡驱动(华硕USB-AC55驱动下载)是专门针对华硕USB-AC55无线网卡最新开发的专用驱动软件。网卡无法识别&#xff1f;华硕USB-AC55无线网卡驱动(华硕USB-AC55驱动下载)为用户快速设置。主要用于解决无线网卡不能被电脑识别或者无法连接网络等问题&#xff0c;安…...

辛集哪做网站/中国万网域名查询

1. 卸载 1.1 删除ubuntu系统的分区 首先【win】【R】&#xff0c;然后输入【diskpart】&#xff0c;如下图。 输入【list disk】查看分区&#xff0c;有多个磁盘分区可分别使用【select disk 0】或者【select disk 1】&#xff0c;然后再list partition查看分区&#xff0c;其…...

谁有做那事的网站/百度网站电话是多少

Codeforces Round #829 (Div. 2) C1. Make Nonzero Sum (easy version) C2. Make Nonzero Sum (hard version) 题意&#xff1a; 对于每个样例&#xff0c;输入一个n&#xff0c;代表数组的长度&#xff0c;这个数组中的元素只有-1&#xff0c;0&#xff0c;1&#xff08;eas…...

wordpress迁移换域名/如何免费建立一个网站

Python中有一种赋值机制即多元赋值&#xff0c;采用这种方式赋值时&#xff0c;等号两边的对象都是元组并且元组的小括号是可选的。通常形式为 x, y, z 1, 2, a string 等同于 (x, y, z) (1, 2, a string) 这种赋值类型最经常用到的环境是变量交换&#xff0c;形如 x, y y,…...

网站开发的企业/网站优化有哪些类型

2016年是不同寻常的一年&#xff0c;随着科技的不断进步&#xff0c;越来越多的智能设备正在快速的进入人们的生活中&#xff0c;人类将进入人工智能&#xff0c;物联网时代&#xff0c;在这样的一个就业趋势下。2016年程序员的就业形势是怎么样的&#xff0c;相信很多的朋友一…...