当前位置: 首页 > 编程日记 > 正文

【转】android电池(四):电池 电量计(MAX17040)驱动分析篇

关键词:android 电池  电量计  MAX17040 任务初始化宏 power_supply

平台信息:
内核:linux2.6/linux3.0
系统:android/android4.0 
平台:samsung exynos 4210、exynos 4412 、exynos 5250

作者:xubin341719(欢迎转载,请注明作者)

欢迎指正错误,共同学习、共同进步!!

完整驱动代码&规格书下载:MAX17040_PL2301

android 电池(一):锂电池基本原理篇

android 电池(二):android关机充电流程、充电画面显示

android 电池(三):android电池系统

android电池(四):电池 电量计(MAX17040)驱动分析篇

android电池(五):电池 充电IC(PM2301)驱动分析篇

电池电量计,库仑计,用max17040这颗电量IC去计量电池电量,这种方法比较合理。想起比较遥远的年代,做samsung s5pc110/sp5v210的时候,计量电量用一个AD口加两个分压电阻就做了,低电量的时候系统一直判断不准确,“低电关机”提示一会有,一会没有,客户那个郁闷呀,“到底是有电还是没电?”。

如下图,通过两个分压电阻,和一个AD脚去侦测VCC(电池)电压。


一、MAX17040的工作原理

电量计MAX17040,他通过芯片去测量电池电量,芯片本身集成的电路比较复杂,同时可以通过软件上的一些算法去实现一些处理,是测量出的电量更加准确。还有一个好处,就是他之接输出数字量,通过IIC直接读取,我们在电路设计、程序处理上更加的统一化。

如下图所示,MAX17040和电池盒主控的关系,一个AD脚接到电池VBAT+,检测到的电量信息,通过IIC传到主控。


下面是电路图,电路接口比较简单,VBAT+,接到max17040的CELL,IIC接到主控的IIC2接口,这个我们在程序中要配置。看这个器件比较简单吧。


看下max17040的内部结构,其实这也是一个AD转换的过程,单独一颗芯片去实现,这样看起来比较专业些。CELL接口,其实就是一个ADC转换的引脚,我们可以看到芯片内部有自己的时钟(time base),IIC控制器之类的,通过CELL采集到的模拟量,转换成数字量,传输给主控。


通过上面的介绍Max17040的硬件、原理我们基本上都了解了,比较简单,下面我们就重点去分析下驱动程序。

二、MAX17040 总体流程

电量计的工作流程比较简单,max17040通过CELL ADC转换引脚,把电池的相关信息,实时读取,存入max17040相应的寄存器,驱动申请一个定时器,记时结束,通过IIC去读取电池状态信息,和老的电池信息对比,如果用变化上报,然后重新计时;这样循环操作,流程如下所示:


三、MAX17040这个电量计驱动,我们主要用到以下知识点

1、IIC的注册(这个在TP、CAMERA中都有分析);

2、linux 中定时器的使用;

3、任务初始化宏;

4、linux定时器调度队列;

5、max17040测到电量后如何上传到系统(这个电池系统中有简要的分析);

6、AC、USB充电状态的上报,这个和电池电量是一种方法。

7、电池曲线的测量与加入;

1、IIC的注册

IIC这个总线,在工作中用的比较多,TP、CAMERA、电量计、充电IC、音频芯片、电源管理芯片、基本所有的传感器,所以这大家要仔细看下,后面有时间的话单独列一片介绍下IIC,从单片机时代都用的比较多,看来条总线的生命力很强,像C语言一样,很难被同类的东西替代到,至少现在应该是这样的。

看下他结构体的初始化与驱动的申请,这个比较统一,这里就不想想解释了。

(1)、IIC驱动的注册:

