为BeagleBone AI添加MPU6050加速度传感器的Linux驱动程序

【信息科学与工程学】计算机科学与自动化——第一百五十五篇 缓存系统设计06 字段详细内容编号​B1类型​PaaS + MaaS(基于微服务 + 事件溯源 + CQRS + 国产化组件:鲲鹏CPU + 昇腾GPU + TiDB + Ceph国产版 + Kafka国产版 + 东方通中间件 + 华为云CDN + WebSocket + QUIC)问题​微服务 + 事件溯源 + 鲲鹏920 + 昇腾910 + TiDB + Ceph(XSKY)+ 国产Kafka + WebSocket + QUIC 电-热-力耦合:如何支持单个超大客户(10亿注册用户,5亿日活),每秒1亿条消息 + 10 阅读详情

一、修改设备树

不要使用插件设备树更改pinmux,因为在很多板子上都无效,BeagleBone AI也不例外。首先对设备树作如下更改:

  1. 将pinmux@1400节点的cape_pins_default子节点内的CTRL_CORE_PAD_VIN1A_D20(0x4a003544 - 0x4a000000 - 0x2000 - 0x1400 = 0x00000144)、CTRL_CORE_PAD_GPIO6_15(0x4a00368C - 0x4a000000 - 0x2000 - 0x1400 = 0x0000028c)、CTRL_CORE_PAD_GPIO6_14(0x4A003688 - 0x4a000000 - 0x2000 - 0x1400 = 0x00000288)三个寄存器的值分别改为0x0001000f(PIN_OUTPUT | MUX_MODE15)、0x00060009(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE9)、0x00060009(PIN_OUTPUT_PULLUP | INPUT_EN | MUX_MODE9);
  2. 关闭AE2管脚是因为它和i2c3_sda对应的E21管脚在BeagleBone AI上是连在一起的,这个可以通过看板子的原理图和芯片的数据手册知道;
  3. 将i2c3对应的i2c@48060000节点的status属性值从"disabled"更改为"okay";
  4. 在i2c@48060000节点内添加clock-frequency = <0x00061a80>;属性,这个属性指定了i2c的速度为400kHz;
  5. 在i2c@48060000节点内添加i2c_mpu6050@68节点及其内容。

如下为更改后的am5729-beagleboneai.dts文件:

...
    ocp {
        compatible = "ti,dra7-l3-noc", "simple-bus";
        #address-cells = <0x00000001>;
        #size-cells = <0x00000001>;
        ranges = <0x00000000 0x00000000 0x00000000 0xc0000000>;
        ti,hwmods = "l3_main_1", "l3_main_2";
        reg = <0x00000000 0x44000000 0x00000000 0x01000000 0x00000000 0x45000000 0x00000000 0x00001000>;
        interrupts-extended = <0x00000001 0x00000000 0x00000004 0x00000004 0x00000008 0x00000000 0x0000000a 0x00000004>;
        phandle = <0x00000139>;
        l4@4a000000 {
            compatible = "ti,dra7-l4-cfg", "simple-bus";
            #address-cells = <0x00000001>;
            #size-cells = <0x00000001>;
            ranges = <0x00000000 0x4a000000 0x0022c000>;
            phandle = <0x0000013a>;
            scm@2000 {
                compatible = "ti,dra7-scm-core", "simple-bus";
                reg = <0x00002000 0x00002000>;
                #address-cells = <0x00000001>;
                #size-cells = <0x00000001>;
                ranges = <0x00000000 0x00002000 0x00002000>;
                phandle = <0x0000013b>;
...
                pinmux@1400 {
                    compatible = "ti,dra7-padconf", "pinctrl-single";
                    reg = <0x00001400 0x00000468>;
                    #address-cells = <0x00000001>;
                    #size-cells = <0x00000000>;
                    #pinctrl-cells = <0x00000001>;
                    #interrupt-cells = <0x00000001>;
                    interrupt-controller;
                    pinctrl-single,register-width = <0x00000020>;
                    pinctrl-single,function-mask = <0x3fffffff>;
                    phandle = <0x0000013f>;
...
                    cape_pins_default {
                        pinctrl-single,pins = <
                        	...
                            0x00000144 0x0001000f   /* vin1a_d20.off */
                            0x0000028c 0x00060009   /* gpio6_15.i2c3_scl */
                            0x00000288 0x00060009   /* gpio6_14.i2c3_sda */
                        	...
                        >;
                        phandle = <0x00000137>;
                    };
...
                };
...
            };
...
        };
...
        i2c@48060000 {
            compatible = "ti,omap4-i2c";
            reg = <0x48060000 0x00000100>;
            interrupts = <0x00000000 0x00000038 0x00000004>;
            #address-cells = <0x00000001>;
            #size-cells = <0x00000000>;
            ti,hwmods = "i2c3";
            status = "okay";
            clock-frequency = <0x00061a80>;
            phandle = <0x000001db>;
            i2c_mpu6050@68 {
                compatible = "charming,i2c_mpu6050";
                reg = <0x68>;
                status = "okay";
            };
        };
...
    };
