platfrom tree架构下实现3-Wire驱动(DS1302)

目录

概述

1 认识DS1302

1.1 DS1302 硬件电路

1.2 操作DS1302 

1.3 注意要点

2 IO引脚位置

3 添加驱动节点

3.1 更新内核.dts

3.2 更新板卡.dtb

4 驱动程序实现

4.1  编写驱动程序

4.2 编写驱动程序的Makefile

4.3 安装驱动程序

5 验证驱动程序

5.1 编写测试程序

5.2 编写测试程序代码Makefile

5.3 运行测试App

6 实时波形分析


概述

       本文介绍在platform-tree框架下如何实现复杂总线驱动程序,以DS1302为例,详细介绍如何在linux内核中,添加driver tree节点,以及如何在驱动程序中,调用多线接口IO。

1 认识DS1302

DS1302 数据手册和产品信息 | 亚德诺(ADI)半导体 (analog.com)

         DS1302是一款使用非常普遍的实时时钟芯片,可提供,年月日,时分秒,week实时数据。其和MCU直接的电路也非常简单,只需3个引脚(CE, IO , CLK)。

主要特性

  • 完全管理所有计时功能
    • 实时时钟可为秒、分、小时、日期、月、星期和年计数,闰年补偿有效期至2100年
    • 31 x 8电池供电通用RAM
  • 通过简单的串行端口与大多数微控制器进行接口
    • 简单的3线接口
    • TTL兼容(VCC = 5V)
    • 用于读取或写入时钟或RAM数据的单字节或多字节(突发模式)数据传输
  • 低功耗运行可延长备用电池运行时间
    • 2.0V至5.5V全面运行
    • 2.0V时电流消耗小于300nA
  • 8引脚DIP和8引脚SO封装充分减少了所需空间
  • 可选工业温度范围:-40°C至+85°C支持在多种应用中工作

1.1 DS1302 硬件电路

CE: 使能引脚

IO: 数据引脚(读/写数据)

SCLK: 时钟引脚

1.2 操作DS1302 

读寄存器波形如下:

CE: 高电平有效

写地址时,CLK上升沿有效

读数据时,CLK下降沿有效

写寄存器波形:

CE: 高电平有效

写地址时,CLK上升沿有效

写数据时,CLK上升沿有效

1.3 注意要点

从DS1302中读取的时间数据位BCD码,所以,在实际运用时,需要将其转化为十进制,例如:

// 从寄存器中读出的值为: 0x14,使用时需要将其转化为14,方法如下:
static unsigned char bcd_2_dem(unsigned char x)
{return (x>>4)*10+(x&0x0f);                   //高4位乘以10,再加上低4位,即得到数值
}

初始化DS1302寄存器时,要进行上述数据转换的逆操作,方法如下:

// 如果要配置分钟数为25分钟,写到寄存器的值应该是: 0x25。转换方法如下:unsigned char dem_2_bcd( unsigned char val )
{return (((val/10)& 0x0f)<<4)|((val%10)&0x0f);
}

2 IO引脚位置

DS1302芯片在测试底板上的IO引脚位置:

//GPIO4_24:  DS1302_CE
//GPIO4_26:  DS1302_IO
//GPIO4_28:  DS1302_CLKCE_1302  = P2^4;   -----   D3   -- GPIO4_24
IO_1302  = P2^3;   -----   D5   -- GPIO4_26
CLK_1302 = P2^2;   -----   D7   -- GPIO4_28

硬件实物图:

在板卡ATK-DL6Y2C上DS1302的对应接口:

3 添加驱动节点

3.1 更新内核.dts

DS1302引脚和IMX.6ULL引脚对应关系:

GPIO4_24:  DS1302_CE   
GPIO4_26:  DS1302_IO
GPIO4_28:  DS1302_CLK

.dts文件路径:

/home/mftang/linux_workspace/study_atk_dl6y2c/kernel/atk-dl6u2c/arch/arm/boot/dts/imx6ull-14x14-evk.dts

1) 使用 i.MX Pins Tool v6 配置IO Pin

2) 添加IOMUXC数据至.dts文件

3)添加设备compatible至.dts文件

代码信息

	//mftang: user's ds1302, 2024-1-31//GPIO4_24:  DS1302_CE//GPIO4_26:  DS1302_IO//GPIO4_28:  DS1302_CLKmftangds1302 {compatible = "atk-dl6y2c,ds1302";pinctrl-names = "default";pinctrl-0 = <&pinctrl_gpio_mftangds1302>;ce-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>;io-gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>;clk-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>;status = "okay";};	

