分成BL1BL2后为什么printf不能输出变量的结果,可以输出字符串?

在学习嵌入式程序时,编写一个倒计数自启动命令的过程中,使用了wdt定时器中断isr_wdt,由于原来编写的程序bin大于16KB,故分成了BL1和BL2两部分代码,IRQ_handle:部分的代码放在了BL2的start.S的尾部。代码如下:

#define WTCON        0xE2700000

#define SVC_STACK    0xd0037d80    //ARM的栈是满减栈,所以从高位地址开始
#define IRQ_STACK   0XD0037f80    //ARM的栈是满减栈,所以从高位地址开始

.global _start                    // 把_start链接属性改为外部,这样其他文件就可以看见_start了
.global IRQ_handle
_start:
    // 第1步:关看门狗(向WTCON的bit5写入0即可)
    ldr r0, =WTCON
    ldr r1, =0x0
    str r1, [r0]
    
    // 第2步:初始化时钟
    bl clock_init
    
    // 第3步:设置SVC栈
    ldr sp, =SVC_STACK
    
    // 第4步:开/关icache
    mrc p15,0,r0,c1,c0,0;            // 读出cp15的c1到r0中
    //bic r0, r0, #(1<<12)            // bit12 置0  关icache
    orr r0, r0, #(1<<12)            // bit12 置1  开icache
    mcr p15,0,r0,c1,c0,0;

    
    bl main
    
    
    // 从这里之后就可以开始调用C程序了
    //bl led_blink                    // led_blink是C语言实现的一个函数
    
// 汇编最后的这个死循环不能丢
    b .
    

    
    
    
    //在这个汇编函数中,用来做中断irq模式下的现场保护和恢复,并且调用真正的中断处理程序    
IRQ_handle:
    //设置IRQ下的栈
    ldr sp, =IRQ_STACK
    //保存LR(暂存返回地址的)

    //因为有流水线,在中断来临时(此时地址为a),返回地址应该是在当前指令的下一条指令地址为a+4,
    //但是PC此时指向的是返回地址(地址为a+4)的下一条指令(此时地址为a+8),
    //所以PC的值会比真正的执行的代码地址(地址为a)多8个字节,这就是流水线的效果。
    sub lr, lr, #4


    //保存r0~r12和lr到irq模式下的栈里面去
    stmfd sp!, {r0-r12, lr}
    
    //接着调用真正的中断处理程序isr的函数(此函数在int.c中的void irq_handler(void))来处理中断,
    bl irq_handler
    
    //上面的中断处理完成后,接着来恢复处理现场,其实就是做中断返回,关键是将r0-r12, pc, cpsr一起恢复

    ldmfd sp!, {r0-r12, pc}^

在main函数中使用了printf 函数,但是不能输出变量的结果:

int g_bootdelay = 3;    
int main(void)
{
    
    shell_init();//所有初始化(包括绑定中断、使能中断等)
    
    // 自动倒数执行默认命令
    // 在这里等待用户按按键,如果没按就倒计时,如果按了就结束倒计时和自动执行直接
    // 进入shell死循环。如果一直没按按键时间到了也进入shell死循环
    puts("aston#");
    printf("%d", g_bootdelay);   //此句不能输出3,输出只是一个%.
/*
    while ((!g_isgo) && (!is_key_press()));
    //while (!((g_isgo) || (is_key_press())));
    
    intc_disable(NUM_WDT);
    // 也可以在这里通过判断g_isgo的值来判断是不是倒数结束,执行自动命令
    if (g_isgo)
    {
        lcd_test();
    }

    // 执行shell死循环
    shell_loop();
    
*/    
    //while(1)
        
    return 0;
}


// wdt的中断处理程序
void isr_wdt(void)
{
    static int i = 0;
    // 看门狗定时器时间到了时候应该做的有意义的事情
    printf("wdt interrupt, i = %d...\n", i++);  //此句也不能输出,输出结果是:%
    // 计时,然后时间没到的时候在屏幕上打印倒数计数,时间到了自动执行命令
    // 执行完命令进入shell的死循环
    //puts("aston#");
    //g_bootdelay--;
    //putchar('\b');
    printf("%d", g_bootdelay);    //此句也不能输出,输出结果是:%
/*
    if (g_bootdelay == 0)
    {
        g_isgo = 1;
        
        // 把要自动执行的命令添加到这里,但是这里是中断处理程序,不适合执行长代码
        // 所以放在外面要好一些
        
        //printf("g_isgo = 1.\n");
        // 关闭wdt
        //intc_disable(NUM_WDT);
    }
*/
    // 清中断
    intc_clearvectaddr();
    rWTCLRINT = 1;
}

为什么在没有分成BL1和BL2的情况下,也在使用此中断函数 isr_wdt()的里面和main函数里使用printf函数时输出结果正常,而当在有BL1和BL2的情况下,也使用此中断isr_wdt的里面和main函数里使用printf函数时输出结果就不正常呢?出现不正常的结果是不是BL1和BL2的内容没有调整对(IRQ_handle:是不是放在BL1的start.S中的尾部?),网上好多帖子说中断里不能使用printf函数,但是我的分成BL1和BL2的时候程序中,中断里使用printf函数都正常着呢?

哪位朋友给予指点!不胜感激!


 

猜你喜欢

转载自blog.csdn.net/weixin_41632560/article/details/83346124