1.通用GPIO控制函数:

gpio_set_value(port_num,0/1) 一般只是在这个GPIO口的寄存器上写上某个值,至于这个端口是否设置为输出,它就管不了!而gpio_direction_output (port_num,0/1),在某个GPIO口写上某个值之后,还会把这个端口设置为输出模式。首先要调用gpio_direction_output(),以后要设置高低电平时,直接使用gpio_set_value()就可以了

2.http://wenku.baidu.com/link?url=5ry8VUdQA7-vhasbcfWwfOOTOteFvZCHxWVqAnix3z7kd7TVK4VRPHv22M2C17MAoSdd25mGYCI2qAhs9gwC-TZ1sCVpF24MTBzr8ET3AkGstruct

pinctrl * evm_pinctrl_get(struct device *dev);根据设备获取pin操作句柄,所以的pin操作必须基于此pinctrl句柄。与pinctrl_get接口功能完全一样,只是devm_pinctrl_get会将申请的pinctrl句柄做记账,绑定到设备句柄信息中。

改写后:设备树:msm8916-pinctrl.dtsi

gpio_cameral_flash {
        compatible = "qcom,gpio_cameral_flash";
        qcom,gpio_cameral_flash = <&msm_gpio 105 0>;
    };

驱动:leds-cameral-flash.c

//#include <Linux/types.h>
#include <linux/pm.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/fsl_devices.h>
#include <asm/setup.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/stat.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/spinlock.h>
#include <linux/err.h>
#include <linux/regulator/consumer.h>

int gpio_ldo_pin = -1;
int gpio_flag = -1;
static struct class *gpio_cameral_flash_class = NULL;
static struct device *gpio_cameral_flash_dev = NULL;

#define CTL_POWER_ON    "1"
#define CTL_POWER_OFF   "0"

//cat
static ssize_t gpio_105_show(struct device *dev,
        struct device_attribute *attr, char *buf)
{
    printk("%s\n", __func__);
    sprintf(buf, "gpio_105 is %d\n", gpio_flag);
    return strlen(buf);
}
//echo
static ssize_t gpio_105_store(struct device *dev,
        struct device_attribute *attr, const char *buf,
        size_t count)
{
    if(!strncmp(buf, CTL_POWER_ON, strlen(CTL_POWER_ON))) {
        printk("%s: to enable gpio_105\n", __func__);
        gpio_set_value(gpio_ldo_pin, 1);
        gpio_flag = 1;

} else if(!strncmp(buf, CTL_POWER_OFF, strlen(CTL_POWER_OFF))) {
        printk("%s: to disable gpio_105\n", __func__);
        gpio_set_value(gpio_ldo_pin, 0);
        gpio_flag = 0;
    }

return count;
}

static struct device_attribute gpio_105_dev_attr = {    //  /sys/class/gpio_cameral_flash下生成gpio_105设备节点
    .attr = {
        .name = "gpio_105",
        .mode = S_IRWXU|S_IRWXG|S_IRWXO,   //节点读写权限设置
    },
    .show = gpio_105_show,        //节点读方法
    .store = gpio_105_store,        //节点写方法
};

static int gpio_cameral_flash_probe(struct platform_device *pdev)
{
    int ret = 0;

printk("qcom enter gpio_cameral_flash_probe \n");

gpio_ldo_pin = of_get_named_gpio(pdev->dev.of_node, "qcom,gpio_cameral_flash", 0);
    if (gpio_ldo_pin < 0)
        printk("xcz gpio_ldo_pin is not available \n");

ret = gpio_request(gpio_ldo_pin, "gpio_cameral_flash");//取名
    if(0 != ret) {
        printk("qcom gpio request %d failed.", gpio_ldo_pin);
        goto fail1;
    }

gpio_direction_output(gpio_ldo_pin, 0);

gpio_set_value(gpio_ldo_pin, 0);
    gpio_flag = 0;

gpio_cameral_flash_class = class_create(THIS_MODULE, "gpio_cameral_flash");
    if(IS_ERR(gpio_cameral_flash_class))
    {
        ret = PTR_ERR(gpio_cameral_flash_class);
        printk("Failed to create class.\n");
        return ret;
    }

gpio_cameral_flash_dev = device_create(gpio_cameral_flash_class, NULL, 0, NULL, "gpio_gpio_105");//取名
    if (IS_ERR(gpio_cameral_flash_dev))
    {
        ret = PTR_ERR(gpio_cameral_flash_class);
        printk("Failed to create device(gpio_cameral_flash_dev)!\n");
        return ret;
    }

ret = device_create_file(gpio_cameral_flash_dev, &gpio_105_dev_attr);
    if(ret)
    {
        pr_err("%s: gpio_105 creat sysfs failed\n",__func__);
        return ret;
    }

printk("xcz enter  gpio_cameral_flash_probe, ok \n");

fail1:
    return ret;
}
//硬件卸载时调用
static int gpio_cameral_flash_remove(struct platform_device *pdev)
{
    device_destroy(gpio_cameral_flash_class, 0);
    class_destroy(gpio_cameral_flash_class);
    device_remove_file(gpio_cameral_flash_dev, &gpio_105_dev_attr);

return 0;
}

