Android input touchpanel驱动流程_touchpanel驱动详解-程序员宅基地

技术标签: Android_Driver  linux  tp  

TP的结构

TP驱动芯片厂商主要有:focaltech(敦泰科技),synaptics(新思),atmel(爱特梅尔),iliteck(奕立)

手机显示屏LCD&TP的不同贴合工艺
主要结构上主要分为in-cell on-cell ogs,主要是面板模组厂商和触摸屏模组厂商的不同倾向的选择所产生的。

OGS(ONE GLASSS SOLUTION)技术,现在主要由触控屏厂商主导并发展,显示面板厂商倾向推动On-Cell或In-Cell的技术是因为其本身就是生产显示屏的,因此倾向于将触摸层制作在显示屏;而触控模组厂商或上游材料厂商则倾向于OGS,即将触控层制作在保护玻璃上,主要原因是该技术具备较强的制作工艺能力和技术。

In-cell是指将TP触摸面板功能嵌入到LCD液晶像素中的方法,因此原本3层的保护玻璃+TP+LCD变成了两层的保护玻璃+带触控功能的LCD,这样能使屏幕变得更加轻薄,留给手机的空间就更大,可扩充电池,同时若出现触摸出现问题,需要同屏幕一起换掉。

On-cell是指将触摸屏嵌入到显示屏的彩色滤光片基板和偏光片之间的方法,即在液晶面板上配触摸传感器,相比in-cell技术难度降低不少。三星、日立、LG等厂商在on-cell结构触摸屏上进展较快,目前,on-cell多应用于三星Amoled面板产品上,技术上尚未能克服薄型化、触控时产生的颜色不均等问题。

目前InCell&Oncell是一个阵营,OSG是一个阵营。低端一般用OSG。

TP的硬件接口

硬件原理图可以结合Android Qcom Display学习博客中的部分,硬件接口主要是
硬件接口
中断引脚:TS_INT_N GPIO80
复位引脚:TS_RESET_N GPIO71
总线通信:TOUCH_SCL TS_I2C_SCL/SDA GPIO7 GPIO6
供电相关:LCD_IOVDD_1P8 VREG_L9A_1P8 1.65V to 3.3V
TP使能引脚:TOUCH_3V3_EN_GPIO90 GPIO45