static const struct i2c_device_id max17040_id[] = {{ "max17040", 0 },{ }
};
MODULE_DEVICE_TABLE(i2c, max17040_id);static struct i2c_driver max17040_i2c_driver = {.driver    = {.name    = "max17040",},.probe        = max17040_probe,.remove        = __devexit_p(max17040_remove),.suspend    = max17040_suspend,.resume        = max17040_resume,.id_table    = max17040_id,
};static int __init max17040_init(void)
{printk("MAX17040 max17040_init !!\n");wake_lock_init(&vbus_wake_lock, WAKE_LOCK_SUSPEND, "vbus_present");return i2c_add_driver(&max17040_i2c_driver);
}
module_init(max17040_init);

(2)在arch/arm/mach-exynos/mach-smdk4x12.c中,IC平台驱动的注册:

static struct i2c_board_info i2c_devs2[] __initdata = {
#if defined(CONFIG_BATTERY_MAX17040){I2C_BOARD_INFO("max17040", 0x36),//IIC地址;.platform_data = &max17040_platform_data,},
#endif
……………………
};

下图就是我们IIC驱动注册生成的文件;

/sys/bus/i2c/drivers/max17040

2、linux 中定时器的使用

定时器,就是定一个时间, 比如:申请一个10秒定时器,linux系统开始计时,到10秒,请示器清零重新计时并发出信号告知系统计时完成,系统接到这个信号,做相应的处理;

#include <linux/delay.h>
#define MAX17040_DELAY            msecs_to_jiffies(5000)

3、任务初始化宏

    INIT_WORK(work,func);INTI_DELAYED_WORK(work,func);INIT_DELAYED_WORK_DEFERRABLE(work,func);

任务结构体的初始化完成后,接下来要将任务安排进工作队列。 可采用多种方法来完成这一操作。 首先,利用 queue_work 简单地将任务安排进工作队列(这将任务绑定到当前的 CPU)。 或者,可以通过 queue_work_on 来指定处理程序在哪个 CPU 上运行。 两个附加的函数为延迟任务提供相同的功能(其结构体装入结构体 work_struct 之中,并有一个 计时器用于任务延迟 )。

    INIT_DELAYED_WORK_DEFERRABLE(&chip->work, max17040_work);把调度函数 max17040_work加入chip->work队列;

4、linux定时器调度队列

    INIT_DELAYED_WORK_DEFERRABLE(&chip->work, max17040_work);schedule_delayed_work(&chip->work, MAX17040_DELAY);通过定时器调度队列;

5、max17040测到电量后如何上传到系统(这个电池系统中有简要的分析);

4中的定时器记时完成,就可以调度队列,chip->work执行:max17040_work函数,把改读取的信息上传,我们看下max17040_work函数的实现:

static void max17040_work(struct work_struct *work)
{struct max17040_chip *chip;int old_usb_online, old_online, old_vcell, old_soc;chip = container_of(work, struct max17040_chip, work.work);#ifdef MAX17040_SUPPORT_CURVE/* The module need to be update per hour (60*60)/3 = 1200 */if (g_TimeCount >= 1200) {handle_model(0);g_TimeCount = 0;}g_TimeCount++;
#endifold_online = chip->online;//(1)、保存老的电池信息,如电量、AC、USB是否插入;old_usb_online = chip->usb_online;old_vcell = chip->vcell;old_soc = chip->soc;max17040_get_online(chip->client);//(2)、读取电池新的状态信息max17040_get_vcell(chip->client);max17040_get_soc(chip->client);max17040_get_status(chip->client);if ((old_vcell != chip->vcell) || (old_soc != chip->soc)) {//(3)、如果电池信息有变化,就上报系统;/* printk(KERN_DEBUG "power_supply_changed for battery\n"); */power_supply_changed(&chip->battery);}#if !defined(CONFIG_CHARGER_PM2301)//(4)、如果用PM2301充电IC,USB充电功能不用;if (old_usb_online != chip->usb_online) {/* printk(KERN_DEBUG "power_supply_changed for usb\n"); */power_supply_changed(&chip->usb);}
#endifif (old_online != chip->online) {//(5)、如果有DC插入,则更新充电状态;/* printk(KERN_DEBUG "power_supply_changed for AC\n"); */power_supply_changed(&chip->ac);}schedule_delayed_work(&chip->work, MAX17040_DELAY);
}