4) 编译.dts文件

在内核根目录下使用

make dtbs

5) 复制 .dtb 文件至NFS共享目录

cp arch/arm/boot/dts/imx6ull-14x14-emmc-4.3-480x272-c.dtb  /home/mftang/nfs/atk_dl6y2c/

3.2 更新板卡.dtb

开发版中的.dtb文件存放位置:

cd /run/media/mmcblk1p1

在开发板上把 .dtb文件复制到应用目录中:

cp /mnt/atk_dl6y2c/imx6ull-14x14-emmc-4.3-480x272-c.dtb /run/media/mmcblk1p1

复制.dtb文件到相应的运行目录,然后重新板卡。在/proc/device-tree中可以看见device节点,然后可以在driver中使用该节点。

4 驱动程序实现

4.1  编写驱动程序

驱动程序源码:

/***************************************************************
Copyright  2024-2029. All rights reserved.
文件名     : drv_09_tree_hs0038.c
作者       : tangmingfei2013@126.com
版本       : V1.0
描述       : ds1302 驱动程序
其他       : 无
日志       : 初版V1.0 2024/02/01  使用方法:
1) 在.dts文件中定义节点信息//mftang: user's ds1302, 2024-1-31//GPIO4_24:  DS1302_CE//GPIO4_26:  DS1302_IO//GPIO4_28:  DS1302_CLKmftangds1302 {compatible = "atk-dl6y2c,ds1302";pinctrl-names = "default";pinctrl-0 = <&pinctrl_gpio_mftangds1302>;gpios-ce = <&gpio4 24 GPIO_ACTIVE_HIGH>;gpios-io = <&gpio4 26 GPIO_ACTIVE_HIGH>;gpios-clk = <&gpio4 28 GPIO_ACTIVE_HIGH>;status = "okay";};2) 在驱动匹配列表 
static const struct of_device_id ds1302_of_match[] = {{ .compatible = "atk-dl6y2c,ds1302" },{ } // Sentinel
};3) 驱动使用方法:
typedef struct{unsigned char second;unsigned char minute;unsigned char hour;unsigned char week;unsigned char day;unsigned char month;unsigned char year;
}stru_ds1302_rtc;stru_ds1302_rtc rtc;read(fd, &rtc, sizeof(stru_ds1302_rtc));***************************************************************/
#include <linux/module.h>
#include <linux/poll.h>#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <asm/current.h>#define DEVICE_NAME      "treeds1302"     // dev/treeds1302/* ds1302dev设备结构体 */
struct ds1302stru_dev{dev_t   devid;                 /* 设备号          */struct  cdev cdev;             /* cdev            */struct  class *class;          /* 类              */struct  device *device;        /* 设备            */int     major;                 /* 主设备号        */struct  device_node *node;     /* ds1302设备节点  */int     userds1302;            /* ds1302 GPIO标号 */struct  gpio_desc *pin_ce;struct  gpio_desc *pin_io;struct  gpio_desc *pin_clk;
};struct ds1302stru_dev ds1302dev;         /* ds1302设备 */
static wait_queue_head_t ds1302_wq;static const unsigned char RTC_REG[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};/*device 相关的驱动程序 
*/
static unsigned char bcd_2_dem(unsigned char x)
{return (x>>4)*10+(x&0x0f);                   //高4位乘以10,再加上低4位,即得到数值
}static void ds1302_wr_byte(unsigned char dat)    //DS1302:写入操作
{unsigned char i;for(i=0;i<8;i++){if(dat&0x01){                            //从低字节开始传送gpiod_direction_output(ds1302dev.pin_io, 1); // ds1302 io = 1}else {gpiod_direction_output(ds1302dev.pin_io, 0); // ds1302 io = 0}// CLK_1302=0;  gpiod_direction_output(ds1302dev.pin_clk, 0);// CLK_1302=1;gpiod_direction_output(ds1302dev.pin_clk, 1);dat = dat>>1;}
}static unsigned char ds1302_rd_byte(void)  //DS1302:读取操作   
{unsigned char i,temp = 0;// IO_1302 as inputgpiod_direction_input( ds1302dev.pin_io );for(i=0;i<8;i++){if( gpiod_get_value(ds1302dev.pin_io) )temp=temp|0x80;elsetemp=temp&0x7f;// CLK_1302 = 1gpiod_direction_output(ds1302dev.pin_clk, 1);// CLK_1302 = 0gpiod_direction_output(ds1302dev.pin_clk, 0);temp=temp>>1;}return(temp);
}static void write_ds1302_reg(unsigned char addr,unsigned char dat)
{unsigned long flags;local_irq_save(flags);//CLK_1302=0;gpiod_direction_output(ds1302dev.pin_clk,0);//CE_1302=1; gpiod_direction_output(ds1302dev.pin_ce, 1);ds1302_wr_byte(addr); ds1302_wr_byte(dat);//CE_1302=0;gpiod_direction_output(ds1302dev.pin_ce, 0);//CLK_1302=0;gpiod_direction_output(ds1302dev.pin_clk,0);local_irq_restore(flags); 
}static unsigned char read_ds1302_reg(unsigned char addr)   
{unsigned long flags;unsigned char temp;local_irq_save(flags);// CLK_1302=0gpiod_direction_output(ds1302dev.pin_clk, 0);// CE_1302=1 gpiod_direction_output(ds1302dev.pin_ce, 1);ds1302_wr_byte(addr);      //写入地址temp = ds1302_rd_byte();// CE_1302=0gpiod_direction_output(ds1302dev.pin_ce, 0);// CLK_1302=0gpiod_direction_output(ds1302dev.pin_clk, 0);local_irq_restore(flags);return(temp);
} static void ds1302_wr_wp(unsigned char wp)
{if (wp)write_ds1302_reg(0x8e,0x80);elsewrite_ds1302_reg(0x8e,0x00);
}static void ds1302_stop(unsigned char flag)
{unsigned char chold;chold = read_ds1302_reg(0x81);if (flag)write_ds1302_reg(0x80,chold|0x80);elsewrite_ds1302_reg(0x80,chold&0x7f);
}static unsigned char ds1302_read_rtc( unsigned char reg )
{unsigned char dat;dat = read_ds1302_reg(reg);return  bcd_2_dem(dat);
}static void ds1302_get_rtc( unsigned char *buff)
{int LEN = sizeof(RTC_REG);int i = 0;for( i = 0; i < LEN; i++ ){buff[i] = ds1302_read_rtc( RTC_REG[i]|0x01);}
}static void ds1302_drv_init( unsigned char *buff )
{unsigned long flags;unsigned char temp,val;int LEN = sizeof(RTC_REG);int i;ds1302_stop(1);    // stop clockds1302_wr_wp(0);   // enable write local_irq_save(flags);for ( i=0; i < LEN; i++){val = buff[i];temp = (((val/10)& 0x0f)<<4)|((val%10)&0x0f);write_ds1302_reg( RTC_REG[i], temp );}local_irq_restore(flags);ds1302_wr_wp(1);  // disable write ds1302_stop(0);   // enable clock 
}/*linux driver 驱动接口: 实现对应的open/read/write等函数,填入file_operations结构体
*/
static ssize_t ds1302_drv_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{int LEN = sizeof(RTC_REG);unsigned char tempbuff[LEN];int length;length = copy_from_user(tempbuff, buf, LEN);if( cnt != LEN ){printk(" %s line %d write ds1302 register error! \r\n",  __FUNCTION__, __LINE__);return 0;}else{ds1302_drv_init( tempbuff );}return cnt;
}static ssize_t ds1302_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{int LEN = sizeof(RTC_REG);unsigned char tempbuff[LEN];int length;ds1302_get_rtc( tempbuff );length = copy_to_user(buf, tempbuff, LEN);return length;
}static unsigned int ds1302_drv_poll(struct file *fp, poll_table * wait)
{printk(" %s line %d \r\n",  __FUNCTION__, __LINE__);return 0;
}static int ds1302_drv_close(struct inode *node, struct file *file)
{printk(" %s line %d \r\n",  __FUNCTION__, __LINE__);return 0;
}/* 定义driver的file_operations结构体
*/
static struct file_operations ds1302_fops = {.owner   = THIS_MODULE,.write   = ds1302_drv_write,.read    = ds1302_drv_read,.poll    = ds1302_drv_poll,.release = ds1302_drv_close,
};/* 1. 从platform_device获得GPIOmftangds1302 {compatible = "atk-dl6y2c,ds1302";pinctrl-names = "default";pinctrl-0 = <&pinctrl_gpio_mftangds1302>;ce-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>;io-gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>;clk-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>;status = "okay";};*/
static int ds1302_probe(struct platform_device *pdev)
{printk("ds0302 driver and device was matched!\r\n");/* 1. 获得硬件信息 */ds1302dev.pin_ce = gpiod_get(&pdev->dev, "ce", 0);if (IS_ERR(ds1302dev.pin_ce)){printk("%s line %d get ce parameter error! \n", __FUNCTION__, __LINE__);}ds1302dev.pin_io = gpiod_get(&pdev->dev, "io", 0);if (IS_ERR(ds1302dev.pin_io)){printk("%s line %d get io parameter error! \n", __FUNCTION__, __LINE__);}ds1302dev.pin_clk = gpiod_get(&pdev->dev, "clk", 0);if (IS_ERR(ds1302dev.pin_clk)){printk("%s line %d get clk parameter error! \n", __FUNCTION__, __LINE__);}/* 2. device_create */device_create( ds1302dev.class, NULL, MKDEV( ds1302dev.major, 0 ), NULL, DEVICE_NAME);  return 0;
}static int ds1302_remove(struct platform_device *pdev)
{device_destroy( ds1302dev.class, MKDEV( ds1302dev.major, 0));gpiod_put(ds1302dev.pin_ce);gpiod_put(ds1302dev.pin_io);gpiod_put(ds1302dev.pin_clk);return 0;
}static const struct of_device_id atk_dl6y2c_ds1302[] = {{ .compatible = "atk-dl6y2c,ds1302" },{ },
};/* 1. 定义platform_driver */
static struct platform_driver ds1302_pltdrv = {.probe      = ds1302_probe,.remove     = ds1302_remove,.driver     = {.name   = "atk_ds1302",.of_match_table = atk_dl6y2c_ds1302,},
};/* 2. 在入口函数注册platform_driver */
static int __init ds1302_init(void)
{printk("%s line %d\n",__FUNCTION__, __LINE__);/* register file_operations  */ds1302dev.major = register_chrdev( 0, DEVICE_NAME,     /* device name */&ds1302_fops);  /* create the device class  */ds1302dev.class = class_create(THIS_MODULE, "ds1302_class");if (IS_ERR(ds1302dev.class)) {printk("%s line %d\n", __FUNCTION__, __LINE__);unregister_chrdev( ds1302dev.major, DEVICE_NAME);return PTR_ERR( ds1302dev.class );}init_waitqueue_head(&ds1302_wq);return platform_driver_register(&ds1302_pltdrv); 
}/* 3. 有入口函数就应该有出口函数:卸载驱动程序时,就会去调用这个出口函数*    卸载platform_driver*/
static void __exit ds1302_exit(void)
{printk("%s line %d\n", __FUNCTION__, __LINE__);platform_driver_unregister(&ds1302_pltdrv);class_destroy(ds1302dev.class);unregister_chrdev(ds1302dev.major, DEVICE_NAME);
}/* 7. 其他完善:提供设备信息,自动创建设备节*/module_init(ds1302_init);
module_exit(ds1302_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("tangmingfei2013@126.com");

4.2 编写驱动程序的Makefile

PWD := $(shell pwd)KERNEL_DIR=/home/mftang/linux_workspace/study_atk_dl6y2c/kernel/atk-dl6u2c
ARCH=arm
CROSS_COMPILE=/home/ctools/gcc-linaro-4.9.4-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-export  ARCH  CROSS_COMPILEobj-m:= drv_10_tree_ds1302.oall:$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modulesclean:rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions *.order *.symvers

4.3 安装驱动程序

在dev/目录下查看驱动程序

5 验证驱动程序

5.1 编写测试程序

测试程序源码

/***************************************************************
Copyright  2024-2029. All rights reserved.
文件名  : test_10_tree_ds1302.c
作者    : tangmingfei2013@126.com
版本    : V1.0
描述    : ds1302 测试程序,用于测试 drv_10_tree_ds1302
日志    : 初版V1.0 2024/1/29***************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>#define DEV_NAME    "/dev/treeds1302"typedef struct{unsigned char second;unsigned char minute;unsigned char hour;unsigned char week;unsigned char day;unsigned char month;unsigned char year;
}stru_ds1302_rtc;stru_ds1302_rtc rtc;int main(int argc, char **argv)
{int fd;fd = open(DEV_NAME, O_RDWR);if (fd < 0){printf("can not open file %s \r\n", DEV_NAME);return -1;}// init rtc rtc.year = 24;rtc.month = 2;rtc.day = 1;rtc.week = 4;rtc.hour = 18;rtc.minute = 2;rtc.second = 0;write(fd, &rtc, sizeof(stru_ds1302_rtc));while(1){read(fd, &rtc, sizeof(stru_ds1302_rtc));printf(" %02d-%02d-%02d week %d   %02d:%02d:%02d \r\n",  rtc.year, rtc.month, rtc.day, rtc.week,rtc.hour,rtc.minute, rtc.second);sleep(1);}close(fd);return 0;
}

5.2 编写测试程序代码Makefile

CFLAGS= -Wall -O2
CC=/home/ctools/gcc-linaro-4.9.4-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
STRIP=/home/ctools/gcc-linaro-4.9.4-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-striptest_10_tree_ds1302: test_10_tree_ds1302.o$(CC) $(CFLAGS) -o test_10_tree_ds1302 test_10_tree_ds1302.o$(STRIP) -s test_10_tree_ds1302clean:rm -f test_10_tree_ds1302 test_10_tree_ds1302.o

5.3 运行测试App

运行测试程序后,系统会初始化DS1302的时间,然后每隔1s从芯片中读取时间

6 实时波形分析

分析一个简单的波形,从寄存器:0x81中读取秒数据,秒数为57,具体波形图如下

读一个完整的年月日时分秒波形

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

何时以及如何选择制动电阻

制动电阻的选择是优化变频器应用的关键因素 制动电阻器在变频器中是如何工作的&#xff1f; 制动电阻器在 VFD 应用中的工作原理是将电机减速到驱动器设定的精确速度。它们对于电机的快速减速特别有用。制动电阻还可以将任何多余的能量馈入 VFD&#xff0c;以提升直流母线上的…

Electron实战(二):将Node.js和UI能力(app/BrowserWindow/dialog)等注入html

文章目录 设置webPreferences参数安装electron/remotemain进程中初始化html中使用dialog踩坑参考文档 上一篇&#xff1a;Electron实战(一)&#xff1a;环境搭建/Hello World/打包exe 设置webPreferences参数 为了能够在html/js中访问Node.js提供fs等模块&#xff0c;需要在n…

新概念英语第二册(54)

【New words and expressions】生词和短语&#xff08;14&#xff09; sticky adj. 粘的 finger n. 手指 pie n. 馅饼 mix v. 混合&#xff0c;拌和 pastr…

踩坑实录(First Day)

2023 年一整年感觉我的进步都很小&#xff0c;所以自 2024 年起&#xff0c;我将专门开设专栏记录自己在工作期间踩过的所有坑&#xff0c;一来是为了有个记录&#xff0c;自己不会再踩&#xff0c;而来也是为了跟大家做一个分享&#xff0c;与大家进行讨论&#xff0c;提升自己…

力扣宝石补给

欢迎各位勇者来到力扣新手村&#xff0c;在开始试炼之前&#xff0c;请各位勇者先进行「宝石补给」。 每位勇者初始都拥有一些能量宝石&#xff0c; gem[i] 表示第 i 位勇者的宝石数量。现在这些勇者们进行了一系列的赠送&#xff0c;operations[j] [x, y] 表示在第 j 次的赠送…

QT 范例阅读:系统托盘 The System Tray Icon example

main.cpp QApplication app(argc, argv);//判断系统是否支持 系统托盘功能if (!QSystemTrayIcon::isSystemTrayAvailable()) {QMessageBox::critical(0, QObject::tr("Systray"),QObject::tr("I couldnt detect any system tray ""on this system.&qu…

利用jmeter完成简单的压力测试

Jmeter是一个非常好用的压力测试工具。Jmeter用来做轻量级的压力测试&#xff0c;非常合适&#xff0c;只需要十几分钟&#xff0c;就能把压力测试需要的脚本写好。 1、什么是压力测试 顾名思义&#xff1a;压力测试&#xff0c;就是 被测试的系统&#xff0c;在一定的访问压…

下载、安装Jenkins

进入官网 下载Jenkins https://www.jenkins.io 直接点击Download 一般是下长期支持版 因为它是java写的&#xff0c;你要运行它&#xff08;Jenkins.war&#xff09;肯定要有java环境 有两种方式去运行它&#xff0c;一种是下载Tomcat&#xff08;是很经典的java容器或者jav…

代码随想录day16 Java版 二叉树部分

404.左叶子之和 感觉就是遍历&#xff0c;遇到叶子结点就累加&#xff0c;试了下居然过了 class Solution {int sum 0;public int sumOfLeftLeaves(TreeNode root) {add(root);return sum;}void add(TreeNode root){if (root null) return;if (root.left ! null &&…

linux编译ffmpeg动态库

1&#xff0c;获取源码&#xff1a;git clone https://git.ffmpeg.org/ffmpeg.git 2&#xff0c;创建编译目录&#xff0c;并编译、安装&#xff0c; cd ffmpeg mkdir build cd build ../configure --prefix~/ffmpeg --enable-shared --enable-debug1 //configure后需要使…

深入探索C++ Move语义:现代编程中的性能革命

1. 引言 介绍C中的Move语义 Move语义是C11中引入的一个重要特性&#xff0c;它为C编程语言带来了显著的性能改进。在这之前&#xff0c;C只支持拷贝语义&#xff0c;即通过拷贝构造函数和拷贝赋值操作符来复制对象。Move语义通过允许"移动"而非"拷贝"资源…

Git版本管理工具(基础):这一篇基本能满足Git基本的使用需求了!

文章目录 Git01-什么是Git作用 02-使用Git03-Git仓库创建 04-Git的三个区域三个区域 05-Git文件状态06-Git暂存区使用07-Git回退版本08-删除文件 Git 01-什么是Git 答&#xff1a;他是一个免费开源的&#xff0c;分布式代码版本控制系统&#xff0c;帮助开发团队维护代码 作用…

三、消除分心的事物(Eliminating Distractions)

External Improvements 外部改进 1.Eliminating Distractions 一、消除分心的事物 Distractions are the most obvious problem when it comes to focus, and they are often the easiest to fix. In particular, you want to find an environment for focus that minimizes b…

爬虫工作量由小到大的思维转变---<第四十五章 Scrapyd 关于gerapy遇到问题>

前言: 本章主要是解决一些gerapy遇到的问题,会持续更新这篇! 正文: 问题1: 1400 - build.py - gerapy.server.core.build - 78 - build - error occurred (1, [E:\\项目文件名\\venv\\Scripts\\python.exe, setup.py, clean, -a, bdist_uberegg, -d, C:\\Users\\Administrat…

网络安全面试题收集

1 Web篇 1.1 什么是SQL注入攻击&#xff1f;如何防止SQL注入攻击&#xff1f; SQL注入攻击是指攻击者通过向Web应用程序的输入框中插入恶意SQL语句来执行未经授权的操作。防止SQL注入攻击的方法包括使用参数化查询和输入验证&#xff0c;以及避免使用动态SQL语句。 1.2 什么…

红队渗透靶机:TIKI: 1

目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb 目录探测 1、dirsearch 2、gobuster WEB web信息收集 searchsploit cms信息收集 ssh登录 提权 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:2…

数据结构-数组

1.容器 容器用于容纳元素集合&#xff0c;并对元素集合进行管理和维护&#xff0e; 传统意义上的管理和维护就是&#xff1a;增&#xff0c;删&#xff0c;改&#xff0c;查&#xff0e; 我们分析每种类型容器时&#xff0c;主要分析其增&#xff0c;删&#xff0c;改&#xf…

Matlab 移动最小二乘求解仿射变换

文章目录 一、简介二、实现代码三、实现效果参考文献一、简介 在现实生活中,我们常常应用一些刚性的变换来实现物体的旋转平移,对于非刚性的变换我们都没有在意,其实这种变换也是无处不在的,如我们经常看的动画就可以通过一些非刚性的变换达到一些非常夸张的效果。这里,我…

iMazing 3中文版双平台版本同步,iOS 设备在 Windows 上也能自动备份了

自从WWDC 2019 宣布 iTunes 退役后&#xff0c;也许很多小伙伴都对「上位者」iMazing 有所耳闻。 这款设计更加人性化、功能细致强大的 iOS 备份管理工具。 iMazing 支持在 Windows 及 Mac 上运行&#xff0c;而这个月 Windows 版本更新至 2.17. 之后&#xff0c;iMazing 的双…

Kubernetes基础(十一)-CNI网络插件用法和对比

1 CNI概述 1.1 什么是CNI&#xff1f; Kubernetes 本身并没有实现自己的容器网络&#xff0c;而是借助 CNI 标准&#xff0c;通过插件化的方式来集成各种网络插件&#xff0c;实现集群内部网络相互通信。 CNI&#xff08;Container Network Interface&#xff0c;容器网络的…