部分dtsi
&qupv3_se2_i2c {
     /* BLSP1 QUP4 (Touch) */
    status = "okay";
    atmel_maxtouch_ts@4a {
    
        compatible = "atmel,maxtouch-ts";
        reg = <0x4a>;

        vdd-supply = <&L9A>; //vddio, 1.8v
        atmel,vdd-voltage = <1800000>;
        atmel,tp-enable-gpio = <&tlmm 45 0x00>;//3.3v enable
        atmel,reset-gpio = <&tlmm 71 0x00>;
        interrupt-parent = <&tlmm>;
        interrupts = <80 0x2008>;//irq gpio + irq flags(interrupt.h)
        atmel,irq-gpio = <&tlmm 80 0x2008>;
        pinctrl-names = "pmx_ts_active", "pmx_ts_suspend";
        pinctrl-0 = <&ts_int_active    &ts_reset_active  &ts_en_active>;
        pinctrl-1 = <&ts_reset_suspend &ts_int_suspend  &ts_en_suspend>;

        atmel,display-coords = <0  0 1080 1920>;
        atmel,panel-coords = <0  0 1080 1920>;
        atmel,cfg-name = "mxt640u.raw"; 
        /delete-property/ atmel,fw-name;
        atmel,middle-keycode = <256>;
        panel  = <&dsi_hx8399_1080_video>;  
};

&tlmm{
    
	pmx_ts_reset_active {
    
		ts_reset_active: ts_reset_active {
    
			mux {
    
				pins = "gpio71";
				function = "gpio";
			};

			config {
    
				pins = "gpio71";
				drive-strength = <8>;
				bias-pull-up;
			};
		};
	};
	pmx_ts_reset_suspend {
    
		ts_reset_suspend: ts_reset_suspend {
    
			mux {
    
				pins = "gpio71";
				function = "gpio";
			};

			config {
    
				pins = "gpio71";
				drive-strength = <2>;
				bias-pull-down;
			};
		};
	};

	pmx_ts_int_active {
    
		ts_int_active: ts_int_active {
    
			mux {
    
				pins = "gpio80";
				function = "gpio";
			};

			config {
    
				pins = "gpio80";
				drive-strength = <8>;
				bias-pull-up;
			};
		};
	};

	pmx_ts_int_suspend {
    
		ts_int_suspend: ts_int_suspend {
    
			mux {
    
				pins = "gpio80";
				function = "gpio";
			};

			config {
    
				pins = "gpio80";
				drive-strength = <2>;
				bias-pull-down;
			};
		};
	};

	pmx_ts_en_active {
    
		ts_en_active: ts_en_active {
    
			mux {
    
				pins = "gpio45";
				function = "gpio";
			};

			config {
    
				pins = "gpio45";
				drive-strength = <8>;
				bias-pull-up;
			};
		};
	};

	pmx_ts_en_suspend {
    
		ts_en_suspend: ts_en_suspend {
    
			mux {
    
				pins = "gpio45";
				function = "gpio";
			};
			
			config {
    
				pins = "gpio45";
				drive-strength = <2>;
				bias-pull-down;
			};
		};
	};
};

TP驱动代码解析

[Linux] 内核通知链 notifier
Linux firmware子系统的实现机制学习笔记
TouchPanel–Qcom DRM休眠唤醒通知链的注册及回调流程
在这里插入图片描述

mxt_probe
	mxt_parse_dt(&client->dev, pdata);
		mxt_get_dt_coords(dev, "atmel,panel-coords", pdata);
		mxt_get_dt_coords(dev, "atmel,display-coords", pdata);
	atmel_check_dt_panel(client->dev.of_node) /* data->active_panel */
		node = of_parse_phandle(np, "panel", i);
		panel = of_drm_find_panel(node); /* panel的注册列表中找到匹配的 */
	gpio_to_irq(data->pdata->gpio_irq);
	request_threaded_irq(data->irq, NULL, mxt_interrupt,data->pdata->irqflags 
						| IRQF_ONESHOT,client->name, data);
	mxt_regulator_enable(data); /* 使能 设置上下电时序 */
		gpio_set_value(data->pdata->gpio_reset, 0);
		regulator_enable(data->reg_vdd);
		gpio_set_value(data->pdata->tp_en_gpio, 1);
		mdelay(MXT_640U_REGULATOR_DELAY);
		gpio_set_value(data->pdata->gpio_reset, 1);
		mdelay(MXT_640U_POWERON_DELAY);
	disable_irq(data->irq);
	mxt_initialize(data);
		mxt_read_info_block(data); 
			mxt_update_cfg_version(data); /* 读取cfg_version 后续mxt_load_cfg */
			mxt_update_mode(data); /* __mxt_read_reg 读取寄存器的值存入mxt_data-> cfg_mode*/
			mxt_choose_mode(data); /* configure mode enum 根据cfgmode去更新mxt_data->cfg_name */
		mxt_check_fw_version(data); /* 判断fw是否需要更新*/
		request_firmware_nowait(THIS_MODULE, true, data->cfg_name,&data->client->dev, GFP_KERNEL, 
								data,mxt_config_cb);
			fw_get_filesystem_firmware(device, fw->priv); // fw_path = {fw_path_para, "vendor/firmware"};
		mxt_load_cfg(ctx, cfg, false);/* download configuration to chip */
		mxt_configure_objects(data); /* 创建了input device*/
			mxt_create_input_dev(data);
				input_allocate_device();
				input_dev->open = mxt_input_open;
				input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
				input_set_abs_params(input_dev, ABS_X,data->pdata->disp_minx, data->pdata->disp_maxx,0, 0);
				input_set_abs_params(input_dev, ABS_Y,data->pdata->disp_miny, data->pdata->disp_maxy,0, 0);
				input_register_device(input_dev);
	sysfs_create_group(&client->dev.kobj, &mxt_attr_group); /* 注册文件 */
		/sys/devices/platform/soc/4a88000.i2c/i2c-1/1-004a/fw_version 
	sysfs_bin_attr_init(&data->mem_access_attr); /* lockdep死锁检测需要分配动态 attr.name = mem_access */
	ata->fb_notif.notifier_call = fb_notifier_callback;
	drm_panel_notifier_register(data->active_panel,&data->fb_notif); /* 休眠唤醒通知链 */
	request_firmware_nowait(THIS_MODULE, true, data->fw_name,&data->client->dev, GFP_KERNEL, data,mxt_fw_cb);
	
部分log:
atmel_maxtouch_ts 1-004a: enter mxt_parse_dt
atmel_maxtouch_ts 1-004a: success to update touch cords.
atmel_maxtouch_ts 1-004a: success to update display cords.
atmel_maxtouch_ts 1-004a: touch cords: 0 0 1079 1919 , diplay cords: 0 0 1079 1919
atmel_maxtouch_ts 1-004a: mxt_parse_dt: atmel,reset-gpio is 1238
atmel_maxtouch_ts 1-004a: mxt_parse_dt: atmel,irq-gpio is 1247
atmel_maxtouch_ts 1-004a: read atmel middle scan key success. 
atmel_maxtouch_ts 1-004a: Success to get active_panel
atmel_maxtouch_ts 1-004a: tp_en_gpio : 1212 
atmel_maxtouch_ts 1-004a: Linked as a consumer to regulator.30
atmel_maxtouch_ts 1-004a: mxt_regulator_enable 3124 set tp_en_gpio high ...
atmel_maxtouch_ts 1-004a: Family: 166 Variant: 1 Firmware V1.1.AA Objects: 41 cfg version: 0.7.0.5 
						  ( driver function:mxt_read_info_block )
atmel_maxtouch_ts 1-004a: path: mxt640u.raw ( mxt_choose_mode )
atmel_maxtouch_ts 1-004a: Initialised power cfg: ACTV 16, IDLE 32 ( mxt_init_t7_power_cfg )
atmel_maxtouch_ts 1-004a: Falling back to syfs fallback for: mxt640u.raw
input: atmel_mxt_ts as /devices/platform/soc/4a88000.i2c/i2c-1/1-004a/input/input5 ( input_register_device )
counters_connect atmel_mxt_ts
atmel_maxtouch_ts 1-004a: Register drm_fb_notifier success
atmel_maxtouch_ts 1-004a: mxt_config_cb >>>>>> 
atmel_maxtouch_ts 1-004a: controller version:0.7.0.5 file version:0.7.0.5
atmel_maxtouch_ts 1-004a: configuration is up-to-date
atmel_maxtouch_ts 1-004a: Unable to load_cfg
如果request_firmware_nowait没有找到cfg文件则会打印
atmel_maxtouch_ts 1-004a: Failure to request config file mxt640u.raw

Linux 固件子系统

linux firmware 实现原理
Linux固件子系统的实现机制简介
linux内核下载固件函数request_firmware流程分析

int request_firmware(const struct firmware **fw, 
				const char *name, struct device *device);
int request_firmware_nowait(struct module *module, /*= THIS_MODULE*/
			    int uevent, const char *name, struct device *device,
   				gfp_t gfp,void *context,/*不由固件子系统使用的私有数据指针*/
   				void (*cont)(const struct firmware *fw, void *context));
	INIT_WORK(&fw_work->work, request_firmware_work_func); 
	chedule_work(&fw_work->work);

request_firmware 会请求用户空间,所以返回前将保持休眠,若probe函数调用会一直等待文件系统的挂载
request_firmware_nowait 是通过异步的工作队列去获取固件,使得请求固件不会进入休眠,可以不阻塞probe函数,会通过任务队列调用request_firmware_work_func,request_firmware相关的底层都会调用到_request_firmware函数

从源码driver/base/firmware_loader/main.c fallback.c中得知查找固件有三种方式:
第一种:builtin段,判断是否被编译到kernel中,Hacker_Albert博客有分享一种

fw_get_builtin_firmware(firmware, name, dbuf, size)

CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE_DIR="firmware"  // this means $(source_dir)/firmware
CONFIG_EXTRA_FIRMWARE="fw_sst_0f28.bin"

第二种:cache,寻找之前是否有保存了以前load过的fw的信息,比如name, data, size等

alloc_lookup_fw_priv(name, &fw_cache, &fw_priv, dbuf, size, opt_flags);

第三种:fw_path,比较直观的可以知道从列表支持的file system路径中去寻找是否有存在对应的固件

fw_get_filesystem_firmware(device, fw->priv);

static const char * const fw_path[] = {
    
        fw_path_para,
        "/mnt/vendor/persist/tpp",
        "/lib/firmware/updates/" UTS_RELEASE,
        "/lib/firmware/updates",
        "/lib/firmware/" UTS_RELEASE,
        "/lib/firmware"
};
module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644);
firmware_class.path=$CUSTOMIZED_PATH'
firmware_class.path=/system/etc/firmware

