转自:https://www.cnblogs.com/lifexy/p/7628889.html

本节的触摸屏驱动也是使用之前的输入子系统


1.先来回忆之前第12节分析的输入子系统

其中输入子系统层次如下图所示,

其中事件处理层的函数都是通过input_register_handler()函数注册到input_handler_list链表中

搜索input_register_handler注册函数,就可以看到都是事件处理层里的函数:

所以最终如下图所示:

右边的驱动事件处理,内核是已经写好了的,所以我们的触摸屏只需要写具体的驱动设备,然后内核会与触摸屏驱动tsdev.c自动连接

2.本节需要用到的结构体成员如下:

struct input_dev {
void *private;
const char *name; //设备名字
const char *phys; //文件路径,比如 input/buttons
const char *uniq;
struct input_id id; unsigned long evbit[NBITS(EV_MAX)]; //表示支持哪类事件,常用有以下几种事件(可以多选)
//EV_SYN 同步事件,当使用input_event()函数后,就要使用这个上报个同步事件
//EV_KEY 键盘事件
//EV_REL (relative)相对坐标事件,比如鼠标
//EV_ABS (absolute)绝对坐标事件,比如摇杆、触摸屏感应
//EV_MSC 其他事件,功能
//EV_LED LED灯事件
//EV_SND (sound)声音事件
//EV_REP 重复键盘按键事件
//(内部会定义一个定时器,若有键盘按键事件一直按下/松开,就重复定时,时间一到就上报事件) //EV_FF 受力事件
//EV_PWR 电源事件
//EV_FF_STATUS 受力状态事件 unsigned long keybit[NBITS(KEY_MAX)]; //存放支持的键盘按键值
//键盘变量定义在:include/linux/input.h, 比如: KEY_L(按键L)、BTN_TOUCH(触摸屏的按键) unsigned long relbit[NBITS(REL_MAX)]; //存放支持的相对坐标值
unsigned long absbit[NBITS(ABS_MAX)]; //存放支持的绝对坐标值,存放下面4个absxxx[]
unsigned long mscbit[NBITS(MSC_MAX)]; //存放支持的其它事件,也就是功能
unsigned long ledbit[NBITS(LED_MAX)]; //存放支持的各种状态LED
unsigned long sndbit[NBITS(SND_MAX)]; //存放支持的各种声音
unsigned long ffbit[NBITS(FF_MAX)]; //存放支持的受力设备
unsigned long swbit[NBITS(SW_MAX)]; //存放支持的开关功能
... ... /*以下4个数组都会保存在上面成员absbit[]里,数组号为:ABS_xx ,位于include/linux/input.h */
/*比如数组0,标志就是ABS_X,以下4个的absXXX[0]就是表示绝对位移X方向的最大值、最小值... */
/*对于触摸屏常用的标志有:
ABS_X(X坐标方向), ABS_Y(Y坐标方向), ABS_PRESSURE(压力方向,比如绘图,越用力线就越粗)* /
int absmax[ABS_MAX + 1]; //绝对坐标的最大值
int absmin[ABS_MAX + 1]; //绝对坐标的最小值
int absfuzz[ABS_MAX + 1]; //绝对坐标的干扰值,默认为0,
int absflat[ABS_MAX + 1]; //绝对坐标的平焊位置,默认为0
... ...

3.本节需要用到的函数:

struct input_dev *input_allocate_device(void);  //向内存中分配input_dev结构体

input_free_device(struct input_dev *dev);   //释放内存中的input_dev结构体

input_register_device(struct input_dev *dev);   //注册一个input_dev,若有对应的驱动事件,
则在/sys/class/input下创建这个类设备 input_unregister_device(struct input_dev *dev); //卸载/sys/class/input目录下的
input_dev这个类设备 set_bit(nr,p); //设置某个结构体成员p里面的某位等于nr,支持这个功能
/* 比如:
set_bit(EV_KEY,buttons_dev->evbit); //设置input_dev结构体buttons_dev->evbit支持EV_KEY
set_bit(KEY_S,buttons_dev->keybit); //设置input_dev结构体buttons_dev->keybit支持按键”S” */ input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat);
//设置绝对位移的支持参数
//dev: 需要设置的input_dev结构体
//axis : 需要设置的数组号,常用的有: ABS_X(X坐标方向), ABS_Y(Y坐标方向), ABS_PRESSURE(压力方向)//min: axis方向的最小值, max:axis方向的最大值, fuzz: axis方向的干扰值, flat:axis方向的平焊位置