...

执行如下命令编译设备树文件:

dtc -I dts -O dtb -o am5729-beagleboneai.dtb am5729-beagleboneai.dts

然后将编译好的am5729-beagleboneai.dtb文件替换掉开发板根文件系统中的/boot/dtbs/4.14.108-ti-r143/am5729-beagleboneai.dtb文件。

二、编写程序

i2c_mpu6050.c:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/i2c.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <asm/mach/map.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <asm/io.h>
#include <linux/device.h>
#include <linux/platform_device.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		0x6B
#define WHO_AM_I		0x75

/*------------------字符设备内容----------------------*/
#define DEV_NAME		"I2C3_mpu6050"
#define DEV_CNT			(1)

/*定义 led 资源结构体,保存获取得到的节点信息以及转换后的虚拟寄存器地址*/
static dev_t mpu6050_devno;				 //定义字符设备的设备号
static struct cdev mpu6050_chr_dev;		 //定义字符设备结构体chr_dev
struct class *class_mpu6050;			 //保存创建的类
struct device *device_mpu6050;			 // 保存创建的设备
struct device_node *mpu6050_device_node; //rgb_led的设备树节点结构体

/*------------------IIC设备内容----------------------*/
struct i2c_client *mpu6050_client = NULL; //保存mpu6050设备对应的i2c_client结构体,匹配成功后由.prob函数带回。

/*通过i2c 向mpu6050写入数据
*mpu6050_client:mpu6050的i2c_client结构体。
*address, 数据要写入的地址,
*data, 要写入的数据
*返回值,错误返回-1,成功返回0
*/
static int i2c_write_mpu6050(struct i2c_client *mpu6050_client, u8 address, u8 data)
{
	int error = 0;
	u8 write_data[2];
	struct i2c_msg send_msg; //要发送的数据结构体

	/*设置要发送的数据*/
	write_data[0] = address;
	write_data[1] = data;

	/*发送 iic要写入的地址 reg*/
	send_msg.addr = mpu6050_client->addr; //mpu6050在 iic 总线上的地址
	send_msg.flags = 0;					  //标记为发送数据
	send_msg.buf = write_data;			  //写入的首地址
	send_msg.len = 2;					  //reg长度

	/*执行发送*/
	error = i2c_transfer(mpu6050_client->adapter, &send_msg, 1);
	if (error != 1)
	{
		printk(KERN_DEBUG "\n i2c_transfer error \n");
		return -1;
	}
	return 0;
}