第四中:usespace,通过通过/sys/class/firmware/ 内核向用户空间发送uevent,udevd接收到事件后去寻找

firmware_fallback_sysfs(fw, name, device, opt_flags, ret);
	fw_load_from_user_helper(fw, name, device, opt_flags);
	
system/core/rootdir/ueventd.rc
	firmware_directories /etc/firmware/ /odm/firmware/ /vendor/firmware/ /firmware/image/

Linux 中断子系统

linux驱动request_threaded_irq()
linux中断申请之request_threaded_irq
中断要尽可能耗时比较短,尽快恢复系统正常调试,所以把中断触发、中断执行分开,也就是所说的“上半部分(中断触发)、底半部(中断执行)”,也就是所说的中断上下文。上半部分处理紧急、不耗时的硬件操作,下半部分一般处理不紧急的耗时操作采用tasklet、workqueue实现

int request_irq(unsigned int irq, irq_handler_t handler,
                unsigned long flags,const char* name, void *dev)
int request_threaded_irq(unsigned int irq, irq_handler_t handler,        
             	irq_handler_t thread_fn,
             	unsigned long flags, const char *name, void *dev);
IRQF_SHARED : allow sharing the irq among several devices
IRQF_SHARED 共享中断时,dev_id不能为空,因为释放irq时要区分哪个共享中断
IRQF_ONESHOT:Interrupt is not reenabled after the hardirq handler finished.Used by threaded interrupts 
			 which need to keep the irq line disabled until the threaded handler has been run
