MTK—
6 开机过程--l4 \UEM\NVRAM\MED:...15
15.10 Initialize单步之后的流程//6253.47
1 说明:
2 术语:
DCL (Driver Common Layer)
MPU(Memory Protection Unit)
3 系统开机流程框图:
1 MMI开机过程:
1.1 MMI TASK
TASK创建:
TaskInit.c
mmi_create()
{
MMI_task, /* task entry function */
MMI_Init, /* task initialization function */
NULL,
};
另留意Mmi_create.c文件里有
mmi_create(comptask_handler_struct **handle)
{
static comptask_handler_struct mmi_handler_info =
{
mmi_task_main, /* task entry function */
NULL, /* task initialization function */
};
}
这个文件的函数不执行具体内容,看这个文件出现的作用和是否生效。(简单分析,它由#ifndef PLUTO_MMI这个宏来控制,应该是给AT版本使用的,因为AT版本不需要MMI界面,另这个文件也不在LIS文件之中。)
MMI初始化执行在系统的栈初始过程中,先执行。
-000|MMI_Init(task_indx = INDX_MMI)
-001|stack_init_tasks(asm)
-002|stack_init(asm)
-003|mainp(asm)
-004|Application_Initialize()
-005|INC_Initialize(asm)
-006|MTK_Initialize(asm)
----|end of frame
|
任务启动执行在进程创建过程中,后执行。进入MMI TASK后,开始没有有效信号,任务空转,等到键盘发出信号提示开机后,MMI TASK正式开机。
-000|MMI_task(entry_param = 0x00126E28)
-001|TCC_Task_Shell(asm)
----|end of frame
|
|
队列管理:
初始化:
重要信号:
MSG_ID_MMI_EQ_POWER_ON_IND
是MMI TASK收到的很早一个信号,给MMI提示开机。
MSG_ID_MMI_EQ_PWNON_DUAL_SIM_IND
在开机动画过程中会收到
重要变量:
g_pwr_context
g_pwr_context_2
g_charbat_context
StartUpTime
g_phnset_cntx
1.2 开机流程分支
锁类型:无锁、SIM1 PIN1、SIM2 PIN1、SIM1 PUK、SIM2 PUK、SIM1 SML(5种)、SIM2 SML(5种)、PHONE LOCK。
开机模式:飞行模式、只开卡1,只开卡2,开双卡
开机方式:按键、闹钟、充电。。。
POWER_ON_KEYPAD = 0 ,
POWER_ON_ALARM ,
POWER_ON_CHARGER_IN ,
POWER_ON_EXCEPTION ,
POWER_ON_USB ,
POWER_ON_UNINIT ,
POWER_ON_PRECHARGE = 8
卡状态:不插卡、只插卡1,只插卡2,插双卡
卡类型:正常卡、无效卡、欠费卡;
卡兼容:慢卡、协议不兼容卡、不同协议版本的卡等。
组合起来就相当庞大的分支,下面是一个组合矩阵的示例:
1.1 MMI启动流程图
以按键开机举例,正常的双卡开机,没有锁的MMI开机流程图如下:
1.1 MMI启动函数调用过程和说明
MSG_ID_MMI_EQ_POWER_ON_IND
在MMI_Task()中,进入:
switch (p->poweron_mode)
case POWER_ON_KEYPAD:
mmi_bootup_entry_disk_check
根据FS_SanityCheck()结果执行不同流程。一般走FS_NO_ERROR。
mmi_bootup_exit_disk_check()
mmi_frm_power_on_init_procedure
进行一系列的应用初始化,包括InitializeAll
mmi_bootup_entry_flight_mode_query()空函数
FlightModeCheckBeforeAnimation()判断飞行模式
MTPNP_AD_Bootup
PowerOnNormalMode
会发送信令PRT_NW_CFUN_STATE_REQ给
L4,让l4c_nw_cfun_state_req()得到执行,启
动网络和SMU等功能,这个事件在双卡项目会
收到两次
mmi_bootup_exit_flight_mode_query();
mmi_bootup_entry_animation()定时器执行
等待期间,会来下面的事件
MSG_ID_MMI_EQ_BATTERY_STATUS_IND
(这个颜色的信号都是被CATCHER弄丢了的,所以
CATCHER不可以全信)
。。。。。。
这里有一个调用栈,是对上面过程的一个验证:
-000|mmi_bootup_exit_flight_mode_query()
-001|PowerOnNormalMode()
-002|MTPNP_AD_Bootup()
-003|FlightModeCheckBeforeAnimation()
-004|mmi_bootup_exit_disk_check()
-005|mmi_bootup_entry_disk_check()
-006|MMI_task(?)
-007|TCC_Task_Shell(asm)
----|end of frame
代码里关于开机流程有一个简单过程说明
* Power On Procedure
*
* Power On Display NAND SIM Net Search Idle Scr
* #----------------------#----------#----------#-------------#-----------#
* (option) (option) (option)
mmi_bootup_entry_animation()
mmi_pwron_entry_animation_screen()
ShowCategory166Screen(mmi_pwron_show_image_callback() ),
进入并播放动画,通过回调函数进入后面的流程。
播放动画期间,会来下面的事件(选取比较重要的部分事件)
MSG_ID_MMI_SMU_SIM_STATUS_UPDATE_IND
MSG_ID_MMI_SMU_STARTUP_INFO_IND
smu_main : MSG_ID_SIM_START_CNF 26 0 0
smu_main : MSG_ID_SIM_MMI_SECURITY_IND 26 0 0
SML-SIM2 feature: m_handle_chv_validation begin
smu_main : MSG_ID_SIM_MMRR_READY_IND 26 0 0
(这部分蓝色的位置不太确定,蓝色表示安全检查)
MSG_ID_MMI_EQ_PWNON_DUAL_SIM_IND
( sim_config_status = 2 , sim_insert_status = 3 都是双卡 )
MSG_ID_MMI_NW_PWNON_DUAL_SIM_IND
MSG_ID_MMI_NW_CFUN_STATE_RSP
MSG_ID_MMI_CPHS_MMI_INFO_IND
MSG_ID_L4AUD_AUDIO_PLAY_FINISH_IND
MSG_ID_MMI_SMU_PASSWORD_REQUIRED_IND
MSG_ID_MMI_NW_SEL_MODE_IND
MSG_ID_MMI_RAC_ACTIVATED_ IND
MSG_ID_MMI_SMU_CHECK_PIN_STATUS_RSP
mmi_pwron_show_image_callback
状态不同走的流程也不同,下面是进入这个函数之后的调用栈:
-000|PowerOnBatteryIndicationCompletePhase2()
-001|mmi_bootup_entry_security_check()
-002|mmi_bootup_exit_low_battery_warning()
-003|BatteryCheckAfterPowerOnAnimation()
-004|mmi_bootup_entry_low_battery_warning()
-005|mmi_bootup_exit_animation()
-006|CallBackPowerOnAnimationComplete(?)
-007|mmi_pwron_show_image_callback(?)
-008|cat166_animation_complete_callback_int(?)
-009|gdi_anim_callback_timer(?)
-010|L4CallBackTimer(?)
-011|evshed_timer_handler(asm)
-012|EvshedMMITimerHandler(?)
-013|MMI_task(?)
-014|TCC_Task_Shell(asm)
----|end of frame
在这之后,会根据安全检查走不同的开机流程,或直接走IDLE,或进入SimPasswdReqResponse()进行安全验证,这个时候会有一下信令交互和界面交互。关于安全验证,会另有专题介绍,本文档专注于开机流程到进入IDLE的过程。
MSG_ID_MMI_SMU_SIM_STATUS_UPDATE_IND
MSG_ID_MMI_SMU_STARTUP_INFO_IND
。。。。。。
MSG_ID_MMI_NW_MMRR_SERVICE_STATUS_IND
MSG_ID_MMI_NW_ATTACH_IND
MSG_ID_MMI_SAT_SETUP_MENU_IND
如果需要安全检查,则安全检查后收到事件
MSG_ID_MMI_READY_TO_IDLE_SCREEN_IND
它会触发下面的栈流程进入IDLE:
-000|EntryIdleScreen() 到这里,historyData已经被清空;这里有根据启动模式走不同的分
支;进搜网mmi_idle_entry_searching_screen()
-001|mmi_idle_entry_dual_sim_root_screen() 这里有根据卡在位的状态进入不同的分支
-002|BeforeEntryIdleScr()
-003|mmi_bootup_exit_welcome_screen()
-004|ShowWelcomeScr() 这里有显示开机问候的分支处理
-005|exit_custom_startup_screen() 这个分支有关闭动画的行为
-006|goto_opening_screen() 会有InitAllApplications进行初始化
-007|mmi_ready_to_idle_screen_ind_hdlr()
-008|mmi_frm_execute_current_protocol_handler(eventID = 5289, MsgStruct = 0x0, m
-009|ProtocolEventHandler(eventID = 5289, MsgStruct = 0x0, mod_src = 68, peerBuf
-010|MMI_task(?)
-011|TCC_Task_Shell(asm)
----|end of frame
mmi_idle_entry_searching_screen()
MSG_ID_MMI_PHB_STARTUP_BEGIN_IND
MSG_ID_MMI_SAT_SETUP_MENU_RES_RSP
MSG_ID_MMI_SAT_NO_OTHER_CMD_IND
MSG_ID_MMI_EMAIL_INIT_RSP
再回IDLE,基本上算完成了开机流程,之后还会收到很多事件,如关于网络、短信、电话吧、EMAIL、MMS、WAP、SAT等。这些模块的启动和完成,要另外单独再分析。
|EntryIdleScreen()
1 APP INIT:
网络、短信、电话吧、EMAIL、MMS、WAP、SIM、SAT、NVRAM
kal_bool phb_ready_flag;
kal_bool sms_ready_flag;
kal_bool ciss_ready_flag;
kal_bool tcm_ready_flag;
kal_bool mmi_ready_flag;
kal_bool sms_init_sent; //true: MSG_ID_L4CSMSAL_INIT_REQ is sent
3 开机过程--l4 \UEM\NVRAM\MED:
下面是从BMT开始,到MSG_ID_MMI_EQ_POWER_ON_IND发送给MMI TASK的一个流程分析。
3.1 BMT
bmt_task_main()
任务启动,即发送MSG_ID_DRVUEM_POWER_ON_IND给MOD_UEM,
3.2 UEM
uem_main
MSG_ID_DRVUEM_POWER_ON_IND
uemdrv_power_on_ind_hdlr()
uem_poweron_timer_expiry_hdlr()TARGET执行这个函数,模拟器跳过,执行下一个
uemdrv_keypad_power_on_ind()
l4cuem_power_on_ind()
发送MSG_ID_NVRAM_STARTUP_REQ给MOD_NVRAM
根据开机原因不同,uemdrv_power_on_ind_hdlr会执行的不同的函数,我们调试的是键盘开机,所以是uemdrv_keypad_power_on_ind()。
typedef enum{
PWRKEYPWRON = 0,
CHRPWRON = 1,
RTCPWRON = 2,
CHRPWROFF = 3,
WDTRESET = 4, /*NORMAL*/
ABNRESET = 5, /*ABNORMAL RESET*/
USBPWRON = 6,
USBPWRON_WDT = 7,
PRECHRPWRON = 8,
UNKNOWN_PWRON = 0xF9
}power_on_enum;
3.3 NVRAM
nvram_main
MSG_ID_NVRAM_STARTUP_REQ
nvram_startup_handler()
nvram_startup_confirm()
完成几个NV项的处理后,发确认信号MSG_ID_NVRAM_STARTUP_CNF给UEM.
3.4 L4C
l4c_main
MSG_ID_NVRAM_STARTUP_CNF
nvram_startup_cnf_hdlr()
l4c_send_msg_to_uem(MSG_ID_L4CUEM_STARTUP_REQ)
3.5 UEM
MSG_ID_L4CUEM_STARTUP_REQ
ueml4c_startup_req_hdlr()
uem_startup_process()
uem_send_msg_to_nvram(MSG_ID_NVRAM_READ_REQ, NVRAM_EF_UEM_RMI_DATA_LID, 0, 0);
。。。
通过和NVRAM的几个读交互
uemnvm_read_data_cnf_hdlr()
NVRAM_EF_UEM_RMI_DATA_LID
NVRAM_EF_CUST_HW_LEVEL_TBL_LID
NVRAM_EF_UEM_MANUFACTURE_DATA_LID
然后发出uem_send_msg_to_aud(MSG_ID_MED_STARTUP_REQ)给MOD_MED
3.6 MOD_MED
med_main.c
MSG_ID_MED_STARTUP_REQ
med_startup_hdlr()
启动相关模块和进行一些初始化,然后发送aud_send_startup_cnf(MED_RES_OK),
MSG_ID_MED_STARTUP_CNF
3.7 UEM
MSG_ID_MED_STARTUP_CNF
uemaud_startup_cnf_hdlr
发送MSG_ID_L4CUEM_STARTUP_CNF给L4,并做一些简单的硬件初始,如语音通道、RTC。
3.8 L4C
MSG_ID_L4CUEM_STARTUP_CNF
通过L4特有的函数数组映射方法,对应到
l4cuem_startup_cnf_hdlr()
l4c_eq_power_on_lind()
l4a_eq_power_on_lind()
发送MSG_ID_MMI_EQ_POWER_ON_IND给MMI TASK,至此,MMI TASK收到开机事件的流程结束了。
1.1 信令流程图
1 开机过程--BMT\PMIC:
2 开机过程--BOOT:
3 l4介绍:
3.1 COMMON
l4_sap.h
l4c_ft.c
l4c_cnf_ft
3.2 Architecture
1.1 L4 TASK
kal_bool l4_create(comptask_handler_struct **handle)
{
static const comptask_handler_struct l4_handler_info =
{
layer4_task_main, /* task entry function */
layer4_init, /* task initialization function */
NULL, /* task configuration function */
l4_reset, /* task reset handler */
NULL, /* task termination handler */
};
}
-000|l4_create(handle = 0x40006320)
-001|stack_init_comp_info(asm)
-002|stack_init(asm)
-003|mainp(asm)
-004|Application_Initialize()
-005|INC_Initialize(asm)
-006|MTK_Initialize(asm)
----|end of frame
|
process_ilm()
L4 TASK是分解成多个不同的模块来处理的,下面主要是SIM1的模块,如果是双卡,每个模块还有一个对应的SIM2的处理模块:
(mod_id == MOD_L4C
||mod_id == MOD_RAC
||mod_id == MOD_TCM
||mod_id == MOD_CSM
|| mod_id == MOD_SMSAL
||mod_id == MOD_PHB
||mod_id == MOD_SMU
|| mod_id == MOD_UEM
|| mod_id == MOD_ATCI)
1.1 L4C Module
MMI和PS的接口层。其中包含L4A的处理过程。
l4_sap.h 信号定义文件
l4c_main()
这个是L4C Module的处理函数,主要是通过处理函数数组的方式来处理的,这个处理方式有别于其他的模块的信号处理方式,下面是几个处理函数数组:
l4c_ind_ft[]/l4c_cnf_ft[]/l4c_req_ft[]/l4a_recv_msg_ft[]
另外还有一些信号是单独处理的,见模块的主处理函数。
1.2 UEM Module
uem_main.c
g_uem_cntx_p
UEM主要是MMI和硬件驱动的一个接口层,处理操作和响应各种硬件行为的事件。
uem_main()
1.3 RAC Module
网络注册、PLMN、信号强度报告
1.4 TCM Module
终端管理,负责QOS、PDP、PPP、TCPIP等数据传输。
1.5 SMLAL Module
短消息管理,包括信箱管理、短信收发、小区广播。
1.6 CSM Module
呼叫服务管理。包括承载管理、语音业务、SS相关、CSD数据业务、呼叫信息维护、语音编解码等。
1.7 SMU Module
安全管理。PL、PIN、SML。
1.8 PHB Module
电话本管理。
1.9 ATCI Module
AT接口,忽略。
2 MED介绍:
3 KEY PAD介绍:
(6251平台)
3.1 简单说明
按键处理分几个部分,一个是芯片内部的处理,如按键检测和扫描,我们控制不到,主要是通过读寄存器来完成对按键的检测;一个是驱动部分的处理,主要是配置GPIO、中断,并将按键中断转化为驱动层事件,再发送到MMI;另一个是MMI部分的按键处理逻辑。
驱动部分暂不讨论。
MMI部分暂不讨论。
3.2 文件
DclS_kbd.c
DclH_kbd.c
keypad_def.c
3.3 相关部分
键盘的初始化调用栈
DclSKBD_Initialize(); //注册中断等操作
DclSKBD_Initialize();
Drv_Init_Phase2();
对POWER KEY的判断,决定开机原因
DclPW_PowerInit()
DclHKBD_Control(pw_KeypadHandler,HKBD_CMD_GET_POWER_KEY_STATUS , (DCL_CTRL_DATA_T*)&powerkeyStatus);
PowerKey_Press()
通过映射函数和映射数据,将代码内部使用的按键值和寄存器的物理地址做一个映射,来决定POWERKEY是否被按下,其他键是否被按下也可以用同样的方法来检查。
MTK平台对按键的硬件扫描是芯片完成的,不需要驱动来处理。驱动对按键的检测都是读寄存器。
DRV_KBD_NOT_EXIST
4 BMT介绍:
bmt_create.c
bmt_create(comptask_handler_struct **handle)
{
static const comptask_handler_struct bmt_handler_info =
{
bmt_task_main, /* task entry function */
bmt_task_init, /* task initialization function */
NULL, /* task configuration function */
bmt_task_reset, /* task reset handler */
bmt_task_end /* task termination handler */
};
*handle = (comptask_handler_struct *)&bmt_handler_info;
return KAL_TRUE;
}
current_count=DRV_Reg(GPT3_LEN);
5 PROGRESS:
5.1 进程优先级
优先级定义在stack_config.h,下面列出我们感兴趣的几个(优先级以数字小者为高)
a. Priority within 160-199 are evenly distributed between 120-219; but
reserving 160 ~ 169 for MA debugging.
b. Priority in range of 0 ~ 9 are specific for RTOS.
c. Priority in range of 10 ~ 119 are special for 2G / 3G protocol, besides,
special driver or sensitive driver, eg. DRV_TEST on BASIC load, and
windows driver.
#define TASK_PRIORITY_L1 (KAL_PRIORITY_CLASS2)
#define TASK_PRIORITY_MM KAL_PRIORITY_CLASS9
#define TASK_PRIORITY_SIM (KAL_PRIORITY_CLASS9+5)
#define TASK_PRIORITY_CC KAL_PRIORITY_CLASS10
#define TASK_PRIORITY_SM (KAL_PRIORITY_CLASS10+5)
#define TASK_PRIORITY_DATA KAL_PRIORITY_CLASS11
#define TASK_PRIORITY_DRVKBD (KAL_PRIORITY_CLASS8+5)
#define TASK_PRIORITY_L1AUDIO (KAL_PRIORITY_CLASS12+2)
#define TASK_PRIORITY_MED KAL_PRIORITY_CLASS13
#define TASK_PRIORITY_L4 KAL_PRIORITY_CLASS16
#define TASK_PRIORITY_TCPIP (KAL_PRIORITY_CLASS17+6)
#define TASK_PRIORITY_SOC (KAL_PRIORITY_CLASS17+8)
#define TASK_PRIORITY_EMAIL (KAL_PRIORITY_CLASS18+5)
#define TASK_PRIORITY_WPS (KAL_PRIORITY_CLASS18+8)
#define TASK_PRIORITY_BMT KAL_PRIORITY_CLASS20
#define TASK_PRIORITY_MMI KAL_PRIORITY_CLASS22
#define TASK_PRIORITY_WAP KAL_PRIORITY_CLASS22
#define TASK_PRIORITY_GDC (KAL_PRIORITY_CLASS22+2)
#define TASK_PRIORITY_GDD (KAL_PRIORITY_CLASS22+3)
#define TASK_PRIORITY_MMS (KAL_PRIORITY_CLASS22+4)
#define TASK_PRIORITY_DM KAL_PRIORITY_CLASS23
#define TASK_PRIORITY_NVRAM KAL_PRIORITY_CLASS24
#define TASK_PRIORITY_WEB (KAL_PRIORITY_CLASS24+9)
#define TASK_PRIORITY_IDLE (KAL_PRIORITY_CLASS25+5)
5.2 进程创建
syscomp_config.c
sys_comp_config_tbl[]
mod_task_g[]
MODULE_ID_TYPE
MMI初始化执行在系统的栈初始过程中,先执行。
-000|MMI_Init(task_indx = INDX_MMI)
-001|stack_init_tasks(asm)
-002|stack_init(asm)
-003|mainp(asm)
-004|Application_Initialize()
-005|INC_Initialize(asm)
-006|MTK_Initialize(asm)
----|end of frame
|
INT_Vectors
INT_Initialize
//MTK_LoadPC
//MTK_INITIALIZE_PTR 、Copy_INT_Entry
MTK_Initialize
6 BOOT:
(6251平台)
6.1 MCU块图
1.1 MEMORY重映射
ARM7-EJS总线宽度32BIT,寻址空间4GB。各设备进行地址重映射后分布如上。其中内部RAM和ROM的寻址空间都可达到128MB,实际的内部RAM为384KB,ROM为56KB。可使用的外部FLASH大小为1GB。
1.1 PWR ON
在芯片层,有4种模式能够开机,PWRKEY/RTC/CHARGE/EXCEPTION,开机的时序图如下:
没按下power key时,PWRKEY在上拉电阻和可变二极管中间,有一个高电平,按下power key后,PWRKEY接地形成低电平,在芯片内部,,PWRKEY检测到低电平,驱动PMIC,先打开VCORE BUCK转换器,同时打开VIO18/VSF LDOs,再打开其他几个LDOs(VIO28/VA/VUSB/VRF28/VTCXO),使BB的供电源准备就绪。之后BB复位,并发送PWRBB事件给PMU, power key要按的时间足够长,以确保PMU能收到这个事件。BB起来进入软件开机程序,完成开机。
从这个PMU的模块图上可以看出,
VCORE是DC-DC方式的供电源,提供1.2、0.9、1.3V的电源(给BB),
VRTC是连接电池的2.8V的电源,
VA是2.8V的电源(给BB),模拟基带使用的电源,(BB供电的主电源,),
VIO18是1.8V的电源(给BB),
VIO28是2.8V的电源(给BB和SD设备),,
VSF是1.8V的电源(给串行FLASH),
VSIM1/VSIM2是1.8V的电源(给SIM卡),
VUSB是2.8V的电源(给BB),
VRF/VTCXO是2.8V的电源(给射频收发器和本振,13、26M的晶振电源),
VFM是2.8V的电源(给FM),
VIBR是多种电压范围的电源(给Vibrate),
6251共有12种用途的LDO。
1.1 BOOT
ARM7-EJS从0地址开始运行,而6251平台的SYS-ROM的起始地址在0X4800 0000,
这个内部ROM完成系统BOOT的工作。我们要执行这部分的代码,就需要加上一段BOOT CODE在0地址,让系统能到SYS-ROM里执行。在6251平台,这个BOOT CODE如下: