开发板:tiny4412(1611)

内核:linux4.4

编译器: arm-none-linux-gnueabi-gcc (gcc version 4.8.3 20140320)

mma7660连接的是i2c3和xeint25。

在以前的内核中(arch/arm/mach-exynos/mach-tiny4412.c)中,是这样初始化i2c控制器及设备的

static struct s3c2410_platform_i2c tiny4412_i2c3_data __initdata = {        //__initdata宏用于数据定义,目的是将数据放入名叫.init.data的段。.flags                  = 0,.bus_num                = 3,.slave_addr             = 0x10,.frequency              = 200*1000,.sda_delay              = 100,
};
static struct mma7660_platform_data mma7660_pdata = {.irq                    = IRQ_EINT(25),.poll_interval  = 100,.input_fuzz             = 4,.input_flat             = 4,
};
static struct i2c_board_info smdk4x12_i2c_devs3[] __initdata = {
#ifdef CONFIG_MXC_MMA845X{.type = "mma845x",.addr = 0x1D,           /*mma845x i2c slave address*/.platform_data = (void *)&mma845x_data,},
#endif
#ifdef CONFIG_SENSORS_MMA7660{I2C_BOARD_INFO("mma7660", 0x4c),.platform_data = &mma7660_pdata,},
#endif
};
…………
s3c_i2c3_set_platdata(&tiny4412_i2c3_data); //设置i2c3控制器信息
i2c_register_board_info(3, smdk4x12_i2c_devs3,ARRAY_SIZE(smdk4x12_i2c_devs3));//注册挂接在i2c3上的设备的信息
…………

重要信息:MMA7660的器件地址是0x4c,I2C3的CLK信号新的频率为200KHz。

有了设备树之后:

在exynos4.dtsi文件下可以看到i2c_3的初始化,