(1)、保存老的电池信息,如电量、AC、USB是否插入

    old_online = chip->online;old_usb_online = chip->usb_online;old_vcell = chip->vcell;old_soc = chip->soc;

(2)、读取电池新的状态信息

    max17040_get_online(chip->client);//读取是否有AC插入;max17040_get_vcell(chip->client);//读取电池电压;(这个地方原来写错,多谢细心网友,更正!!)max17040_get_soc(chip->client);//读取电池电量;max17040_get_status(chip->client);//读取状态;

(3)、如果电池信息有变化,就上报系统

    if ((old_vcell != chip->vcell) || (old_soc != chip->soc)) {/* printk(KERN_DEBUG "power_supply_changed for battery\n"); */power_supply_changed(&chip->battery);}

power_supply_changed这个函数比较重要, 我们后面分析;

(4)、如果用PM2301充电IC,USB充电功能不用

这个是由于我们的系统耗电比较大,用USB充电时,电流过小,所以出现越充越少的现象,所以这个功能给去掉了。

(5)、如果有DC插入,则跟新充电状态

    power_supply_changed(&chip->ac);

6、AC、USB充电状态怎么更新到应用

如上面所说,通过power_supply_changed上报;

7、电池曲线的测量与加入

电池曲线,就是电池的冲放电信息,就是用专业的设备,对电池连续充放电几天,测出一个比较平均的值。然后转换成针对电量IC(如我们用的max17040)的数字量,填入一个数组中,如下图所示:

下面数据时针对电池曲线的数字量,和相关参数。如上图所示,为160小时的电池信息,包括:不同颜色分别代表不同的曲线:如temperature ,reference SOC ,fuel gauge SOC,Vcell,Empty Voltage

数据表格如下:

Device=MAX17040
Title = 1055_2_113012
EmptyAdjustment = 0
FullAdjustment= 100
RCOMP0=161
TempCoUp =0
TempCoDown = -2
OCVTest = 56224
SOCCheckA = 113
SOCCheckB = 115
bits= 18
0xC2 0xE8 0x0D 0x37 0x51 0x5B 0x5E 0x62 
0x6A 0x88 0xA6 0xCB 0xF1 0x3C 0x99 0x1A 
0x60 0x0D 0x80 0x0D 0xA0 0x01 0xC0 0x0C 
0xF0 0x0F 0x30 0x0F 0x90 0x06 0x10 0x06 0xAC 0x20 0xAE 0x80 0xB0 0xD0 0xB3 0x70
0xB5 0x10 0xB5 0xB0 0xB5 0xE0 0xB6 0x20 
0xB6 0xA0 0xB8 0x80 0xBA 0x60 0xBC 0xB0 
0xBF 0x10 0xC3 0xC0 0xC9 0x90 0xD1 0xA0 
0x02 0x90 0x0E 0x00 0x0C 0x10 0x0E 0x20 
0x2C 0x60 0x4C 0xB0 0x39 0x80 0x39 0x80 
0x0C 0xD0 0x0C 0xD0 0x0A 0x10 0x09 0xC0 
0x08 0xF0 0x07 0xF0 0x05 0x60 0x05 0x60 0xC0 0x09 0xE0 0x00 0x00 0x01 0x30 0x02 
0x52 0x06 0x54 0x0B 0x53 0x080x63  0x08 
0x29 0xE0 0xC1 0xE2 0xC6 0xCB 0x98 0x98 
0xCD 0xCD 0xA1 0x9C 0x8F 0x7F 0x56 0x56

加入驱动中的值:

/driver/power/max17040_common.c中

