RK3568 Android11 sh366006驱动
sh366006.c
/* 谁愿压抑心中怒愤冲动咒骂这虚与伪与假从没信要屈膝面对生命纵没有别人帮一生只靠我双手让我放声疯狂叫囔今天的他 呼风可改雨不可一世太嚣张 --《不可一世》Beyond
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/workqueue.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/sizes.h>#define SHFG_ENABLE_LOG 1#define SH_PROPERTIES "sh366006-bat"#define SHFG_NAME "sh366006"#define sh_printk(fmt, arg...) \{ \if (SHFG_ENABLE_LOG) \printk(KERN_INFO "SH366006 : %s-%d : " fmt, __FUNCTION__ ,__LINE__,##arg); \else {} \}#define queue_delayed_work_time 1000
#define queue_start_work_time 50#define SH366006_SMBUS_ADDR 0x16
#define SH366006_MANUFACTURER_DATA 0x07static const uint8_t crc8_table[256] ={0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d,0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d,0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd,0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2, 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea,0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a,0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42, 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4,0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44,0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63,0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b, 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13,0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3};/* 完整的SBS Command Codes (0x00-0x3F) */
enum sh366006_commands {MANUFACTURER_ACCESS = 0x00, // 制造商访问DEVICE_TYPE = 0x01, // 设备类型REMAINING_CAPACITY = 0x0F, // 剩余容量(mAh)VOLTAGE = 0x09, // 电池电压(mV)CURRENT = 0x0A, // 实时电流(mA)AVERAGE_CURRENT = 0x0B, // 平均电流(mA)RELATIVE_SOC = 0x0D, // 相对电量百分比(%)ABSOLUTE_SOC = 0x0E, // 绝对电量百分比(%)HEALTHY_SOC = 0x4F, // 电池健康度TEMPERATURE = 0x08, // 温度(0.1K)FULL_CHARGE_CAPACITY = 0x10, // 满电容量BATTERY_STATUS = 0x16, // 电池状态字CYCLE_COUNT = 0x17, // 循环次数DESIGN_CAPACITY = 0x18, // 设计容量(mAh)DESIGN_VOLTAGE = 0x19, // 标称电压(mV)SPECIFICATION_INFO = 0x1A, // 规格信息MANUFACTURE_DATE = 0x1B, // 生产日期SERIAL_NUMBER = 0x1C, // 序列号CELL_VOLTAGE_1 = 0x3C, // 第1节电压(mV)CELL_VOLTAGE_2 = 0x3D, // 第2节电压(mV)CELL_VOLTAGE_3 = 0x3E, // 第3节电压(mV)CELL_VOLTAGE_4 = 0x3F, // 第4节电压(mV)// 安全扩展命令(0x20-0x2F)SAFETY_STATUS = 0x20, // 安全状态寄存器SAFETY_ALERT = 0x21, // 安全警报阈值SAFETY_STATUS_EXT = 0x22, // 扩展安全状态CHG_VOLTAGE = 0x30, // 充电电压设置(mV)CHG_CURRENT = 0x31, // 充电电流设置(mA)DISCHG_CURRENT = 0x39, // 放电电流限制(mA)// 制造商专用命令(0x40-0x5F)QMAX_UPDATE = 0x41, // Qmax校准命令BALANCE_CONTROL = 0x42, // 电池均衡控制JEITA_CONTROL = 0x43, // JEITA温度补偿SHA1_AUTH = 0x44, // SHA-1认证CELL_TEMP_1 = 0x50, // 第1节温度CELL_TEMP_2 = 0x51, // 第2节温度// 时间预测命令REMAINING_TIME = 0x11, // 剩余使用时间(min)AVG_TIME_TO_EMPTY = 0x12, // 平均耗尽时间AVG_TIME_TO_FULL = 0x13, // 平均充满时间
};struct sh36606_chip {struct i2c_client *client;struct workqueue_struct *shfg_workqueue;struct delayed_work monitor_work;#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)struct power_supply sh_bat;
#elsestruct power_supply *sh_bat;
#endifint battery_temp;int voltage;int soc;int battery_current;int cycle_count;int battery_healthy;int status;
};static int sh_read_reg(struct i2c_client *client, u8 reg, u8 *buf, int len)
{struct i2c_msg msgs[2] = {{.addr = client->addr,.flags = 0,.len = 1,.buf = ®,},{.addr = client->addr,.flags = I2C_M_RD,.len = len,.buf = buf,},};if (i2c_transfer(client->adapter, msgs, 2) != 2) {dev_err(&client->dev, "I2C read error\n");return -EIO;}return 0;
}static int sh_write_reg(struct i2c_client *client, u8 reg, u8 val)
{u8 buf[2] = {reg, val};struct i2c_msg msg = {.addr = client->addr,.flags = 0,.len = 2,.buf = buf,};if (i2c_transfer(client->adapter, &msg, 1) != 1) {dev_err(&client->dev, "I2C write error\n");return -EIO;}return 0;
}uint8_t crc8_check(uint8_t *data , uint16_t len)
{uint16_t i = 0;uint8_t fcs = 0;for(i=0 ; i<(len) ; i++){fcs = crc8_table[(uint8_t)fcs ^ (*data)];data++;}return fcs;
}/*读SBS命令,返回两个字节数据
ID :SBS命令号,只能是返回两个字节的子命令
value:返回的两字节数据组成的16bit数据*/
int SH366100_Read_SBS_Word(struct i2c_client *client, uint8_t reg, uint16_t* val)
{uint8_t address = 0x16;uint8_t recieve_data[6] = {0x00};uint8_t crc_check = 0x00;recieve_data[0] = address;recieve_data[1] = reg;recieve_data[2] = address | 0x01;if(0 != sh_read_reg( client, reg, recieve_data+3, 3) ){*val = 0;return -1;}else{crc_check = crc8_check(recieve_data , 5);if(crc_check == recieve_data[5] ){*val = recieve_data[3] + (((uint16_t)recieve_data[4])<<8);return 0;}else{*val = 0;return -1;}}
}static int sh366006_get_voltage(struct sh36606_chip *sh_chip)
{int ret;uint16_t reg_val[2] = {0, 0};unsigned int voltage;ret = SH366100_Read_SBS_Word(sh_chip->client, VOLTAGE, reg_val);if(ret <0 ) {sh_chip->voltage = 3000;return ret;}voltage = reg_val[0];sh_chip->voltage = voltage;return 0;
}static int sh366006_get_cycle_count(struct sh36606_chip *sh_chip)
{int ret;uint16_t reg_val[2] = {0, 0};unsigned int cycle_count;ret = SH366100_Read_SBS_Word(sh_chip->client, CYCLE_COUNT, reg_val);if(ret <0 ) {sh_chip->cycle_count = 1;return ret;}cycle_count = reg_val[0];sh_chip->cycle_count = cycle_count;return 0;
}static int sh366006_get_current(struct sh36606_chip *sh_chip)
{int ret;uint16_t reg_val[2] = {0, 0};unsigned int battery_current;ret = SH366100_Read_SBS_Word(sh_chip->client, AVERAGE_CURRENT, reg_val);if(ret <0 ) {sh_chip->battery_current = 65284;return ret;}battery_current = reg_val[0];sh_chip->battery_current = battery_current;return 0;
}static int sh366006_get_soc(struct sh36606_chip *sh_chip)
{int ret;uint16_t reg_val[2] = {0, 0};unsigned int soc;ret = SH366100_Read_SBS_Word(sh_chip->client, RELATIVE_SOC, reg_val);if(ret <0 ) {sh_chip->soc = 1;return ret;}soc = reg_val[0] ;sh_chip->soc = soc;return 0;
}static int sh366006_get_temperature(struct sh36606_chip *sh_chip)
{int ret;unsigned char reg_val[2] = {0, 0};unsigned int temperature;ret = SH366100_Read_SBS_Word(sh_chip->client, TEMPERATURE, reg_val);if(ret <0 ) {sh_chip->battery_temp = 26;return ret;}temperature = reg_val[0] ;sh_chip->battery_temp = temperature;return 0;
}static int sh366006_get_battery_healthy(struct sh36606_chip *sh_chip)
{int ret;unsigned char reg_val[2] = {0, 0};unsigned int healthy;ret = SH366100_Read_SBS_Word(sh_chip->client, HEALTHY_SOC, reg_val);if(ret <0 ) {sh_chip->battery_healthy = 2;return ret;}healthy = reg_val[0] ;sh_chip->battery_healthy = healthy;return 0;
}static int sh_init_data(struct sh36606_chip *sh_chip)
{int ret = 0;u16 device_type;/* 验证芯片ID */ret = SH366100_Read_SBS_Word(sh_chip->client, DEVICE_TYPE, &device_type);if (ret != 0 || device_type != 410) {dev_err(&sh_chip->client->dev, "Invalid chip ID: 0x%02X\n", device_type);sh_chip->battery_temp = 26;sh_chip->voltage = 3000;sh_chip->soc = 50;sh_chip->battery_current = 65284;sh_chip->cycle_count = 1;sh_chip->battery_healthy = 2;sh_chip->status = POWER_SUPPLY_STATUS_CHARGING;return -1;} else {sh_printk("check ok\r\n");}ret += sh366006_get_voltage(sh_chip);ret += sh366006_get_current(sh_chip);ret += sh366006_get_soc(sh_chip);ret += sh366006_get_temperature(sh_chip);ret += sh366006_get_cycle_count(sh_chip);ret += sh366006_get_battery_healthy(sh_chip);sh_chip->status = POWER_SUPPLY_STATUS_DISCHARGING;sh_printk("voltage : %d, current : %d, soc : %d, temperature : %d, cycle_count:%d, battery_healthy:%d ,ret : %d \n",\sh_chip->voltage, sh_chip->battery_current, sh_chip->soc, sh_chip->battery_temp, sh_chip->cycle_count, sh_chip->battery_healthy, ret);return ret;
}/*
定期循环的工作队列
*/
static void sh366006_monitor_work(struct work_struct *work)
{struct delayed_work *delay_work;struct sh36606_chip *sh_chip;int ret;delay_work = container_of(work, struct delayed_work, work);sh_chip = container_of(delay_work, struct sh36606_chip, monitor_work);ret += sh366006_get_voltage(sh_chip);ret += sh366006_get_current(sh_chip);ret += sh366006_get_soc(sh_chip);ret += sh366006_get_temperature(sh_chip);ret += sh366006_get_cycle_count(sh_chip);ret += sh366006_get_battery_healthy(sh_chip);sh_printk("voltage : %d, current : %d, soc : %d, temperature : %d, cycle_count:%d, battery_healthy:%d ,ret : %d \n",\sh_chip->voltage, sh_chip->battery_current, sh_chip->soc, sh_chip->battery_temp, sh_chip->cycle_count, sh_chip->battery_healthy, ret);//向Android系统上报电池参数
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)power_supply_changed(&sh_chip->sh_bat);
#elsepower_supply_changed(sh_chip->sh_bat);
#endifqueue_delayed_work(sh_chip->shfg_workqueue, &sh_chip->monitor_work, msecs_to_jiffies(queue_delayed_work_time));
}static int sh_battery_set_property(struct power_supply *psy,enum power_supply_property psp,const union power_supply_propval *val)
{int ret = 0;#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)struct sh36606_chip *sh_bat;sh_bat = container_of(psy, struct sh36606_chip, sh_bat); #elsestruct sh36606_chip *sh_bat = power_supply_get_drvdata(psy); #endifswitch(psp) {default:ret = -EINVAL; break; }return ret;
}static int sh_get_capacity_level(struct sh36606_chip *sh_bat)
{if (sh_bat->soc < 1)return POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;else if (sh_bat->soc <= 20)return POWER_SUPPLY_CAPACITY_LEVEL_LOW;else if (sh_bat->soc <= 70)return POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;else if (sh_bat->soc <= 90)return POWER_SUPPLY_CAPACITY_LEVEL_HIGH;elsereturn POWER_SUPPLY_CAPACITY_LEVEL_FULL;
}static int sh_battery_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val)
{int ret = 0;#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)struct sh36606_chip *sh_bat;sh_bat = container_of(psy, struct sh36606_chip, sh_bat);
#elsestruct sh36606_chip *sh_bat = power_supply_get_drvdata(psy);
#endif switch(psp) {case POWER_SUPPLY_PROP_CYCLE_COUNT:val->intval = sh_bat->cycle_count;break;case POWER_SUPPLY_PROP_CAPACITY:val->intval = sh_bat->soc;break;case POWER_SUPPLY_PROP_PRESENT:val->intval = sh_bat->voltage <= 0 ? 0 : 1;break; case POWER_SUPPLY_PROP_VOLTAGE_NOW:val->intval = sh_bat->voltage;break;case POWER_SUPPLY_PROP_CURRENT_NOW:val->intval = sh_bat->battery_current;break;case POWER_SUPPLY_PROP_TEMP: val->intval = 250;break;case POWER_SUPPLY_PROP_HEALTH: val->intval = POWER_SUPPLY_HEALTH_GOOD;break;case POWER_SUPPLY_PROP_TECHNOLOGY:val->intval = POWER_SUPPLY_TECHNOLOGY_LION;break;case POWER_SUPPLY_PROP_CAPACITY_LEVEL:val->intval = sh_get_capacity_level(sh_bat);break;case POWER_SUPPLY_PROP_STATUS:val->intval = sh_bat->status;break;default:ret = -EINVAL; break;} return ret;
}static enum power_supply_property sh_battery_properties[] = {POWER_SUPPLY_PROP_CYCLE_COUNT,POWER_SUPPLY_PROP_TEMP,POWER_SUPPLY_PROP_CAPACITY,POWER_SUPPLY_PROP_PRESENT,POWER_SUPPLY_PROP_VOLTAGE_NOW,POWER_SUPPLY_PROP_CURRENT_NOW,POWER_SUPPLY_PROP_HEALTH,POWER_SUPPLY_PROP_TECHNOLOGY,POWER_SUPPLY_PROP_CAPACITY_LEVEL,POWER_SUPPLY_PROP_STATUS,
};static int sh366006_probe(struct i2c_client *client, const struct i2c_device_id *id)
{int ret;static struct sh36606_chip *sh_bat;struct power_supply_desc *psy_desc;struct power_supply_config psy_cfg = {0};sh_printk("\n");sh_bat = devm_kzalloc(&client->dev, sizeof(*sh_bat), GFP_KERNEL);if (!sh_bat) {sh_printk("%s : sh_bat create fail!\n", __func__);return -ENOMEM;}// sh_printk("fuck 1\n");i2c_set_clientdata(client, sh_bat);sh_bat->client = client;// sh_printk("fuck 2.5\n");ret = sh_init_data(sh_bat);if (ret < 0) {sh_printk(" sh_init_data fail!\n");// return ret;}#ifdef SH_PROPERTIES
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)sh_bat->sh_bat.name = SH_PROPERTIES;sh_bat->sh_bat.type = POWER_SUPPLY_TYPE_BATTERY;sh_bat->sh_bat.properties = sh_battery_properties;sh_bat->sh_bat.num_properties = ARRAY_SIZE(sh_battery_properties);sh_bat->sh_bat.get_property = sh_battery_get_property;sh_bat->sh_bat.set_property = sh_battery_set_property;ret = power_supply_register(&client->dev, &sh_bat->sh_bat);if (ret < 0) {power_supply_unregister(&sh_bat->sh_bat);sh_printk("failed to register battery: %d\n", ret);return ret;}// sh_printk("fuck 2.6\n");
#elsepsy_desc = devm_kzalloc(&client->dev, sizeof(*psy_desc), GFP_KERNEL);if (!psy_desc)return -ENOMEM;psy_cfg.drv_data = sh_bat;psy_desc->name = SH_PROPERTIES;psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;psy_desc->properties = sh_battery_properties;psy_desc->num_properties = ARRAY_SIZE(sh_battery_properties);psy_desc->get_property = sh_battery_get_property;psy_desc->set_property = sh_battery_set_property;sh_bat->sh_bat = power_supply_register(&client->dev, psy_desc, &psy_cfg);if (IS_ERR(sh_bat->sh_bat)) {ret = PTR_ERR(sh_bat->sh_bat);sh_printk("failed to register battery: %d\n", ret);return ret;}// sh_printk("fuck 2.7\n");
#endif
#endif
// sh_printk("fuck 3\n");sh_bat->shfg_workqueue = create_singlethread_workqueue("shfg_gauge");INIT_DELAYED_WORK(&sh_bat->monitor_work, sh366006_monitor_work);queue_delayed_work(sh_bat->shfg_workqueue, &sh_bat->monitor_work , msecs_to_jiffies(queue_start_work_time));// sh_printk("fuck 4\n");sh_printk("sh366006 driver probe success!\n");return 0;
}static int sh366006_remove(struct i2c_client *client)
{sh_printk("\n");return 0;
}static const struct i2c_device_id sh366006_id_table[] = {{ SHFG_NAME, 0 },{ }
};static struct of_device_id sh366006_match_table[] = {{ .compatible = "shunwei,sh366006", },{ },
};static struct i2c_driver sh366006_driver = {.driver = {.name = SHFG_NAME,.owner = THIS_MODULE,.of_match_table = sh366006_match_table,},.probe = sh366006_probe,.remove = sh366006_remove,.id_table = sh366006_id_table,
};static int __init sh366006_init(void)
{sh_printk("\n");i2c_add_driver(&sh366006_driver);return 0;
}static void __exit sh366006_exit(void)
{i2c_del_driver(&sh366006_driver);
}module_init(sh366006_init);
module_exit(sh366006_exit);MODULE_AUTHOR("SRED Cole");
MODULE_DESCRIPTION("SH366006 Device Driver V0.1");
MODULE_LICENSE("GPL");
设备树
sh366006@0b {status = "okay";compatible = "shunwei,sh366006";reg = <0x0b>;};
相关文章:
RK3568 Android11 sh366006驱动
sh366006.c /* 谁愿压抑心中怒愤冲动咒骂这虚与伪与假从没信要屈膝面对生命纵没有别人帮一生只靠我双手让我放声疯狂叫囔今天的他 呼风可改雨不可一世太嚣张 --《不可一世》Beyond */ #include <linux/module.h> #include <linux/init.h> #include <linux/fs.h…...
蓝桥杯学习——二叉树+奇点杯题目解析
基础认知 一、二叉树种类: 1.满二叉树。记深度k,节点数量2^k-1。 2.完全二叉树:除了底层,其余全满,底部从左到右连续。 3,平衡二叉搜索树:左子树和右子树高度差不大于1。 二、存储方式&…...
基于django+vue的购物商城系统
开发语言:Python框架:djangoPython版本:python3.8数据库:mysql 5.7数据库工具:Navicat11开发软件:PyCharm 系统展示 系统首页 热卖商品 优惠资讯 个人中心 后台登录 管理员功能界面 用户管理 商品分类管理…...
AI安全、大模型安全研究(DeepSeek)
DeepSeek 点燃AI应用革命之火,但安全 “灰犀牛” 正在逼近 DeepSeek-R1国产大模型的发布,以技术创新惊艳了全球,更是极致的性价比推动国内千行百业接入 AI,政府、企业竞速开发智能业务处理、智能客服、代码生成、营销文案等应用,“落地效率” 成为第一关键词。然而与此相…...
卷积神经网络 - 汇聚层
卷积神经网络一般由卷积层、汇聚层和全连接层构成,本文我们来学习汇聚层。 汇聚层(Pooling Layer)也叫子采样层(Subsampling Layer),其作用是进 行特征选择,降低特征数量,从而减少参数数量。 卷积层虽然可以显著减少网络中连接的…...
蓝桥杯备赛-贪心-管道
问题描述 有一根长度为 lenlen 的横向的管道,该管道按照单位长度分为 lenlen 段,每一段的中央有一个可开关的阀门和一个检测水流的传感器。 一开始管道是空的,位于 LiLi 的阀门会在 SiSi 时刻打开,并不断让水流入管道。 对…...
论文分享:PL-ALF框架实现无人机低纹理环境自主飞行
在室内仓库、地下隧道等低纹理复杂场景中,无人机依赖视觉传感器进行自主飞行时,往往会遇到定位精度低、路径规划不稳定等难题。针对这一问题,重庆邮电大学计算机学院雷大江教授团队在IEEE Trans期刊上提出了一种新型自主飞行框架:…...
Nodejs使用redis
框架:koa,通过koa-generator创建 redis: 本地搭建,使用默认帐号,安装说明地址以及默认启动设置:https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/install-redis-on-linux/ 中间件&#x…...
GitHub 超火的开源终端工具——Warp
Warp 作为近年来 GitHub 上备受瞩目的开源终端工具,以其智能化、高性能和协作能力重新定义了命令行操作体验。以下从多个维度深入解析其核心特性、技术架构、用户评价及生态影响力: 一、背景与核心团队 Warp 由前 GitHub CTO Jason Warner 和 Google 前…...
计算机视觉技术探索:美颜SDK如何利用深度学习优化美颜、滤镜功能?
时下,计算机视觉深度学习正在重塑美颜技术,通过智能人脸检测、AI滤镜、深度美肤、实时优化等方式,让美颜效果更加自然、精准、个性化。 那么,美颜SDK如何结合深度学习来优化美颜和滤镜功能?本文将深入解析AI在美颜技术…...
应用商店上新:Couchbase Enterprise Server集群
可移植的冗余数据平台,这往往是创建可扩展的云原生应用程序的先决条件。而不依赖特定平台的工具可用于为多云、多区域工作负载提供企业级应用所需的灵活性。 Couchbase是一种高性能NoSQL数据库,专为当今复杂的云生态系统所需的动态扩展能力而设计。最近…...
Redis解决缓存击穿问题——两种方法
目录 引言 解决办法 互斥锁(强一致,性能差) 逻辑过期(高可用,性能优) 设计逻辑过期时间 引言 缓存击穿:给某一个key设置了过期时间,当key过期的时候,恰好这个时间点对…...
前端 Blob 详解
前端 Blob 详解 1. 什么是 Blob? Blob(Binary Large Object)表示二进制大对象,用于存储二进制数据。在前端开发中,Blob 常用于处理文件、图像、视频等二进制数据。 2. 创建 Blob 可以通过 Blob 构造函数创建 Blob …...
Debezium + Kafka-connect 实现Postgres实时同步Hologres
基于 Debezium Kafka 的方案实现 PostgreSQL 到 Hologres 的实时数据同步,是一种高可靠性、高扩展性的解决方案。以下是详细的实现步骤: 1. 方案架构 Debezium:捕获 PostgreSQL 的变更数据(CDC),并将变更…...
JavaScript性能优化的12种方式
当涉及到JavaScript性能优化时,有几个关键的方面需要考虑。下面是一些常见的JavaScript性能优化技巧和实践: 减少DOM操作: 频繁的DOM操作会导致重绘和重新布局,影响性能。建议将多个DOM操作合并为一个操作,或者使用Do…...
在Ubuntu上安装MEAN Stack的4个步骤
在Ubuntu上安装MEAN Stack的4个步骤为:1.安装MEAN;2.安装MongoDB;3.安装NodeJS,Git和NPM;4.安装剩余的依赖项。 什么是MEAN Stack? 平均堆栈一直在很大程度上升高为基于稳健的基于JavaScript的开发堆栈。…...
集成学习之随机森林
目录 一、集成学习的含义 二、集成学习的代表 三、集成学习的应用 1、分类问题集成。(基学习器是分类模型) 2、回归问题集成。(基学习器是回归模型) 3、特征选取集成。 四、Bagging之随机森林 1、随机森林是有多个决策树&a…...
在线JSON格式校验工具站
在线JSON校验格式化工具(Be JSON)在线,JSON,JSON 校验,格式化,xml转json 工具,在线工具,json视图,可视化,程序,服务器,域名注册,正则表达式,测试,在线json格式化工具,json 格式化,json格式化工具,json字符串格式化,json 在线查看器,json在线,json 在线验…...
SAP的WPS导出找不到路径怎么办;上载报错怎么办
一.打开注册编辑器 二.输入以下地址 计算机\HKEY_CLASSES_ROOT\ExcelWorksheet\Protocol\StdFileEditing\Server 去除掉EXE后面的命令即可 二:WPS上载文件没反应怎么办 如何切换整合模式或多组件模式-WPS学堂 根据官方操作把整合模式改成多组件模式...
Moonlight-16B-A3B: 变革性的高效大语言模型,凭借Muon优化器打破训练效率极限
近日,由Moonshot AI团队推出的Moonlight-16B-A3B模型,再次在AI领域引发了广泛关注。这款全新的Mixture-of-Experts (MoE)架构的大型语言模型,凭借其创新的训练优化技术,特别是Muon优化器的使用,成功突破了训练效率的极…...
rust学习笔记17-异常处理
今天聊聊rust中异常错误处理 1. 基础类型:Result 和 Option,之前判断空指针就用到过 Option<T> 用途:表示值可能存在(Some(T))或不存在(None),适用于无需错误信息的场景。 f…...
PyTorch系列教程:使用预训练语言模型增强文本分类
文本分类仍是自然语言处理(NLP)领域的一项基础任务,其目标是将文本数据归入预先设定的类别之中。预训练语言模型的出现极大地提升了这一领域的性能。本文将探讨如何利用 PyTorch 来利用这些模型,展示它们如何能增强文本分类任务。…...
LabVIEW 线性拟合
该 LabVIEW 程序实现了 线性拟合(Linear Fit),用于计算给定一组数据点的斜率(Slope)和截距(Intercept),并将结果可视化于 XY Graph 中。本案例适用于数据拟合、实验数据分析、传感器…...
nacos安装,服务注册,服务发现,远程调用3个方法
安装 点版本下载页面 服务注册 每个微服务都配置nacos的地址,都要知道 服务发现 2个是知道了解 远程调用基本实现 远程调用方法2,负载均衡API测试 远程调用方法3,注解 负载均衡的远程调用, 总结 面试题...
k8s主要控制器简述(一)ReplicaSet与Deployment
目录 一、ReplicaSet 关键特性 示例 解释 支持的 Operator 二、Deployment 1. 声明式更新 示例 2. 滚动更新 示例 3. 回滚 示例 4. ReplicaSet 管理 示例 5. 自动恢复 示例 6. 扩展和缩容 示例 示例 一、ReplicaSet ReplicaSet 是 Kubernetes 中的一个核心控…...
Java中的消息中间件对比与解析:RocketMQ vs RabbitMQ
消息中间件(Message Queue, MQ)是分布式系统中实现异步通信、解耦服务和流量削峰的关键组件。在Java生态中,RocketMQ和RabbitMQ是两个广泛应用的消息队列系统,但它们在设计理念、功能特性和适用场景上存在显著差异。本文将从核心功…...
Android14 Log.isLoggable判断的分析
Android14 Log.isLoggable判断的分析 文章目录 Android14 Log.isLoggable判断的分析一、前言二、答案和分析1、Log.isLoggable 设置成true2、Log.isLoggable 分析(1)Log.java(2)android_util_Log.cpp(3)pro…...
Mac:JMeter 下载+安装+环境配置(图文详细讲解)
📌 下载JMeter 下载地址:https://jmeter.apache.org/download_jmeter.cgi 📌 无需安装 Apache官网下载 JMeter 压缩包,无需安装,下载解压后放到自己指定目录下即可。 按我自己的习惯,我会在用户 jane 目…...
Python IP解析器 ip2region使用
说明:最近需要在python项目内使用IP定位所在城市的需求,没有采用向外部ISP服务商API请求获取信息的方案,则翻了翻,在搞Java时很多的方案,在Python端反而可选择范围很小。 # 示例查询 ips ["106.38.188.214"…...
labview与西门子1500plc进行S7通讯(仿真效果)
环境: 1.博图V16 2.S7-PLCSIM Advanced V3.0 3.labview2020 4.HslCommunication的dll文件 运行效果图 通过使用HslCommunication的库文件来对西门子plc进行通讯 labview代码 代码打包 通过网盘分享的文件:labview进行s7通讯测试.rar 链接: https:/…...