i2c_3: i2c@13890000 {#address-cells = <1>;#size-cells = <0>;compatible = "samsung,s3c2440-i2c";reg = <0x13890000 0x100>;interrupts = <0 61 0>;clocks = <&clock CLK_I2C3>;clock-names = "i2c";pinctrl-names = "default";pinctrl-0 = <&i2c3_bus>;status = "disabled";};

i2c_3是这个节点的标号,可以通过&i2c_3的方式来调用这个节点。引用时,添加的新属性会合并,相同属性会被合并。添加MMA7660和I2C的硬件信息,可以参考内核文档,Documentation/devicetree/bindings/i2c/i2c.txt和Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt,中断资源的填写可以参考内核文档Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt。
例子如下:

        i2c@13870000 {compatible = "samsung,s3c2440-i2c";reg = <0x13870000 0x100>;interrupts = <345>;samsung,i2c-sda-delay = <100>;samsung,i2c-max-bus-freq = <100000>;/* Samsung GPIO variant begins here */gpios = <&gpd1 2 0 /* SDA */&gpd1 3 0 /* SCL */>;/* Samsung GPIO variant ends here *//* Pinctrl variant begins here */pinctrl-0 = <&i2c3_bus>;pinctrl-names = "default";/* Pinctrl variant ends here */#address-cells = <1>;#size-cells = <0>;wm8994@1a {compatible = "wlf,wm8994";reg = <0x1a>;};};

在exynos4412-tiny4412.dts下添加如下节点:

&i2c_3 {samsung,i2c-sda-delay = <100>;    samsung,i2c-slave-addr = <0x10>; samsung,i2c-max-bus-freq = <200000>;status = "okay";mma7660@4c {compatible = "tiny4412,mma7660";reg = <0x4c>;interrupt-parent = <&gpx3>;interrupts = <1 2>;poll_interval = <100>;input_fuzz = <4>;input_flat = <4>;status = "okay";};
};

为i2c_3添加了3个自定义属性,覆写了status属性,并在其下添加了子节点,因为子节点的中断控制器不是i2c_3,所以添加interrupt-parent属性,关于如何填写这个中断资源,可以查看Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
对于interrupts = <1 2>,其中1表示GPX3_1,2表示的是下降沿触发。加载新的设备树后,可以在sys/firmware/devicetree/base/i2c@13890000下找到mma7660@4c节点。
grep 'samsung,s3c2440-i2c' -nr
i2c-s3c2410.c:154:      { .compatible = "samsung,s3c2440-i2c", .data = (void *)QUIRK_S3C2440 },

可以在i2c-s3c2410.c找到i2c控制器的驱动,所以我们只要写i2c设备的驱动。

在i2c驱动中添加of_device_id属性,来匹配设备树节点

  1. static const struct of_device_id dt_ids[] = {
  2. { .compatible = "tiny4412,mma7660", },
  3. {},
  4. };

驱动匹配上节点之后,报出如下错误:

mma7660 3-004c: lack of platform data!

原因是client->dev.platform_data还没包含数据,所以我们现在往probe中添加解析设备树节点信息并设置client->dev.platform_data的函数。

static struct mma7660_platform_data *mma7660_parse_dt(struct device *dev){struct mma7660_platform_data *pdata;struct device_node *np = dev->of_node;if (!np)return NULL;pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);if (!pdata) {dev_err(dev, "failed to allocate platform data\n");return NULL;}if (of_property_read_u32(np, "poll_interval", &pdata->poll_interval)) {dev_err(dev, "failed to get poll_interval property\n");return NULL;}if (of_property_read_u32(np, "input_fuzz", &pdata->input_fuzz)) {dev_err(dev, "failed to get input_fuzz property\n");return NULL;}if (of_property_read_u32(np, "input_flat", &pdata->input_flat)) {dev_err(dev, "failed to get input_flat property\n");return NULL;}pdata->irq=irq_of_parse_and_map(np, 0);printk("%d",pdata->irq);return pdata;
}

注册驱动后打印如下:

驱动:

/** linux/drivers/hwmon/mma7660.c** 3-Axis Orientation/Motion Detection Sensor support** Copyright (C) 2009-2010 Freescale Semiconductor Ltd.** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <linux/module.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/input-polldev.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/mma7660.h>
#include <linux/of_irq.h>#define MMA7660_NAME     "mma7660"#define POLL_INTERVAL        100
#define INPUT_FUZZ          4
#define INPUT_FLAT          4static struct i2c_client   *mma7660_client;static struct device        *hwmon_dev;
static struct input_polled_dev  *mma7660_idev;
static struct mma7660_platform_data *plat_data;static int                   last_tilt = 0;
//static int                    oper_mode;/*-----------------------------------------------------------------------------* MMA7660 operations*/#define __need_retry(__v)    (__v & (1 << 6))
#define __is_negative(__v)  (__v & (1 << 5))static const char *mma7660_bafro[] = {"Unknown", "Front", "Back"
};
static const char *mma7660_pola[] = {"Unknown","Left", "Right","Rsvd", "Rsvd","Down", "Up","Rsvd",
};static int mma7660_read_xyz(struct i2c_client *client, int idx, int *xyz)
{int val;do {val = i2c_smbus_read_byte_data(client, idx + MMA7660_XOUT);if (val < 0) {dev_err(&client->dev, "Read register %02x failed, %d\n",idx + MMA7660_XOUT, val);return -EIO;}} while (__need_retry(val));*xyz = __is_negative(val) ? (val | ~0x3f) : (val & 0x3f);return 0;
}static int mma7660_read_tilt(struct i2c_client *client, int *tilt)
{int val;do {val = i2c_smbus_read_byte_data(client, MMA7660_TILT);if (val < 0) {dev_err(&client->dev, "Read register %02x failed, %d\n",MMA7660_TILT, val);return -EIO;}} while (__need_retry(val));*tilt = (val & 0xff);return 0;
}static int mma7660_initialize(struct i2c_client *client)
{int val;/* Using test mode to probe chip */i2c_smbus_write_byte_data(client, MMA7660_MODE, 0x00);mdelay(10);i2c_smbus_write_byte_data(client, MMA7660_MODE, 0x04);mdelay(10);i2c_smbus_write_byte_data(client, MMA7660_XOUT, 0x3f);i2c_smbus_write_byte_data(client, MMA7660_YOUT, 0x01);i2c_smbus_write_byte_data(client, MMA7660_ZOUT, 0x15);val = i2c_smbus_read_byte_data(client, MMA7660_ZOUT);if (val != 0x15) {dev_err(&client->dev, "no device\n");return -ENODEV;}/* Goto standby mode for configuration */i2c_smbus_write_byte_data(client, MMA7660_MODE, 0x00);mdelay(10);/* Sample rate: 64Hz / 16Hz; Filt: 3 samples  */i2c_smbus_write_byte_data(client, MMA7660_SR, ((2<<5) | (1<<3) | 1));/* Sleep count */i2c_smbus_write_byte_data(client, MMA7660_SPCNT, 0xA0);/* Tap detect and debounce ~4ms */i2c_smbus_write_byte_data(client, MMA7660_PDET, 4);i2c_smbus_write_byte_data(client, MMA7660_PD, 15);/* Enable interrupt except exiting Auto-Sleep */i2c_smbus_write_byte_data(client, MMA7660_INTSU, 0xe7);/* IPP, Auto-wake, auto-sleep and standby */i2c_smbus_write_byte_data(client, MMA7660_MODE, 0x59);mdelay(10);/* Save current tilt status */mma7660_read_tilt(client, &last_tilt);mma7660_client = client;return 0;
}/*-----------------------------------------------------------------------------* sysfs group support*/static ssize_t mma7660_show_regs(struct device *dev,struct device_attribute *attr, char *buf)
{int reg, val;int i, len = 0;for (reg = 0; reg < 0x0b; reg++) {val = i2c_smbus_read_byte_data(mma7660_client, reg);len += sprintf(buf + len, "REG: 0x%02x = 0x%02x ...... [ ", reg, val);for (i = 7; i >= 0; i--) {len += sprintf(buf + len, "%d", (val >> i) & 1);if ((i % 4) == 0) {len += sprintf(buf + len, " ");}}len += sprintf(buf + len, "]\n");}return len;
}static ssize_t mma7660_write_reg(struct device *dev,struct device_attribute *attr, const char *buf, size_t count)
{unsigned int reg, val;int ret;ret = sscanf(buf, "%x %x", &reg, &val);if (ret == 2) {if (reg >= 0 && reg <= 0x0a) {i2c_smbus_write_byte_data(mma7660_client, reg, val);val = i2c_smbus_read_byte_data(mma7660_client, reg);printk("REG: 0x%02x = 0x%02x\n", reg, val);}}return count;
}static ssize_t mma7660_show_xyz_g(struct device *dev,struct device_attribute *attr, char *buf)
{int axis[3];int i;for (i = 0; i < 3; i++) {mma7660_read_xyz(mma7660_client, i, &axis[i]);}return sprintf(buf, "%3d, %3d, %3d\n", axis[0], axis[1], axis[2]);
}static ssize_t mma7660_show_axis_g(struct device *dev,struct device_attribute *attr, char *buf)
{int n = to_sensor_dev_attr(attr)->index;int val;mma7660_read_xyz(mma7660_client, n, &val);return sprintf(buf, "%3d\n", val);
}static ssize_t mma7660_show_tilt(struct device *dev,struct device_attribute *attr, char *buf)
{int val = 0, len = 0;mma7660_read_tilt(mma7660_client, &val);len += sprintf(buf + len, "%s", mma7660_bafro[val & 0x03]);len += sprintf(buf + len, ", %s", mma7660_pola[(val >> 2) & 0x07]);if (val & (1 << 5)) {len += sprintf(buf + len, ", Tap");}if (val & (1 << 7)) {len += sprintf(buf + len, ", Shake");}len += sprintf(buf + len, "\n");return len;
}static SENSOR_DEVICE_ATTR(registers, 0660,mma7660_show_regs, mma7660_write_reg, 0);
static SENSOR_DEVICE_ATTR(x_axis_g, S_IRUGO, mma7660_show_axis_g, NULL, 0);
static SENSOR_DEVICE_ATTR(y_axis_g, S_IRUGO, mma7660_show_axis_g, NULL, 1);
static SENSOR_DEVICE_ATTR(z_axis_g, S_IRUGO, mma7660_show_axis_g, NULL, 2);
static SENSOR_DEVICE_ATTR(all_axis_g, S_IRUGO, mma7660_show_xyz_g, NULL, 0);
static SENSOR_DEVICE_ATTR(tilt_status, S_IRUGO, mma7660_show_tilt, NULL, 0);static struct attribute* mma7660_attrs[] = {&sensor_dev_attr_registers.dev_attr.attr,&sensor_dev_attr_x_axis_g.dev_attr.attr,&sensor_dev_attr_y_axis_g.dev_attr.attr,&sensor_dev_attr_z_axis_g.dev_attr.attr,&sensor_dev_attr_all_axis_g.dev_attr.attr,&sensor_dev_attr_tilt_status.dev_attr.attr,NULL
};static const struct attribute_group mma7660_group = {.attrs      = mma7660_attrs,
};/*-----------------------------------------------------------------------------* Input interfaces*/
static void mma7660_report_abs(void)
{int axis[3];int i;for (i = 0; i < 3; i++) {mma7660_read_xyz(mma7660_client, i, &axis[i]);}input_report_abs(mma7660_idev->input, ABS_X, axis[0]);input_report_abs(mma7660_idev->input, ABS_Y, axis[1]);input_report_abs(mma7660_idev->input, ABS_Z, axis[2]);input_sync(mma7660_idev->input);//printk("3-Axis ... %3d, %3d, %3d\n", axis[0], axis[1], axis[2]);
}static void mma7660_dev_poll(struct input_polled_dev *dev)
{mma7660_report_abs();
}/*-----------------------------------------------------------------------------* Interrupt handler*/static void mma7660_worker(struct work_struct *work)
{int bafro, pola, shake, tap;int val = 0;mma7660_read_tilt(mma7660_client, &val);/* TODO: report it ? */bafro = val & 0x03;if (bafro != (last_tilt & 0x03)) {printk("%s\n", mma7660_bafro[bafro]);}pola = (val >> 2) & 0x07;if (pola != ((last_tilt >> 2) & 0x07)) {printk("%s\n", mma7660_pola[pola]);}shake = (val >> 5) & 0x01;if (shake && shake != ((last_tilt >> 5) & 0x01)) {printk("Shake\n");}tap = (val >> 7) & 0x01;if (tap && tap != ((last_tilt >> 7) & 0x01)) {printk("Tap\n");}/* Save current status */last_tilt = val;
}DECLARE_WORK(mma7660_work, mma7660_worker);static irqreturn_t mma7660_interrupt(int irq, void *dev_id)
{schedule_work(&mma7660_work);return IRQ_HANDLED;
}static struct mma7660_platform_data *mma7660_parse_dt(struct device *dev){struct mma7660_platform_data *pdata;struct device_node *np = dev->of_node;if (!np)return NULL;pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);if (!pdata) {dev_err(dev, "failed to allocate platform data\n");return NULL;}if (of_property_read_u32(np, "poll_interval", &pdata->poll_interval)) {dev_err(dev, "failed to get poll_interval property\n");return NULL;}if (of_property_read_u32(np, "input_fuzz", &pdata->input_fuzz)) {dev_err(dev, "failed to get input_fuzz property\n");return NULL;}if (of_property_read_u32(np, "input_flat", &pdata->input_flat)) {dev_err(dev, "failed to get input_flat property\n");return NULL;}pdata->irq=irq_of_parse_and_map(np, 0);printk("%d",pdata->irq);return pdata;
}
/*-----------------------------------------------------------------------------* I2C client driver interfaces*/static int mma7660_probe(struct i2c_client *client,const struct i2c_device_id *id)
{struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);struct input_dev *idev;int poll_interval = POLL_INTERVAL;int input_fuzz = INPUT_FUZZ;int input_flat = INPUT_FLAT;int ret;ret = i2c_check_functionality(adapter,I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA);if (!ret) {dev_err(&client->dev, "I2C check functionality failed\n");return -ENXIO;}client->dev.platform_data=mma7660_parse_dt(&client->dev);plat_data = (struct mma7660_platform_data *)client->dev.platform_data;if (plat_data == NULL) {dev_err(&client->dev, "lack of platform data!\n");return -ENODEV;}/* Get parameters from platfrom data */if (plat_data->poll_interval > 0)poll_interval = plat_data->poll_interval;if (plat_data->input_fuzz > 0)input_fuzz = plat_data->input_fuzz;if (plat_data->input_flat > 0)input_flat = plat_data->input_flat;if (mma7660_initialize(client) < 0) {goto error_init_client;}ret = sysfs_create_group(&client->dev.kobj, &mma7660_group);if (ret) {dev_err(&client->dev, "create sysfs group failed!\n");goto error_init_client;}/* register to hwmon device */hwmon_dev = hwmon_device_register(&client->dev);if (IS_ERR(hwmon_dev)) {dev_err(&client->dev, "hwmon register failed!\n");ret = PTR_ERR(hwmon_dev);goto error_rm_dev_file;}/* input poll device register */mma7660_idev = input_allocate_polled_device();if (!mma7660_idev) {dev_err(&client->dev, "alloc poll device failed!\n");ret = -ENOMEM;goto error_rm_hwmon_dev;}mma7660_idev->poll = mma7660_dev_poll;mma7660_idev->poll_interval = plat_data->poll_interval;idev = mma7660_idev->input;idev->name = MMA7660_NAME;idev->id.bustype = BUS_I2C;idev->id.vendor = 0x12FA;idev->id.product = 0x7660;idev->id.version = 0x0100;idev->dev.parent = &client->dev;set_bit(EV_ABS, idev->evbit);set_bit(ABS_X, idev->absbit);set_bit(ABS_Y, idev->absbit);set_bit(ABS_Z, idev->absbit);input_set_abs_params(idev, ABS_X, -512, 512, input_fuzz, input_flat);input_set_abs_params(idev, ABS_Y, -512, 512, input_fuzz, input_flat);input_set_abs_params(idev, ABS_Z, -512, 512, input_fuzz, input_flat);ret = input_register_polled_device(mma7660_idev);if (ret) {dev_err(&client->dev, "register poll device failed!\n");goto error_free_poll_dev;}/* register interrupt handle */ret = request_irq(plat_data->irq, mma7660_interrupt,IRQF_TRIGGER_FALLING, MMA7660_NAME, idev);if (ret) {dev_err(&client->dev, "request irq (%d) failed %d\n", plat_data->irq, ret);goto error_rm_poll_dev;}dev_info(&client->dev, "MMA7660 device is probed successfully.\n");#if  0set_mod(1);
#endifreturn 0;error_rm_poll_dev:input_unregister_polled_device(mma7660_idev);
error_free_poll_dev:input_free_polled_device(mma7660_idev);
error_rm_hwmon_dev:hwmon_device_unregister(hwmon_dev);
error_rm_dev_file:sysfs_remove_group(&client->dev.kobj, &mma7660_group);
error_init_client:mma7660_client = NULL;return 0;
}static int mma7660_remove(struct i2c_client *client)
{free_irq(plat_data->irq, mma7660_idev->input);input_unregister_polled_device(mma7660_idev);input_free_polled_device(mma7660_idev);hwmon_device_unregister(hwmon_dev);sysfs_remove_group(&client->dev.kobj, &mma7660_group);mma7660_client = NULL;return 0;
}/*
static int mma7660_suspend(struct i2c_client *client, pm_message_t state)
{int ret;oper_mode = i2c_smbus_read_byte_data(client, MMA7660_MODE);ret = i2c_smbus_write_byte_data(client, MMA7660_MODE, 0);if (ret) {printk("%s: set mode (0) for suspend failed, ret = %d\n",MMA7660_NAME, ret);}return 0;
}
*//*
static int mma7660_resume(struct i2c_client *client)
{int ret;ret = i2c_smbus_write_byte_data(client, MMA7660_MODE, oper_mode);if (ret) {printk("%s: set mode (%d) for resume failed, ret = %d\n",MMA7660_NAME, oper_mode, ret);}return 0;
}
*/static const struct of_device_id mma7660[] = {  { .compatible = "freescale,mma7660", },  {},
};  MODULE_DEVICE_TABLE(of,mma7660); static const struct i2c_device_id mma7660_ids[] = {{ "mma7660", 0 },{ },
};
MODULE_DEVICE_TABLE(i2c, mma7660_ids);static struct i2c_driver i2c_mma7660_driver = {.driver       = {.name   = MMA7660_NAME,.of_match_table=mma7660, },.probe      = mma7660_probe,.remove        = mma7660_remove,//.suspend        = mma7660_suspend,//.resume        = mma7660_resume,.id_table       = mma7660_ids,
};static int __init init_mma7660(void)
{int ret;ret = i2c_add_driver(&i2c_mma7660_driver);printk(KERN_INFO "MMA7660 sensor driver registered.\n");return ret;
}static void __exit exit_mma7660(void)
{i2c_del_driver(&i2c_mma7660_driver);printk(KERN_INFO "MMA7660 sensor driver removed.\n");
}module_init(init_mma7660);
module_exit(exit_mma7660);MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("MMA7660 sensor driver");
MODULE_LICENSE("GPL");

