1、修改dts,添加新的i2c设备。

在 arch/arm/boot/dts/rk312x-sdk-v2.2.dtsi中添加i2c设备的相关信息:

ts@40 {compatible = "gslX680";reg = <0x40>;wake-gpio = <&gpio0 GPIO_D3 GPIO_ACTIVE_LOW>;irp-gpio = <&gpio0 GPIO_A2 IRQ_TYPE_LEVEL_HIGH>;revert_x = <0>;revert_y = <0>;};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
&i2c2 {status = "okay";/*ts@55 {compatible = "goodix,gt8xx";reg = <0x55>;touch-gpio = <&gpio1 GPIO_B0 IRQ_TYPE_LEVEL_LOW>;reset-gpio = <&gpio2 GPIO_C1 GPIO_ACTIVE_LOW>;//power-gpio = <&gpio0 GPIO_C5 GPIO_ACTIVE_LOW>;max-x = <1280>;max-y = <800>;};*/ts@40 {compatible = "gslX680";reg = <0x40>;//wake-gpio = <&gpio0 GPIO_D3 GPIO_ACTIVE_LOW>;irp-gpio = <&gpio0 GPIO_A2 IRQ_TYPE_LEVEL_HIGH>;revert_x = <0>;revert_y = <0>;};/* ... */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

表示i2c2总线上下挂在了多个i2c设备。 
其中ts@40是表示此i2c设备的设备类型为触摸屏,设备地址为0x40(7位地址,注意:在i2c的传输函数中,会将此地址左移一位,因此实际上gslx680的i2c设备地址为0x80)。该节点下有多个属性: 
1、compatible = "gslX680";属性用于驱动和设备的绑定。表示特定的设备名称,此处为gslX680; 
2、reg = <0x40>;属性表示此设备的i2c地址为0x40,等同于@40; 
3、wake-gpio = <&gpio0 GPIO_D3 GPIO_ACTIVE_LOW>;表示复位引脚使用的是GPIO0 中的GPIO_D3这个引脚,低电平有效。 
irp-gpio = <&gpio0 GPIO_A2 IRQ_TYPE_LEVEL_HIGH>;表示中断引脚使用的是GPIO0中的GPIO_A2这个引脚,高电平触发。 
很奇怪,为什么这里没有上电的信息,以及在整个驱动程序中都没有给ic上电的操作。在前面的MTK平台上的tp驱动都有上电的动作,暂时还搞不懂在RK平台上为什么没有。 
4、revert_x = <0>; revert_y = <0>;标记x和y是否需要翻转。 
在上述的信息中,可以通过of接口获取到属性对应的值。在后面的probe()函数中就会使用到。

注:关于dts的详细信息可以查看ARM Linux 3.x的设备树(Device Tree)和Device Tree Usage

2、修改Makefile、Kconfig、defconfig

(1)、修改Makefile添加gslx680驱动

在 drivers/input/touchscreen/Makefile中添加驱动: 
obj-$(CONFIG_TOUCHSCREEN_GSLX680) += gslx680/。 
只要当配置了CONFIG_TOUCHSCREEN_GSLX680的选项才会去编译gslx680目录下的内容。在配置内核的时候会通过make menuconfig来配置对应的选项。或者是直接在defconfig文件中强制设置该选项。

注:如果不想要这么复杂,可以将该语句写成obj-y += gslx680/来强制编译该驱动。

(2)、修改Kconfig添加驱动配置描述

在 drivers/input/touchscreen/Kconfig中添加驱动配置描述:

config TOUCHSCREEN_GSLX680tristate "gslX680 touchscreen driver"helpgslX680 touchscreen driver
  • 1
  • 2
  • 3
  • 4

(3)、配置defconfig设置编译驱动

一般在内核中会有配置好的默认的config文件供参考,可以直接修改defconfig来选择编译某个驱动。此处在arch/arm/configs/rockchip_defconfig文件中添加CONFIG_TOUCHSCREEN_GSLX680=y并将该文件拷贝到kernel目录下命名为.config即可。

2、添加i2c驱动

#define GSLX680_I2C_NAME    "gslX680"
#define GSLX680_I2C_ADDR    0x40static const struct i2c_device_id gsl_ts_id[] = {{GSLX680_I2C_NAME, 0},{}
};MODULE_DEVICE_TABLE(i2c, gsl_ts_id);static struct i2c_driver gsl_ts_driver = {.driver = {.name = GSLX680_I2C_NAME,.owner = THIS_MODULE,},
#ifndef CONFIG_HAS_EARLYSUSPEND
//  .suspend    = gsl_ts_suspend,
//  .resume = gsl_ts_resume,
#endif.probe      = gsl_ts_probe,.remove     = gsl_ts_remove,.id_table   = gsl_ts_id,
};static int __init gsl_ts_init(void)
{int ret;printk("==gsl_ts_init==\n");ret = i2c_add_driver(&gsl_ts_driver);printk("ret=%d\n",ret);return ret;
}
static void __exit gsl_ts_exit(void)
{printk("==gsl_ts_exit==\n");i2c_del_driver(&gsl_ts_driver);return;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

注册名字为GSLX680_I2C_NAME的i2c驱动,即gslx680,该驱动支持的设备名为字gsl_ts_id[]里的设备名称。因为我们在dts中已注册了一个名字为gslx680的i2c设备。因此,设备与驱动可以匹配成功并正确执行probe()函数。 
至于设备与驱动是如何匹配的,可以参照Linux i2c子系统

3、gsl_ts_probe()

static int  gsl_ts_probe(struct i2c_client *client,const struct i2c_device_id *id)
{struct gsl_ts *ts;int rc;struct device_node *np = client->dev.of_node;enum of_gpio_flags wake_flags;unsigned long irq_flags;// 检查i2c适配器的能力printk("GSLX680 Enter %s\n", __func__);if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)){dev_err(&client->dev, "I2C functionality not supported\n");return -ENODEV;}// 为ts申请内核空间ts = kzalloc(sizeof(*ts), GFP_KERNEL);if(!ts)return -ENOMEM;printk("==kzalloc success=\n");ts->client = client;i2c_set_clientdata(client, ts);ts->device_id = id->driver_data;// 从设备节点np中获取到irq和wake 的gpio的信息ts->irq_pin=of_get_named_gpio_flags(np, "irp-gpio", 0, (enum of_gpio_flags *)&irq_flags);ts->wake_pin=of_get_named_gpio_flags(np, "wake-gpio", 0, &wake_flags);// 为设备申请gpio,并设置默认电平if(gpio_is_valid(ts->wake_pin)){rc = devm_gpio_request_one(&client->dev, ts->wake_pin, (wake_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, "gslX680 wake pin");if(rc != 0){dev_err(&client->dev, "gslX680 wake pin error\n");return -EIO;}g_wake_pin = ts->wake_pin;//msleep(100);}else{dev_info(&client->dev, "wake pin invalid\n");}if(gpio_is_valid(ts->irq_pin)){rc = devm_gpio_request_one(&client->dev, ts->irq_pin, (irq_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, "gslX680 irq pin");if (rc != 0){dev_err(&client->dev, "gslX680 irq pin error\n");return -EIO;}}else{dev_info(&client->dev, "irq pin invalid\n");}// 创建工作队列,申请input设备rc = gslX680_ts_init(client, ts);if(rc < 0){dev_err(&client->dev, "GSLX680 init failed\n");goto error_mutex_destroy;}   gsl_client = client;// 从设备节点中获取属性信息of_property_read_u32(np,"revert_x",&revert_x);//sssof_property_read_u32(np,"revert_y",&revert_y);//sss// 初始化IC,包括复位,测试i2c以及加载ic配置信息init_chip(ts->client);check_mem_data(ts->client);// 申请中断号ts->irq=gpio_to_irq(ts->irq_pin);       //If not defined in clientif (ts->irq){// 为client->dev设备的中断号ts->irq申请irq_flags触发的中断,中断服务子程序为gsl_ts_irqrc = devm_request_threaded_irq(&client->dev, ts->irq, NULL, gsl_ts_irq, irq_flags | IRQF_ONESHOT, client->name, ts);if(rc != 0){printk(KERN_ALERT "Cannot allocate ts INT!ERRNO:%d\n", rc);goto error_req_irq_fail;}//disable_irq(ts->irq);}else{printk("gsl x680 irq req fail\n");goto error_req_irq_fail;}ts->tp.tp_resume = gsl_ts_late_resume;ts->tp.tp_suspend = gsl_ts_early_suspend;tp_register_fb(&ts->tp);#ifdef CONFIG_HAS_EARLYSUSPENDts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;//ts->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1;ts->early_suspend.suspend = gsl_ts_early_suspend;ts->early_suspend.resume = gsl_ts_late_resume;register_early_suspend(&ts->early_suspend);
#endif#ifdef GSL_MONITORprintk( "gsl_ts_probe () : queue gsl_monitor_workqueue\n");INIT_DELAYED_WORK(&gsl_monitor_work, gsl_monitor_worker);gsl_monitor_workqueue = create_singlethread_workqueue("gsl_monitor_workqueue");queue_delayed_work(gsl_monitor_workqueue, &gsl_monitor_work, 1000);
#endifprintk("[GSLX680] End %s\n", __func__);return 0;//exit_set_irq_mode:
error_req_irq_fail:free_irq(ts->irq, ts);  error_mutex_destroy:input_free_device(ts->input);kfree(ts);return rc;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131

(1)、自定义的数据结构gsl_ts

一般在自己的驱动程序中,都会为该驱动程序封装一个数据结构,这里的gsl_ts就充当这种角色。 
在该驱动程序中自定义了一个数据结构:

struct gsl_ts {struct i2c_client *client;struct input_dev *input;struct work_struct work;struct workqueue_struct *wq;struct gsl_ts_data *dd;u8 *touch_data;u8 device_id;int irq;int irq_pin;int wake_pin;struct  tp_device  tp;
#if defined(CONFIG_HAS_EARLYSUSPEND)struct early_suspend early_suspend;
#endif
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

client表示一个i2c的设备; 
input表示一个输入设备; 
work表示一个工作,用于处理中断到来之后获取坐标等信息; 
wq表示一个工作队列,将上面的work加入到该工作队列中; 
ddtouch_data用来存储坐标的相关信息; 
device_id表示i2c设备的设备号; 
irq申请的中断号; 
irq_pin中断引脚; 
wake_pin复位引脚;这两个引脚信息可以通过dts获取到. 
tp创建一个为tp_device的数据结构,里面有个成员notifier_block用来接收LCD背光灯的亮暗的通知进而调用suspend()resume()。主要的实现在tp_suspend.h中。至于这里面的详细机制还不是很明白。

(2)、检查i2c适配器的能力

在很多i2c设备驱动程序中,一进入probe()就要检查i2c适配器的能力。现在还不清楚这么做的目的是什么。后面会仔细的学习一下linux 的i2c子系统。

(3)、获取wake和irq的引脚信息

在前面配置dts说过:dts中设备节点的属性的值可以通过of_接口获取到。

// 从设备节点np中获取到irq和wake 的gpio的信息ts->irq_pin=of_get_named_gpio_flags(np, "irp-gpio", 0, (enum of_gpio_flags *)&irq_flags);ts->wake_pin=of_get_named_gpio_flags(np, "wake-gpio", 0, &wake_flags);
  • 1
  • 2
  • 3

可以通过设备节点np获取到它irq-gpio这一个属性的值存放在ts->irq_pin中,以及将其flag刚到变量irq_flags中。因此我们可以知道:

ts->irq_pin = GPIO_A2
irq_flag = IRQ_TYPE_LEVEL_HIGH
  • 1
  • 2

同理,wake_pin也是一样。

(4)、申请gpio并设置输出电平

将irq和wake 引脚电平都设置输出低电平。

(5)、gslX680_ts_init

static int gslX680_ts_init(struct i2c_client *client, struct gsl_ts *ts)
{struct input_dev *input_device;int rc = 0;printk("[GSLX680] Enter %s\n", __func__);// 配置获取坐标信息ts->dd = &devices[ts->device_id];if(ts->device_id == 0){ts->dd->data_size = MAX_FINGERS * ts->dd->touch_bytes + ts->dd->touch_meta_data;ts->dd->touch_index = 0;}// 申请空间存放坐标信息ts->touch_data = kzalloc(ts->dd->data_size, GFP_KERNEL);if(!ts->touch_data){pr_err("%s: Unable to allocate memory\n", __func__);return -ENOMEM;}// 申请一个input_dev 设备input_device = input_allocate_device();if (!input_device) {rc = -ENOMEM;goto error_alloc_dev;}// 初始化input_devicets->input = input_device;input_device->name = GSLX680_I2C_NAME;input_device->id.bustype = BUS_I2C;input_device->dev.parent = &client->dev;input_set_drvdata(input_device, ts);//
#ifdef REPORT_DATA_ANDROID_4_0__set_bit(EV_ABS, input_device->evbit);__set_bit(EV_KEY, input_device->evbit);__set_bit(EV_REP, input_device->evbit);__set_bit(INPUT_PROP_DIRECT, input_device->propbit);input_mt_init_slots(input_device, (MAX_CONTACTS+1),0);
#elseinput_set_abs_params(input_device,ABS_MT_TRACKING_ID, 0, (MAX_CONTACTS+1), 0, 0);set_bit(EV_ABS, input_device->evbit);set_bit(EV_KEY, input_device->evbit);__set_bit(INPUT_PROP_DIRECT, input_device->propbit);input_device->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
#endif#ifdef HAVE_TOUCH_KEYinput_device->evbit[0] = BIT_MASK(EV_KEY);//input_device->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);for (i = 0; i < MAX_KEY_NUM; i++)set_bit(key_array[i], input_device->keybit);
#endifset_bit(ABS_MT_POSITION_X, input_device->absbit);set_bit(ABS_MT_POSITION_Y, input_device->absbit);set_bit(ABS_MT_TOUCH_MAJOR, input_device->absbit);set_bit(ABS_MT_WIDTH_MAJOR, input_device->absbit);input_set_abs_params(input_device,ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);input_set_abs_params(input_device,ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);input_set_abs_params(input_device,ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);input_set_abs_params(input_device,ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);// 创建工作队列ts->wq = create_singlethread_workqueue("kworkqueue_ts");if(!ts->wq){dev_err(&client->dev, "Could not create workqueue\n");goto error_wq_create;}flush_workqueue(ts->wq);    // 初始化工作 ts->work,其操作为 gslX680_ts_worker()INIT_WORK(&ts->work, gslX680_ts_worker);// 向input子系统注册一个input_devrc = input_register_device(input_device);if (rc)goto error_unreg_device;return 0;error_unreg_device:destroy_workqueue(ts->wq);
error_wq_create:input_free_device(input_device);
error_alloc_dev:kfree(ts->touch_data);return rc;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96

gslX680_ts_init()中主要做了如下工作:

配置获取坐标信息

每次当中断来了之后,就要求通过i2c去读取坐标的信息,至于从哪里读取以及读取多少个,都是通过ts->dd来决定的。

为存储坐标信息申请空间

坐标信息放在ts->touch_data中。

申请及初始化input_dev设备,向input子系统注册该设备

这里面的内容涉及到input子系统,我还没有做过深入的了解。

初始化工作 ts->work

ts->work对应的操作为gslX680_ts_worker(),在中断来了之后,会queue_work(ts->wq, &ts->work);ts->work工作起来,就会去读取坐标等信息,然后通过input子系统上报给Android系统。

(6)、获取属性信息

通过of_接口获取revert_x和revert_y的信息,以此来决定坐标是否要翻转。

(7)、初始化ic

初始化的内容会放到一个全局的数组之中,这项工作一般都要FAE来完成。

(8)、申请中断号以及中断服务子程序

通过devm_request_threaded_irq接口为设备申请一个中断服务子程序gsl_ts_irq(),触发方式为irq_flagsIRQ_TYPE_LEVEL_HIGH高电平触发。

(9)、配置休眠唤醒

在前面说过,tp的休眠唤醒是通过LCD亮暗屏来决定的,这个动作由tp_register_fb()来实现。

ts->tp.tp_resume = gsl_ts_late_resume;
ts->tp.tp_suspend = gsl_ts_early_suspend;
tp_register_fb(&ts->tp);
  • 1
  • 2
  • 3

注:如果申请资源出错的话一定要记得释放资源以及前面的资源。比如说这里为ts申请的内核空间、申请的中断号、申请的input设备、申请的工作队列。

上述probe()配置完成之后就是等待中断,如果中断到来,关闭中断,启动工作去读取坐标等信息并通过input子系统上报,之后再使能中断。如此反复。

4、中断服务子程序

static irqreturn_t gsl_ts_irq(int irq, void *dev_id)
{   struct gsl_ts *ts = dev_id;print_info("========gslX680 Interrupt=========\n");              disable_irq_nosync(ts->irq);if (!work_pending(&ts->work)) {queue_work(ts->wq, &ts->work);}return IRQ_HANDLED;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

一旦有中断到来,立马调用gsl_ts_irq(),在这个中断服务子程序中先判断ts->work是否挂起,如果没有挂起就启动工作队列ts->wq的工作ts->workts->workgslX680_ts_worker()对应,主要用来读取坐标信息。

5、休眠唤醒

关于休眠和唤醒的内容根据ic的特性设置。如休眠的时候需要关闭中断、配置进入休眠模式、拉低wake引脚。唤醒的时候唤醒ic,使能wake引脚、使能中断等。

https://www.cnblogs.com/zzb-Dream-90Time/p/7615770.html

Rockchip平台TP驱动详解相关推荐

  1. MTK 驱动(64)---Mtk touch panel驱动/TP驱动详解

    Mtk touch panel驱动/TP驱动详解 TP还算是比LCM好理解的多. 在启动过程中,先注册/mediatek/custom/command/kernel/touchpanel目录下的具体驱 ...

  2. 深入学习Linux摄像头(四)三星平台fimc驱动详解

    深入学习Linux摄像头系列 深入学习Linux摄像头(一)v4l2应用编程 深入学习Linux摄像头(二)v4l2驱动框架 深入学习Linux摄像头(三)虚拟摄像头驱动分析 深入学习Linux摄像头 ...

  3. 三星平台fimc驱动详解

    一.硬件接口 摄像头 摄像头传感器由摄像头接口和控制接口(一般为i2c)组成 摄像头接口用于传输传感器采集到的数据 控制接口用于控制摄像头传感器(例如设置图像格式-) 芯片 芯片上由多个摄像头控制器, ...

  4. 基于瑞芯微3399的嵌入式linux,瑞芯微x3399 linux QT平台WIFI移植详解

    原标题:瑞芯微x3399 linux QT平台WIFI移植详解 第1章 内核配置 硬件平台:x3399开发板或ibox3399卡片电脑 操作系统:linux4.4.5+ QT5.6 WIFI型号:AP ...

  5. Pixhawk(PX4)之驱动详解篇(0)_前期准备(招贤令)

    Pixhawk(PX4)之驱动详解篇(0)_前期准备(招贤令) 原创 2017年03月01日 22:58:39 标签: 开发人员 / UAV / 软件 / 硬件 一.开篇 开源精神常在!!! 谁说软件 ...

  6. imx6ul 驱动详解

    链表的知识: struct list_head {struct list_head *next, *prev; }; API函数 函数 功能 LIST_HEAD 声明并初始化双向链表. INIT_LI ...

  7. linux usb gadget驱动详解(一)

    由于PC的推广,USB(通用串行总线)是我们最熟知的通信总线规范之一,其他的还有诸如以太网.PCIE总线和RS232串口等.这里我们主要讨论USB. USB是一个主从通信架构,但只能一主多从.其中us ...

  8. 博通wifi驱动详解

    1        WLAN技术 WLAN是英文WirelessLAN的缩写,就是无线局域网的意思.无线以太网技术是一种基于无线传输的局域网技术,与有线网络技术相比,具有灵活.建网迅速.个人化等特点.将 ...

  9. LCD液晶屏驱动详解

    开发环境: 开发板:JZ2440V3 CPU:samsunS3C2440 内核:Linux3.4.2 编译工具:arm-linux-gcc 4.3.2 LCD:4.3存液晶屏AT043TN24 参考文 ...

  10. 农行网上在线支付平台接口安装详解

    农行网上在线支付平台接口安装详解 2017年05月07日 16:02:53 白云下载站 阅读数:3426 中国农业银行的网上支付平台接口的安装还是有点复杂的,摸索了很久才搞定,总结了一下与大家共享. ...

最新文章

  1. 高亚芳 mysql_MySQL · 专家投稿 · MySQL数据库SYS CPU高的可能性分析
  2. Python程序设计之如何设置统一编码格式
  3. 机器学习中的数学(1)-回归(regression)、梯度下降(gradient descent)
  4. xulrunner html5,XULRunner入门
  5. 为什么德国人工作这么慢,但效率却很高?
  6. 魔兽 如何屏蔽F1键弹出帮助菜单
  7. python关于二手房的课程论文_python之数据清理-以二手房信息为例
  8. c语言输入字符串smallbig,为什么输出不了small,这里big和small都是一样的操
  9. poj 1129 也算是遍历的吧 两种方法
  10. 设计一个完善可用的服务框架
  11. ThreadLocal 遇上线程池的问题及解决办法
  12. 使用bbscope进行大规模域名收集扫描
  13. 分享180个动态模板PPT模板,总有一款适合你
  14. 基于php的校园垃圾分类网站的设计与实现
  15. Ubuntu 安装磁盘分区及启动项添加
  16. QPS,TPS,RT是什么?
  17. 计算机英语教学教案模板,英语教学设计模板
  18. 【angular-实践】实现浏览器F11全屏效果
  19. IDEA提交git代码,配置文件乱码
  20. 【MapReduce】综合案例

热门文章

  1. 亚马逊美国UL 299,第 11 版,2012 年 4 月 13 日- UL 安全干粉灭火器标准
  2. python习题练习1224
  3. MySQL必知必会——第十四章使用子查询
  4. 最强大脑-星际迷航-JQuery 版本
  5. 星际迷航的William Shatner发推文支持Vitalik Buterin
  6. 原生JS实现网页导航条特效
  7. 光刻机巨头ASML爆料:芯片太缺,都开始拆洗衣机了!
  8. lua工具库penlight--06数据(二)
  9. 小武与SSD与pytorch-尝试手撕代码
  10. 怎么使用outlook发送邮件?outlook群发邮件怎么撤回?