Ft5x06_ts驱动程序的重写

2024-05-11 11:18
文章标签 重写 ts 驱动程序 ft5x06

本文主要是介绍Ft5x06_ts驱动程序的重写,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 我们分析内核源码可知,Ft5x06_ts触摸屏驱动程序涉及如下内容:

1.  Linux下I2C驱动框架

2.  Linux下中断系统

3.  Linux下workqueue机制

4.  Linux下输入子系统

5.  中断初始化、I2C控制器相关初始化。在arch/arm/mach-exynos/mach-smdk4x12.c中的s3c_i2c1_set_platdata(&tiny4412_i2c1_data);

     

      Ft5x06_ts触摸屏驱动相关的源文件包括:  Ft5x06_ts.c、Ft5x06_ts.h、plat/ft5x0x_touch.h、Ts-if.c、Tiny4412_1wire_host.c(背光控制和一线精准触摸)等。

      内核中,Ft5x06_ts触摸屏驱动都被静态地编译进了内核,不方便调试,我们如何动态地加载此驱动呢,需要基于bus-dev-drv模型重新设计此驱动程序,步骤如下:


1.  配置内核

(1)去掉内核原有的驱动

make  menuconfig后去掉 < >   FocalTech ft5x0x TouchScreen driver一项。

  Symbol: TOUCHSCREEN_FT5X0X_SINGLE [=n]                                                            |
 Type  : boolean                                                                                   |
  Prompt: Disable MULTI-Touch Mode                                                                  |
     Defined at drivers/input/touchscreen/Kconfig:327                                                |
     Depends on: !S390 && !UML && INPUT [=y] && INPUT_TOUCHSCREEN [=y] && TOUCHSCREEN_FT5X0X [=n]    |
     Location:                                                                                       |
       -> Device Drivers                                                                             |
         -> Input device support                                                                     |
           -> Generic input layer (needed for keyboard, mouse, ...) (INPUT [=y])                     |
             -> Touchscreens (INPUT_TOUCHSCREEN [=y])                                                |
               -> FocalTech ft5x0x TouchScreen driver (TOUCHSCREEN_FT5X0X [=n])


(2)修改内核源码

      修改mach-Tiny4412.c中2215行,注释掉即可。

     //i2c_register_board_info(1, smdk4x12_i2c_devs1,ARRAY_SIZE(smdk4x12_i2c_devs1));

     如果配置内核时,去掉了一线触摸和ft05txx驱动,这里不用注释掉。


2.  实现dev


i2c_touchscreen_dev.c : 


#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/regmap.h>
#include <linux/slab.h>#include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>#include <plat/ft5x0x_touch.h>
static struct ft5x0x_i2c_platform_data ft5x0x_pdata = {.gpio_irq		= EXYNOS4_GPX1(6),//对应原理图中EINT14.irq_cfg		= S3C_GPIO_SFN(0xf),.screen_max_x	= 800,.screen_max_y	= 1280,.pressure_max	= 255,
};//0x50表示I2C设备的地址,一般在	I2C设备芯片手册可以查到
static struct i2c_board_info ft5x0x_info = {	I2C_BOARD_INFO("ft5x0x_ts", (0x70 >> 1)),//这个名字要和drv程序中的id_table中名字要一样.platform_data = &ft5x0x_pdata,
};static struct i2c_client *ft5x0x_client;static int ft5x0x_dev_init(void)
{struct i2c_adapter *i2c_adap;
/*1.触摸屏这个I2C设备挂接在了处理器的第一条总线上2.把这个总线号改为5,也能成功加载此驱动,原因在于i2c_new_device而不是i2c_new_probed_device方法
*/int busNum = 1 ;printk("ft5x0x dev of bus-dev-drv module_init!\n");i2c_adap = i2c_get_adapter(busNum);//这里要实验的触摸屏是挂接在第1条I2C总线上的,所以这里的参数是1if (!i2c_adap) {pr_err("failed to get adapter i2c%d\n", busNum);return -ENODEV;}ft5x0x_client = i2c_new_device(i2c_adap, &ft5x0x_info);//设置和注册i2c_client结构体if (!ft5x0x_client){//pr_err("failed to register %s to i2c%d\n",ft5x0x_info.type, busNum);pr_err("failed to register ft5x0x to i2c%d\n",busNum);return -ENODEV;}	i2c_put_adapter(i2c_adap);return 0;
}static void ft5x0x_dev_exit(void)
{printk("ft5x0x dev of bus-dev-drv module_exit!\n");i2c_unregister_device(ft5x0x_client);
}module_init(ft5x0x_dev_init);
module_exit(ft5x0x_dev_exit);
MODULE_LICENSE("GPL");

