充电IC和电量计的驱动调试

2023-11-01

  • LK是little kernel的缩写
  • 高通平台android普遍采用LK作为其bootloader,LK是一个开源项目。但是,LK只是整个系统的引导部分,所以它不是独立存在。LK是一个功能极其强大的bootloader,但只支持arm和x86平台。
  • LK的一个显著的特点就是它实现了一个简单的线程机制(thread),和对高通处理器的深度定制和使用。

一、LK部分代码修改

开机电压检测,关机充电使能
1.1、bootable/bootloader/lk/app/aboot/aboot.c

#include <display_menu.h>
 #include "fastboot_test.h"
 
+#include <i2c_qup.h>
+#include <blsp_qup.h>
+static struct qup_i2c_dev *i2c_dev;
 void *info_buf;
 void write_device_info_mmc(device_info *dev);
  	} else if (boot_reason_alarm) {
 		cmdline_len += strlen(alarmboot_cmdline);
-	} else if ((target_build_variant_user() || device.charger_screen_enabled)
-			&& target_pause_for_battery_charge() && !boot_into_recovery) {
+	} else if (/*(target_build_variant_user() || device.charger_screen_enabled)
+			&& */target_pause_for_battery_charge() && !boot_into_recovery) {
 		pause_at_bootup = 1;
 		cmdline_len += strlen(battchg_pause);
 	}
static int blsp_i2c_read_reg(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data)
{
        int ret = 0;

        struct i2c_msg msg_buf[] = {
                {i2c_addr, I2C_M_WR, 1, &reg_addr},
                {i2c_addr, I2C_M_RD, 1, reg_data}
        };

        ret = qup_i2c_xfer(i2c_dev, msg_buf, 2);
        if (ret < 0) {
                dprintf(CRITICAL, "qup_i2c_xfer read error %d, slave addr: %02x\n",
                        ret, i2c_addr);
                return ret;
        }

        return ret;
}

static int blsp_i2c_write_reg(uint8_t i2c_addr, uint8_t reg_addr, uint8_t reg_data)
{
        int ret = 0;
        uint8_t buf[2];

        buf[0] = reg_addr;
        buf[1] = reg_data;

        struct i2c_msg msg_buf[] = {
                {i2c_addr, I2C_M_WR, sizeof(buf), buf},
        };

        ret = qup_i2c_xfer(i2c_dev, msg_buf, 1);
        if (ret < 0) {
                dprintf(CRITICAL, "qup_i2c_xfer write error %d, slave addr: %02x\n",
                        ret, i2c_addr);
                return ret;
        }

        return ret;
}