static int gpio_cameral_flash_suspend(struct platform_device *pdev,pm_message_t state)
{
    return 0;
}

static int gpio_cameral_flash_resume(struct platform_device *pdev)
{
    return 0;
}

static struct of_device_id gpio_cameral_flash_dt_match[] = {
    { .compatible = "qcom,gpio_cameral_flash",},
    { },
};
MODULE_DEVICE_TABLE(of, gpio_cameral_flash_dt_match);

static struct platform_driver gpio_flash_driver = {          //  /sys/class总线下生成设备节点gpio_cameral_flash
    .driver = {
        .name = "gpio_cameral_flash",
        .owner = THIS_MODULE,
        .of_match_table = of_match_ptr(gpio_cameral_flash_dt_match),
    },
    .probe = gpio_cameral_flash_probe,
    .remove = gpio_cameral_flash_remove,
    .suspend = gpio_cameral_flash_suspend,
    .resume = gpio_cameral_flash_resume,
};

static __init int gpio_flash_init(void)
{
    return platform_driver_register(&gpio_flash_driver);
}

static void __exit gpio_flash_exit(void)
{
    platform_driver_unregister(&gpio_flash_driver);
}

module_init(gpio_flash_init);
module_exit(gpio_flash_exit);
MODULE_AUTHOR("GPIO_CAMERAL_FLASH, Inc.");
MODULE_DESCRIPTION("QCOM GPIO_CAMERAL_FLASH");
MODULE_LICENSE("GPL");

来源于:

设备树:msm8916-pinctrl.dtsi

gpio_ldo_power {
        compatible = "xcz,gpio_ldo_power";
        qcom,gpio_ldo_pin = <&msm_gpio 20 0>;
    };

驱动:leds-cameral-flash.c

//#include <Linux/types.h>
#include <linux/pm.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/fsl_devices.h>
#include <asm/setup.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/stat.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/spinlock.h>
#include <linux/err.h>
#include <linux/regulator/consumer.h>

int gpio_ldo_pin = -1;
int gpio_flag = -1;
static struct class *gpio_ldo_power_class = NULL;
static struct device *gpio_ldo_power_dev = NULL;

#define CTL_POWER_ON    "1"
#define CTL_POWER_OFF   "0"

//cat
static ssize_t gpio_22_show(struct device *dev,
        struct device_attribute *attr, char *buf)
{
    printk("%s\n", __func__);
    sprintf(buf, "gpio_22 is %d\n", gpio_flag);
    return strlen(buf);
}
//echo
static ssize_t gpio_22_store(struct device *dev,
        struct device_attribute *attr, const char *buf,
        size_t count)
{
    if(!strncmp(buf, CTL_POWER_ON, strlen(CTL_POWER_ON))) {
        printk("%s: to enable gpio_22\n", __func__);
        gpio_set_value(gpio_ldo_pin, 1);
        gpio_flag = 1;

} else if(!strncmp(buf, CTL_POWER_OFF, strlen(CTL_POWER_OFF))) {
        printk("%s: to disable gpio_22\n", __func__);
        gpio_set_value(gpio_ldo_pin, 0);
        gpio_flag = 0;
    }

return count;
}

static struct device_attribute gpio_22_dev_attr = {
    .attr = {
        .name = "gpio_22",
        .mode = S_IRWXU|S_IRWXG|S_IRWXO,
    },
    .show = gpio_22_show,
    .store = gpio_22_store,
};