/*通过i2c 向mpu6050写入数据
*mpu6050_client:mpu6050的i2c_client结构体。
*address, 要读取的地址,
*data,保存读取得到的数据
*length,读长度
*返回值,错误返回-1,成功返回0  
*/
static int i2c_read_mpu6050(struct i2c_client *mpu6050_client, u8 address, void *data, u32 length)
{
	int error = 0;
	u8 address_data = address;
	struct i2c_msg mpu6050_msg[2];
	/*设置读取位置msg*/
	mpu6050_msg[0].addr = mpu6050_client->addr; //mpu6050在 iic 总线上的地址
	mpu6050_msg[0].flags = 0;					//标记为发送数据
	mpu6050_msg[0].buf = &address_data;			//写入的首地址
	mpu6050_msg[0].len = 1;						//写入长度

	/*设置读取位置msg*/
	mpu6050_msg[1].addr = mpu6050_client->addr; //mpu6050在 iic 总线上的地址
	mpu6050_msg[1].flags = I2C_M_RD;			//标记为读取数据
	mpu6050_msg[1].buf = data;					//读取得到的数据保存位置
	mpu6050_msg[1].len = length;				//读取长度

	error = i2c_transfer(mpu6050_client->adapter, mpu6050_msg, 2);

	if (error != 2)
	{
		printk(KERN_DEBUG "\n i2c_read_mpu6050 error \n");
		return -1;
	}
	return 0;
}

/*初始化i2c
*返回值,错误返回-1,成功返回0
*/
static int mpu6050_init(void)
{
	int error = 0;
	/*配置mpu6050电源管理,0x00,正常启动*/
	error += i2c_write_mpu6050(mpu6050_client, PWR_MGMT_1, 0X00);
	/*设置MPU6050的采样频率*/
	error += i2c_write_mpu6050(mpu6050_client, SMPLRT_DIV, 0X07);
	/*设置数字低通滤波器和帧同步引脚采样*/
	error += i2c_write_mpu6050(mpu6050_client, CONFIG, 0X06);
	/*设置量程和 X、Y、Z 轴加速度自检*/
	error += i2c_write_mpu6050(mpu6050_client, ACCEL_CONFIG, 0X01);

	if (error < 0)
	{
		/*初始化错误*/
		printk(KERN_DEBUG "\n mpu6050_init error \n");
		return -1;
	}
	return 0;
}

/*字符设备操作函数集,open函数实现*/
static int mpu6050_open(struct inode *inode, struct file *filp)
{
	// printk("\n mpu6050_open \n");

	/*向 mpu6050 发送配置数据,让mpu6050处于正常工作状态*/
	mpu6050_init();
	return 0;
}

/*字符设备操作函数集,.read函数实现*/
static ssize_t mpu6050_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off)
{
	char data_H;
	char data_L;
	int error;
	//保存mpu6050转换得到的原始数据
	short mpu6050_result[6]; 

	/*读取3轴加速度原始值*/
	i2c_read_mpu6050(mpu6050_client, ACCEL_XOUT_H, &data_H, 1);
	i2c_read_mpu6050(mpu6050_client, ACCEL_XOUT_L, &data_L, 1);
	mpu6050_result[0] = data_H << 8;
	mpu6050_result[0] += data_L;

	i2c_read_mpu6050(mpu6050_client, ACCEL_YOUT_H, &data_H, 1);
	i2c_read_mpu6050(mpu6050_client, ACCEL_YOUT_L, &data_L, 1);
	mpu6050_result[1] = data_H << 8;
    mpu6050_result[1] += data_L;

	i2c_read_mpu6050(mpu6050_client, ACCEL_ZOUT_H, &data_H, 1);
	i2c_read_mpu6050(mpu6050_client, ACCEL_ZOUT_L, &data_L, 1);
	mpu6050_result[2] = data_H << 8;
	mpu6050_result[2] += data_L;

	/*读取3轴角速度原始值*/
	i2c_read_mpu6050(mpu6050_client, GYRO_XOUT_H, &data_H, 1);
	i2c_read_mpu6050(mpu6050_client, GYRO_XOUT_L, &data_L, 1);
	mpu6050_result[3] = data_H << 8;
	mpu6050_result[3] += data_L;

	i2c_read_mpu6050(mpu6050_client, GYRO_YOUT_H, &data_H, 1);
	i2c_read_mpu6050(mpu6050_client, GYRO_YOUT_L, &data_L, 1);
	mpu6050_result[4] = data_H << 8;
	mpu6050_result[4] += data_L;

	i2c_read_mpu6050(mpu6050_client, GYRO_ZOUT_H, &data_H, 1);
	i2c_read_mpu6050(mpu6050_client, GYRO_ZOUT_L, &data_L, 1);
	mpu6050_result[5] = data_H << 8;
	mpu6050_result[5] += data_L;


	// printk("AX=%d, AY=%d, AZ=%d \n",(int)mpu6050_result[0],(int)mpu6050_result[1],(int)mpu6050_result[2]);
	// printk("GX=%d, GY=%d, GZ=%d \n \n",(int)mpu6050_result[3],(int)mpu6050_result[4],(int)mpu6050_result[5]);

	/*将读取得到的数据拷贝到用户空间*/
	error = copy_to_user(buf, mpu6050_result, cnt);

	if(error != 0)
	{
		printk("copy_to_user error!");
		return -1;
	}
	return 0;
}