static void battery_voltage_check_loop(void)
{
        int ret;
        uint8_t reg_sysmin = 0x03;
        uint8_t reg_wdt = 0x07;
        uint8_t reg_chip_id = 0x14;
        uint8_t reg_vbat = 0x0E;
        uint8_t reg_charger_online = 0x0B;
        uint8_t reg_adc_convert = 0x02;
        uint8_t chip_id, sysmin, wdt, adc_convert, vbat, charger_online;
        uint32_t vbat_voltage, power_on_voltage = 3500;

        gpio_tlmm_config(2, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA, GPIO_DISABLE);
        //gpio_tlmm_config(137, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA, GPIO_DISABLE);
        gpio_set_dir(2, 0); // enable charge chip enable
        //gpio_set_dir(137, 2); // connect usb dpdm to sc60 module

        i2c_dev = qup_blsp_i2c_init(BLSP_ID_1, QUP_ID_2, 100000, 19200000);
        thread_sleep(100);
    ret = blsp_i2c_read_reg(0x6A, reg_chip_id, &chip_id);
        if (ret < 0 || ((chip_id >> 3) & 7) != 3) {
                dprintf(CRITICAL, "get ba25890 chip id failed\n");
                return;
        }
        // reset chip
        ret = blsp_i2c_write_reg(0x6A, 0x14, 0x80);
        if (ret < 0) { // any error will exit battery voltage check
                dprintf(CRITICAL, "reset chip failed\n");
                return;
        }
        thread_sleep(100);
        ret = blsp_i2c_read_reg(0x6A, reg_wdt, &wdt);
        if (ret < 0) { // any error will exit battery voltage check
                dprintf(CRITICAL, "get wdt reg failed\n");
                return;
        }
        wdt &= ~(3 << 4);
        ret = blsp_i2c_write_reg(0x6A, reg_wdt, wdt);
        if (ret < 0) { // any error will exit battery voltage check
                dprintf(CRITICAL, "disable wdt failed\n");
                return;
        }
        ret = blsp_i2c_read_reg(0x6A, reg_sysmin, &sysmin);
        if (ret < 0) { // any error will exit battery voltage check
                dprintf(CRITICAL, "get sysmin reg failed\n");
                return;
        }
        sysmin &= ~(7 << 1);
		 ret = blsp_i2c_write_reg(0x6A, reg_sysmin, sysmin);
        if (ret < 0) { // any error will exit battery voltage check
                dprintf(CRITICAL, "set sysmin reg failed\n");
                return;
        }
        ret = blsp_i2c_read_reg(0x6A, reg_adc_convert, &adc_convert);
        if (ret < 0) { // any error will exit battery voltage check
                dprintf(CRITICAL, "get adc convert reg failed\n");
                return;
        }
        adc_convert |= 3 << 6;
        ret = blsp_i2c_write_reg(0x6A, reg_adc_convert, adc_convert);
        if (ret < 0) { // any error will exit battery voltage check
                dprintf(CRITICAL, "enable adc convert failed\n");
                return;
        }
        // wait adc start convert
        thread_sleep(100);
        while (1) {
                ret = blsp_i2c_read_reg(0x6A, reg_vbat, &vbat);
                if (ret < 0) {
                        dprintf(CRITICAL, "get vbat reg failed\n");
                        break;
                }
                ret = blsp_i2c_read_reg(0x6A, reg_charger_online, &charger_online);
                if (ret < 0) { // any error will exit battery voltage check
                        dprintf(CRITICAL, "get charger_online reg failed\n");
                        break;
                }
                charger_online = (charger_online >> 2) & 1;
                vbat_voltage = 2304 + (vbat & 0x7f) * 20;
                // if charger online, decrease 50mV from battery voltage
                if (charger_online)
                        vbat_voltage -= 50;
                dprintf(CRITICAL, "battery voltage %d\n", vbat_voltage);
                // if battery is absent, ntc will report cold, boot into android
                if (vbat_voltage >= power_on_voltage)
                        break; // exit battery voltage check
                else {
                        // sleep 1 minute, then recheck battery voltage
                        if (charger_online)
                                thread_sleep(3000);
                        else {
                                dprintf(CRITICAL, "battery voltage too low, shutdown device\n");
                                ret = blsp_i2c_write_reg(0x6A, 0x14, 0x80);
                                if (ret < 0) { // any error will exit battery voltage check
                                        dprintf(CRITICAL, "reset chip failed\n");
                                        break;
                                }
                                shutdown_device();
                        }
                }
        }
}

以下文件关于 I2C-2 使能
1.2、bootable/bootloader/lk/platform/msm8953/acpuclock.c

 #include <clock.h>
 #include <platform/clock.h>
 #include <platform.h>
+#include <blsp_qup.h>
void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
{
        uint8_t ret = 0;
        char clk_name[64];

        struct clk *qup_clk;

        snprintf(clk_name, sizeof(clk_name), "blsp1_ahb_clk");

        ret = clk_get_set_enable(clk_name, 0 , 1);

        if (ret) {
                dprintf(CRITICAL, "Failed to enable %s clock\n", clk_name);
                return;
        }

        snprintf(clk_name, sizeof(clk_name), "gcc_blsp1_qup3_i2c_apps_clk");

        qup_clk = clk_get(clk_name);

        if (!qup_clk) {
                dprintf(CRITICAL, "Failed to get %s\n", clk_name);
                return;
        }

        ret = clk_enable(qup_clk);

        if (ret) {
                dprintf(CRITICAL, "Failed to enable %s\n", clk_name);
                return;
        }
}

1.3、bootable/bootloader/lk/platform/msm8953/gpio.c

