当前位置:首页>Linux>嵌入式linux打卡第三天

嵌入式linux打卡第三天

  • 2026-08-25 10:06:39
嵌入式linux打卡第三天
基于正点原子IMX6U左神教程
今天看到了第二期的15.4讲
IMX6U时钟
/*初始化时钟*/void imx6u_clkinit(void){    unsigned int reg = 0;//初始化6U的主频为528MHzif(((CCM->CCSR >> 2) & 0X1) == 0)//当前时钟使用pll1_main_clk也就是pll1    {        CCM->CCSR &= ~(1 << 8);//设置step_clk = osc_clk=24M        CCM->CCSR |= (1 << 2);//pll1_sw_clk = 24MHz    }//设PLL1=1056MHz    CCM_ANALOG->PLL_ARM = (1 << 13) | ((88 << 0) & 0X7f);    CCM->CACRR = 1;//设置2分频    CCM->CCSR &= ~(1 << 2);//设置pll1_sw_clk=pll1_main_clk=1056MHz//设置PLL2的4路PFD    reg = CCM_ANALOG->PFD_528;    reg &= ~(0X3F3F3F3F);    reg |= (32 << 24); //PLL2_PFD3=297MHz    reg |= (24 << 16); //PLL2_PFD2=396MHz    reg |= (16 << 8 ); //PLL2_PFD1=594MHz    reg |= (27 << 0 ); //PLL2_PFD0=352MHz    CCM_ANALOG->PFD_528 = reg;//设置PLL2的4路PFD    reg = 0;    reg = CCM_ANALOG->PFD_480;    reg &= ~(0X3F3F3F3F);    reg |= (19 << 24); //PLL3_PFD3=454.7MHz    reg |= (17 << 16); //PLL3_PFD2=508.2MHz    reg |= (16 << 8 ); //PLL3_PFD1=540MHz    reg |= (12 << 0 ); //PLL3_PFD0=720MHz    CCM_ANALOG->PFD_480 = reg;//设置AHB_CLK_ROOT=132MHz    CCM->CBCMR &= ~(3 << 18);    CCM->CBCMR |= 1 << 18;//pre_periph_clock=PLL2_PFD2=396MHz    CCM->CBCDR &= ~(1 << 25);while(CCM->CDHIPR & (1 << 5));/*    CCM->CBCDR &= ~(7 << 10);    CCM->CBCDR |= (2 << 10);//3分频    while(CCM->CDHIPR & (1 << 1));//等待握手信号完成*///IPG_CLK_ROOT=66MHz    CCM->CBCDR &= ~(3 << 8);    CCM->CBCDR |= (1 << 8);//IPG_CLK_ROOT=AHB_CLK_ROOT=132/2=66MHz//PER_CLK_ROOT=66MHz    CCM->CSCMR1 &= ~(1 << 6);//PER_CLK_ROOT时钟源为IPG_CLK_ROOT=66MHz    CCM->CSCMR1 &= ~(0X3f << 0);//1分频,PER_CLK_ROOT=66MHz}
.global _start.global _bss_start_bss_start:    .word _bss_start.global _bss_end_bss_end:    .word _bss_end_start:    ldr pc, =Reset_Handler/*复位中断服务函数 */    ldr pc, =Undefined_Handler/*未定义指令中断服务函数 */    ldr pc, =SVC_Hander/*SVC */    ldr pc, =PreAbort_Handler/*预取终止 */    ldr pc, =DataAbort_Handler/*数据终止 */    ldr pc, =NotUsed_Handler/*未使用 */    ldr pc, =IRQ_Handler/*IRQ中断 */    ldr pc, =FIQ_Handler/*FIQ中断 *//*复位中断服务函数 */Reset_Handler:    cpsid i /*关闭IRQ *//*关闭I/D cache和MMU      *修改SCTLR寄存器,采用读-改-写的方式     */    MRC p15, 0, r0, c1, c0, 0/*读取SCTLR寄存器的数据到r0寄存器里面 */    bic r0, r0, #(1 << 12) /*关闭Icache */    bic r0, r0, #(1 << 11) /*关闭分支预测 */    bic r0, r0, #(1 << 2 ) /*关闭Dcache */    bic r0, r0, #(1 << 1 ) /*关闭对齐 */    bic r0, r0, #(1 << 0 ) /*关闭MMU */     MCR p15, 0, r0, c1, c0, 0/*将r0寄存器里面的数据写入到SCTLR里面 *//*设置中断向量偏移 */    ldr r0, =0x87800000    dsb/*数据同步 */    isb/*指令同步 */    MCR p15, 0, r0, c12, c0, 0/*设置VBAR寄存器=0x87800000 */    dsb    isb/*清除BSS段 */    ldr r0, _bss_start    ldr r1, _bss_end    mov r2, #0bss_loop:    stmia r0!, {r2}    cmp r0, r1/* 比较R0和R1里面的值*/    ble bss_loop/* 如果R0地址小于等于R1,继续清除BSS段*//*设置处理器进入IRQ模式 */    mrs r0, cpsr /*读取cpsr到r0 */    bic r0, r0, #0x1f/*清除cpsr的bit4-0*/    orr r0, r0, #0x12/*使用IRQ模式*/    msr cpsr, r0 /*将r0写入到cpsr */    ldr sp, =0x80600000/*设置SP指针 *//*设置处理器进入SYS模式 */    mrs r0, cpsr /*读取cpsr到r0 */    bic r0, r0, #0x1f/*清除cpsr的bit4-0*/    orr r0, r0, #0x1f/*使用SYS模式*/    msr cpsr, r0 /*将r0写入到cpsr */    ldr sp, =0x80400000/*设置SP指针 *//*设置处理器进入SVC模式 */    mrs r0, cpsr /*读取cpsr到r0 */    bic r0, r0, #0x1f/*清除cpsr的bit4-0*/    orr r0, r0, #0x13/*使用SVC模式*/    msr cpsr, r0 /*将r0写入到cpsr */    ldr sp, =0x80200000/*设置SP指针 */    cpsie i /*打开IRQ */    b main /*跳转到C语言main函数 *//*未定义指令中断服务函数 */Undefined_Handler:    ldr r0, =Undefined_Handler    bx r0 /*SVC中断服务函数 */SVC_Hander:    ldr r0, =SVC_Hander    bx r0 /*预取终止中断服务函数 */PreAbort_Handler:    ldr r0, =PreAbort_Handler    bx r0 /*数据终止中断服务函数 */DataAbort_Handler:    ldr r0, =DataAbort_Handler    bx r0 /*未使用中断 */NotUsed_Handler:    ldr r0, =NotUsed_Handler    bx r0 /*IRQ中断服务函数 */IRQ_Handler:  push {lr} /* 保存lr地址 */  push {r0-r3, r12} /* 保存r0-r3,r12寄存器 */  mrs r0, spsr /* 读取spsr寄存器 */  push {r0} /* 保存spsr寄存器 */  mrc p15, 4, r1, c15, c0, 0/* 从CP15的C0寄存器内的值到R1寄存器中                * 参考文档ARM Cortex-A(armV7)编程手册V4.0.pdf P49                * Cortex-A7 Technical ReferenceManua.pdf P68 P138                */add r1, r1, #0X2000 /* GIC基地址加0X2000,也就是GIC的CPU接口端基地址 */  ldr r0, [r1, #0XC] /* GIC的CPU接口端基地址加0X0C就是GICC_IAR寄存器,                 * GICC_IAR寄存器保存这当前发生中断的中断号,我们要根据                 * 这个中断号来绝对调用哪个中断服务函数                 */  push {r0, r1} /* 保存r0,r1 */  cps #0x13 /* 进入SVC模式,允许其他中断再次进去 */  push {lr} /* 保存SVC模式的lr寄存器 */  ldr r2, =system_irqhandler /* 加载C语言中断处理函数到r2寄存器中*/  blx r2 /* 运行C语言中断处理函数,带有一个参数,保存在R0寄存器中 */  pop {lr} /* 执行完C语言中断服务函数,lr出栈 */  cps #0x12 /* 进入IRQ模式 */  pop {r0, r1}   str r0, [r1, #0X10] /* 中断执行完成,写EOIR */  pop {r0}   msr spsr_cxsf, r0 /* 恢复spsr */  pop {r0-r3, r12} /* r0-r3,r12出栈 */  pop {lr} /* lr出栈 */  subs pc, lr, #4 /* 将lr-4赋给pc *//*FIQ中断服务函数 */FIQ_Handler:    ldr r0, =FIQ_Handler    bx r0

关键汇编指令详解表

最新文章

随机文章