static int gpio_ldo_power_probe(struct platform_device *pdev)
{
    int ret = 0;

printk("xcz enter gpio_ldo_power_probe \n");

gpio_ldo_pin = of_get_named_gpio(pdev->dev.of_node, "qcom,gpio_ldo_pin", 0);
    if (gpio_ldo_pin < 0)
        printk("xcz gpio_ldo_pin is not available \n");

ret = gpio_request(gpio_ldo_pin, "gpio_ldo_pin");
    if(0 != ret) {
        printk("xcz gpio request %d failed.", gpio_ldo_pin);
        goto fail1;
    }

gpio_direction_output(gpio_ldo_pin, 0);

gpio_set_value(gpio_ldo_pin, 0);
    gpio_flag = 0;

gpio_ldo_power_class = class_create(THIS_MODULE, "gpio_ldo_power");
    if(IS_ERR(gpio_ldo_power_class))
    {
        ret = PTR_ERR(gpio_ldo_power_class);
        printk("Failed to create class.\n");
        return ret;
    }

gpio_ldo_power_dev = device_create(gpio_ldo_power_class, NULL, 0, NULL, "gpio_gpio_22");
    if (IS_ERR(gpio_ldo_power_dev))
    {
        ret = PTR_ERR(gpio_ldo_power_class);
        printk("Failed to create device(gpio_ldo_power_dev)!\n");
        return ret;
    }

ret = device_create_file(gpio_ldo_power_dev, &gpio_22_dev_attr);
    if(ret)
    {
        pr_err("%s: gpio_22 creat sysfs failed\n",__func__);
        return ret;
    }

printk("xcz enter gpio_ldo_power_probe, ok \n");

fail1:
    return ret;
}
//硬件卸载时调用
static int gpio_ldo_power_remove(struct platform_device *pdev)
{
    device_destroy(gpio_ldo_power_class, 0);
    class_destroy(gpio_ldo_power_class);
    device_remove_file(gpio_ldo_power_dev, &gpio_22_dev_attr);

return 0;
}

static int gpio_ldo_power_suspend(struct platform_device *pdev,pm_message_t state)
{
    return 0;
}

static int gpio_ldo_power_resume(struct platform_device *pdev)
{
    return 0;
}

static struct of_device_id gpio_ldo_power_dt_match[] = {
    { .compatible = "xcz,gpio_ldo_power",},
    { },
};
MODULE_DEVICE_TABLE(of, gpio_ldo_power_dt_match);

static struct platform_driver gpio_power_driver = {
    .driver = {
        .name = "gpio_ldo_power",
        .owner = THIS_MODULE,
        .of_match_table = of_match_ptr(gpio_ldo_power_dt_match),
    },
    .probe = gpio_ldo_power_probe,
    .remove = gpio_ldo_power_remove,
    .suspend = gpio_ldo_power_suspend,
    .resume = gpio_ldo_power_resume,
};

static __init int gpio_power_init(void)
{
    return platform_driver_register(&gpio_power_driver);
}

static void __exit gpio_power_exit(void)
{
    platform_driver_unregister(&gpio_power_driver);
}

module_init(gpio_power_init);
module_exit(gpio_power_exit);
MODULE_AUTHOR("GPIO_LDO_POWER, Inc.");
MODULE_DESCRIPTION("XCZ GPIO_LDO_POWER");
MODULE_LICENSE("GPL");

关于高通8053平台i2c和spi配置的学习总结

发表于2016/9/29 17:16:02  858人阅读

分类: 技术