3.  实现drv


i2c_touchscreen_drv.c :

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/err.h>#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <plat/ctouch.h>
#include <plat/ft5x0x_touch.h>#include "ft5x06_ts.h"#ifndef CONFIG_TOUCHSCREEN_FT5X0X_SINGLE
#define CONFIG_FT5X0X_MULTITOUCH		1
#endif#define TOUCH_MAX_X						0x700
#define TOUCH_MAX_Y						0x400static int swap_xy = 0;
static int scal_xy = 0;/*---------------------------------------------------------* Chip I/O operations*/static struct i2c_client *this_client;static int ft5x0x_i2c_rxdata(char *rxdata, int length) 
{int ret;struct i2c_msg msgs[] = {{.addr	= this_client->addr,.flags	= 0,.len	= 1,.buf	= rxdata,},{.addr	= this_client->addr,.flags	= I2C_M_RD,.len	= length,.buf	= rxdata,},};ret = i2c_transfer(this_client->adapter, msgs, 2);if (ret < 0)pr_err("%s: i2c read error: %d\n", __func__, ret);return ret;
}#if 0
static int ft5x0x_i2c_txdata(char *txdata, int length) 
{int ret;struct i2c_msg msg[] = {{.addr	= this_client->addr,.flags	= 0,.len	= length,.buf	= txdata,},};ret = i2c_transfer(this_client->adapter, msg, 1);if (ret < 0)pr_err("%s: i2c write error: %d\n", __func__, ret);return ret;
}static int ft5x0x_write_reg(u8 addr, u8 val) 
{u8 buf[4];int ret;buf[0] = addr;buf[1] = val;ret = ft5x0x_i2c_txdata(buf, 2);if (ret < 0) {pr_err("write 0x%02x to reg (0x%02x) failed, %d", addr, val, ret);return -1;}return 0;
}
#endifstatic int ft5x0x_read_reg(u8 addr, u8 *pdata) 
{u8 buf[4] = { 0 };struct i2c_msg msgs[] = {{.addr	= this_client->addr,.flags	= 0,.len	= 1,.buf	= buf,},{.addr	= this_client->addr,.flags	= I2C_M_RD,.len	= 1,.buf	= buf,},};int ret;buf[0] = addr;ret = i2c_transfer(this_client->adapter, msgs, 2);if (ret < 0) {pr_err("read reg (0x%02x) error, %d\n", addr, ret);} else {*pdata = buf[0];}return ret;
}static int ft5x0x_read_fw_ver(unsigned char *val)
{int ret;*val = 0xff;ret = ft5x0x_read_reg(FT5X0X_REG_FIRMID, val);if (*val == 0x06) {
#if 0swap_xy = 1;scal_xy = 1;
#endif} else {/* TODO: Add support for other version */}return ret;
}/*---------------------------------------------------------* Touch core support*/static void ft5x0x_ts_report(struct ft5x0x_ts_data *ts) 
{struct ft5x0x_event *event = &ts->event;int x, y;int i;#ifdef CONFIG_FT5X0X_MULTITOUCHfor (i = 0; i < event->touch_point; i++) {if (swap_xy) {x = event->y[i];y = event->x[i];} else {x = event->x[i];y = event->y[i];}if (scal_xy) {x = (x * ts->screen_max_x) / TOUCH_MAX_X;y = (y * ts->screen_max_y) / TOUCH_MAX_Y;}input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);input_report_abs(ts->input_dev, ABS_MT_PRESSURE, event->pressure);input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, i);input_mt_sync(ts->input_dev);}
#elseif (event->touch_point == 1) {if (swap_xy) {x = event->y[i];y = event->x[i];} else {x = event->x[i];y = event->y[i];}if (scal_xy) {x = (x * ts->screen_max_x) / TOUCH_MAX_X;y = (y * ts->screen_max_y) / TOUCH_MAX_Y;}input_report_abs(ts->input_dev, ABS_X, x);input_report_abs(ts->input_dev, ABS_Y, y);input_report_abs(ts->input_dev, ABS_PRESSURE, event->pressure);}input_report_key(ts->input_dev, BTN_TOUCH, 1);
#endifinput_sync(ts->input_dev);
}static void ft5x0x_ts_release(struct ft5x0x_ts_data *ts) 
{
#ifdef CONFIG_FT5X0X_MULTITOUCH
#if 0/* NOT needed for ICS */input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
#endifinput_mt_sync(ts->input_dev);
#elseinput_report_abs(ts->input_dev, ABS_PRESSURE, 0);input_report_key(ts->input_dev, BTN_TOUCH, 0);
#endifinput_sync(ts->input_dev);
}static int ft5x0x_read_data(struct ft5x0x_ts_data *ts) 
{struct ft5x0x_event *event = &ts->event;u8 buf[32] = { 0 };int ret;#ifdef CONFIG_FT5X0X_MULTITOUCHret = ft5x0x_i2c_rxdata(buf, 31);
#elseret = ft5x0x_i2c_rxdata(buf, 7);
#endifif (ret < 0) {printk("%s: read touch data failed, %d\n", __func__, ret);return ret;}memset(event, 0, sizeof(struct ft5x0x_event));event->touch_point = buf[2] & 0x07;if (!event->touch_point) {ft5x0x_ts_release(ts);return 1;}#ifdef CONFIG_FT5X0X_MULTITOUCHswitch (event->touch_point) {case 5:event->x[4] = (s16)(buf[0x1b] & 0x0F)<<8 | (s16)buf[0x1c];event->y[4] = (s16)(buf[0x1d] & 0x0F)<<8 | (s16)buf[0x1e];case 4:event->x[3] = (s16)(buf[0x15] & 0x0F)<<8 | (s16)buf[0x16];event->y[3] = (s16)(buf[0x17] & 0x0F)<<8 | (s16)buf[0x18];case 3:event->x[2] = (s16)(buf[0x0f] & 0x0F)<<8 | (s16)buf[0x10];event->y[2] = (s16)(buf[0x11] & 0x0F)<<8 | (s16)buf[0x12];case 2:event->x[1] = (s16)(buf[0x09] & 0x0F)<<8 | (s16)buf[0x0a];event->y[1] = (s16)(buf[0x0b] & 0x0F)<<8 | (s16)buf[0x0c];case 1:event->x[0] = (s16)(buf[0x03] & 0x0F)<<8 | (s16)buf[0x04];event->y[0] = (s16)(buf[0x05] & 0x0F)<<8 | (s16)buf[0x06];break;default:printk("%s: invalid touch data, %d\n", __func__, event->touch_point);return -1;}
#elseif (event->touch_point == 1) {event->x[0] = (s16)(buf[0x03] & 0x0F)<<8 | (s16)buf[0x04];event->y[0] = (s16)(buf[0x05] & 0x0F)<<8 | (s16)buf[0x06];}
#endifevent->pressure = 200;return 0;
}static void ft5x0x_ts_pen_irq_work(struct work_struct *work) {struct ft5x0x_ts_data *ts = container_of(work, struct ft5x0x_ts_data, work);if (!ft5x0x_read_data(ts)) {ft5x0x_ts_report(ts);}enable_irq(this_client->irq);
}static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id) {struct ft5x0x_ts_data *ts = dev_id;disable_irq_nosync(this_client->irq);if (!work_pending(&ts->work)) {queue_work(ts->queue, &ts->work);}return IRQ_HANDLED;
}/*---------------------------------------------------------* I2C client driver functions*/#ifdef CONFIG_HAS_EARLYSUSPEND
static void ft5x0x_ts_suspend(struct early_suspend *handler)
{
#if 0struct ft5x0x_ts_data *ts;ts = container_of(handler, struct ft5x0x_ts_data, early_suspend);disable_irq(this_client->irq);cancel_work_sync(&ts->work);flush_workqueue(ts->queue);ft5x0x_set_reg(FT5X0X_REG_PMODE, PMODE_HIBERNATE);
#endifprintk("ft5x0x_ts: suspended\n");
}static void ft5x0x_ts_resume(struct early_suspend *handler)
{
#if 0/* Wakeup: output_L --> 100ms --> output_H --> 100ms */enable_irq(this_client->irq);
#endifprintk("ft5x0x_ts: resumed\n");
}
#endifstatic int ft5x0x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
{struct ft5x0x_i2c_platform_data *pdata;struct ft5x0x_ts_data *ts;struct input_dev *input_dev;unsigned char val;unsigned int ctp_id;int err = -EINVAL;printk("ft5x0x_ts_probe match OK!\n");ctp_id = tiny4412_get_ctp();if (ctp_id != CTP_FT5X06 && ctp_id != CTP_AUTO) {return -ENODEV;}if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {err = -ENODEV;goto exit_check_functionality_failed;}ts = kzalloc(sizeof(*ts), GFP_KERNEL);if (!ts) {err = -ENOMEM;goto exit_alloc_data_failed;}pdata = client->dev.platform_data;if (!pdata) {dev_err(&client->dev, "failed to get platform data\n");goto exit_no_pdata;}ts->screen_max_x = pdata->screen_max_x;ts->screen_max_y = pdata->screen_max_y;ts->pressure_max = pdata->pressure_max;ts->gpio_irq = pdata->gpio_irq;if (ts->gpio_irq != -EINVAL) {client->irq = gpio_to_irq(ts->gpio_irq);} else {goto exit_no_pdata;}if (pdata->irq_cfg) {s3c_gpio_cfgpin(ts->gpio_irq, pdata->irq_cfg);s3c_gpio_setpull(ts->gpio_irq, S3C_GPIO_PULL_NONE);}ts->gpio_wakeup = pdata->gpio_wakeup;ts->gpio_reset = pdata->gpio_reset;INIT_WORK(&ts->work, ft5x0x_ts_pen_irq_work);this_client = client;i2c_set_clientdata(client, ts);ts->queue = create_singlethread_workqueue(dev_name(&client->dev));if (!ts->queue) {err = -ESRCH;goto exit_create_singlethread;}input_dev = input_allocate_device();if (!input_dev) {err = -ENOMEM;dev_err(&client->dev, "failed to allocate input device\n");goto exit_input_dev_alloc_failed;}ts->input_dev = input_dev;set_bit(EV_SYN, input_dev->evbit);set_bit(EV_ABS, input_dev->evbit);set_bit(EV_KEY, input_dev->evbit);#ifdef CONFIG_FT5X0X_MULTITOUCHset_bit(ABS_MT_TRACKING_ID, input_dev->absbit);set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit);set_bit(ABS_MT_POSITION_X, input_dev->absbit);set_bit(ABS_MT_POSITION_Y, input_dev->absbit);input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, ts->screen_max_x, 0, 0);input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, ts->screen_max_y, 0, 0);input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, ts->pressure_max, 0, 0);input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, FT5X0X_PT_MAX, 0, 0);
#elseset_bit(ABS_X, input_dev->absbit);set_bit(ABS_Y, input_dev->absbit);set_bit(ABS_PRESSURE, input_dev->absbit);set_bit(BTN_TOUCH, input_dev->keybit);input_set_abs_params(input_dev, ABS_X, 0, ts->screen_max_x, 0, 0);input_set_abs_params(input_dev, ABS_Y, 0, ts->screen_max_y, 0, 0);input_set_abs_params(input_dev, ABS_PRESSURE, 0, ts->pressure_max, 0 , 0);
#endifinput_dev->name = FT5X0X_NAME;input_dev->phys = "input(mt)";input_dev->id.bustype = BUS_I2C;input_dev->id.vendor = 0x12FA;input_dev->id.product = 0x2143;input_dev->id.version = 0x0100;err = input_register_device(input_dev);if (err) {input_free_device(input_dev);dev_err(&client->dev, "failed to register input device %s, %d\n",dev_name(&client->dev), err);goto exit_input_dev_alloc_failed;}msleep(3);err = ft5x0x_read_fw_ver(&val);if (err < 0) {dev_err(&client->dev, "chip not found\n");goto exit_irq_request_failed;}err = request_irq(client->irq, ft5x0x_ts_interrupt,IRQ_TYPE_EDGE_FALLING /*IRQF_TRIGGER_FALLING*/, "ft5x0x_ts", ts);if (err < 0) {dev_err(&client->dev, "Request IRQ %d failed, %d\n", client->irq, err);goto exit_irq_request_failed;}disable_irq(client->irq);dev_info(&client->dev, "Firmware version 0x%02x\n", val);#ifdef CONFIG_HAS_EARLYSUSPENDts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;ts->early_suspend.suspend = ft5x0x_ts_suspend;ts->early_suspend.resume = ft5x0x_ts_resume;register_early_suspend(&ts->early_suspend);
#endifenable_irq(client->irq);tiny4412_set_ctp(CTP_FT5X06);dev_info(&client->dev, "FocalTech ft5x0x TouchScreen initialized\n");return 0;exit_irq_request_failed:input_unregister_device(input_dev);exit_input_dev_alloc_failed:cancel_work_sync(&ts->work);destroy_workqueue(ts->queue);exit_create_singlethread:i2c_set_clientdata(client, NULL);exit_no_pdata:kfree(ts);exit_alloc_data_failed:
exit_check_functionality_failed:dev_err(&client->dev, "probe ft5x0x TouchScreen failed, %d\n", err);return err;
}static int __devexit ft5x0x_ts_remove(struct i2c_client *client) 
{struct ft5x0x_ts_data *ts = i2c_get_clientdata(client);printk("ft5x0x drv of bus-dev-drv at24cxx_remove!\n");#ifdef CONFIG_HAS_EARLYSUSPENDunregister_early_suspend(&ts->early_suspend);
#endifif (client->irq) {free_irq(client->irq, ts);}cancel_work_sync(&ts->work);destroy_workqueue(ts->queue);i2c_set_clientdata(client, NULL);input_unregister_device(ts->input_dev);if (ts->input_dev)kfree(ts->input_dev);kfree(ts);return 0;
}//用到哪些就声明哪些内容,比如driver_data用不到,所以这里就写0
static const struct i2c_device_id ft5x0x_ts_id[] = {{ FT5X0X_NAME, 0 },{ }
};MODULE_DEVICE_TABLE(i2c, ft5x0x_ts_id);/* 1. 分配/设置i2c_driver */
static struct i2c_driver ft5x0x_ts_driver = {.probe		= ft5x0x_ts_probe,.remove		= __devexit_p(ft5x0x_ts_remove),.id_table	= ft5x0x_ts_id,.driver	= {.name	= FT5X0X_NAME,//在这里,这个名字并不重要,重要的是id_table里面的名字,所以这里可以随便起.owner	= THIS_MODULE,},
};static int __init ft5x0x_ts_init(void)
{int ret;printk("ft5x0x drv of bus-dev-drv module_init!\n");/* 2. 注册i2c_driver */ret = i2c_add_driver(&ft5x0x_ts_driver);if (ret != 0){pr_err("Failed to register ft5x0x I2C driver: %d\n", ret);}return ret;
}static void __exit ft5x0x_ts_exit(void)
{printk("ft5x0x drv of bus-dev-drv module_exit!\n");i2c_del_driver(&ft5x0x_ts_driver);
}module_init(ft5x0x_ts_init);
module_exit(ft5x0x_ts_exit);MODULE_AUTHOR("<wenfs@Focaltech-systems.com>");
MODULE_DESCRIPTION("FocalTech ft5x0x TouchScreen driver");
MODULE_LICENSE("GPL");

4.  编译模块之Makefile


Makefile:


KERN_DIR = /home/samba/linuxKernel_ext4Fs_src/linux-3.5-2015-8all:make -C $(KERN_DIR) M=`pwd` modules clean:make -C $(KERN_DIR) M=`pwd` modules cleanrm -rf modules.orderobj-m	+= i2c_touchscreen_dev.o
obj-m	+= i2c_touchscreen_drv.o

5.  测试

