Search for posts tagged with: MTK

Avatar

以data abort 为例

Data_Abort_ISR
MOV      a1,#DATA_EXCEPTION_TYPE         ; Set type DATA_ABORT (4)
MOV      a2,lr

saveException
MRS     a3,CPSR                          ; Pickup current CPSR
BIC     a3,a3,#MODE_MASK                 ; Clear the mode bits
ORR     a3,a3,#SUP_MODE                  ; Prepare to switch to supervisor mode (SVC)
MSR     CPSR_cxsf,a3                     ; Switch to supervisor mode (SVC)

LDR     a4, SYSTEM_FATAL_ERROR
BX      a4

SYSTEM_FATAL_ERROR实际是函数stack_system_error的地址
在stack_system_error函数中,首先会切换sp到一个专门为异常处理预留的内存地址上,然后根据异常传入的类型填充必要的参数后调用fatal_error_handler。

kal_fatal_error_handler(kal_char *error_message_ptr, kal_uint32 error_code, kal_uint32 os_error_code)
{
DisableIRQ();
error_param_g.param1 = (kal_uint32)error_message_ptr;
error_param_g.param2 = (kal_uint32)error_code;
error_param_g.param3 = (kal_uint32)os_error_code;
fatal_error_handler((kal_uint8 *)error_param_g.param1, error_param_g.param2, error_param_g.param3);

}
在fatal_error_handler中
{

/* lockout all interrupts */
DisableIRQ();

/* mask all interrupts */
IRQDirectMaskAll();

/*
* NoteXXX: To avoid system hang in the exception handler,
*          watchdog remains active while handling exception (if it is enabled).
*/
WDT_Restart2();

/* increase the coutner */
INT_Exception_Enter++;

/* determine if multi-level exception*/
if (INT_Exception_Enter >= 2) {

tst_sysfatal_trace((kal_uint8 *)"Caution: Possibly Endless Nested Exceptions!");

ex_reboot();
}

//以下开始准备得到reset时的系统状态。
/*
* I. Initialize the exception log.
*/
/* reset hardware */
ex_reset_hw();//dma_recover_all,L1Audio_ResetDevice,L1D_PauseDSP
/* re-start WDT again */
WDT_Restart2();

然后得到当前task,并将其优先级设为0,最高
/* get the current thread id */
current_thread = kal_get_current_thread_ID();

/* determine if the current executed task is a TASK, not a HISR */
if ((current_thread != NULL) && (kal_if_hisr() == KAL_FALSE)) {

/* raise the task priority level to the highest */
kal_change_priority((NU_TASK *)current_thread, 0);
}

/* setup param */
param.ext = KAL_FALSE;
param.e1 = param.e2 = param.e3 = 0;
param.dump_param = NULL;

/* initialize the exception log */

/* determine if ARM pre-defined exceptions */
if (err_code < ASSERT_FAIL_EXCEPTION) {

param.type = (exception_type)err_code;

param.code1 = (kal_uint32 *)&os_err_code;

param.code2 = 0;

ex_init_log(&param);

} else
//在ex_init_log中会取得当前版本信息,当前时间,当前系统堆栈信息,当前task状态,hisr状态

然后
/* output the exception log */
ex_output_log();
最后重启系统
/* reboot silently */
ex_reboot();  //使用watchdog来重启系统。

}

在系统重启后有如下一段代码
;  /* Check if abnormal reset */
LDR   a1,ABN_RST_PTR
BL    INT_SystemReset_Check
在INT_SystemReset_Check中会读取地址为0×80040018 的寄存器的值并且同0×0ffa进行比较不相等就返回否则进入kal_fatal_error_handler

关于0×80040018的这个寄存器,datasheet上如下描述Watchdog Timer Reset Signal Duration Register。This register indicates the reset duration
When Watchdog timer times out

关于这段代码,猜测是因为有可能是系统因为挂起而没有reset watchdog寄存器导致重启,这里就可以进行log的抓取。

Tagged with: .
Avatar

在code已经优化的情况下的做法,其他系统类似也应该可用。

1.code放到internal ram中去执行

2.code中使用的全局变量或动态分配的内存放到internal ram中。

3.执行该code时将系统堆栈设置到internal ram中。

Tagged with: .
Avatar

该项目平台是MTK6225,ARM7处理器,nor boot,128+32
DM技术方案提供商为Red Bend公司。

在加入DM方案以后,系统的划分如下

ROM1 0×00000000 0×00040000
ROM2 0×00040000 0×00d00000
ROM3 0×00d40000 0×000C0000

ROM1用来放FOTA更新程序和Red Bend 提供的lib部分。
ROM2为原来MTK程序,也是版本需要更新部分。
ROM3用来存放差分包,最后两个block一个用来做临时备份使用,一个用来做标志(安全但是浪费啊)。
注意:ARM的中断向量当然要放到ROM1中,*.obj的LEADING_PART部分也是需要的,否则可能无法boot。

片外RAM部分
FOTA部分将会使用很小的一部分,原来的MTK程序依次向后就可以了。FOTA部分程序当然会使用到MTK程序部分的内存,这个是因为FOTA需要很大的heap,并且这样做是没有问题的,因为MTK程序部分后面会再次初始化一次。

片内RAM部分
在这个项目的实现中,我将FLASH驱动代码放在了片内RAM中去执行。MTK程序依次向后就可以了。

进入FOTA的bootloader后,依然是先切换到svc模式,设置系统堆栈,设置EMI和DPLL.配置需要的GPIO,UART,手动将INTSRAM_CODE部分由FLASH copy到对应的RAM中,将FOTA必须的FLASH驱动copy到片内RAM中,禁掉watchdog timer,完成必须的lcd的初始化,然后

int i=0;
char *a=(char *)BACK_BLOCK_ADDR1;char *b=(char *)BACK_BLOCK_ADDR2;
char *backbuferr[2];
backbuferr[0]=a;backbuferr[1]=b;
i = RB_ImageUpdate((unsigned long int)UPDATE_ADDRESS_BEGIN,(unsigned long int)UPDATE_ADDRESS_END,(unsigned char*)FOTA_MEMORY_BEGIN,(unsigned long int)FOTA_MEMORY_SIZE,(unsigned char*)0,(unsigned long int)0,
(unsigned long int *)backbuferr,(unsigned long int)2,(unsigned long int)0);
if(i==S_RB_SUCCESS)
{
PW_Set_FOTA_Flag();
set_successed_flag();
clear_need_update_flag();
return;
}

Done.
Redbend提供给我们的RB_flash.c和RB_ImageUpdate.c是我们必须要完成接口函数,当我们将对应的驱动实现后,这些函数还是很容易完成的。

Tagged with: , .