/*字符设备操作函数集,.release函数实现*/
static int mpu6050_release(struct inode *inode, struct file *filp)
{
	// printk("\n mpu6050_release \n");
	return 0;
}

/*字符设备操作函数集*/
static struct file_operations mpu6050_chr_dev_fops =
	{
		.owner = THIS_MODULE,
		.open = mpu6050_open,
		.read = mpu6050_read,
		.release = mpu6050_release,
};

/*----------------平台驱动函数集-----------------*/
static int mpu6050_probe(struct i2c_client *client, const struct i2c_device_id *id)
{

	int ret = -1; //保存错误状态码

	printk(KERN_EMERG "\t  match successed  \n");
	/*---------------------注册 字符设备部分-----------------*/

	//采用动态分配的方式,获取设备编号,次设备号为0,
	//设备名称为rgb-leds,可通过命令cat  /proc/devices查看
	//DEV_CNT为1,当前只申请一个设备编号
	ret = alloc_chrdev_region(&mpu6050_devno, 0, DEV_CNT, DEV_NAME);
	if (ret < 0)
	{
		printk("fail to alloc mpu6050_devno\n");
		goto alloc_err;
	}

	//关联字符设备结构体cdev与文件操作结构体file_operations
	mpu6050_chr_dev.owner = THIS_MODULE;
	cdev_init(&mpu6050_chr_dev, &mpu6050_chr_dev_fops);

	// 添加设备至cdev_map散列表中
	ret = cdev_add(&mpu6050_chr_dev, mpu6050_devno, DEV_CNT);
	if (ret < 0)
	{
		printk("fail to add cdev\n");
		goto add_err;
	}

	/*创建类 */
	class_mpu6050 = class_create(THIS_MODULE, DEV_NAME);

	/*创建设备 DEV_NAME 指定设备名,*/
	device_mpu6050 = device_create(class_mpu6050, NULL, mpu6050_devno, NULL, DEV_NAME);
	mpu6050_client = client;
	return 0;

add_err:
	// 添加设备失败时,需要注销设备号
	unregister_chrdev_region(mpu6050_devno, DEV_CNT);
	printk("\n error! \n");
alloc_err:

	return -1;
}

static int mpu6050_remove(struct i2c_client *client)
{
	/*删除设备*/
	device_destroy(class_mpu6050, mpu6050_devno);	  //清除设备
	class_destroy(class_mpu6050);					  //清除类
	cdev_del(&mpu6050_chr_dev);						  //清除设备号
	unregister_chrdev_region(mpu6050_devno, DEV_CNT); //取消注册字符设备
	return 0;
}

/*定义ID 匹配表*/
static const struct i2c_device_id gtp_device_id[] = {
	{"charming,i2c_mpu6050", 0},
	{}};