这次完成的任务是要使能高通8053平台的i2c和spi,主要做的工作就是在设备树文件中添加节点信息。主要的工作在于对设备树文件的修改,主要修改了msm8953-pinctrl.dtsi和msm8953.dtsi两个文件。
msm8953-pinctrl.dtsi是配置MSM8953芯片中的GPIO。在此文件中定义i2c使用哪个gpio。
因为引脚复用功能的存在,所以要先配置i2c的引脚复用功能,在msm8953-pinctrl.dtsi中进行如下配置:
i2c_4 {
i2c_4_active: i2c_4_active { /*i2c处于active状态*/
/* active state */
mux {
pins = "gpio14", "gpio15"; /*i2c有两根线,分别是SDA和SCL*/
/* SDA用到了gpio14,SCL用到了gpio15*/
function = "blsp_i2c4"; /*这个gpio组支持功能复用,在i2c_4_active中,gpio说明采用"blsp_i2c4"功能*/
};
config {
pins = "gpio14", "gpio15";
drive-strength = <2>; /*设置gpio14,gpio15这个pin脚组的驱动能力为2MA*/
bias-disable; /*选项有bias-pull-up、bias-pull-down和bias-disable。这里使用bias-disable,代表no-pull*/
};
};
i2c_4_sleep: i2c_4_sleep { /*i2c处于sleep状态*/
/* suspended state */
mux {
pins = "gpio14", "gpio15";
function = "gpio"; /*这时pins的功能设置为普通的gpio功能。这里体现出了pin脚的功能复用。*/
};
config {
pins = "gpio14", "gpio15";
drive-strength = <2>; /*驱动能力设置为2MA*/
bias-disable;
};
};
};
接下来,需要在文件msm8953.dtsi中添加一个新的i2c设备树节点:
根据spec获取物理地址,中断号等。
i2c_4: i2c@78b8000 { /* BLSP1 QUP4 */ /*i2c_4使用的是BLSP1 QUP4,对应的物理地址为0x78b8000*/
compatible = "qcom,i2c-msm-v2";
#address-cells = <1>;
#size-cells = <0>;
reg-names = "qup_phys_addr";
reg = <0x78b8000 0x600>; /*i2c_4对应的物理地址*/
interrupt-names = "qup_irq";
interrupts = <0 98 0>; /*根据spec可以得到BLSP1 QUP4对应的中断号为98,第三个0的含义为:*/
/*1: low-to-high edge triggered;2: high-to-low edge triggered;3: active high-level-sensitive;4: active low-level-sensitive*/
qcom,clk-freq-out = <400000>; /*希望得到的i2c总线时钟频率,HZ*/
qcom,clk-freq-in = <19200000>; /*提供的核心时钟频率,HZ*/
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
<&clock_gcc clk_gcc_blsp1_qup4_i2c_apps_clk>;
pinctrl-names = "i2c_active", "i2c_sleep"; /*用到的pinctrl。*/
pinctrl-0 = <&i2c_4_active>;
pinctrl-1 = <&i2c_4_sleep>;
qcom,noise-rjct-scl = <0>;
qcom,noise-rjct-sda = <0>;
qcom,master-id = <86>;
dmas = <&dma_blsp1 10 64 0x20000020 0x20>,
<&dma_blsp1 11 32 0x20000020 0x20>;
dma-names = "tx", "rx";
status = "okay";
};
确认i2c是否配置成功的方法:
adb shell
cd /dev/
ls i2c*
会看到所添加的i2c设备。
使用示波器可以观察到正确的波形,证明配置正确了。
对spi的配置和i2c类似,主要在msm8953-pinctrl.dtsi和msm8953.dtsi中进行修改:
在msm8953-pinctrl.dtsi中添加如下代码:
spi3 {
spi3_default: spi3_default {
/* active state */
mux {
/* MOSI, MISO, CLK */
pins = "gpio8", "gpio9", "gpio11"; /* 在这里,spi使用四根线,MOSI、MISO、CLK和CS。*/
/* MOSI对应gpio8,MISO对应gpio9,CLK对应gpio11,CS对应gpio10*/
/* spi普遍使用三根或四根线,在需要片选时需要加CS线*/
function = "blsp_spi3"; /* 功能复用,设置功能为"blsp_spi3" */
};
config {
pins = "gpio8", "gpio9", "gpio11";
drive-strength = <12>; /* 12 MA */ /*驱动能力为12MA*/
bias-disable = <0>; /* No PULL */ /*有三个选项:bias-disable、bias-pull-down、bias-pull-up*/
};
};
spi3_sleep: spi3_sleep {
/* suspended state */
mux {
/* MOSI, MISO, CLK */
pins = "gpio8", "gpio9", "gpio11";
function = "gpio"; /* 功能复用,在sleep状态时作为gpio。*/
};
config {
pins = "gpio8", "gpio9", "gpio11";
drive-strength = <2>; /* 2 MA */ /* 睡眠状态时的驱动能力设为2MA */
bias-pull-down; /* PULL Down */
};
};
spi3_cs0_active: cs0_active { /*设置CS片选线的gpio*/
/* CS */
mux {
pins = "gpio10";
function = "blsp_spi3"; /*功能复用*/
};
config {
pins = "gpio10";
drive-strength = <2>;
bias-disable = <0>;
};
};
spi3_cs0_sleep: cs0_sleep {
/* CS */
mux {
pins = "gpio10";
function = "gpio";
};
config {
pins = "gpio10";
drive-strength = <2>;
bias-disable = <0>;
};
};
};
在msm8953.dtsi中添加节点:
spi_3: spi@78b7000 { /* BLSP1 QUP3 */ /*使用BLSP1 QUP3*/
compatible = "qcom,spi-qup-v2";
#address-cells = <1>;
#size-cells = <0>;
reg-names = "spi_physical", "spi_bam_physical";
reg = <0x78b7000 0x600>,
<0x7884000 0x1f000>;
interrupt-names = "spi_irq", "spi_bam_irq";
interrupts = <0 97 0>, <0 238 0>; /*根据表2确定中断号*/
spi-max-frequency = <19200000>; /*最大的SPI设备的频率*/
pinctrl-names = "spi_default", "spi_sleep"; /*所用到的pin脚和功能*/
pinctrl-0 = <&spi3_default &spi3_cs0_active>;
pinctrl-1 = <&spi3_sleep &spi3_cs0_sleep>;
clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>,
<&clock_gcc clk_gcc_blsp1_qup3_spi_apps_clk>;
clock-names = "iface_clk", "core_clk";
qcom,infinite-mode = <0>;
qcom,use-bam; /*使用BAM模式*/
qcom,use-pinctrl;
qcom,ver-reg-exists;
qcom,bam-consumer-pipe-index = <8>;
qcom,bam-producer-pipe-index = <9>;
qcom,master-id = <86>;
};
如果配置正确,可以在/sys/class/spi_master/spi下看到spi总线:
adb shell
cd /sys/class/spi_master/
ls
spi和i2c知识总结:
SPI总线由三条信号线组成。SPI总线可以实现 多个SPI设备互相连接。提供SPI串行时钟的SPI设备为SPI主机或主设备(Master),其他设备为SPI从机或从设备(Slave)。主从设备间可以实现全双工通信,当有多个从设备时,还可以增加一条从设备选择线。 
如果用通用IO口模拟SPI总线,必须要有一个输出口,一个输入口,另一个口则视实现的设备类型而定,如果要实现主从设备,则需输入输出口,若只实现主设备,则需输出口即可,若只实现从设备,则只需输入口即可。
I2C总线是双向、两线、串行、多主控(multi-master)接口标准,具有总线仲裁机制,非常适合在器件之间进行近距离、非经常性的数据通信。在它的协议体系中,传输数据时都会带上目的设备的设备地址,因此可以实现设备组网。 
如果用通用IO口模拟I2C总线,并实现双向传输,则需一个输入输出口,另外还需一个输出口。
iic的两根线:SDA、SCL,结构如下图所示。分别表示:
SDA:串行数据线。
SCl:串行时钟线。
图 IIC结构示意图
图 IIC总线数据传输协议示意图
spi的四根线:MOSI、MISO、CS、CLK,spi总线的结构和数据的传送格式如下图所示。分别代表:
MOSI:主输出,从输入。
MISO:主输入,从输出。
CS:片选。
CLK:同步时钟。
图 spi结构和数据传送格式示意图