input_report_abs(struct input_dev *dev, unsigned int code, int value);
//上报EV_ABS事件
//该函数实际就是调用的input_event(dev, EV_ABS, code, value);
//*dev :要上报哪个input_dev驱动设备的事件
// code: EV_ABS事件里支持的哪个方向,比如X坐标方向则填入: ABS_X
//value:对应的方向的值,比如X坐标126 input_report_key(struct input_dev *dev, unsigned int code, int value);
//上报EV_KEY事件 input_sync(struct input_dev *dev); //同步事件通知,通知系统有事件上报 struct clk *clk_get(struct device *dev, const char *id);
//获得*id模块的时钟,返回一个clk结构体
//*dev:填0即可, *id:模块名字, 比如"adc","i2c"等,名字定义在clock.c中 clk_enable(struct clk *clk);
//开启clk_get()到的模块时钟,就是使能CLKCON寄存器的某个模块的位

4.电阻式触摸屏介绍:

如下图所示,2440开发板使用的是4线触摸屏,该4线连接在2440的AIN4~AIN7引脚上,该引脚专门是用来接收模拟输入信号.

引脚说明:

YM: (Y Minus)触摸屏的Y坐标的负线,也可以用Y -表示

YP : (Y Power)触摸屏的Y坐标的正线, 也可以用Y+表示

XM: (Y Minus)触摸屏的Y坐标的负线, 也可以用X-表示

XP : (Y Power)触摸屏的Y坐标的正线, 也可以用X+表示

4.1  4线触摸屏包含了两个阻性层,如下图所示:

当没有触摸按下时,X层和Y层是分离的,此时就测不到电压

4.2 测X坐标方向时:

如下图,  把XP接3.3V , XM接0V, YP和YM悬空,我们以按压X坐标的中间位置, X层和Y层便闭合了,此时YP就会输出当前X坐标值的1.66V给CPU

4.3 测Y坐标方向时:

如下图, 把YP接3.3V , YM接0V, XP和XM悬空,我们以按压X坐标的中间位置, X层和Y层便闭合了,此时XP就会输出当前X坐标值的1.66V给CPU

5.接下来开始看2440手册

如下图,2440的ADC分辨率为10位(0~0X3FFF)

如下图,若工作在普通ADC模式,则通过寄存器ADCCON->SEL_MUX来选择转换哪个引脚的模拟信号

当设置为ADC等待中断模式时,测到有屏幕笔尖触摸,就会产生INT_TC中断

其中ADC的工作频率最大为2.5MHZ,需要设置寄存器ADCCON->PRSCVL更改分频系数

5.1 获取笔尖触摸按下/松开使用的是ADC等待中断模式:
当笔尖落下时触摸屏控制器产生中断(INT_TC)信号。需要设置寄存器ADCTSC=0xd3/0x1d3

设置寄存器ADCTSC=0x0d3/0x1d3 (X 1101 0011)时(如下图):

开启 YM开关,使能XP上拉, 开启等待中断模式

当有笔尖按下时,X层和Y层闭合,然后会拉低XP和XM电平,输出低电平

设置为0x0d3是检测触摸低电平, 设置为0x1d3是检测触摸上拉电平

(PS:  ADCDAT0的bit15位用来标志笔尖是按下还是松开)

5.2 获取XY坐标时使用的是自动 X/Y 方向转换模式

当ADC转换成功,  X 坐标值到 ADCDAT0 和 Y 坐标值到ADCDAT1 后,就会产生INT_ADC中断

自动获取XY坐标时(如下图):

设置寄存器ADCTSC=0X0C (关闭XP上拉、启动自动XY方向转换)

设置寄存器ADCCON的位[0]=1(开启一次ADC转换,当ADC转换成功该位清0)

6.编写代码

步骤如下:

6.1 在init入口函数中:

1)分配一个input_dev结构体