unsigned char model_data[65] = {0x40,    /* 1st field is start reg address, others are model parameters */0xAC, 0x20,0xAE, 0x80, 0xB0, 0xD0, 0xB3, 0x70,0xB5, 0x10, 0xB5, 0xB0,    0xB5, 0xE0,0xB6, 0x20,0xB6, 0xA0, 0xB8, 0x80, 0xBA, 0x60, 0xBC, 0xB0,0xBF, 0x10, 0xC3, 0xC0, 0xC9, 0x90, 0xD1, 0xA0,0x02, 0x90, 0x0E, 0x00, 0x0C, 0x10,0x0E, 0x20,0x2C, 0x60,0x4C, 0xB0, 0x39, 0x80, 0x39, 0x80,0x0C, 0xD0,0x0C, 0xD0,    0x0A, 0x10,0x09, 0xC0,0x08, 0xF0, 0x07, 0xF0, 0x05, 0x60, 0x05, 0x60,
};unsigned char INI_OCVTest_High_Byte = 0xDB; //56224
unsigned char INI_OCVTest_Low_Byte = 0xA0;
unsigned char INI_SOCCheckA = 0x71;// 113
unsigned char INI_SOCCheckB = 0x73;//115
unsigned char INI_RCOMP = 0xa1;//161
unsigned char INI_bits = 18;
unsigned char original_OCV_1;
unsigned char original_OCV_2;
#elseunsigned char INI_RCOMP = 0x64;
unsigned char INI_bits = 19;
unsigned char original_OCV_1;
<STRONG>unsigned char original_OCV_2;</STRONG>

四、驱动分析

1、Probe函数分析

上面我们简单了解驱动中用到的主要知识点,后面我们把这些点串起来,驱动还是从probe说起;

static int __devinit max17040_probe(struct i2c_client *client,const struct i2c_device_id *id)
{struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);struct max17040_chip *chip;int ret;printk("MAX17040 probe !!\n");if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))return -EIO;chip = kzalloc(sizeof(*chip), GFP_KERNEL);if (!chip)return -ENOMEM;g_chip = chip;g_i2c_client = client;//(1)、IIC 驱动部分client 申请;
chip->client = client;chip->pdata = client->dev.platform_data;i2c_set_clientdata(client, chip);chip->battery.name        = "battery";//(2)、chip name;chip->battery.type        = POWER_SUPPLY_TYPE_BATTERY;chip->battery.get_property    = max17040_get_property;//(3)、获取电池信息;chip->battery.properties    = max17040_battery_props;//(4)、电池各种信息;chip->battery.num_properties    = ARRAY_SIZE(max17040_battery_props);chip->battery.external_power_changed = NULL;ret = power_supply_register(&client->dev, &chip->battery);//(5)、battery加入power_supplyif (ret)goto err_battery_failed;chip->ac.name        = "ac"chip->ac.type        = POWER_SUPPLY_TYPE_MAINS;chip->ac.get_property    = adapter_get_property;chip->ac.properties    = adapter_get_props;chip->ac.num_properties    = ARRAY_SIZE(adapter_get_props);chip->ac.external_power_changed = NULL;ret = power_supply_register(&client->dev, &chip->ac);//(6)、和battery相似,把ac加入power_supplyif (ret)goto err_ac_failed;#if !defined(CONFIG_CHARGER_PM2301)chip->usb.name        = "usb";chip->usb.type        = POWER_SUPPLY_TYPE_USB;chip->usb.get_property    = usb_get_property;chip->usb.properties    = usb_get_props;chip->usb.num_properties    = ARRAY_SIZE(usb_get_props);chip->usb.external_power_changed = NULL;ret = power_supply_register(&client->dev, &chip->usb);//(7)、和battery相似,把usb加入power_supplyif (ret)goto err_usb_failed;if (chip->pdata->hw_init && !(chip->pdata->hw_init())) {dev_err(&client->dev, "hardware initial failed.\n");goto err_hw_init_failed;}
#endif#ifdef MAX17040_SUPPORT_CURVEg_TimeCount = 0;handle_model(0);
#endifmax17040_get_version(client);battery_initial = 1;INIT_DELAYED_WORK_DEFERRABLE(&chip->work, max17040_work);//(8)、任务宏初始化,max17040加入chip->work队列;schedule_delayed_work(&chip->work, MAX17040_DELAY);//(9)、通过定时器调度队列;
printk("MAX17040 probe success!!\n");return 0;err_hw_init_failed:power_supply_unregister(&chip->usb);
err_usb_failed:power_supply_unregister(&chip->ac);
err_ac_failed:power_supply_unregister(&chip->battery);
err_battery_failed:dev_err(&client->dev, "failed: power supply register\n");i2c_set_clientdata(client, NULL);kfree(chip);return ret;
}