高通msm8916 gpio笔记(基于设备树)相关推荐

  1. 基于设备树的中断实现 (24x0平台)

    文章目录 一.平台信息 1. 平台信息 二.中断的驱动实现方式 2. 不使用设备树的中断实现 2.1 mach-mini2440.c文件中注册中断 2.2 注册中断 3. 使用设备树的中断实现 设备树 ...

  2. 【MIUI9_7.12.05】小米6 sagit 高通骁龙835 基于安卓N(Android 7.1)时间刺客修改精简优化版本

    小米6 sagit 高通骁龙835 基于安卓N(Android 7.1) MIUI9 时间刺客修改精简优化版本 搞机条款:(温馨提醒,不看者默认代表同意!) (1)本人任何刷机包均自带Supersu_ ...

  3. 嵌入式编程笔记之六--设备树初体验

    设备树的起源 设备树(Device Tree)是一种描述硬件资源的数据结构,它由 uboot 传递给 Linux 内核,被内核解析,内核根据设备树中的硬件描述信息加载利用相应驱动资源.在引入设备树之前 ...

  4. Zynq SOC学习笔记之设备树

    一. 概述 DTS即DeviceTree Source 设备树源码,是一种描述硬件的数据结构 以树状节点的方式描述一个设备的各种硬件信息细节:CPU.GPIO.时钟.中断.内存等,形成类似文本文件dt ...

  5. 基于设备树的TQ2440的中断(2)

    下面以按键中断为例看看基于设备数的中断的用法: 设备树: tq2440_key {compatible = "tq2440,key";interrupt-parent = < ...

  6. 高通平台GPIO模拟PWM控制背光

    很多时候由于节省硬件资源,降低成本,会把PWM控制芯片去掉或者是改做它用,导致当我们想用PWM方式控制背光时只能使用带有clk功能的GPIO口.本篇文档就来讲解下如何使用GPIO模拟PWM功能进行背光 ...

  7. TP X 双击唤醒 X 高通msm8916 X 方案1

    最近要实现双击唤醒屏幕 第一个方案:勉强实现,但是功耗大,还没进行消抖处理 实现步骤如下: 1.找到tp实现的代码kernel/drivers/input/touchscreen/gsl/gslX68 ...

  8. 使用高通QXDM工具实现Android设备网络制式更改(如仅注册LTE网络)(独家!)

    修改网络制式需要用到高通的QXDM工具,该工具包下载链接如下: 链接:https://pan.baidu.com/s/1rRNicFvlRSstUhka2JSiOg 密码:pssp 具体操作步骤如下: ...

  9. 高通QCC5181蓝牙芯片耳机修改设备名称

    这里一共有三种方法 一.读写pskey方式实现 通过高通提供的接口,读写pskey的方式实现,主要修改的是app5的值. 二.修改烧录测试脚本实现 主要是修改烧录测试脚本ptsetup.txt,去掉烧 ...

  10. 高通平台GPIO漏电问题分析方法

    在Android智能手机项目开发过程中,我们经常会遇到GPIO漏电导致系统底电流偏高.故总结一下: 1.首先建议HW将怀疑漏电的GPIO与外围电路彻底断开 2.如果依然漏电,使用命令检查GPIO状态: ...

最新文章

  1. 一文看懂深度学习模型压缩和加速
  2. 兼顾效率与安全:如何制止新模版注入漏洞?
  3. Go gin使用html模板
  4. i7怎么老是显示无服务器,i7处理器真有这么差?网友:懂电脑的人都不买!
  5. java操作redis的操作_Java操作redis简单示例
  6. html为何转换为json,将HTML元素的“样式”属性转换为JSON
  7. 无需用户输入,Adobe提出自动高质量图像合成新方法
  8. A. 解决运行php文件出现乱码的问题
  9. 智能语音识别系统-解决方案.pdf
  10. 图像局部特征(二十)--Textons
  11. 衡量失败检测算法的指标
  12. 由数据范围反推算法时间复杂度和需要用到的算法类型
  13. Centos--swoole平滑重启服务
  14. 【转载】透视“专利恶霸”系列之一 双重标准 吃相难看
  15. v.douyin.com/xxx抖音网址官方生成制作抖音缩短口令网址php接口方法
  16. Learn OpenGL 笔记5.11 Anti Aliasing(抗锯齿)
  17. 零基础学习3D建模,第一步:3D建模软件有哪些?给你科普一下
  18. 升级mac最新系统macOS Catalina 10.15
  19. Django框架--一--安装,工程创建,应用创建,配置,基础操作介绍
  20. Eth-Trunk捆绑技术

热门文章

  1. jQuery排他思想(siblings)
  2. jquery常用方法之siblings方法
  3. 豆瓣十年,一个典型精英社区的起伏兴衰
  4. PTA习题 计算某年某月某日是该年中的第几天
  5. 自动化测试遇到的难点_自动化测试不成功的原因和实施过程中存在的问题
  6. 制作产品原型时要注意什么?
  7. 万物互联时代,谷歌、亚马逊Alexa、homekit该如何选择?
  8. c# 微信支付V3商家转账到零钱避坑宝典(一)
  9. PandasSQL数据处理对比
  10. linux执行 ifconfig 命令 eth0没有IP地址(intet addr、Bcast、Mask)