2)设置input_dev的成员

  -> 2.1)设置input_dev->evbit支持按键事件,绝对位移事件

      (触摸屏:通过按键BTN_TOUCH获取按下/松开,通过绝对位移获取坐标)

  -> 2.2)设置input_dev-> keybit支持BTN_TOUCH触摸屏笔尖按下

  -> 2.3)设置input_dev-> absbit 支持ABS_X、ABS_Y、 ABS_PRESSURE

         input_set_abs_params(ts.dev, ABS_X, 0, 0x3FF, 0, 0);

        input_set_abs_params(ts.dev, ABS_Y, 0, 0x3FF, 0, 0);           // 0x3FF:最大值为10位ADC,

      input_set_abs_params(ts.dev, ABS_PRESSURE, 0, 1, 0, 0);   //压力最多就是1

3)注册input_dev 驱动设备到内核中

4)设置触摸屏相关的硬件

  -> 4.1)开启ADC时钟,使用clk_get ()和clk_enable()函数

  -> 4.2) ioremap获取寄存器地址,设置寄存器ADCCON =(1<<14)|(49<<6),分频

  ->4.3)设置寄存器ADCDLY=0xffff,ADC启动延时时间设为最大值,使触摸按压更加稳定

  ->4.4)开启IRQ_TC笔尖中断、开启IRQ_ADC中断获取XY坐标

  -> 4.5)初始化定时器,增加触摸滑动功能

  ->4.6)最后设置寄存器ADCTSC=0x0d3,开启IRQ_TC中断

6.2 在出口函数中:

1)注销内核里的input_dev、

2)释放中断、删除定时器、iounmap注销地址、

3)释放input_dev、

6.3 在IRQ_TC中断函数中:

1)若判断笔尖为松开,设置寄存器ADCTSC =0XD3(按下中断)

2)若判断笔尖按下,设置为XY自动转换模式,启动一次ADC转换,ADC转换成功,会进入ADC中断

6.4 在IRQ_ADC中断函数中:

1)获取ADCDAT0的位[9:0],来算出XY方向坐标值

2)测量n次值保存在数组中,然后再次设置为XY自动转换模式,启动ADC

(PS:要启动ADC转换之前必须设置一次XY为自动转换模式,不然获取的数据会不准)

3)采集完毕,使用快速排序将n次值排序后,以最小值为基准,如有误差非常大的数,则舍弃,如果没有则打印数组的中间值,实现中值滤波。

(PS: 使用快速排序,比冒泡更快,详解:http://www.cnblogs.com/lifexy/p/7597276.html )

4)打印数据后,必须设置寄存器ADCTSC =0X1D3(松开中断IRQ_TC)

(PS:在ADC采样模式下是判断不到ADCDAT0的bit15位的,因为ADCDAT0已被自动设置为X坐标的采样值)

5)设置定时器10ms超时时间

6.5 在定时器超时函数中:

1)判断ADCDAT0的bit15位,若还在按下再次启动ADC转换(实现触摸滑动功能)

2)若松开,设置寄存器ADCTSC =0XD3(按下中断)