+
+void gpio_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
+{
+	/* configure I2C SDA gpio */
+	gpio_tlmm_config(10, 2, GPIO_OUTPUT, GPIO_NO_PULL,
+		GPIO_2MA, GPIO_DISABLE);
+
+	/* configure I2C SCL gpio */
+	gpio_tlmm_config(11, 2, GPIO_OUTPUT, GPIO_NO_PULL,
+		GPIO_2MA, GPIO_DISABLE);
+}
+

1.4、bootable/bootloader/lk/platform/msm8953/include/platform/clock.h

 void clock_usb30_init(void);
 void clock_reset_usb_phy();
+void clock_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id);
 #endif

1.5、bootable/bootloader/lk/platform/msm8953/include/platform/gpio.h

 void gpio_config_uart_dm(uint8_t id);
+void gpio_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id);
 uint32_t gpio_status(uint32_t gpio);

1.6、bootable/bootloader/lk/platform/msm8953/include/platform/iomap.h

 #define USB2_PHY_SEL                       0x01937000
 #define QUSB2_PHY_BASE                     0X79000
 
+#define BLSP_QUP_BASE(blsp_id, qup_id) 	(PERIPH_SS_BASE + 0xB5000 + 0x1000 * qup_id)
+#define GCC_BLSP1_QUP3_APPS_CBCR           (CLK_CTL_BASE + 0x04020)
+#define GCC_BLSP1_QUP3_CMD_RCGR	        (CLK_CTL_BASE + 0x04000)
+#define GCC_BLSP1_QUP3_CFG_RCGR	        (CLK_CTL_BASE + 0x04004)

 /* SS QMP (Qulacomm Multi Protocol) */
 #define QMP_PHY_BASE                0x78000

1.7、bootable/bootloader/lk/platform/msm8953/include/platform/irqs.h

 #define SMD_IRQ                                (GIC_SPI_START + 168)

+#define BLSP_QUP_IRQ(blsp_id, qup_id)          (GIC_SPI_START + 95 + qup_id)
 #endif /* __IRQS_MSM8953_H */

1.8、bootable/bootloader/lk/platform/msm8953/msm8953-clock.c

/* I2C Clocks */
static struct clk_freq_tbl ftbl_gcc_blsp1_qup3_i2c_apps_clk_src[] =
{
        F(      96000,    cxo,  10,   1,  2),
        F(    4800000,    cxo,   4,   0,  0),
        F(    9600000,    cxo,   2,   0,  0),
        F(   16000000,  gpll0,  10,   1,  5),
        F(   19200000,  gpll0,   1,   0,  0),
        F(   25000000,  gpll0,  16,   1,  2),
        F(   50000000,  gpll0,  16,   0,  0),
        F_END
};

static struct rcg_clk gcc_blsp1_qup3_i2c_apps_clk_src =
{
        .cmd_reg      = (uint32_t *) GCC_BLSP1_QUP3_CMD_RCGR,
        .cfg_reg      = (uint32_t *) GCC_BLSP1_QUP3_CFG_RCGR,
        .set_rate     = clock_lib2_rcg_set_rate_hid,
        .freq_tbl     = ftbl_gcc_blsp1_qup3_i2c_apps_clk_src,
        .current_freq = &rcg_dummy_freq,

        .c = {
                .dbg_name = "gcc_blsp1_qup3_i2c_apps_clk_src",
                .ops      = &clk_ops_rcg,
        },
};

static struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {
        .cbcr_reg = (uint32_t *)GCC_BLSP1_QUP3_APPS_CBCR,
        .parent   = &gcc_blsp1_qup3_i2c_apps_clk_src.c,

        .c = {
                .dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",
                .ops      = &clk_ops_branch,
        },
};

/* UART Clocks */

static struct clk_lookup msm_clocks_8953[] =
{
	CLK_LOOKUP("ce1_core_clk", gcc_ce1_clk.c),
 	CLK_LOOKUP("ce1_src_clk",  ce1_clk_src.c),

+    CLK_LOOKUP("blsp1_ahb_clk", gcc_blsp1_ahb_clk.c),
+	CLK_LOOKUP("gcc_blsp1_qup3_i2c_apps_clk_src", gcc_blsp1_qup3_i2c_apps_clk_src.c),
+	CLK_LOOKUP("gcc_blsp1_qup3_i2c_apps_clk", gcc_blsp1_qup3_i2c_apps_clk.c),
}