/*定义设备树匹配表*/
static const struct of_device_id mpu6050_of_match_table[] = {
	{.compatible = "charming,i2c_mpu6050"},
	{/* sentinel */}};

/*定义i2c总线设备结构体*/
struct i2c_driver mpu6050_driver = {
	.probe = mpu6050_probe,
	.remove = mpu6050_remove,
	.id_table = gtp_device_id,
	.driver = {
		.name = "charming,i2c_mpu6050",
		.owner = THIS_MODULE,
		.of_match_table = mpu6050_of_match_table,
	},
};

/*
*驱动初始化函数
*/
static int __init mpu6050_driver_init(void)
{
	int ret;
	pr_info("mpu6050_driver_init\n");
	ret = i2c_add_driver(&mpu6050_driver);
	return ret;
}

/*
*驱动注销函数
*/
static void __exit mpu6050_driver_exit(void)
{
	pr_info("mpu6050_driver_exit\n");
	i2c_del_driver(&mpu6050_driver);
}

module_init(mpu6050_driver_init);
module_exit(mpu6050_driver_exit);

MODULE_LICENSE("GPL");

app.c:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    short resive_data[6];  //保存收到的 mpu6050转换结果数据,依次为 AX(x轴角度), AY, AZ 。GX(x轴加速度), GY ,GZ

    /*打开文件*/
    int fd = open("/dev/I2C3_mpu6050", O_RDWR);
    if(fd < 0)
    {
		printf("open file : %s failed !\n", argv[0]);
		return -1;
	}

    /*读取数据*/
    int error = read(fd,resive_data,12);
    if(error < 0)
    {
        printf("write file error! \n");
        close(fd);
        /*判断是否关闭成功*/
    }

    /*打印数据*/
    printf("AX=%d, AY=%d, AZ=%d ",(int)resive_data[0],(int)resive_data[1],(int)resive_data[2]);
	printf("    GX=%d, GY=%d, GZ=%d \n \n",(int)resive_data[3],(int)resive_data[4],(int)resive_data[5]);

    /*关闭文件*/
    error = close(fd);
    if(error < 0)
    {
        printf("close file error! \n");
    }
    
    return 0;
}

Makefile:

KERNEL_DIR=/opt/ti-processor-sdk-linux-am57xx-evm-05.03.00.07/board-support/linux-4.14.79+gitAUTOINC+e669d52447-ge669d52447

ARCH=arm
CROSS_COMPILE=/opt/ti-processor-sdk-linux-am57xx-evm-05.03.00.07/linux-devkit/sysroots/x86_64-arago-linux/usr/bin/arm-linux-gnueabihf-
export  ARCH  CROSS_COMPILE

obj-m := i2c_mpu6050.o

all:app
	$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules

app:	
	${CROSS_COMPILE}gcc app.c -o App

.PHONE:clean copy 

clean:
	rm *.o *.order *.symvers *.mod.c

delete:
	rm App i2c_mpu6050.ko

执行如下命令编译驱动程序和应用程序:

make
make clean

三、运行程序

执行如下命令加载i2c_mpu6050.ko模块,并且执行App:

debian@beaglebone:~$ sudo insmod i2c_mpu6050.ko
[sudo] password for debian:
[  112.814058]    match successed

Message from syslogd@beaglebone at Mar 22 06:01:50 ...
 kernel:[  112.814058]    match successed
debian@beaglebone:~$ chmod +x ./App
debian@beaglebone:~$ sudo ./App
AX=206, AY=14350, AZ=7764     GX=-246, GY=-126, GZ=-29

debian@beaglebone:~$ sudo ./App
AX=212, AY=14332, AZ=7772     GX=-302, GY=-126, GZ=-29
Linux mpu6050驱动程序 自己写的基于linux mpu6050的iic驱动代码 已在开发板上运行过了 立即下载

相关推荐

bbai-pwm:为新的BeagleBone AI板配置和使用PWM输出