最终代码如下:

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/plat-s3c24xx/ts.h>
#include <asm/arch/regs-adc.h>
#include <asm/arch/regs-gpio.h> static struct input_dev *ts_dev;
static struct clk *ADC_CLK; //adc时钟
static struct timer_list ts_timer; //定时器 struct adc_regs{
unsigned long adccon;
unsigned long adctsc;
unsigned long adcdly;
unsigned long adcdat0;
unsigned long adcdat1;
unsigned long adcupdn;
}; static volatile struct adc_regs *adc_regs; /*启动TC 函数*/
static void set_pen_down(void)
{
/* 设置寄存器ADCTSC=0x0d3,开启IRQ_TC中断*/
adc_regs->adctsc = 0xd3;
} static void set_pen_up(void)
{
/* 设置寄存器ADCTSC=0x0d3,开启IRQ_TC中断*/
adc_regs->adctsc = 0x1d3;
} /*启动ADC 转换函数*/
static void adc_start(void)
{
adc_regs->adctsc= (1<<3)| (1<<2); //启动XY自动转换
adc_regs->adccon|=(1<<0); //启动1次ADC转换
} /*快速排序,比冒泡更快*/
/*快速排序详解:http://www.cnblogs.com/lifexy/p/7597276.html*/
static void find_frst(int *s,int lift,int right)
{
int i=lift,j=right,temp; //(1)初始化i、j
if(lift>=right)
return ;
temp=s[i]; //(2)以第一个数组为比较值,保存到temp中
while(i<j)
{
while(j>i&&s[j]>=temp) //(3)j--,找小值
j--;
s[i]= s[j]; //保存小值,到s[i]上
while(i<j&&s[i]<=temp) //(4)i++,找大值
i++;
s[j--]=s[i]; //保存大值 到s[j]上
} s[i]=temp; //(5)将比较值放在s[i]上 /*(6)拆分成两个数组 s[0,i-1]、s[i+1,n-1]又开始排序 */
find_frst(s,lift,i-1); //左
find_frst(s,i+1,right); //右
} /*查找X Y坐标偏移值是否太大*/
/*return: 0误差大, 1误差小 */
static int find_xy_offset(int x[], int y[],int n)
{
int i;
for(i=n;i>=1;i--)
{
if(x[i]-x[i-1]>10) //判断是否大于误差10,
return 0;

if(y[i]-y[i-1]>10)  //判断是否大于误差10,
return 0;
} return 1;
} /*定时器函数,实现触摸滑动功能 */
void pen_updown_timer(unsigned long cnt)
{
if((adc_regs->adcdat0>>15)&0x01) //此时笔尖已经抬起
{
set_pen_down(); //设置TC中断
}
else
{
adc_start(); //启动一次ADC转换
} } /*触摸中断IRQ_TC */
static irqreturn_t tc_handler(int irq, void *dev_id)
{ if((adc_regs->adcdat0>>15)&0x01) //此时笔尖已经抬起
{
set_pen_down();
} else
{
adc_start(); //启动一次ADC转换
}
return IRQ_HANDLED;
} /*ADC中断IRQ_ADC:测XY坐标 */
static irqreturn_t adc_handler(int irq, void *dev_id)
{
static int adc_x[5],adc_y[5]; //保存XY坐标
static unsigned char xy_cnt=0; //计数 adc_y[xy_cnt] =adc_regs->adcdat1&0x3ff; //10位ADC
adc_x[xy_cnt] =adc_regs->adcdat0&0x3ff; //10位ADC if (adc_regs->adcdat0 & (1<<15))
{
/* 已经松开 */
xy_cnt = 0;
set_pen_down();
}
else{
xy_cnt++;
if(xy_cnt>=5)
{
xy_cnt=0;
find_frst(adc_x,0,4); // 快速排序X
find_frst(adc_y,0,4); // 快速排序y
if(find_xy_offset(adc_x,adc_y,4))
{
printk("X: %04d,y: %04d \n",adc_x[2],adc_y[2]); //中值滤波
} set_pen_up();
mod_timer(&ts_timer ,jiffies+HZ/100); //启动定时10ms
}
else //在测一次
{
adc_start(); //启动 ADC
}
}
return IRQ_HANDLED;
} /*入口函数*/
static int myts_init(void)
{
/*1. 申请input_dev */
ts_dev=input_allocate_device();
/*2. 设置input_dev*/
set_bit(EV_ABS, ts_dev->evbit);
set_bit(EV_KEY, ts_dev->evbit);
set_bit(BTN_TOUCH, ts_dev->keybit);
input_set_abs_params(ts_dev, ABS_X , 0 , 0x3ff , 0 , 0); //adc是个10位的,所以为0X3FF
input_set_abs_params(ts_dev, ABS_Y , 0 , 0x3ff , 0 , 0); //adc是个10位的,所以为0X3FF
input_set_abs_params(ts_dev, ABS_PRESSURE, 0 , 1 , 0 , 0); //adc是个10位的,所以为0X3FF /*3.注册input_dev 驱动设备到内核中*/
input_register_device(ts_dev); /*4.设置触摸屏相关的硬件*/
/*4.1 开启ADC时钟 */
ADC_CLK =clk_get(0,"adc");
clk_enable(ADC_CLK); /*4.2 设置寄存器ADCCON分频,*/
adc_regs=ioremap(0x58000000, sizeof(struct adc_regs));
adc_regs->adccon=(1<<14)|(49<<6); //50Mhz/(49+1)=1Mhz /*4.3 设置中断IRQ_TC IRQ_ADC */
request_irq(IRQ_TC , tc_handler, IRQF_SAMPLE_RANDOM, "pen_updown", 0);
request_irq(IRQ_ADC , adc_handler, IRQF_SAMPLE_RANDOM, "adc" , 0); /*4.4设置寄存器ADCDLY=0xffff */
adc_regs->adcdly =0xffff; /*4.5 初始化定时器*/
init_timer(&ts_timer);
ts_timer.function =pen_updown_timer;
add_timer(&ts_timer); /*4.6设置寄存器ADCTSC=0x0d3,开启IRQ_TC中断*/
set_pen_down();
return 0;
} /*出口函数*/
static void myts_exit(void)
{
/*1.注销内核里的input_dev、*/
input_unregister_device(ts_dev);
/*2.释放中断、删除定时器、iounmap注销地址、*/
free_irq(IRQ_TC, NULL);
free_irq(IRQ_ADC, NULL); del_timer(&ts_timer);
iounmap(adc_regs); /*3.释放input_dev、*/
input_free_device(ts_dev);
} module_init(myts_init);
module_exit(myts_exit);
MODULE_LICENSE("GPL");