1.9、bootable/bootloader/lk/platform/msm_shared/rules.mk

 			$(LOCAL_DIR)/mipi_dsc.o \
 			$(LOCAL_DIR)/mipi_dsi_phy.o \
+			$(LOCAL_DIR)/i2c_qup.o \
 			$(LOCAL_DIR)/mipi_dsi_autopll_thulium.o
 endif

二、sys目录权限添加

2.1、device/qcom/sepolicy/vendor/msm8953/genfs_contexts

 #PMI path
 genfscon sysfs /devices/soc/qpnp-haptic-24/leds/vibrator u:object_r:sysfs_leds:s0
 genfscon sysfs /devices/soc/qpnp-vadc-14/usbin u:object_r:sysfs_battery_supply:s0
 
+genfscon sysfs /devices/platform/soc/78b7000.i2c/i2c-3/3-0062/power_supply/bms u:object_r:sysfs_battery_supply:s0
+genfscon sysfs /devices/platform/soc/78b7000.i2c/i2c-3/3-006a/power_supply/pc_port u:object_r:sysfs_battery_supply:s0
+genfscon sysfs /devices/platform/soc/78b7000.i2c/i2c-3/3-006a/power_supply/usb u:object_r:sysfs_usb_supply:s0
+genfscon sysfs /devices/platform/soc/78b7000.i2c/i2c-3/3-006a/power_supply/main u:object_r:sysfs_usb_supply:s0

三、kernel内核驱动

3.1、添加 ChargerIC 和电量计配置
/kernel/msm-4.9/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi

	bq25890: bq25890@6a {
		compatible = "ti,bq25890";
		reg = <0x6a>;
		ti,otg-charge = <1>;
		ti,otg-sw-supply = <&pm8953_l5>;
		ti,charge-enable-gpio = <&tlmm 2 0x00>;
		ti,interrupt-gpio = <&tlmm 137 0x00>;
		pinctrl-names = "default";
		pinctrl-0 = <&bq25980_gpio_default>;
	};

	cw2015: cw2015@62 {
		compatible = "cellwise,cw2015";
		reg = <0x62>;
	};

3.2、配置 ChargerIC 中断脚
kernel/msm-4.9/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi

bq25980_gpio_default: bq25980_gpio_default {
                        mux {
                                pins = "gpio137";
                                function = "gpio";
                        };

                        config {
                                pins = "gpio137";
                                drive-strength = <2>;
                                bias-pull-up;
                        };
                };

3.3、配置编译宏开关
kernel/msm-4.9/arch/arm64/configs/msm8953_defconfig

 CONFIG_CRYPTO_CRC32_ARM64=y
 CONFIG_QMI_ENCDEC=y
 CONFIG_KEYBOARD_TCA8418=y
+CONFIG_CHARGER_BQ25890=y
+CONFIG_BATTERY_CW2015=y

3.4、配置编译宏开关
kernel/msm-4.9/drivers/power/supply/Makefile

 obj-$(CONFIG_CHARGER_BQ24735)	+= bq24735-charger.o
 obj-$(CONFIG_CHARGER_BQ25890)	+= bq25890_charger.o
+obj-$(CONFIG_BATTERY_CW2015)	+= cw2015_battery.o
 obj-$(CONFIG_CHARGER_SMB347)	+= smb347-charger.o
 obj-$(CONFIG_CHARGER_TPS65090)	+= tps65090-charger.o

3.5、ChargerIC 驱动
kernel/msm-4.9/drivers/power/supply/bq25890_charger.c
3.6、电量计驱动
kernel/msm-4.9/drivers/power/supply/xxxx_battery.c

四、关机充电显示电量百分比

4.1、/system/core/healthd/healthd_draw.cpp