(1)、IIC 驱动部分client 申请;

(2)、chip name;

(3)、获取电池信息;

通过传递下来的参数,来读取结构体中相应的状态,这个函数实现比较简单。

static int max17040_get_property(struct power_supply *psy,enum power_supply_property psp,union power_supply_propval *val)
{struct max17040_chip *chip = container_of(psy,struct max17040_chip, battery);switch (psp) {case POWER_SUPPLY_PROP_STATUS:val->intval = chip->status;break;case POWER_SUPPLY_PROP_ONLINE:val->intval = chip->online;break;case POWER_SUPPLY_PROP_VOLTAGE_NOW:case POWER_SUPPLY_PROP_PRESENT:val->intval = chip->vcell;if (psp  == POWER_SUPPLY_PROP_PRESENT)val->intval = 1; /* You must never run Odrioid1 without Battery. */break;case POWER_SUPPLY_PROP_CAPACITY:val->intval = chip->soc;break;case POWER_SUPPLY_PROP_TECHNOLOGY:val->intval = POWER_SUPPLY_TECHNOLOGY_LION;break;case POWER_SUPPLY_PROP_HEALTH:if (chip->vcell  < 2850)val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;elseval->intval = POWER_SUPPLY_HEALTH_GOOD;break;case POWER_SUPPLY_PROP_TEMP:val->intval = 365;break;default:return -EINVAL;}return 0;
}

(4)电池各种信息


static enum power_supply_property max17040_battery_props[] = {POWER_SUPPLY_PROP_PRESENT,POWER_SUPPLY_PROP_STATUS,/*POWER_SUPPLY_PROP_ONLINE,*/POWER_SUPPLY_PROP_VOLTAGE_NOW,POWER_SUPPLY_PROP_CAPACITY,POWER_SUPPLY_PROP_TECHNOLOGY,POWER_SUPPLY_PROP_HEALTH,POWER_SUPPLY_PROP_TEMP,};

(5)、battery加入power_supply;


(6)、和battery相似,把ac加入power_supply;

(7)、和battery相似,把usb加入power_supply;

(8)、max17040加入chip->work队列;

前面已经分析;

(9)、通过定时器调度队列;

前面已经分析;

2、power_supply_changed简要分析

如:把电池电量信息上报:我们在max17040_work队列调度函数中, 如果有电池信息、状态变化,则上用power_supply_changed上报。

power_supply_changed(&chip->battery);

Kernel/drivers/power/power_supply_core.c中:

void power_supply_changed(struct power_supply *psy)
{unsigned long flags;dev_dbg(psy->dev, "%s\n", __func__);spin_lock_irqsave(&psy->changed_lock, flags);psy->changed = true;wake_lock(&psy->work_wake_lock);spin_unlock_irqrestore(&psy->changed_lock, flags);schedule_work(&psy->changed_work);//调度psy->changed_work
}
Psy->changed_work的执行函数:
static void power_supply_changed_work(struct work_struct *work)
{unsigned long flags;struct power_supply *psy = container_of(work, struct power_supply,changed_work);dev_dbg(psy->dev, "%s\n", __func__);spin_lock_irqsave(&psy->changed_lock, flags);if (psy->changed) {psy->changed = false;spin_unlock_irqrestore(&psy->changed_lock, flags);class_for_each_device(power_supply_class, NULL, psy,__power_supply_changed_work);power_supply_update_leds(psy);kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE);//uevent状态spin_lock_irqsave(&psy->changed_lock, flags);}if (!psy->changed)wake_unlock(&psy->work_wake_lock);spin_unlock_irqrestore(&psy->changed_lock, flags);
}