IRQF_ONESHOT 例如:设备是低电平产生中断,而硬中断函数为NULL,如果不使用IRQF_ONESHOT,
			 就会一直产生中断执行NULL函数,中断线程得不到执行,声明IRQF_ONESHOT后,会执行完线程才使能该中断

request_threaded_irq 是在将上半部的硬件中断处理缩短为所需设备的硬体中断,唤醒kernel thread 执行任务。没必要再使用request_irq加tasklet/workqueue或者内核线程的方式;如果中断处理简单时也不要执着使用request_threaded_irq

Android 输入系统架构

input
以上是Android input系统的整体架构,可以查看十分钟了解Android触摸事件原理(InputManagerService)
个人学习总结,Android input gpio driver手动对焦 + Android input epoll/inotify机制

MT协议上报点位

linux下多点电容触摸屏实验
Type A:适用于触摸点不能被区分或者追踪,此类型的设备上报原始数据(此类型在实际使用中非常少!
Type B:适用于有硬件追踪并能区分触摸点的触摸设备,此类型设备通过 slot 更新某一个触摸点的信息,并且可以可以减少上报到用户空间的数据量,当只在X轴上移动时,只会上报ABS_MT_POSITION_Y。

1.设置能力,不然上报的过程中会被拦截
__set_bit(EV_ABS, input_dev->evbit);  
input_set_capability(input_dev, EV_KEY, BTN_TOUCH);  
input_set_abs_params(input_dev, ABS_X,
        data->pdata->disp_minx, data->pdata->disp_maxx, 0, 0);
input_set_abs_params(input_dev, ABS_Y,
        data->pdata->disp_miny, data->pdata->disp_maxy, 0, 0);

input_mt_init_slots(input_dev, num_mt_slots, mt_flags); //多点触摸的个数

2.根据MT协议上报点位                                                              
input_mt_slot(input_dev, id);			              //slot                  
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1);     //tracking id            
input_report_abs(input_dev, ABS_MT_POSITION_X, x);            //MT_X                               
input_report_abs(input_dev, ABS_MT_POSITION_Y, y);            //MT_Y    

