MTK驱动开发
编译
查看out编译的版本
out\target\product\k61v1_32_bsp_1g\system
ro.build.display.id=full_k61v1_32_bsp_1g-userdebug 11 RP1A.200720.011 mp1V8465 test-keys
Android 14
Android 12及以上版本平台厂商开始将system.img和vendor.img拆分为两部分代码。平台文档解释为了解决Android碎片化问题。
平台 | system | vendor |
---|---|---|
高通 | qssi | target |
联发科 | mssi | vendor_ap |
编译脚本命令
source build/envsetup.sh
python vendor/mediatek/proprietary/scripts/releasetools/split_build_helper.py --run full_k62v1_64_bsp-userdebug --vf-path ../vendor_ap_s0/
python vendor/mediatek/proprietary/scripts/releasetools/split_build_helper.py --run full_k62v1_64_bsp-user --vf-path ../vendor_ap_s0/
MTK Android 14 更新api
export OUT_DIR=out_sys && lunch sys_mssi_64_cn-userdebug && make sys_images
export OUT_DIR=out_sys && lunch sys_mssi_64_cn-user && make sys_images
烧录路径
vendor_ap_s0\out\target\product\k62v1_64_bsp\merged\MT6765_Android_scatter.txt
.mk文件
调用方式
声明路径:
device/mediatek/[TARGET_PRODUCT]/device.mk
device/mediateksample/[PLATFORM]/device.mk
声明方式:
include vendor/tms/vnd/config/tmsNfcVendorConfig.mk
include [PATH]/xxxx.mk
$(call inherit-product, device/mediatek/system/common/device.mk)
在 Android 开发中,PRODUCT_PACKAGES 或 PRODUCT_COPY_FILES 是常用的标准语句,用于定义需要编译和复制到设备中的文件和包。然而,有时由于编译环境的限制,可能会导致无法在平台端的.mk 文件中使用这些语句。为了解决这个问题,你可以执行以下命令在 device 目录下查找使用了 PRODUCT_PACKAGES 语句的.mk 文件
grep "PRODUCT_PACKAGES" -rn device/
通过命令的结果,你可以找到已经使用了该语句的.mk 文件。找到了对应工程的.mk 文件,你只需要在该文件中添加所需的 include 语句即可解决问题。
打印logo
/*在终端显示一条消息日志*/
$(info "This is a info logo")
/*在终端显示一条警告日志*/
$(warning "add nfc_aidl manifest files on aosp 13 and later")
/*在终端显示一条错误日志*/
$(error "add nfc_aidl manifest files on aosp 13 and later")
复制文件到系统指定目录中 – PRODUCT_COPY_FILES
使用方式:
PRODUCT_COPY_FILES += vendor/tms/sys/config/libnfc-nci.conf:$(TARGET_COPY_OUT_VENDOR)/etc/libnfc-nci.conf
PRODUCT_COPY_FILES += [编译前的文件目录/文件]:$(TARGET_COPY_OUT_VENDOR)[编译后的目标目录/文件]
驱动函数
模块加载
声明路径:kernel/include/linux/init.h
module_init
优点:
module_init 函数是一个模块的入口函数,用于初始化模块,它的执行时间相对较短,不会影响系统启动时间。
缺点:
module_init 函数的执行顺序无法保证,可能会导致一些初始化顺序带来的问题
late_initcall_sync
优点:
late_initcall_sync 函数被用于模块初始化时,可以保证它在所有 initcall 函数执行后才会被调用,因此可以避免一些初始化顺序带来的问题。
late_initcall_sync 是同步执行的,也就是说在它执行完毕之前,不会有其他进程或线程调用它。
缺点:
late_initcall_sync 的执行时间相对较长,可能会影响系统启动时间。
late_initcall
优点:
late_initcall 函数同样可以保证在所有 initcall 函数执行后才会被调用,但它是异步执行的,也就是说它的执行不会阻塞其他进程或线程。
缺点:
late_initcall 可能会在其他进程或线程已经开始运行之后才执行,可能会导致一些初始化顺序带来的问题。
综上所述,late_initcall_sync 和late_initcall适用于需要保证初始化顺序的场合,而 module_init 适用于初始化时间较短的场合
中断唤醒
device_init_wakeup(&client->dev, 1);
用来设置一个驱动可以被唤醒,函数中的can_wakeup为1时,表明一个设备可以被唤醒, 在设备初始化的时候调用。
disable_irq_wake(irq_num);//禁止中断唤醒功能
enable_irq_wake(irq_num);//使能中断唤醒功能
&client->dev 设备地址
irq_num 中断号
模块外可调用声明
EXPORT_SYMBOL_GPL([函数名]);
驱动配置
uart log打印
关闭控制台服务
路径:
device/mediatek/mt6580/factory_init.rc
device/mediatek/mt6580/meta_init.rc
system/core/rootdir/init.rc
修改点:
#service console /system/bin/sh
# class core
# console
# disabled
# user shell
# group shell log readproc
# seclabel u:r:shell:s0
on property:ro.debuggable=1
# Give writes to anyone for the trace folder on debug builds.
# The folder is used to store method traces.
chmod 0773 /data/misc/trace
# start console
kernrl层 log打印
路径:
$(LINUX_KERNEL_VERSION)\drivers\misc\mediatek\mtprintk\mtk_printk_ctrl.c
修改点:
static ssize_t mt_printk_ctrl_write(struct file *filp,const char *ubuf, size_t cnt, loff_t *data)
{
...
if (ret < 0)
return ret;
val = 1;
switch (val) {
...
}
user版 打开串口log
路径:
vendor\mediatek\proprietary\bootable\bootloader\lk\app\mt_boot\mt_boot.c
修改点:
目标: cmdline_append("mtk_printk_ctrl.disable_uart=1 ...");
改为: cmdline_append("mtk_printk_ctrl.disable_uart=0 ...");
屏蔽开机log
路径:
$(LINUX_KERNEL_VERSION)\drivers\misc\mediatek\mtprof\bootprof.c
修改点:
static void bootup_finish(void)
{
initcall_debug = 0;
#ifdef CONFIG_MTK_PRINTK_UART_CONSOLE
mt_disable_uart(); //注释掉即可关闭开机 log
#endif
}
兼容字库
//字库上电文件目录:
vendor/mediatek/proprietary/bootable/bootloader/preloader/tools/emigen/MT6761/MemoryDeviceList_MT6761.xls
//兼容配置
vendor/mediatek/proprietary/bootable/bootloader/preloader/custom/k61v1_32_bsp_1g/inc/custom_MemoryDevice.h
//添加方式
#define CS_PART_NUMBER[1] H9TQ64A8GTCCUR_KUM
Part Number:H9TQ64A8GTCCUR_KUM
GPIO
dws配置工具
mt6580
路径:$(LINUX_KERNEL_VERSION)\tools\dct\old_dct\DrvGen.exe
mt6739
路径:vendor\mediatek\proprietary\tools\dct\DrvGen.exe
Kernel中配置和使用GPIO
1) pinctrl子系统
dts 配置
&xxx {
pinctrl-names = "xxx_default", "xxx_init";
pinctrl-0 = <&xxx_default>;
pinctrl-1 = <&xxx_init>;
status = "okay";
};
&pio {
xxx_default: xxx_default {
};
xxx_init: xxxinit {
pins_cmd0_dat {
pinmux = <MT8163_PIN_142_EINT21__FUNC_GPIO142>; /*普通gpio模式*/
slew-rate = <0>; /*0输入 1输出*/
bias-disable; /*浮空 bias-pull-up = <00>上拉 bias-pull-down= <00>下拉*/
};
pins_cmd1_dat {
pinmux = <MT8163_PIN_27_EINT5__FUNC_GPIO27>;
slew-rate = <0>;
bias-disable;
};
};
};
pinmux = <MT8163_PIN_142_EINT21__FUNC_ANT_SEL0>;//配置复用功能
Pinctrl API 的应用:
struct pinctrl *pctl = devm_pinctrl_get(&pdev->dev);//获取一个 pinctrl 句柄,参数dev是包含这个 pin 的device结构体,即xxx这个设备的device
struct pinctrl_state *dc_charge_init = pinctrl_lookup_state(pctl, "dc_charge_init");//获取这个pin对应pin_state。
pinctrl_select_state(pctl, dc_charge_init);//设置引脚为某个stata。
2) GPIOLib 库函数
dts 配置
xx_gpio_dev:xx_gpio_dev {
compatible = "mediatek,gpio_dev";
};
&xx_gpio_dev{
xxx_gpio = <&pio 19 0>;
status = "okay";
};
获取 DTS
#ifdef CONFIG_OF
static const struct of_device_id of_match[] = {
{.compatible = "mediatek,gpio_dev"},
{},
};
#endif
struct PORTS_MANAGER *ports_manager;
ports_manager = devm_kzalloc(&pdev->dev,sizeof(struct PORTS_MANAGER),GFP_KERNEL); //注册内存空间
platform_set_drvdata(pdev, ports_manager);//绑定驱动数据结构体
node = of_find_matching_node(NULL, of_match);//获取dts相关数据
gpio_num = of_get_named_gpio(node, "xxx-gpio", 0);//获取 xxx-gpio 设置的GPIO
irq_num = gpio_to_irq(gpio_num); //获取中断号
GPIOLIB API 接口
static inline int gpio_request(unsigned int gpio, const char *label)
static inline void gpio_free(unsigned gpio)
static inline int gpio_direction_input(unsigned int gpio)
static inline int gpio_direction_output(unsigned int gpio, int v)
static inline int gpio_set_debounce(unsigned gpio, unsigned debounce) //防抖
static inline int gpio_get_value(unsigned int gpio)
static inline void gpio_set_value(unsigned int gpio, int v)
static inline int gpio_to_irq(unsigned int gpio)
static inline int irq_to_gpio(unsigned int irq的)
I2C
注意
datesheet 提供addr是包含读/写位在内的8位地址,而我们配置不需要包含读写位,所以将其右移一位 获取其设备IIC地址
IIC addr如下:
配置DTSI
&i2c3{
status = "okay"; //配置i2c通道的加载状态
clock-frequency = <100000>; //配置i2c的时钟频率
i2c_dev: i2c_dev@28 { //@28 : i2c设备的7位地址
status = "okay"; //配置该设备的加载状态
compatible = "mediatek,i2c_dev";
reg = <0x28>; //配置i2c设备的7位地址
i2c,device-name = "tms_nfc"; //配置i2c设备的自定义名称
i2c,irq-gpio = <&gpio1 0 0>; //配置i2c设备的io
};
};
LCM
配置屏幕密度
路径:
device\mediateksample\$(ARCH_MTK_PROJECT)\device.mk
修改点:
//密度为320
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.sf.lcd_density=320
//密度为240
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.sf.lcd_density=240
旋转180°
路径:
device\mediateksample\$(ARCH_MTK_PROJECT)\ProjectConfig.mk
$(LINUX_KERNEL_VERSION)/arch/arm/configs/$(ARCH_MTK_PROJECT)_debug_defconfig
$(LINUX_KERNEL_VERSION)/arch/arm/configs/$(ARCH_MTK_PROJECT)_defconfig
vendor\mediatek\proprietary\bootable\bootloader\lk\project\$(ARCH_MTK_PROJECT).mk
修改点:
MTK_LCM_PHYSICAL_ROTATION = 0
//当旋转180°时,开机动画异常:
/* In GB, no need to adjust 180 showing logo ,for fb driver dealing the change */
/* but in JB, need adjust it for screen 180 roration */
phical_screen.need180Adjust = 0; // need sync with chip driver
dprintf(INFO, "[lk logo: %s %d]MTK_LCM_PHYSICAL_ROTATION = %s\n",__FUNCTION__,__LINE__, MTK_LCM_PHYSICAL_ROTATION);
if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "270", 3)) {
phical_screen.rotation = 270;
} else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "90", 2)) {
phical_screen.rotation = 90;
} else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "180", 3) && (phical_screen.need180Adjust == 1)) {
phical_screen.rotation = 180;
} else {
phical_screen.rotation = 0;
}
当旋转180°时开机动画异常
路径
vendor\mediatek\proprietary\bootable\bootloader\lk\platform\mt6765\mt_logo.c
修改点
void init_fb_screen()
{
...
/* In GB, no need to adjust 180 showing logo ,for fb driver dealing the change */
/* but in JB, need adjust it for screen 180 roration */
phical_screen.need180Adjust = 0; // need sync with chip driver
dprintf(INFO, "[lk logo: %s %d]MTK_LCM_PHYSICAL_ROTATION = %s\n",__FUNCTION__,__LINE__, MTK_LCM_PHYSICAL_ROTATION);
if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "270", 3)) {
phical_screen.rotation = 270;
} else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "90", 2)) {
phical_screen.rotation = 90;
} else if (0 == strncmp(MTK_LCM_PHYSICAL_ROTATION, "180", 3) && (phical_screen.need180Adjust == 1)) {
phical_screen.rotation = 180;
} else {
phical_screen.rotation = 0;
}
...
}
//当phical_screen.need180Adjust等于0时,导致旋转180°失败。将其设置为1即可
SIM 卡
配置 Dts
路径:
$(LINUX_KERNEL_VERSION)/arch/arm/boot/dts/cust_$(MTK_PLATFORM)_msdc.dtsi
修改点:
sd-uhs-ddr50;
no-mmc;
no-sdio;
pinctl = <&msdc1_pins_default>;
cd_level = /bits/ 8 <MSDC_CD_HIGH>; //根据原理图配置识卡触发方式
cd-gpios = <&pio 1 0>; //根据原理图配置sd卡的中断脚
配置 Config
路径:
device/mediateksample/$(ARCH_MTK_PROJECT)/ProjectConfig.mk
修改点:
MTK_MULTI_SIM_SUPPORT = dsds //双卡
MTK_MULTI_SIM_SUPPORT = ss //单卡
MTK_SIM_HOT_SWAP= yes
MTK_SIM_HOT_SWAP_COMMON_SLOT = yes //打开关于sim卡热插拔的宏开关
配置 IO
修改点:
Camera
配置加载的摄像头
在项目的ProjectConfig.mk中配置摄像头的kernel层与hal层,一个是驱动加载,一个是效果显示
路径:
device/mediateksample/$(ARCH_MTK_PROJECT)/ProjectConfig.mk
修改点:(本例用ov8865作后摄,gc5005做前摄)
CUSTOM_HAL_IMGSENSOR =ov8865_mipi_raw gc5005_mipi_raw
CUSTOM_HAL_MAIN_IMGSENSOR =ov8865_mipi_raw
CUSTOM_HAL_SUB_IMGSENSOR =gc5005_mipi_raw
CUSTOM_KERNEL_IMGSENSOR =ov8865_mipi_raw gc5005_mipi_raw
CUSTOM_KERNEL_MAIN_IMGSENSOR =ov8865_mipi_raw
CUSTOM_KERNEL_SUB_IMGSENSOR =gc5005_mipi_raw
在项目的config配置,决定加载的驱动
路径:
$(LINUX_KERNEL_VERSION)/arch/arm/configs/$(ARCH_MTK_PROJECT)_debug_defconfig
$(LINUX_KERNEL_VERSION)/arch/arm/configs/$(ARCH_MTK_PROJECT)_defconfig
修改点:(本例用ov8865作后摄,gc5005做前摄)
CONFIG_CUSTOM_KERNEL_IMGSENSOR="ov8865_mipi_raw gc5005_mipi_raw"
dst里面配置的加载
路径:
$(LINUX_KERNEL_VERSION)/arch/arm/boot/dts/cust_mt6761_camera.dtsi
修改点:(本例用ov8865作后摄,gc5005做前摄)
cam0_enable_sensor = "ov8865_mipi_raw"; //后摄
cam1_enable_sensor = "gc5005_mipi_raw"; //前摄
kd_imgsensor.h里面配置SENSOR_ID与SENSOR_DRVNAME
路径:
device/mediatek/common/kernel-headers/kd_imgsensor.h
$(LINUX_KERNEL_VERSION)/drivers/misc/mediatek/imgsensor/inc/kd_imgsensor.h
修改点:
#define OV8865_SENSOR_ID 0x8865
#define GC5005_SENSOR_ID 0x5005
#define SENSOR_DRVNAME_OV8865_MIPI_RAW "ov8865_mipi_raw"
#define SENSOR_DRVNAME_GC5005_MIPI_RAW "gc5005_mipi_raw"
添加驱动
路径:
$(LINUX_KERNEL_VERSION)/drivers/misc/mediatek/imgsensor/src/common/v1/ov8865_mipi_raw/
$(LINUX_KERNEL_VERSION)/drivers/misc/mediatek/imgsensor/src/common/v1/ov8865_mipi_raw/
驱动初始化加载对应的函数
路径:
$(LINUX_KERNEL_VERSION)/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_sensor_list.h
修改点:
UINT32 OV8865_MIPI_RAW_SensorInit(struct SENSOR_FUNCTION_STRUCT **pfFunc);
UINT32 GC5005_MIPI_RAW_SensorInit(struct SENSOR_FUNCTION_STRUCT **pfFunc);
路径:
$(LINUX_KERNEL_VERSION)/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_sensor_list.c
修改点:
#if defined(OV8865_MIPI_RAW)
{OV8865_SENSOR_ID,
SENSOR_DRVNAME_OV8865_MIPI_RAW,
OV8865_MIPI_RAW_SensorInit},
#endif
#if defined(GC5005_MIPI_RAW)
{GC5005_SENSOR_ID,
SENSOR_DRVNAME_GC5005_MIPI_RAW,
GC5005_MIPI_RAW_SensorInit},
#endif
配置上电
路径:
$(LINUX_KERNEL_VERSION)/drivers/misc/mediatek/imgsensor/src/$(MTK_PLATFORM)/camera_hw/imgsensor_cfg_table.c
修改点:
#if defined(GC5005_MIPI_RAW)
{
SENSOR_DRVNAME_GC5005_MIPI_RAW,
{
{PDN, Vol_High, 0},
{RST, Vol_Low, 0},
{AVDD, Vol_2800, 0},
{DOVDD, Vol_1800, 0},
{DVDD, Vol_1200, 0},
{SensorMCLK, Vol_High, 1},
{PDN, Vol_Low, 0},
{RST, Vol_High, 10}
},
},
#endif
#if defined(OV8865_MIPI_RAW)
{
SENSOR_DRVNAME_OV8865_MIPI_RAW,
{
{SensorMCLK, Vol_High, 0},
{PDN, Vol_High, 5},
{RST, Vol_Low, 5},
{DOVDD, Vol_1800, 5},
{AVDD, Vol_2800, 5},
{DVDD, Vol_1200, 5},
{AFVDD, Vol_2800, 5},
{PDN, Vol_Low, 5},
{RST, Vol_High, 5}
},
},
#endif
HAL层摄像头效果文件加载
路径
vendor/mediatek/proprietary/custom/$(MTK_PLATFORM)/hal/imgsensor_src/sensorlist.cpp
修改点:
#if defined(GC5005_MIPI_RAW)
RAW_INFO(GC5005_SENSOR_ID, SENSOR_DRVNAME_GC5005_MIPI_RAW, NULL),
#endif
#if defined(OV8865_MIPI_RAW)
RAW_INFO(OV8865_SENSOR_ID, SENSOR_DRVNAME_OV8865_MIPI_RAW,NULL),
#endif
设置或取消镜像
路径:
frameworks\av\camera\CameraUtils.cpp
修改点:
if (!mirror) { //后摄不带镜像
switch (orientation) {
case 0:
flags = 0;
break;
case 90:
flags = NATIVE_WINDOW_TRANSFORM_ROT_90;
break;
case 180:
flags = NATIVE_WINDOW_TRANSFORM_ROT_180;
break;
case 270:
flags = NATIVE_WINDOW_TRANSFORM_ROT_270;
break;
default:
ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
__FUNCTION__, orientation);
return INVALID_OPERATION;
}
} else { //前摄带镜像
// Front camera needs to be horizontally flipped for mirror-like behavior.
// Note: Flips are applied before rotates; using XOR here as some of these flags are
// composed in terms of other flip/rotation flags, and are not bitwise-ORable.
switch (orientation) {
case 0:
flags = NATIVE_WINDOW_TRANSFORM_FLIP_H;
break;
case 90:
flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
NATIVE_WINDOW_TRANSFORM_ROT_270;
break;
case 180:
flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
NATIVE_WINDOW_TRANSFORM_ROT_180;
break;
case 270:
flags = NATIVE_WINDOW_TRANSFORM_FLIP_H ^
NATIVE_WINDOW_TRANSFORM_ROT_90;
break;
default:
ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
__FUNCTION__, orientation);
return INVALID_OPERATION;
}
}
}
设置显示方向
路径:
vendor/mediatek/proprietary/custom/$(MTK_PLATFORM)/hal/imgsensor_src/cfg_setting_imgsensor.cpp;
修改点:
static CUSTOM_CFG gCustomCfg[] = {
//后摄
{
.sensorIdx = IMGSENSOR_SENSOR_IDX_MAIN,
.mclk = eMclk_1,
.port = EMipiPort_CSI2,
.dir = CUSTOM_CFG_DIR_REAR,
.bitOrder = CUSTOM_CFG_BITORDER_9_2,
.orientation = 90,
.horizontalFov = 67,
.verticalFov = 49,
.PadPclkInv = 0,
},
//前摄
{
.sensorIdx = IMGSENSOR_SENSOR_IDX_SUB,
.mclk = eMclk_2,
.port = EMipiPort_CSI0,
.dir = CUSTOM_CFG_DIR_FRONT,
.bitOrder = CUSTOM_CFG_BITORDER_9_2,
.orientation = 180,
.horizontalFov = 67,
.verticalFov = 40,
.PadPclkInv = 0,
}
};
配置单前摄调试环境
MTK 调试软件要调试前摄必须有后摄,所以配置后摄使用前摄时钟、CSI通道、IO
配置后摄使能
device/mediateksample/$(ARCH_MTK_PROJECT)/ProjectConfig.mk
CUSTOM_HAL_IMGSENSOR =ov8865_mipi_raw
CUSTOM_HAL_MAIN_IMGSENSOR =ov8865_mipi_raw
CUSTOM_HAL_SUB_IMGSENSOR =ov8865_mipi_raw
CUSTOM_KERNEL_IMGSENSOR =ov8865_mipi_raw
CUSTOM_KERNEL_MAIN_IMGSENSOR =ov8865_mipi_raw
CUSTOM_KERNEL_SUB_IMGSENSOR =ov8865_mipi_raw
配置camera dtsi,后摄使用前摄IO,后摄所有IO与前摄保持一致
设置后摄使用前摄CSI通道与eMclk,与前摄保持一致
vendor/mediatek/proprietary/custom/$(MTK_PLATFORM)/hal/imgsensor_src/cfg_setting_imgsensor.cpp;
//后摄
{
.sensorIdx = IMGSENSOR_SENSOR_IDX_MAIN,
.mclk = eMclk_1,
.port = EMipiPort_CSI2,
.dir = CUSTOM_CFG_DIR_REAR,
.bitOrder = CUSTOM_CFG_BITORDER_9_2,
.orientation = 90,
.horizontalFov = 67,
.verticalFov = 49,
.PadPclkInv = 0,
},
//前摄
{
.sensorIdx = IMGSENSOR_SENSOR_IDX_SUB,
.mclk = eMclk_2,
.port = EMipiPort_CSI0,
.dir = CUSTOM_CFG_DIR_FRONT,
.bitOrder = CUSTOM_CFG_BITORDER_9_2,
.orientation = 180,
.horizontalFov = 67,
.verticalFov = 40,
.PadPclkInv = 0,
}
配置喇叭频率
路径:
kernel-4.19/sound/soc/mediatek/mt6580/mt_soc_codec_63xx.c
修改方式
#define AW8736_MODE_CTRL
#ifdef AW8736_MODE_CTRL
#define USE_AW8736_MODE1 (0)
#define USE_AW8736_MODE2 (0)
#define USE_AW8736_MODE3 (1)
#define USE_AW8736_MODE4 (0)
#endif
电池曲线配置
名词解释
Cmax/Qmax | 最大电池容量 |
---|---|
VBAT | 电池闭路电压,即电池有负载时测得的电压 |
R | 电池内阻 |
I | 电池放电电流 (I = (OCV - VBAT)/R) |
DOD | 放电深度,100-DOD即为电池容量 |
temperature | 电池特性受温度影响,一般用一个热敏电阻来测量温度 |
ZCV | Zero current Voltage,一般指zcv表格,也是开路电压的意思 |
OCV | 电池开路电压,即电池断开负载时测得的电压 |
VC | 闭路电压 |
CAR | 库仑计 |
SOC | 当前电量百分比(SOC = 当前电荷量 / Q_MAX × 100%) |
UI SOC | 当前显示电量百分比 |
SOH | 健康状态(电池容量衰减程度: SOH = 当前Q_MAX / 初始Q_MAX × 100%) |
Rcn | 连接线电阻补偿 |
Car_tune_value | 电流校准系数,用于校正系统读取的电流值与实际电流的偏差(Car_tune_value = 实际电流值 / 系统读取电流值 × 100)。需在多个电流点(200mA、300mA等)测试后取平均值,确保电流检测精度 |
CC | 恒流阶段,电流限制(如0.2C~1C),电压上限(4.2V±1%) |
CV | 恒压阶段,电流逐渐减小至0.05C时判定充满 |
FULL OCV | 电流逐渐小电流逐渐减小至FULL OCV设置的值时判定充满 |
USB配置
UVC
**UVC (USB Video Class)**是USB协议中专门针对视频设备(如网络摄像头、视频采集卡等)制定的标准化规范,它定义了视频设备通过USB接口进行数据传输和控制方式,使得符合UVC标准的设备无需安装专用驱动程序即可在主流修改点系统(如Windows、macOS、Linux)上即插即用。
UVC设备遵循统一的协议规范,修改点系统内置通用驱动,用户无需额外安装厂商专用驱动。兼容常见的视频格式,如MJPEG、H.264、YUV、RGB等,满足不同分辨率和帧率的需求。
宏配置
/*MTK额外配置*/
CONFIG_USB_MTK_OTG=y
CONFIG_USB_MTK_HDRC=y
CONFIG_USB_MTK_HDRC_HCD=y
/*Linux内核配置*/
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_VIDEO_CLASS=y
CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
CONFIG_MEDIA_USB_SUPPORT=y
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_VIDEOBUF2_CORE=y
CONFIG_VIDEOBUF2_MEMOPS=y
CONFIG_VIDEOBUF2_VMALLOC=y
修改带宽限制
路径:
$(LINUX_KERNEL_VERSION)/drivers/misc/mediatek/usb20/mt6765/usb20.c
修改点:
- isoc_ep_end_idx = 1;
- isoc_ep_gpd_count = 248;
+ isoc_ep_end_idx = 2;
+ isoc_ep_gpd_count = 680;
Internet
USB Internet 是指通过 USB 接口 实现设备联网的技术,常见于手机共享网络、USB 调制解调器等场景。USB 网络共享(USB Tethering):将手机或其他移动设备的蜂窝网络(4G/5G)或 Wi-Fi 通过 USB 共享给电脑或其他设备。**USB 调制解调器(USB Dongle):插入 USB 接口的无线网卡或蜂窝模块(如 4G/5G 上网卡),直接提供互联网接入。USB 网卡(Ethernet Adapter)**:通过 USB 转以太网接口,连接有线网络(如光纤、宽带)。
/*PPP拨号相关配置*/
CONFIG_PPP=y
CONFIG_PPP_BSDCOMP=y
CONFIG_PPP_DEFLATE=y
CONFIG_PPP_FILTER=y
CONFIG_PPP_MPPE=y
CONFIG_PPP_MULTILINK=y
CONFIG_PPPOE=y
CONFIG_PPPOLAC=y
CONFIG_PPPOPNS=y
CONFIG_PPP_ASYNC=y
CONFIG_PPP_SYNC_TTY=y
CONFIG_SLIP=y
CONFIG_SLHC=y
/*rndis配置*/
CONFIG_USB_USBNET=y
CONFIG_USB_NET_CDCETHER=y
CONFIG_USB_NET_RNDIS_HOST=y
/*options配置:USB转串口驱动*/
CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_WWAN=y
CONFIG_USB_SERIAL_OPTION=y
Audio电源控制C
gpio
KaTeX parse error: Expected group after '_' at position 46: …m/boot/dts/cust_̲(MTK_PLATFORM).dts
&audgpio {
"extamp-pullhigh",
"extamp-pulllow";
pinctrl-8 = <&extamp_pullhigh>;
pinctrl-9 = <&extamp_pulllow>;
};
&pio {
extamp_pullhigh: extamp_pullhigh {
pins_cmd_dat {
pinmux = <PINMUX_GPIO23__FUNC_GPIO23>;
slew-rate = <1>;
output-high;
};
};
extamp_pulllow: extamp_pulllow {
pins_cmd_dat {
pinmux = <PINMUX_GPIO23__FUNC_GPIO23>;
slew-rate = <1>;
output-low;
};
};
};
修改电源控制模式
路径:
kernel-4.19\sound\soc\mediatek\codec\mt6357\mtk-soc-codec-6357.c
修改点:
int AudDrv_GPIO_EXTAMP_Select(int bEnable, int mode);
int bEnable: 控制电源是否打开
int mode: 电源控制模式
static void Ext_Speaker_Amp_Change(bool enable)
{
pr_debug("%s(), enable %d\n", __func__, enable);
#define SPK_WARM_UP_TIME (25) /* unit is ms */
if (enable) {
AudDrv_GPIO_EXTAMP_Select(false, 3);
/*udelay(1000); */
usleep_range(1 * 1000, 2 * 1000);
AudDrv_GPIO_EXTAMP_Select(true, 3);
usleep_range(5 * 1000, 10 * 1000);
} else {
AudDrv_GPIO_EXTAMP_Select(false, 3);
udelay(500);
}
}
Android
系统默认常亮
路径:
修改点:
修改默认语言
if [ -n "$PRODUCT_DEFAULT_LOCALE" ] ; then
- echo "ro.product.locale=$PRODUCT_DEFAULT_LOCALE"
+ echo "ro.product.locale=zh-CN"
fi
添加App
路径:
device/mediatek/[平台名]/device.mk
修改点:
PRODUCT_PACKAGES += [app-name]
路径:
vendor\mediatek\proprietary\packages\3rd-party\config\3rd-party-apps.mk
修改点:
PRODUCT_PACKAGES += \
Ros \
路径:
vendor\mediatek\proprietary\packages\3rd-party
修改点:
在路径下新建文件夹 [软件名]
路径:
vendor\mediatek\proprietary\packages\3rd-party\[文件名]
修改点:
在该路径下添加apk文件
新建Android.mk 内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := [apk-name]
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_CERTIFICATE := PRESIGNED
include $(BUILD_PREBUILT)
io配置
vendor\mediatek\proprietary\scripts\dct\DrvGen.exe
modem
参考目录
vendor\mediatek\release_note\MT6761\ReleaseNote*.xlsx
//modem 参考页:Build_Configure_Modem
编译命令
mcu目录下:
./m "TK_MD_BASIC(LWCTG_67xx).mak" new //参考 mcu\make\projects 下的 .mak
apps目录下:
./build.sh clean,build,pack all GEN93_USER
流程
1.将硬件提供的 modem 文件,解压至 mcu\pcore\custom\modem 文件中,(需保留 common、ps 文件)。
2.在 MCU 目录下使用 ./m “TK_MD_BASIC(LWCTG_67xx).mak” new 命令。
3.找到任意该平台工程根目录下使用 ./device/mediatek/build/build/tools/modemRenameCopy.pl …/…/modem/mcu “TK_MD_BASIC(LWCTG_67xx).mak” 命令,在编译后会生成 temp_modem。
4.将生成的 modem 文件放在 vendor\mediatek\proprietary\modem 目录下取名 (Project)_MODEM_COTSX 或 (platform)_MODEM_COTSX 文件中。
5.若新建 (Project)_MODEM_COTSX 则在 device/mediateksample/k39tv1_bsp_512/ProjectConfig.mk 修改
CUSTOM_MODEM = (Project)_MODEM_COTSX
更新项目modem编译命令
make update-modem
6762-61-r :TK_MD_BASIC(LWG_AGO1_6177M_R3_6761).mak
error
错误代码1
Can’t locate XML/LibXML.pm in @INC
修改方式
//根据具体报错模块选择对应命令
sudo cpan install XML::Simple
sudo cpan install XML::LibXML
sudo cpan install XML::Parse
sudo cpan install File::Copy::Recursive
sudo apt-getinstall libswitch-perl
开机logo
路径:
vendor\mediatek\proprietary\bootable\bootloader\lk\dev\logo
文件介绍:
横屏
文件名 | 分辨率 | 宽高比 |
---|---|---|
qvganl | 320 x 240 | 4 : 3 |
wvgalnl | 800 x 480 | |
wsvganl | 1024 x 600 | |
xganl | 1024 x 768 | |
wuxga | 1200 x 1920 | |
wuxga2000 | 1200 x 2000 | 3 : 5 |
wxganl | 1280 x 800 | 8 : 5 |
wqhd | 1440 x 2560 | |
qxga | 1536 x 2048 |
竖屏
文件名 | 分辨率 |
---|---|
qvga | 240 x 240 |
qvgal | 240 x 320 |
wqvga | 240 x 400 |
hvga | 320 x 480 |
wvga | 480 x 800 |
fwvga | 480 x 854 |
fwvgaplus | 480 x 960 |
qhd | 540 x 960 |
wsvga | 600 x 1024 |
wsvgalnl | 600 x 1024 |
hd720 | 720 x 1280 |
hdplus | 720 x 1440 |
hdplus1500 | 720 x 1500 |
hdplus1520 | 720 x 1520 |
hdplus1560 | 720 x 1560 |
hdplus1600 | 720 x 1600 |
hdplus1680 | 720 x 1680 |
xga | 768 x 1024 |
wxga | 800 x 1280 |
fhd | 1080 x 1920 |
fhdplus | 1080 x 2160 |
fhdplus2280 | 1080 x 2280 |
fhdplus2280 | 1080 x 2280 |
fhdplus2300 | 1080 x 2300 |
fhdplus2340 | 1080 x 2340 |
fhdplus2400 | 1080 x 2400 |
fhdplus2408 | 1080 x 2408 |
fhdplus2502 | 1080 x 2502 |
工程模式
*#*#3646633#*#* //电话拨号
[DESCRIPTION]
实际电池测试存在一些电量跳变问题,对一些由于电池特性引起的跳变,做如下解释。
[SOLUTION]
1. 多次连续开关机或者recovery,导致电量跳变。
– 这是因为电池的特性,电池恢复回原始电压需要30min.
– 多次开关机会造成电池电压一直再下降,而电量会在头几次采用RTC的数值,当误差超过default 40%,就会产生跳变。
2. 更换电池,手机显示电量不变。具体现象可以是:
A电池在A手机上面显示50%,B电池在B手机上面显示70%. A电池在B手机上面显示70%.
– 这是因为RTC记忆功能与更换新电池后容量变化不大的矛盾引起的。
– 如果打开RTC功能,更换电池以后若电池容量在RTC偏差范围内则不会显示新电池容量,造成更换新电池D0偏差较大.
– 只要是手机端的gauge方案,电池插拔就会有这些变化限制, 只能看电池变化的最大值去调整default的40%.
– 一般原则,修改RTC default数值越小,越可以避免该问题.
3. 动态测试手机, 特别大电流耗电到某一电量,此时突然关机或者扣电池,重新开机显示电量误差大。
– 这是由于电池特性,电池恢复回原始电压需要30min. 短时间内大电流抽电,造成电池瞬间被拉低。再次开机,电量超过default的40%。
– Software gauge(软件电量计)对于误差适应性很强,都会因为闭路回路系统而收敛误差,每次的计算就是在tracking. 短时间内的误差,会在后续使用中,慢慢校正过来。
调试注意
功耗
1.飞行模式打开时功耗正常,关闭飞行模式后再休眠,功耗上升并维持一段时间:
注意查看天线、sim卡等与网络相关的配置与实体。