转载于:https://www.cnblogs.com/cslunatic/p/3637968.html

相关文章:

hihoCoder#1384 : Genius ACM

对于一个固定的区间$[l,r]$&#xff0c;显然只要将里面的数字从小到大排序后将最小的$m$个和最大的$m$个配对即可。 如果固定左端点&#xff0c;那么随着右端点的右移&#xff0c;$SPD$值单调不降&#xff0c;所以尽量把右端点往右移&#xff0c;贪心分割即可。 为了使得扫过的…

微信小程序开发 笔记

1.[wxss]设置带透明度的rgb颜色&#xff1a;rgb(0,0,0,0.5); 2.小程序使用类似于iOS的NSNotification&#xff1a;&#xff08;第三方:https://github.com/icindy/WxNotificationCenter&#xff09; (1)在需要收发通知的页面引入WxNotificationCenter&#xff1a; var WxNotifi…

简单两行,实现无线WiFi共享上网,手机抓包再也不用愁了

你是否为WiFi共享而发愁&#xff0c;各个无线共享软件&#xff0c;某某共享精灵&#xff0c;某某免费WiFi&#xff0c;某某共享大师&#xff0c;某某随身WiFi&#xff0c;一个比一个难用&#xff0c;一个比一个私货多&#xff0c;一个比一个广告多&#xff0c;如果装上了它们&a…

用C#实现的条形码和二维码编码解码器

本篇介绍可以在C#中使用的1D/2D编码解码器。条形码的应用已经非常普遍&#xff0c;几乎所有超市里面的商品上面都印有条形码&#xff1b;二维码也开始应用到很多场合&#xff0c;如火车票有二维码识别、网易的首页有二维码图标&#xff0c;用户只需要用手机扫描一下就可以看到手…

【iOS】通过NSURLProtocol提高Web加载速度

一.项目需求 项目中有个海报功能&#xff0c;是用UIWebView加载h5网页的形式。因为海报的使用率比较高&#xff0c;如果网页加载得比较慢会严重影响用户体验&#xff0c;因此我们想了一个方法&#xff0c;在用户启动APP后&#xff0c;如果连接了Wi-Fi&#xff0c;就将一些css和…

rand()和srand()关系很简单——一看就明白(通过一个可移植的源码)

1 函数rand和srand实现及描述 #include <stdlib.h> //供rand()使用的种子数&#xff0c;初值为1 unsigned long int next 1; /* * 描述&#xff1a;函数rand() 用于生成介于 0和RAND_MAX之间的伪随机整数序列 * 其中RAND_MAX是在头文件<stdlib.h> 中定义的…

Windows下Python 3.6 安装BeautifulSoup库

“ 介绍Python库BeautifulSoup安装。”01—BeautifulSoup库介绍Beautiful Soup是Python的一个库&#xff0c;支持Python 2和Python 3,最主要的功能是从网页抓取数据&#xff0c;即爬虫,官网介绍如下&#xff1a;Beautiful Soup provides a few simple methods and Pythonic idi…

struts2配置详解

01.Struts 2基本结构 使用Struts2框架实现用登录的功能&#xff0c;使用struts2标签和ognl表达式简化了试图的开发&#xff0c;并且利用struts2提供的特性对输入的数据进行验证&#xff0c;以及访问ServletAPI时实现用户会话跟踪&#xff0c;其简单的程序运行流程图如下 Struts…

Xcode调试技巧

1、给断点设定触发条件 如下代码&#xff0c;右键断点&#xff0c;选择Edit Breakpoint&#xff0c;设定只有i8时&#xff0c;才触发断点。 此时只有i8时&#xff0c;才触发断点。 2、断点调试时修改变量 上面代码i8成立时&#xff0c;触发短点&#xff0c;此时右击变量窗口…

MiniGUI - UNIX Domain Socket 封装