测试:

cd /sys/devices/platform/13890000.i2c/i2c-3/3-004c/ 
可以看到如下输出:

tiny4412 设备树之i2c设备(二)相关推荐

  1. 设备树解析 i2c设备模型

    目录 1.基础概念 1.总线 2.手机启动流程 1.MTK启动流程 2.高通启动流程的差别 3.设备树解析 1.设备树相关 2.设备树解析 4. i2c 设备初始化流程 1.基础概念 1.总线 总线是 ...

  2. 高通平台msm8953 Linux DTS(Device Tree Source)设备树详解之二(DTS设备树匹配过程)

    本系列导航: 高通平台8953  Linux DTS(Device Tree Source)设备树详解之一(背景基础知识篇) 高通平台8953 Linux DTS(Device Tree Source ...

  3. linux设备和驱动匹配的方法,Linux使用设备树的i2c驱动与设备匹配方式

    Linux使用设备树的i2c驱动与设备匹配有3种方式: of_driver_match_device acpi_driver_match_device i2c_match_id 源码: static ...

  4. 【Linux驱动开发】设备树详解(二)设备树语法详解

    ​ 活动地址:CSDN21天学习挑战赛 [Linux驱动开发]设备树详解(一)设备树基础介绍 [Linux驱动开发]设备树详解(二)设备树语法详解 [Linux驱动开发]设备树详解(三)设备树Kern ...

  5. Linux 设备驱动开发 —— 设备树在platform设备驱动中的使用

    关与设备树的概念,我们在Exynos4412 内核移植(六)-- 设备树解析 里面已经学习过,下面看一下设备树在设备驱动开发中起到的作用 Device Tree是一种描述硬件的数据结构,设备树源(De ...

  6. 设备树下字符设备驱动

    设备树下字符设备驱动 一.在设备树里添加自己的节点 二.驱动代码 三.makefile 四.应用层代码 运行测试 总结 一.在设备树里添加自己的节点 alphaled { 2 #address-cel ...

  7. Linux设备树led,linux设备树下LED灯控制

    linux设备树下LED灯控制 linux设备树下LED灯控制 原理图: 所以在设备树下子节点下插入gpioled节点: gpioled { #address-cells = <1>; # ...

  8. Linux设备驱动篇——[I2C设备驱动-1]

    Linux 设备驱动篇之I2c设备驱动 fulinux 一.I2C驱动体系 虽然I2C硬件体系结构和协议都很容易理解,但是Linux I2C驱动体系结构却有相当的复杂度,它主要由3部分组成,即I2C设 ...

  9. linux更改设备树,petalinux 修改设备树

    一.设备树生成及编译 1.执行petalinux-create创建工程 2.执行petalinux-config --get-hw-description导入硬件配置 3.执行petalinux-co ...

最新文章

  1. nginx telnet sshd
  2. java excel导入前台_java上传excel表格并读取数据返回到前台
  3. 马斯克不仅承包NASA火箭发射,现在连火箭“摆渡车”都换成特斯拉了
  4. TensorFlow配置日志等级
  5. [云炬创业基础笔记]第九章企业的法律形态测试1
  6. matlab二维矩阵可视化几种方法
  7. 史上超全halcon常见3D算子汇总(一)
  8. xgboost算法_XGBoost算法可能会长期占据你的视野!
  9. php 项目中引用对方接口_关于PHP中为什么要写接口的问题说明
  10. ASP.NET调用Oracle分页存储过程并结合ASPnetpager分页控件 实现分页功能
  11. csv是python内置模块吗_Python--CSV模块 - 一只小小的寄居蟹 - 博客园
  12. SharePoint JavaScript API in application pages
  13. UVa 11292 勇者斗恶龙(The Dragon of Loowater)
  14. strcpy sprintf memcpy 它们之间的区别
  15. 合并两个有序数组(C语言)
  16. UI实战教程之切图标注篇(UI必备)
  17. 清华EMBA课程系列思考之十六(2) -- 领导艺术
  18. 工作经验的Java学习心得
  19. r5 7600x和r7 7700x差距
  20. 基于铂电阻测温电路的设计

热门文章

  1. 启明星辰:安全管理平台(SOC)
  2. NOI-1.5(18) 鸡尾酒疗法
  3. UnicodeDecodeError: ‘ascii‘ codec can‘t decode byte 0xbb in position 51: ord
  4. 个人作业-Week3
  5. Simulink Boost电路仿真实例
  6. 教你通过数据库共享和备份所有快递信息
  7. 中美AI争高下的秘诀!一文看尽中国AI计算力发展
  8. Test Case Design Method - OATS
  9. 京东到家djencrypt和signKeyV1还原
  10. U盘制作Ubuntu系统启动盘的官方推荐软件