#define STR_LEN 8
void HealthdDraw::draw_percent(const animation* anim) {
  int cur_level = anim->cur_level;
  if (anim->cur_status == BATTERY_STATUS_FULL) {
    cur_level = 100;
  }

  if (cur_level <= 0) return;

  const animation::text_field& field = anim->text_percent;
  if (field.font == nullptr || field.font->char_width == 0 ||
      field.font->char_height == 0) {
    char cap_str[STR_LEN];
    int x, y;
    int str_len_px;
    static int char_height = -1, char_width = -1;

    if (char_height == -1 && char_width == -1)
        gr_font_size(gr_sys_font(), &char_width, &char_height);

    snprintf(cap_str, (STR_LEN - 1), "%d%%", cur_level);
    str_len_px = gr_measure(gr_sys_font(), cap_str);
    x = (gr_fb_width() - str_len_px) / 2;
    y = (gr_fb_height() + char_height) / 2;
    gr_color(0xa4, 0xc6, 0x39, 255);
    gr_text(gr_sys_font(), x, y, cap_str, 0);
    LOGE("draw_percent use default\n");
  } else {
    std::string str = base::StringPrintf("%d%%", cur_level);
    int x, y;
    determine_xy(field, str.size(), &x, &y);

    LOGV("drawing percent %s %d %d\n", str.c_str(), x, y);
    gr_color(field.color_r, field.color_g, field.color_b, field.color_a);
    draw_text(field.font, x, y, str.c_str());
  }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

充电IC和电量计的驱动调试 的相关文章

  • [CocoaPods]podspec文件中的resource和resource_bundle

    相信基本上所有的iOS开发同学针对于CocoaPods都不陌生 即便没有用过 也是久闻大名如雷贯耳 作为Objective C和Swift中非常流行的依赖管理工具 它拥有超过10000个公有程序库 通过一份Podfile文件和pod ins
  • Linux集群常用脚本(个人总结)

    声明 1 本文为我的个人复习总结 并非那种从零基础开始普及知识 内容详细全面 言辞官方的文章 2 由于是个人总结 所以用最精简的话语来写文章 3 若有错误不当之处 请指出 常用脚本编写汇总 自定义脚本放在 bin下 并把这个目录配到PATH
  • js生成随机字符串

    function randomString len len len 32 var str ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678 默认去掉了容易混淆的字符oOLl 9gq Vv Uu
  • 2023-9-8 求组合数(一)

    题目链接 求组合数 I include
  • C语言 _ 指针(超详解析 3分钟完全掌握 总结性讲解 经典通俗)

    目 录 1 指针 指针变量及指针的大小 2 指针类型 3 指针的解引用 4 指针运算 4 1指针 整数 4 2指针 指针 5 野指针 5 1 为什么会有野指针 5 2 如何规避野指针 6 指针和数组 7 二级指针 7 1二级指针的定义 8
  • Java中的加号“+”

    在Java中 加号 与数学上的加号有些不同 它有两个意思 一个是算术运算中的 一个是连接符的重要 类似于C语言中的strcat函数 怎么区分这两种作用呢 1 当 两边是非数值类型 就被看作连接符 2 当 两边都是数值类型 就被看作算术运算中
  • ZYNQ平台在SDK下引导启动UBOOT

    ZYNQ芯片 Linux系统搭建完成后 希望通过QSPI Flash的方式来进行程序加载 QSPI Flash启动则需要烧录以下文件 BOOT bin fsbl elf uboot elf uImage linux内核 zynq board
  • 小吴学前端--Element-UI tree 组件 选中节点高亮(持续高亮)

    最近开发的时候遇到的一个需求 1 加深选中单据颜色框 2 在不切换tree组件时 选中的一直保持高亮 由于对该组件不是很熟悉 记下笔记 用来巩固学习 1 点击后高亮显示的背景颜色修改 仅仅需要修改css部分即可 deep el tree n
  • 从语言到品牌

    在竞争激烈的商业环境中 一个强大的品牌所带来的广泛品牌影响力是企业成功的关键要素之一 无论是刚刚起步的初创公司 还是已经存在多年的大型企业 都需要创建最符合自身 最贴合市场受众的品牌名称 并且持续努力来塑造和维护自己的品牌 以吸引更多客户
  • WSDL文档结构详解(五)

    1 实例截图 2 wsdl文件分析
  • C++静态链接库

    1 打开VS2010 新建win32项目 命名libm 下一步选中静态库完成 2 新建空文件mylib h和mylib cpp 其中mylib h文件中代码如下 ifndef LIB H define LIB H extern C int
  • 9个爬虫基础实战汇总+4个专业爬虫练手站推荐

    个人主页 互联网阿星 格言 选择有时候会大于努力 但你不努力就没得选 作者简介 大家好我是互联网阿星 和我一起合理使用Python 努力做时间的主人 如果觉得博主的文章还不错的话 请点赞 收藏 留言 支持一下博主哦 行业资料 PPT模板 简
  • 嵌入式系统图解

    嵌入式系统组成 嵌入式系统硬件结构图 嵌入式软件运行流程 体系结构和接口 ARM Cotex M3内核架构图
  • 查看jvm运行情况

    使用 jps 或top显示当前所有java进程pid 详细的使用方法可参考博客 https blog csdn net u013250071 article details 80496623 https blog csdn net weix
  • Yolov4部署到ZYNQ系列4-网络地址调整和部署

    文章目录 前言 一 笔记本上的步骤 二 开发板上的步骤 三 部署 四 总结 前言 本文参照上一节的工作 使用Vitis AI 1 4与Vitis AI 2 5的工具得到的量化和编译 在开发板上部署 但在此之前 不想使用路由的方式 直接通过网
  • HIVE介绍(五)

    文章目录 HIVE介绍 hql语法 hive优缺点 Hive运行原理 Hive为什么要分区 partitioned by Hive与mysql的对比 Hive内部表和外部表 hive数据类型 hive数据存格式 自定义函数UDF和UDTF
  • 数字IC笔试面试常考问题及答案

    来源 知乎 链接 https zhuanlan zhihu com p 261298869 基础知识 原理务必理解透彻 锁存器的结构 DFF的结构 建立保持时间 亚稳态 STA CDC 亚稳态的成因 危害 解决方法 建立保持时间的计算 违例
  • centos 软件卸载

    1 查找系统注册名称 rpm q a grep 软件名 2 卸载 rpm e package name 即可卸载软件 参数e的作用是使rpm进入卸载模式 对名为 package name 的软件包进行卸载 由于系统中各个软件包之间相互有依赖
  • Linux 非阻塞connect

    套接字执行I O操作有阻塞和非阻塞两种模式 在阻塞模式下 在I O操作完成前 执行操作的函数一直等候而不会立即返回 该函数所在的线程会阻塞在这里 相反 在非阻塞模式下 套接字函数会立即返回 1 而不管I O是否完成 该函数所在的线程会继续运
  • https流程详解(含ca证书校验)

    首先来说 一下 为什么需要https 加密 由于http 传输是明文传输 信息在传输的过程中容易被篡改 不安全 所以 就有了 加密传输 对称加密 aes等 对称加密很容易理解 就是 只有一个秘钥 可以使用这个秘钥加密和解密 但是这样只要被别

随机推荐

  • 关系型数据库RDBMS -MySQL基础入门(五)数据备份与恢复

    一 物理备份 innodbackupex 二 逻辑备份 mysqldump Binlog 二进制 日志文件 备份恢复 主从同步 除查询sql所有命令都记录 索引文件 bin index bin 000001 Purge master log
  • 蓝牙之九-AT命令

    AT命令用于HF协议 该命令使参考3GPP 27 007协议 以下是HFP规范 每个命令行只有一个命令 AG侧默认不回显命令 AG使用冗长的格式返回结果 以下字符将被用于AT命令和返回结果格式中
  • Spring MVC详解

    第一节 Spring MVC 简介 1 Spring MVC SpringMVC是一个Java 开源框架 是Spring Framework生态中的一个独立模块 它基于 Spring 实现了Web MVC 数据 业务与展现 设计模式的请求驱
  • Session的生命周期

    以前在学习的时候没怎么注意 今天又回过头来仔细研究研究了一下Session的生命周期 Session存储在服务器端 一般为了防止在服务器的内存中 为了高速存取 Sessinon在用户访问第一次访问服务器时创建 需要注意只有访问JSP Ser
  • 什么是DDL和DML语句?

    1 什么是DDL和DML语句 SQL语言分成三大类 1 DDL语言 2 DML语言 3 DCL语言 可恶 竟然在技术内幕只提及了一部分 内幕661 要知道DDL是什么意思 必须先了解它的英文全称 data definition langua
  • 【华为OD机试】TLV解析Ⅰ【2023 B卷

    华为OD机试 真题 点这里 华为OD机试 真题考点分类 点这里 题目描述 TLV 编码是按 Tag Length Value 格式进行编码的 一段码流中的信元用Tag标识 Tag在码流中 唯一不重复 Length表示信元Value的长度 V
  • Linux 定时任务crontab配置

    https www cnblogs com zoulongbin p 6187238 html
  • [718]canal的配置详解

    文章目录 canal的配置加载方式 properties配置文件 canal properties介绍 instance properties介绍 canal的配置加载方式 介绍配置之前 先了解下canal的配置加载方式 canal配置方式
  • 【斯坦福CS224W笔记之一】 图的基本表示

    是来自b站up主同济子豪兄的中文精讲 自己做来总结给自己学习滴 如果感兴趣的话可以去b站搜索或者去子豪兄的github图神经进行学习 https github com TommyZihao zihao course blob main CS
  • Java线程安全与等待通知

    目录 1 线程不安全原因 1 1 引入 线程不安全的例子 抢占式执行 1 2 线程不安全的原因 5点 其他 2 抢占式执行引起的线程不安全 synchronized 3 内存可见性引起的线程不安全 volatile 3 1 例子 编译器优化
  • Win10操作系统隐藏6个实用小功能

    目录 功能一 分屏 功能二 录屏 功能三 截图 功能四 便签功能 功能五 视频剪辑 功能六 计算器 功能一 分屏 Win10操作系统其实是自带分屏功能的 这个功能对我来说真的太喜欢了 尤其是核对文档的时候 真的是太方便了 操作方法 在文档页
  • 内网离线安装Docker

    文章目录 描述 下载docker离线包地址 1 安装docker 1 下载 Docker 二进制文件 离线安装包 2 上传离线包 3 解压安装包 4 将docker 相关命令拷贝到 usr bin 5 docker注册成系统服务 6 添加执
  • QT--信号槽与带参Lambda表达式

    一 常规的不带参数的Lambda表达式响应槽函数 connect ui btn QushButton clicked to do something 二 带参的Lambda表达式响应槽函数 connect ui spbox static c
  • ArcSDE超出最大连接数问题解决

    ARCSDE数据库默认连接的实例数为48 可用 sdemon o info I users 命令查看当前的用户链接数 因为连接的用户很多时 会导致实例数不够用 这个时候需要对连接的实例数进行修改 修改方法如下 1 plsql登录sde用户
  • 你还没有Aspose 2021中文开发指南吗?中文指南打包带走

    说到文档处理 就得来说说Aspose系列 Aspose是全球领先的图表控件开发商 旗下产品覆盖Word Excel PDF 条码 ZIP CAD HTML 电子邮件 PSD等各个文档管理领域 为全球 NET Java C 等各大平台程序员提
  • ARM平台移植libcurl curl-7.49.0

    libcurl是免费的轻量级的客户端网络库 支持DICT FILE FTP FTPS Gopher HTTP HTTPS IMAP IMAPS LDAP LDAPS POP3 POP3S RTMP RTSP SCP SFTP SMTP SM
  • SpringMVC重要接口(三)HttpMessageConverter

    大部分人的第一反应是通过SpringMVC拦截器 Interceptor 中的postHandler方法处理 实际这是行不通的 因为当程序运行到该方法 是在返回数据之后 渲染页面之前 所以这时候HttpServletResponse中的输出
  • C++-类和对象(上)

    类和对象 上 一 构造函数 1 概念 2 特性 二 析构函数 1 概念 2 特性 三 拷贝构造 1 概念 2 特性 四 运算符重载 1 概念 2 赋值运算符重载 五 重载与const 重载 六 总结 一 构造函数 1 概念 class St
  • Java后端、前端、大数据、python、Golang学习路线

    面向招聘要求学编程 加油 小y同学 blibli很多资源 黑马 尚硅谷 狂神说等等 1 后端 Java基础 完成 Java Web 完成 Maven 完成 Git 完成 SSM Spring框架 SpringMVC 持久层框架Mybatis
  • 充电IC和电量计的驱动调试

    LK是little kernel的缩写 高通平台android普遍采用LK作为其bootloader LK是一个开源项目 但是 LK只是整个系统的引导部分 所以它不是独立存在 LK是一个功能极其强大的bootloader 但只支持arm和x