TC27x启动过程(2)-TC277

接上文,继续学习TC277的启动过程。分析启动函数

有关用的寄存器说明,参考文章

TC27x寄存器学习

目录

TC27x寄存器学习

start函数分析

isync汇编指令(同步指令)

dsync汇编指令(同步数据),

1清除endinit

2设置中断堆栈

3启用对系统全局寄存器的写访问

4初始化SDA基指针

5关闭对系统全局寄存器的写访问

6关闭看门狗,恢复Endinit位

7初始化CSA

8初始化ram,拷贝rom数据到ram

9跳转主函数


start函数分析

__asm ("_START: movh.a %a10,hi:0xD000F000");
__asm ("  lea  %a10,[%a10]lo:0xD000F000");
__asm ("  movh.a %a15,hi:_start");
__asm ("  lea  %a15,[%a15]lo:_start");
__asm ("  ji %a15");

movh.a是(Move High to Address),将0xD000F000的高16bit写入address resgster A[10]地址寄存器中

TC27x启动过程(2)-TC277_第1张图片

A[10]是堆栈指针寄存器(SP)

lea指令(Load Effective Address)将0xD000F000的低16bit 写入address resgster A[10]的低16bit

0xD000F000应该表示SP地址值

A[15]是隐式地址寄存器, movh.a %a15,hi:_start 将 _start函数的地址高16位写入A[15]

ji指令(Jump Indirect)将A[15]的地址写入PC指针,并跳转到相应地址,即跳转到_start函数中执行

这个汇编的跳转没太懂,为什么要这么写?

void _start(void)

{

unsigned int coreID = _mfcr(CPU_CORE_ID) & IFX_CPU_CORE_ID_CORE_ID_MSK;

const CoreInit_t *core; /* the core initialisation structure */

core = &CPUInit[coreID];//初始化core0

cstart(core);//启动core0

}

_mfcr是汇编语言中的获取寄存器中的值

MTCR是写操作_mtcr(regaddr, val) 对寄存器写值

CPU_CORE_ID是Core Identification Register CSFR_Base + FE1CH

头文件中定义为 #define CPU_CORE_ID (0xFE1C)

CPU必须使用MTCR和MFCR指令访问自己的CSFR寄存器。其他CPU的CSFR寄存器可以通过XBAR_SRI使用加载和存储指令进行访问。任何CPU的SFR寄存器只能通过XBAR_SRI使用加载和存储指令进行访问。目前,CPUx的覆盖控制和访问保护寄存器映射到CPUx SFR地址范围。

CSFR-Core Special Function Registers.

TC27x启动过程(2)-TC277_第2张图片

void cstart(constCoreInit_t *)__attribute__ ((interrupt,noinline)); 声明为非内联函数。

interrupt此属性指示编译器以适合用作异常处理程序的方式生成函数

isync汇编指令(同步指令)

,强制完成之前的所有指令,然后刷新CPU管道,并在继续执行下一条指令之前使任何缓存的管道状态无效。ISYNC指令应该跟在MTCR指令之后。

dsync汇编指令(同步数据),

强制所有数据访问在与指令关联的任何数据访问之前完成,为确保内存一致性,必须在访问活动CSA内存位置之前执行DSYNC指令。

/*

* the initial startup routine 初始化启动程序

* - initialise the global RAM 初始化全局ram

* - start the other CPUs 启动其他CPU

* - disable/enable System Watchdog 关闭/开启 系统开门狗

* - call the main function 调用主函数

*/

void cstart(const CoreInit_t *core)