/* Returns fd if all OK, -1 on error. */ int serv_listen (const char* name);服务器调用该函数建立一个监听套接字&#xff0c;并返回套接字文件描述符。建议将服务器监听套接字建立在 /var/tmp/ 目录下。MAX_NR_LISTEN_FD 宏定义了系统能够监听的最多文件描述符数&#xf…

RSA加密算法破解及原理

“ RSA加密算法是一种非对称加密算法&#xff0c;目前被广泛应用。本文介绍RSA算法的基本原理和破解方法。”RSA在互联网上被广泛应用&#xff0c;典型的如各个网站的证书。很多应用数据的加密也是使用RSA。本文介绍RSA算法的原理&#xff0c;并介绍其破解方法和工具。01—RSA算…

SpringMvc之@RequestParam详解

RequestParam是传递参数的. RequestParam用于将请求参数区数据映射到功能处理方法的参数上。 public String queryUserName(RequestParam String userName) 在url中输入:localhost:8080/**/?userNamezhangsan 请求中包含username参数&#xff08;如/requestparam1?userNamezh…

MLeaksFinder简单实现原理

MLeaksFinder是 iOS 平台的自动内存泄漏检测工具&#xff0c;下面以demo来实现检测视图控制器是否内存泄漏&#xff0c;实现类似的功能&#xff0c;简单地了解MLeaksFinder的原理。 总体思路&#xff1a;在视图控制器弹出栈 && 视图完全消失时&#xff0c;监听对象是否…

CSipSimple 工程分析 1

有两种方法,但是个人只有一种方法可以实现build并且生成应用,那么就是直接下载Google Code CSipSimple中提供已经设置好所有的配置的额\ubuntu虚拟机镜像文件. 打开这个镜像文件需要virtual Box,这个在oracle官方网站上面有,是个免费开源的软件. Google Code : https://code.go…

干货,Wireshark使用技巧-过滤规则

“介绍Wireshark抓包时使用的过滤规则。”熟练使用Wireshark&#xff0c;对协议分析大有帮助。本文介绍抓取报文时使用的过滤规则和对已有报文的显示进行控制的显示规则。01—过滤规则使用在抓取报文时使用的规则&#xff0c;称为过滤规则&#xff0c;Wireshark底层是基于Winpc…

《图解HTTP》笔记之TCP/IP

TCP/IP 通常使用的网络&#xff08;包括互联网&#xff09;是在TCP/IP协议族的基础上运作的。把互联网相关联的协议集合起来总称为TCP/IP。而HTTP属于它内部的一个子集&#xff08;HTTP协议是建立在TCP协议之上的一种应用&#xff09;&#xff1a; TCP/IP协议族里最重要的一…

JS --正则表达式验证、实战之邮箱模式

JS验证格式&#xff1a;提高用户体验&#xff0c;验证文本。需要防止程序员的代码结构更改攻击&#xff0c;因为web段的代码有可能会被更改&#xff0c;更改后JS有可能会验证不住那么&#xff0c;C#端在JS段通过验证的情况下&#xff0c;还需要进行二次验证 <body><fo…

《ASP.NET MVC4 WEB编程》学习笔记------Web API 续

目录 ASP.NET WEB API的出现缘由 ASP.NET WEB API的强大功能 ASP.NET WEB API的出现缘由 随着UI AJAX 请求适量的增加&#xff0c;ASP.NET MVC基于JsonResult的控制器操作将无法满足高级AJAX前端的需求。如果真的出现这种情况&#xff0c;就应该好好寻找一种更简单&#xff0c;…

干货:Wireshark使用技巧-显示规则

“ 介绍Wireshark对已有报文的显示进行控制的显示规则。”之前对Wireshark抓包时使用的过滤规则进行了介绍&#xff0c;本文介绍对已有报文的显示进行控制的显示规则。掌握了显示规则&#xff0c;你使用Wireshark的动作都会炫起来。点击回顾&#xff1a;过滤规则01—显示规则使…

【转载】Linux系统与性能监控

原文: Linux System and Performance Monitoring Darren Hoch 译:Roger 这是[叔度]给我的一篇非常不错的关于Linux性能监控的文档&#xff0c;可惜是英文的&#xff0c;网上只能找到些中文节选&#xff0c;并不完整。 准备花些时间将原文共43页认真学习一下&#xff0c;顺便翻译…