7.测试运行

7.1 重新设置编译内核(去掉默认的触摸屏驱动)

make menuconfig ,进入menu菜单重新设置内核参数:

进入Device Drivers-> Input device support -> Touchscreens ->

< >   S3C2410/S3C2440 touchscreens     //将自带的触摸屏驱动去掉, 不编进内核和模块

然后make uImage 编译内核

将新的触摸屏驱动模块放入nfs文件系统目录中

7.2然后烧写内核,装载触摸屏驱动模块

如下图, 通过 ls -l /dev/event* 命令可以看到我们的触摸屏驱动的设备为event0

7.3 测试运行:

如下图所示,可以看到在同一个点按下时,变化都一致,没有误差

有了定时器后,也能支持滑动功能, 如下图滑动Y方向:

此时的驱动只是打印数据,并没有上报EV_KYE事件和EV_ABS事件

8.添加上报事件

设置上报事件之前还要删除printk打印信息,步骤如下:

8.1 在IRQ_TC中断函数滤波处,添加:

input_report_abs(ts_dev, ABS_X, adc_x[2]);   //上报X方向值
input_report_abs(ts_dev, ABS_X, adc_y[2]); //上报Y方向值
input_report_abs(ts_dev, ABS_PRESSURE, 1); //上报压力方向值
input_report_key(ts_dev,BTN_TOUCH,1); //上报BTN_TOUCH按键值按下
input_sync(ts_dev); //上报同步事件,通知系统有事件上报

8.2 在(ADCDAT0的bit15位==1)触摸松开处,添加:

input_report_abs(ts_dev, ABS_PRESSURE, 0);  //上报压力值为0
//(PS:必须要上报一次压力值,否则压力值会一直为1,会影响tslib的测试运行)
input_report_key(ts_dev,BTN_TOUCH,0); //上报BTN_TOUCH按键值松开
input_sync(ts_dev); //上报同步事件,通知系统有事件上报

9.测试运行:

如下图, 通过 ls -l /dev/event* 命令可以看到我们的触摸屏驱动的设备为event0

9.1使用hexdump命令来调试代码