bbai-pwm 为新的BeagleBone AI板配置和使用PWM输出

AI 边缘计算平台 - BeagleBone AI 64 简介

​Beagleboard 组织 2022年 6 月份发布了BeagleBone® AI-64平台的B1版本,由seeedstudio开发,是一款用于开发人工智能 (AI) 和机器学习解决方案的完整系统的平台,有 8 Tops(8b)的 AI 算力,有 GPU 和 DSP 加持,具有 BeagleBone® 兼容接口和板载外围设备的便利性和可扩展性,可以开箱立即开始学习和构建应用程序。..........................................

weixin_43978579的博客 3723

基于Linux的加速度传感器mma8653驱动程序的设计.pdf

基于Linux的加速度传感器mma8653驱动程序的设计.pdf

AI 边缘计算平台 - 回归开源 BeagleY-AI 简介

BeagleY®-AI 采用德州仪器新推出的 AM67A AI 视觉处理器。这款处理器集成了四个 64 位 Arm® Cortex®-A53 CPU 核心,时钟频率高达 1.4 GHz,两个通用 C7x DSP 和矩阵加速器(MMA),能提供 4 TOPS 的深度学习性能。此外,它还配备了视觉处理加速器、GPU 核心和多个专门用于实现低功耗、低延迟的 GPIO 控制 Arm Cortex-R5 核心。

weixin_43978579的博客 3051

麒麟V10桌面操作系统安装Qt5.12.3

在虚拟机中如何安装麒麟V10桌面系统,以及在麒麟系统中安装Qt框架,并正常编译运行Qt程序

阿龙的思考 3599

数学建模——相关系数(4)——斯皮尔曼相关系数(spearman)

文章目录引述斯皮尔曼相关系数(spearman)定义 引述 经过之前几节的学习,我们了解并掌握了皮尔逊相关系数。在学习中我们发现,皮尔逊相关系数的使用条件相当苛刻:两组变量必须是连续数据、呈现正态分布,且两者间必须成线性关系。如果我们在数学建模中拿到一组数据无法满足以上条件,那么有没有其他的方法去判断两组变量之间的相关性呢?答案是肯定的,它就是斯皮尔曼相关系数(spearman). 斯皮尔曼相关系...

东 6万+

底层原理_beaglebone ai底层原理分析:spl阶段

beaglebone ai底层原理分析:spl阶段1.本文说明2.为什么需要SPL3.SPL的工作流程3.1 链接脚本分析3.2 代码执行流程3.3 从board_init_f看驱动初始化3.4 代码重定位4.beaglebone ai的led调试5.总结1.本文说明在去深入分析一款芯片的使用的时候,往往需要关注其启动的流程与底层初始化的代码。只有掌握了这些信息,做代码优化和裁剪才能游刃...

weixin_32467423的博客 1258

告别Link180!在Ansys Mechanical 2020R2中正确启用Cable280绳索单元(附Beta选项开启指南)

本文详细介绍了在Ansys Mechanical 2020R2中启用Cable280绳索单元的全过程,包括Beta选项的开启步骤、建模技巧及高阶应用。Cable280作为专为绳索仿真设计的单元,相比传统的Link180单元,在大变形模拟和计算效率上表现更优,特别适合斜拉桥、电梯牵引绳等工程场景。

weixin_33711647的博客 405

2021-09-20 BeagleBone 系列 简介

​ BeagleBone 系列简介 BeagleBoard.org 推出了一系列的BeagleBone的板卡,从最初的300多元的BeagleBone Black,到后来的Blue,Green,Wireless,Industrial,Enhanced,一直到现在700多元的BeagleBone AI;功能也从最初的 ARM + DDR RAM + EMMC + 外设扩展,到增加工业扩展,增加WIFI扩展,到现在的试图加上最火的 AI 能力,可谓与时俱进了。

weixin_43978579的博客 2772

西工大总分396上岸学长的经验分享|西北工业大学通信考研信号与系统