iOS端Socket连接、发送数据(一)

一、Socket的应用 IM即时通讯是通过Socket的方式实现长连接&#xff0c;可运用于 &#xff08;1&#xff09;直播聊天室、礼物 &#xff08;2&#xff09;微信、QQ等即时聊天 &#xff08;3&#xff09;游戏对话、技能等 二、SOCKET原理 套接字&#xff08;socket&#x…

dataTable 从服务器获取数据源的两种表现形式

1 var table $(#example1).DataTable({2 "processing": true,//加载效果3 "autoWidth": false,4 "iDisplayLength": 25,//设置每页要显示的条数5 "lengthMenu": [[25, 50, 100], [25, 50, 100]],//设…

干货!链家二手房数据抓取及内容解析要点

“本文对链家官网网页进行内容分析&#xff0c;可以作为一般HTTP类应用协议进行协议分析的参考&#xff0c;同时&#xff0c;对链家官网的结构了解后&#xff0c;可以对二手房相关信息进行爬取&#xff0c;并且获取被隐藏的近期成交信息。”另外&#xff0c;近期将对包含登录帐…

Atitit.软件兼容性原理与实践 v3 q326.docx

Atitit.软件兼容性原理与实践 v3 q326.docx 1. 架构兼容性1 2. Api兼容性1 2.1. 新api vs 修改旧的api1 3. Web方面的兼容性&#xff08;js&#xff0c;html&#xff09;1 3.1. Threadlocal2 4. 数据库表兼容性2 4.1. 2. 扩展表模式2 5. 兼容性策略2 5.1. Atitit.兼容性的“一…

用PULL解析器解析XML文件

第一种方式&#xff08;简洁&#xff0c;直接用pullparser.nextText()来返回下一个String类型的值&#xff09;&#xff1a; 1 package lee.service; 2 3 import java.io.InputStream; 4 import java.util.ArrayList; 5 import java.util.List; 6 import org.xmlpull…

iOS端Socket(二)ProtocolBuffer使用

ProtocolBuffer使用 一、环境及ProtocolBuffer的安装 分别在终端执行以下命令&#xff1a; ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"brew install protobuf-swift brew install automake brew install libtoo…

Wireshark分析实战:某达速递登录帐号密码提取

“使用某达速递的官网登陆及APP登录&#xff0c;来学习Wireshark的使用。”在如今这个HTTPS深入人心的情况下&#xff0c;作为一个也不算很小的快递&#xff0c;某达速递&#xff0c;不但全站HTTP&#xff0c;而且登录帐号密码明文未加密传输&#xff0c;也算是技术落后到了一定…

【并行计算-CUDA开发】从零开始学习OpenCL开发(一)架构

多谢大家关注 转载本文请注明&#xff1a;http://blog.csdn.net/leonwei/article/details/8880012 本文将作为我《从零开始做OpenCL开发》系列文章的第一篇。 1 异构计算、GPGPU与OpenCL OpenCL是当前一个通用的由很多公司和组织共同发起的多CPU\GPU\其他芯片 异构计算&#xf…

使用 fcntl 函数 获取,设置文件的状态标志

前言 当打开一个文件的时候&#xff0c;我们需要指定打开文件的模式( 只读&#xff0c;只写等 )。那么在程序中如何获取&#xff0c;修改这个文件的状态标志呢&#xff1f;本文将告诉你如何用 fcntl函数 获取指定文件的状态标志。 解决思路 1. 对于获取文件状态标志&#xff0c…

UILabel显示带颜色边的文字

需求如图&#xff0c;UILabel要实现带红色边的文字显示。 1、新建UILabel的子类JXBorderLabel 2、重写drawRect:方法 #import "JXBorderLabel.h"implementation JXBorderLabel- (void)drawRect:(CGRect)rect {//1.获取上下文CGContextRef context UIGraphicsGe…