(hexdump命令调试代码详解地址:http://www.cnblogs.com/lifexy/p/7553550.html)

测试效果如下:

(PS:必须要保证有ABS_X、ABS_Y、压力、触摸按键上传,不然TSLIB测试会失败)

9.2 使用TSLIB应用程序测试

(TSLIB安装以及使用详解地址: http://www.cnblogs.com/lifexy/p/7628780.html)

TSLIB: 为触摸屏驱动获得的采样提供诸如滤波、去抖、校准等功能,通常作为触摸屏驱动的适配层,为上层的应用提供了一个统一的接口。

校验界面如下图所示:

运行测试如下图所示,能随意画图:

最终,触摸屏驱动测试成功

下章开始学习:

19.Linux-USB总线驱动分析

18.Llinux-触摸屏驱动(详解)【转】的更多相关文章

  1. S3C2440触摸屏驱动详解

    2440的触摸屏转换接口搭载在ADC接口之上,使用上比ADC接口多了一些花样,首先,触摸屏接口有几种转换模式 1. 普通转换模式 单转换模式是最合适的通用ADC转换.此模式可以通过设置ADCCON(A ...

  2. 16.Linux-LCD驱动(详解)

    在上一节LCD层次分析中,得出写个LCD驱动入口函数,需要以下4步: 1) 分配一个fb_info结构体: framebuffer_alloc(); 2) 设置fb_info 3) 设置硬件相关的操作 ...

  3. 16.Linux-LCD驱动(详解)【转】

    转自:https://www.cnblogs.com/lifexy/p/7604011.html 在上一节LCD层次分析中,得出写个LCD驱动入口函数,需要以下4步: 1) 分配一个fb_info结构 ...

  4. linux usb 驱动详解

    linux usb 驱动详解 USB 设备驱动代码通过urb和所有的 USB 设备通讯.urb用 struct urb 结构描述(include/linux/usb.h ). urb 以一种异步的方式 ...

  5. 25.Linux-Nor Flash驱动(详解)

    1.nor硬件介绍: 从原理图中我们能看到NOR FLASH有地址线,有数据线,它和我们的SDRAM接口相似,能直接读取数据,但是不能像SDRAM直接写入数据,需要有命令才行 1.1其中我们2440的 ...

  6. 使用VS2010编译MongoDB C++驱动详解

    最近为了解决IM消息记录的高速度写入.多文档类型支持的需求,决定使用MongoDB来解决. 考虑到MongoDB对VS版本要求较高,与我现有的VS版本不兼容,在leveldb.ssdb.redis.h ...

  7. 18.Llinux-触摸屏驱动(详解)

    本节的触摸屏驱动也是使用之前的输入子系统 1.先来回忆之前第12节分析的输入子系统 其中输入子系统层次如下图所示, 其中事件处理层的函数都是通过input_register_handler()函数注册 ...

  8. 13.Linux键盘驱动 (详解)

    版权声明:本文为博主原创文章,未经博主允许不得转载. 在上一节分析输入子系统内的intput_handler软件处理部分后,接下来我们开始写input_dev驱动 本节目标: 实现键盘驱动,让开发板的 ...

  9. 21.Linux-写USB键盘驱动(详解)

    本节目的: 根据上节写的USB鼠标驱动,来依葫芦画瓢写出键盘驱动 1.首先我们通过上节的代码中修改,来打印下键盘驱动的数据到底是怎样的 先来回忆下,我们之前写的鼠标驱动的id_table是这样: 所以 ...

随机推荐

  1. Azure 架构师认证考试

    Azure认证路线 AZ-300 AZ-301 https://blog.csdn.net/pg_edb/article/details/86794505 免费题 https://iteablue.c ...

  2. Ubuntu16.04 安装 JDK

    1.到Oracle官网下载 地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html ...

  3. SQL Server存储过程备份数据库的脚本-干货

    拿AAAAAAAA数据库为例子,除了汉字标注的替换真实的数据,其他都不动        CREATE proc [dbo].[p_log_backupAAAAAAAA]    @dbname sysn ...

  4. SQL Server 通过游标重新定义单据数据的单据编号

    DECLARE @Index INTSET @Index=100DECLARE UpdateCursor  CURSOR  FOR (SELECT DISTINCT AA.Id FROM dbo.表 ...

  5. RMAN 'Duplicate From Active Database' Feature in Oracle11g (Doc ID 452868.1)

    RMAN 'Duplicate From Active Database' Feature in Oracle11g (Doc ID 452868.1) APPLIES TO: Oracle Data ...

  6. git 现在本地创建仓库 再 推送到 远程 github 仓库中

    今天,需要再本地使用git管理代码,但是当代码创建好的时候,想发布到github上面的私有仓库中,但是没有提前创建远端仓库,所以需要把本地git仓库推送到远端另外一个仓库了,下面进行简要记录,刚刚经过 ...

  7. kettle教程---通过配置表格配置实现数据的批量增量更新(实用)

    本文接上篇文章,上面文章讲的是,通过配置文件的全量更新,现在说下增量更新 如上图所示,涉及到1个转换和1个作业. 1-表增量同步(转换) 可以通过读取同步表参数这个excel表格文件,获取表名称和同步 ...

  8. IT兄弟连 Java语法教程 数组 数组的声明

    Java语言支持两种语法格式来定义数组: type[] arrayName; type arrayName[]; 对这两种语法格式而言,通常推荐使用第一种格式,因为第一种格式不仅具有更好的语义,而且具 ...

  9. pytest框架之allure报告生成

    一.关于安装 allure是跟pytest一起集成使用的,所以需要同时安装pytest以及allure-pytest插件: pip install pytest pip install allure- ...

  10. 第一章 1.18 re模块

    方法使用 1. compile(正则表达式) - 编译创建正则表达式对象 re_obj = re.compile(r'\d{3}') re_obj.fullmatch('234') re.fullma ...