    测试时加载模块后才运行QT程序。   

这篇关于Ft5x06_ts驱动程序的重写的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/979380

相关文章

Ext重写手法

常用的几种方式:1、Ext.apply()和Ext.applyIf()2、Ext.override()3、想做某个类大的修改,可以把该类单独从源码中拿出来,直接修改,然后引用时先应用ext-all.js,再引用从源码中拿出修改的那个类4、obj.prototype.method=function(){}

C#通过ACE OLEDB驱动程序访问 Access和 Excel

ACE 代表 Access Connectivity Engine。它是 Microsoft 提供的一组组件,用于访问和操作 Microsoft Access 数据库以及其他类似的文件格式,如 Excel 工作簿。ACE 主要包括以下几部分: ACE OLEDB 驱动程序:用于通过 OLE DB 提供程序访问 Access 数据库和 Excel 文件。例如,Microsoft.ACE.OLED

泛型第二课,派生子类、属性类型、方法重写、泛型擦除

子类(实现类) 子类与父类|接口一样使用泛型子类指定具体的类型子类与父类|接口 同时擦除类型子类泛型,父类|接口 擦除错误:不能子类擦除,父类|接口泛型 package com.pkushutong.genericity3;/*** 父类为泛型类* 1、属性* 2、方法* * 要么同时擦除,要么子类大于等于父类的类型* 不能子类擦除,父类泛型* 1、属性类型* 父类中,随父类型定

Python中的方法重写与多态:解锁编程的无限可能

在编程的世界里,灵活性与扩展性往往是衡量一个语言是否强大、易于维护的关键指标。Python,作为一种被广泛使用的高级编程语言,不仅以其简洁易读的语法赢得了众多开发者的喜爱,更因其支持多种面向对象特性而备受青睐。其中,“方法重写”与“多态”便是两个核心概念,它们不仅能够极大地提高代码的复用性和可维护性,还能帮助我们构建更加灵活、健壮的软件系统。本文将通过一系列由浅入深的例子,带你一起探索这两个概念的

【大数据Java基础-JAVA 面向对象13】面向对象的特征二:继承性 (二) 方法的重写

1.什么是方法的重写(override 或 overwrite)? 子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作. 2. 应用: 重写以后,当创建子类对象以后,通过子类对象调用子父类中的同名同参数的方法时,实际执行的是子类重写父类的方法。 3.举例: class Circle{ public double findArea(){}//求面积 } class Cylinder e

vue ts 本地缓存数据

vue ts 本地缓存数据 需求是:给每日最高热度的数据,每个用户弹窗三次,持续五秒 // 每日最高热度 弹窗三次const popupKey = 'dailyPopupCount_';const today = new Date().toISOString().split('T')[0]; // dailyPopupCount_2024-08-26const popupCount =

随手记(2)-java.sql.SQLException: [Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序

问题描述: 在使用Java连接access数据的.mdb文件时候程序报如下错误 java.sql.SQLException: [Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序     错误原因: 在win7 office2013下报错 解决方法:  查看Java桥连程序连接字符串是否写成{Microsoft Access Driver (*.m

记录一个拖拽组件vue3+ts

记录一个拖拽组件vue+ts “vue”: “^3.0.0” “typescript”: “~4.1.5” 我这个是vue 3的最高版本,可以使用defineModel 父组件 <h1>props传值</h1><ModuleOrder v-model:orderList="orderList" v-model:defaultList="defaultList" ></ModuleO

【TS高频面试题】interface与type的区别

参考文章 一、基本概念 1. type(类型别名) 用来给一个类型起新名字,使用 type 创建类型别名。 2. interface(接口) 专门用于定义对象的结构(比如属性和方法) 二、相同点 (1)都可以描述对象或函数 interface interface User {name: stringage: number}interface SetUser {(name: st

iis7 url重写和重定向

注意不管是重写还是redirect重定向,匹配的url都要写成当前网站的url,也就是真是真实可以访问的,如当前网站ip为127.0.0.1,可以写成^127.0.0.1$ (1)url重写(可以实现伪静态) IIS实现反向代理 新建两个站点,端口分别使用 80 和 81,在DNS中新建A记录,指向该计算机(10.4.34.41) 配置过程如下: 1.在Windows Server