//以下几个点由于没有set_bit所以在上报过程中会被过滤掉                   
input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, major);       //触摸点区域大小                      
input_report_abs(input_dev, ABS_MT_PRESSURE, pressure);       //触摸点压力                  
input_report_abs(input_dev, ABS_MT_DISTANCE, distance);       //触摸点与触摸面的距离                      
input_report_abs(input_dev, ABS_MT_ORIENTATION, orientation); //触底的方向       

//单点+Sync同步
input_mt_report_pointer_emulation(input_dev, false);//input_event + BTN_TOUCH+ABS_X+ABS_Y
input_sync(input_dev);

Event Types
#define EV_SYN			0x00
#define EV_KEY			0x01
#define EV_ABS			0x03
Code
#define ABS_MT_SLOT		0x2f	/* MT slot being modified */
#define ABS_MT_TRACKING_ID	0x39	/* Unique ID of initiated contact */
#define ABS_MT_POSITION_X	0x35	/* Center X touch position */
#define ABS_MT_POSITION_Y	0x36	/* Center Y touch position */

#define BTN_TOUCH		0x14a   /* pressure on/off */
#define ABS_X			0x00
#define ABS_Y			0x01
  

根据getevent来查看具体的上报事件, type code value

TypeB  slot
单点                                         单点slot可能会被忽略
/dev/input/event4: 0003 0039 00000066        type=0x3代表为EV_ABS事件,上报Tracking id       
/dev/input/event4: 0003 0035 00000004        上报触摸点的X轴坐标(触摸点靠近左上角)         
/dev/input/event4: 0003 0036 0000000d        上报触摸点的Y轴坐标(x = 04 y = 0d)       
/dev/input/event4: 0001 014a 00000001        BTN_TOUCH type为KEY的事件代表触摸点摁下    
/dev/input/event4: 0003 0000 00000004        用于单点触摸的时候上报的X轴坐标,同MT_X      
/dev/input/event4: 0003 0001 0000000d        同上,ABS_Y = ABS_POSITION_Y            
/dev/input/event4: 0000 0000 00000000        input_sync的EV_SYN事件同步上报操作
/frameworks/native/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp

多点
/dev/input/event4: 0003 002f 00000000         0x2f代表slot,用于区分点value=0第一个点    
/dev/input/event4: 0003 0039 0000007c         ABS_MT_TRACKING_ID            
/dev/input/event4: 0003 0035 0000025c         ABS_MT_POSITION_X         
/dev/input/event4: 0003 0036 00000318         ABS_MT_POSITION_Y             
/dev/input/event4: 0003 002f 00000001         slot1,表示当前有两个点在触摸     
/dev/input/event4: 0003 0039 0000007d         ABS_MT_TRACKING_ID                
/dev/input/event4: 0003 0035 000001d5         ABS_MT_POSITION_X       
/dev/input/event4: 0003 0036 00000260         ABS_MT_POSITION_Y   
/dev/input/event4: 0001 014a 00000001         BTN_TOUCH    
/dev/input/event4: 0003 0000 0000025c         ABS_X         
/dev/input/event4: 0003 0001 00000318         ABS_Y      
/dev/input/event4: 0000 0000 00000000         EV_SYN
/frameworks/native/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp 

抬手                                                                         
/dev/input/event4: 0003 0039 ffffffff         0xffffffff代表触摸点离开屏幕   
/dev/input/event4: 0001 014a 00000000         BTN_TOUCH = 0 手指离开屏幕       
/dev/input/event4: 0000 0000 00000000

tp旋转
有可能会遇到模组厂于实际安装位置出现翻转的现象,其实也是很容易就能解决的,当然如果厂商能修改寄存器或者类型atmel的cfg更新,以下可以当作临时修改,还得防止出现负值的情况

x = (int)data->pdata->panel_maxx -x;
y = (int)data->pdata->panel_maxy -y;
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_40405527/article/details/123110077

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签