{

1清除endinit

/* reset endinit and disable watchdog */复位endinit 关闭看门狗

/* clear endinit bit in CPU0 WDT */

/* clear endinit bit in safety WDT */

WDT_ClearEndinit(volatileunsignedint *wdtbase)

{

unsigned int passwd;

passwd = *wdtbase;//读取寄存器中的值,获取原始密码

passwd &= 0xffffff00;//低8位清0

*wdtbase = passwd | 0xf1;//lck位置0,endinit位置1 应该是Password Access过程,[7:2]置111100

*wdtbase = passwd | 0xf2;//【2】lck位置1,endinit位置0,获取访问许可,应该是Modify Access过程

/* read back new value ==> synchronise LFI */

(void)*wdtbase;//读取更新返回值

}

2设置中断堆栈

/* setup interrupt stack */

_mtcr(CPU_ISP, (unsigned int)core->istack);//_mtcr(regaddr, val) 对寄存器写值

//加载中断向量指针寄存器

/* install trap handlers */

//加载陷阱向量表指针寄存器

_mtcr(CPU_PCON0, (unsigned int)0);//操作PMI0,程序允许缓存

_isync();//同步指令

/* initialise call depth counter */

psw = _mfcr(CPU_PSW);//读寄存器值

psw |= IFX_CPU_PSW_CDC_MSK;//禁用call depth counter

//关闭call depth counter,其实上面设置就够了

_mtcr(CPU_PSW, psw);//写入PSW

_isync();//同步指令

3启用对系统全局寄存器的写访问

/* enable write access to system global registers */

psw = _mfcr(CPU_PSW);//读寄存器值

//启用A[0], A[1], A[8], A[9] 写入权限

_mtcr(CPU_PSW, psw);//写入PSW

_isync();

4初始化SDA基指针

/* initialise SDA base pointers */

目的是啥?

5关闭对系统全局寄存器的写访问

/* disable write access to system global registers */

psw = _mfcr(CPU_PSW);

//关闭A[0], A[1], A[8], A[9] 写入权限

_mtcr(CPU_PSW, psw);

_isync();

6关闭看门狗,恢复Endinit位

/* disable Watchdogs */

if (core == &CPUInit[0])

{

/* safety WDT handled by CPU0 */

SCU_WDTSCON1.B.DR = 1;

WDT_SetEndinit(&SCU_WDTSCON0.U);

}

core->wdtCon1->B.DR = 1;

WDT_SetEndinit(&core->wdtCon0->U);

7初始化CSA

init_csa(core->csaBase, core->csaSize);

8初始化ram,拷贝rom数据到ram

/* handle global clear and copy tables */

if (core == &CPUInit[0])

{

clear_table_func(&__clear_table);

copy_table_func(&__copy_table);

}

/* handle core specific clear and copy tables */

clear_table_func(core->cleartable);

copy_table_func(core->copytable);

....

9跳转主函数

(*core->main)(1, (char **)&core->ustack[0]);//调用core0的main函数

}

WDTCPU0定义的联合

/** \brief CPU WDT Control Register 0 */

typedef union

{

unsigned int U; /**< \brief Unsigned access */

signed int I; /**< \brief Signed access */

Ifx_SCU_WDTCPU_CON0_Bits B; /**< \brief Bitfield access */

} Ifx_SCU_WDTCPU_CON0;

/** \brief CPU WDT Control Register 0 */

typedef struct _Ifx_SCU_WDTCPU_CON0_Bits

{

Ifx_Strict_32Bit ENDINIT:1; /**< \brief [0:0] End-of-Initialization Control Bit (rwh) */

Ifx_Strict_32Bit LCK:1; /**< \brief [1:1] Lock Bit to Control Access to WDTxCON0 (rwh) */

Ifx_Strict_32Bit PW:14; /**< \brief [15:2] User-Definable Password Field for Access to WDTxCON0 (rwh) */

Ifx_Strict_32Bit REL:16; /**< \brief [31:16] Reload Value for the WDT (also Time Check Value) (rw) */

} Ifx_SCU_WDTCPU_CON0_Bits;

该main函数在Bswinit.c中

int main(void)

{

BswInit_PreInitPowerOn();

BswInit_InitializeOne();

BswInit_InitializeTwo();

EcuM_Init(); /* never returns */

return 0;

}

BswInit_PreInitPowerOn在BswInit_callout_Stubs.c中

可用于ASR模块未涵盖的任何与硬件相关的初始化

以上还没看到其他CPU启动的过程。需要继续分析后面的代码

你可能感兴趣的:(TC277学习笔记,gnu,单片机)