以上就是我的一些经验,当然每个人的情况与学习习惯都是不一样,以上仅供大家参考,具体的学习进度安排等都要依据个人的实际情况而定。基础阶段:高数比较推荐武忠祥老师,他讲的内容难度比较合适,知识的梳理也比较完备,基础阶段主要集中做书上的例题,在基础阶段,我们很容易出现知识点遗忘现象,所以要及时回顾讲义知识点,这个时候做660的时候建议延迟两三章去练习(比如学完第三章,我在找时间把第一章的660习题做完,对答案)这里不建议硬生生的把讲义过一遍,可以配套做880基础篇,880这本资料还是极力推荐的。

xiaomage_mengma的博客 721

plotly包安装_Plotly(一)安装指南

plotly,是一个快速完善并崛起的交互式的、开源的绘图库库,Python库则是它的一个重要分支。现已支持超过40种独特的图表类型,涵盖了广泛的统计、金融、地理、科学和三维用例。Plotly 通过JavaScript构建,能基于Web显示实现交互式的可视化效果(Plotly最强大之处之一)。所以它的图形呈现可以方便的显示于Jupyter notebook(基于html)、独立的html中(直接显示...

weixin_35907189的博客 3469

BeagleBone AI:嵌入式人工智能的快速通道

BeagleBone AI:嵌入式人工智能的快速通道 项目介绍 BeagleBone AI 是由 BeagleBoard.org 基金会推出的开源单板计算机(SBC),专为嵌入式人工智能(AI)应用设计。基于德州仪器(Texas Instruments)的 AM5729 芯片,BeagleBone AI 不仅继承了 BeagleBone 系列的小巧外形,还集成了强大的工业级计算能力。通过 TI 的...

gitblog_00339的博客 1145

手把手调试Altera FPGA远程升级:从ASMI扇区擦除到Remote Update IP配置的避坑实录

本文详细解析了Altera FPGA远程升级的全流程,重点介绍了Cyclone IV系列FPGA的ASMI扇区擦除和Remote Update IP配置的实战技巧。通过双镜像架构设计、ASMI IP核优化配置及Remote Update IP的隐藏参数设置,帮助开发者避免常见陷阱,提升远程升级的可靠性和效率。

weixin_30872499的博客 446

BeagleBone AI 开源项目教程

BeagleBone AI 开源项目教程 1. 项目的目录结构及介绍 BeagleBone AI 项目的目录结构如下: beaglebone-ai/ ├── HW/ │ ├── MFG/ │ └── Mechanical/ ├── SW/ │ ├── fritzing/ │ └── kicad/ ├── regulatory/ ├── .gitignore ├── .gitmodu...

gitblog_00009的博客 520

Unity 如何使用命令模式

命令模式 游戏中,当你想通过一种通用的方式来存储命令并能够撤消命令时,那么命令模式最有用。 在“示例”中,你将看到一个可以通过GUI按钮移动的简单点。 采取行动后,您可以撤消并重做。我在屏幕上添加了一个简单的OnGUI标签输出,因此您可以看到命令列表,并指出哪个是当前命令。 在此示例中使用了4个类: Command-这是任何命令模式都可以继承的基本结构(抽象类)。您可以在任何项目中使用此类。 MoveCommand-这是从Command类继承的结构,将使用Execute和UnExecute(撤消)。每个移

TxNet 1550

基于STM32L4XX、HAL库的RTL8201F 以太网收发器(PHY)驱动程序设计

define PHY_RESET_DELAY 1000 // PHY复位延迟(ms)#define PHY_AUTONEGO_DELAY 3000 // 自动协商延迟(ms)/* 检查PHY ID (RTL8201F的ID为0x001CC816) *//* 系统时钟配置,确保ETH有50MHz时钟 *//* 初始化CPU, AHB和APB总线时钟 */

zhusl6688的博客 803

基于 BeagleBone AI 的运动目标识别系统

在 BeagleBone AI 板上开发一个 运动目标识别系统,使用 OpenCV 进行基本运动检测,并结合 TensorFlow Lite 或 OpenVINO 进行目标分类,提高识别准确率。

coolboyzk的博客 532

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

【亲测免费】 BeagleBone AI 开源项目教程

BeagleBone AI 开源项目教程 1. 项目介绍 BeagleBone AI 是一个基于 ARM Cortex-A15 架构的单板计算机,专为人工智能和机器学习应用设计。它集成了强大的硬件加速器,支持多种 AI 框架,适用于从嵌入式系统到边缘计算的各种应用场景。 2. 项目快速启动 2.1 硬件准备 BeagleBone AI 开发板 5V 电源适配器 MicroSD 卡(至少 8GB)...

gitblog_00248的博客 851

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

BeagleBone Black使用(二):连接狗板与系统更新

本文对狗板的几种连接方式进行了介绍,推荐初次使用和学习时可以使用 USB 连接和 SSH 访问,在熟悉基本操作后推荐使用网口连接到局域网络中进行使用,但需要单独进行供电。使用狗板建议将系统更新至新版本,可以避免出现一些未知的问题。

Victor_起风了的博客 3032

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

AI智能棋盘使用BeagleBone AI协同PRU运算

本文介绍如何利用BeagleBone AI的PRU实现微秒级响应的智能棋盘系统,结合AI推理与实时控制,完成从传感器检测到棋子移动的闭环操作,适用于教育、康复及自动化展示等场景。

weixin_35753431的博客 378

AI智能棋盘通过BeagleBone AI支持ROS机器人系统

基于BeagleBone AI与ROS构建的AI智能棋盘,实现视觉感知、棋子识别与机械臂自主走棋,支持边缘AI推理与机器人控制的深度融合,适用于教育、展示与人机交互场景。

weixin_30336531的博客 802

BeagleBone AI: 开启嵌入式机器学习的快速通道

BeagleBone AI: 开启嵌入式机器学习的快速通道 1. 项目基础介绍与主要编程语言 BeagleBone AI 是基于 BeagleBoard.org 开源社区的 BeagleBone 黑板系列,打造的一款面向嵌入式人工智能的开源单板计算机。它继承了 BeagleBoard.org® 开源 Linux 的设计理念,拥有小巧的单板计算机形态,同时具备了工业级别计算机的强大性能。Beagle...

gitblog_00889的博客 661

linux驱动i2c子系统之mpu6050

其实也没什么新颖的,因为Linux内核贯彻设备和驱动分离的原则,i2c驱动开发的流程和平台总线设备驱动开发差不太多。这个i2c子系统呢同样也是系统帮我们做好了bus,在硬件外设信息方面,我们描述好i2c外设设备然后注册进去或在设备树中描述好i2c外设硬件信息,设备这部分就搞定了,而i2c驱动方面,也和之前学过的一样,写好匹配的符号表,和proce的函数然后注册这个驱动到系统中,如果在系统中找到对应的设备或者在设备树中找到了一致的compatible,就会进入probe函数。

weixin_62622990的博客 1081

linux i2c 内核初始io,【正点原子Linux连载】第六十一章Linux I2C驱动实验-摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南 (amobbs.com 阿莫电子论坛)...

1#ifndef AP3216C_H2#define AP3216C_H3/***************************************************************4Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved.5文件名 : ap3216creg.h6作者...

weixin_35983453的博客 351

linux下mpu6050驱动

linux下mpu6050驱动 代码 先上代码: github仓库链接 gitee仓库链接 设备树 在i2c的控制器下追加该设备 &i2c2 { clock_frequency = <100000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2>; status = "okay"; mpu6050:mpu6050@68 { compatible = "dar,mpu6050"; re

darcsdn 1713
上一篇: 补码一位乘法公式的推导
下一篇: 解析kobject、kobj_type和kset
Charming Sun
博客等级 码龄11年 212粉丝 36原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值