自制处理器OpenMIPS移植ucos-II过程之5——修改ucos-II源代码

好了我们前面已经建立了移植ucos-II所需的目录,很整齐是吧,现在开始了移植中艰难的一段旅程,需要修改ucos-II的部分代码,主要是port目录下的,这个目录下的文件才是和移植有关的,要修改这么几个方面:
  1. 去掉与MIPS M14K特点有关的代码。
  2. 将一些MIPS M14K具有的指令,而OpenMIPS没有的指令,使用OpenMIPS的指令替换,比如:di指令,该指令的作用是禁止中断,但是OpenMIPS没有实现该指令,所以要使用其余方法替换该指令。
  3. 由于OpenMIPS采用的是向量中断模式,所以对代码的布局会有新的要求,一些多余的section声明会去掉,同时设置从0x0地址开始是vector section,也就是异常向量中断section。
  4. 添加中断处理函数、异常处理函数。
       现在,小伙伴们,准备好了吗,Ready?Go!

       第一步:修改include/cpu.h,去掉如下代码,这两个文件是没有的,可能针对MIPS M14K处理器的有这两个文件:
#include  <cpu_def.h>
#include  <cpu_cfg.h>

       第二步:修改port/cpu_a.s,其中的di指令是MIPSr2的指令,该指令的作用是禁止中断,在OpenMIPS中没有实现该指令,需要修改,去掉di指令,使用如下代替:
    ori   $2,$2,0x0
    mfco  $2,0xc($0)
    addi  $3,$0,0xfffe
    and   $3,$2,$3
    mtco  $3,0xc($0)
       作用是修改status寄存器的最低bit,使其为0以禁止中断。

       第三步:修改port/os_cpu_a.S,去掉如下代码:
    .section .text,"ax",@progbits
    .set noreorder
    .set noat
       在OSStartHighRdy()函数之前添加如下代码,小伙伴们很容易可以看出这是异常向量入口区域,0x0地址是复位异常处理地址,0x20是中断处理地址,0x40是其余异常处理地址:
/* 添加下面的stack section  */
        .section .stack, "aw", @nobits
.space  0x10000

/* 添加下面的异常向量处理区域  */
        .section .vectors, "ax"
  .org 0x0
_reset:
  lui $28,0x0
  la $29,_stack_addr
la $26,main                /* 寄存器$26、$27留给中断、异常的处理程序使用 */
  jr $26
  nop

   .org 0x20             /* 中断处理例程入口地址 */
la $26,InterruptHandler
jr $26
nop

   .org 0x40            /* 异常处理例程入口地址 */
la $26,ExceptionHandler
jr $26
nop

    /* 下面的是text段,可执行 */
    .section .text,"ax",@progbits    
    .set noreorder
    .set noat

       第四步:修改port/os_cpu_a.S,去掉OSStartHighRdy函数的第2-6条指令,这几条指令是与新的MIPS ISA(MIPS M14K采用的就是新的MIPS ISA)有关的,OpenMIPS不需要这些代码,如下:
    addu  $9,  $31, $0   /* Mask off the ISAMode bit   */
    srl   $9,  16
    andi  $31, 0xFFFE
    sll   $9,  16
    addu  $31, $31, $9
       去掉OSStartHighRdy函数的倒数第三条指令,即ei指令,该指令的作用是使能中断,OpenMIPS采取的策略是恢复下一个Task的中断状态,所以此处不用刻意使能中断,如下:
ei

       第五步:修改port/os_cpu_a.S,去掉OSIntCtxSw函数的第2-6条指令,理由同第四步一样,如下:
    addu  $9,  $31, $0 /* Mask off the ISAMode bit  */
    srl   $9,  16
    andi  $31, 0xFFFE
    sll   $9,  16
    addu  $31, $31, $9
       去掉OSIntCtxSw函数的倒数第二条指令,即ei指令,如下:
    ei
       这是和第四步一样的。

       第六步:修改port/os_cpu_a.S,修改OS_CPU_SR_Save函数,原函数如下:
    .ent OS_CPU_SR_Save
OS_CPU_SR_Save:
    jr    $31
    di    $2          /* Disable interrupts, and move the old value of the... */
                      /* ...Status register into v0 ($2)                      */
    .end OS_CPU_SR_Save
       修改为如下,主要还是替换掉di指令,这个中断禁止指令在MIPSr2指令集中才定义,OpenMISP不支持该指令:
    .ent OS_CPU_SR_Save
OS_CPU_SR_Save:
    /*将di指令使用下面5条MIPS32中定义的指令代替  */
    ori   $2,$2,0x0
    mfc0  $2,$12,0
    addi  $3,$0,0xfffe
    and   $3,$2,$3
    mtc0  $3,$12,0
    jr    $31
    nop
.end OS_CPU_SR_Save

       第七步:修改port/os_cpu_a.S,去掉对timer_handler这个section的定义,OpenMIPS采用的向量中断方式,所以不再单独定义timer_handler这个section,如下,去掉该代码:
.section .timer_handler,"ax",@progbits

       第八步:修改port/os_cpu_a.S,修改其中InterruptHandler函数,去掉其第一条di指令,这条指令的作用是禁止中断,但是当OpenMIPS进入中断处理函数InterruptHandler时,已经由硬件禁止中断了,不需要多此一步,而且di指令也不是OpenMIPS支持的指令。
       还要去掉InterruptHandler函数中的如下代码,共出现两次,都要去掉,这几条指令是与新的MIPS ISA(MIPS M14K采用的就是新的MIPS ISA)有关的,OpenMIPS不需要这些代码:
    addu  $9,  $31, $0  /* Mask off the ISAMode bit     */
    srl   $9,  16
    andi  $31, 0xFFFE
    sll   $9,  16
    addu  $31, $31, $9
       去掉InterruptHandler函数倒数第二条指令,即去掉如下代码,理由同第四步一样:
    ei           /* Enable Interrupts       */

       第九步:修改port/os_cpu_a.S,去掉对gen_excpt这个section的定义,不需要该section,即去掉如下代码:
section .gen_excpt,"ax",@progbits

       第十步:修改port/os_cpu_a.S,去掉ExceptionHandler函数的第一条指令,即di指令,这条指令的作用是禁止中断,但是当OpenMIPS进入异常处理函数ExceptionHandler时,已经由硬件禁止中断了,不需要多这一步,而且di指令也不是OpenMIPS支持的指令:
       还要去掉ExceptionHandler函数中的如下代码,这几条指令是与新的MIPS ISA(MIPS M14K采用的就是新的MIPS ISA)有关的,OpenMIPS不需要这些代码:
    addu  $9,  $31, $0  /* Mask off the ISAMode bit     */
    srl   $9,  16
    andi  $31, 0xFFFE
    sll   $9,  16
    addu  $31, $31, $9
       去掉ExceptionHandler函数倒数第二条指令,即去掉如下代码,理由同第四步一样::
    ei           /* Enable Interrupts       */

       第十一步:修改TickISR函数,增加对$8、$9寄存器压栈、出栈的过程,因为在TickISR中使用到了$8、$9寄存器的值,所以要将其先保存到堆栈中,然后再使用,TickISR结束之前,将其从堆栈恢复,如下:
    .ent TickISR
TickISR:
    addiu $29,$29,-24    /* $29中存放的是堆栈指针 */
    sw $16, 0x4($29)     /*  压栈  */
    sw $8, 0x8($29)      /*  压栈  */

……
    
    lw $16, 0x4($29)     /*  出栈  */
    lw $8, 0x8($29)      /*  出栈  */
    addiu $29,$29,24
    jr    $31
    nop
.end TickISR
       去掉TickISR函数中的如下代码,这几条指令是与新的MIPS ISA(MIPS M14K采用的就是新的MIPS ISA)有关的,OpenMIPS不需要这些代码:
    addu  $9,  $31, $0  /* Mask off the ISAMode bit     */
    srl   $9,  16
    andi  $31, 0xFFFE
    sll   $9,  16
    addu  $31, $31, $9

       第十二步:修改port/ os_cpu_c.c文件,去掉开始的如下代码,这两个宏定义没有作用:
extern char vec[], endvec[];  /* Create the hardware interrupt vector      */
asm (".set push\n"
     ".set nomicromips\n"
     ".align 2\n"
     "vec:\n"
     "\tla  $26,InterruptHandler\n"
     "\tjr  $26\n"
     "endvec:\n"
     ".set pop\n");

extern char vec2[], endvec2[]; /* Create the exception vector              */
asm (".set push\n"
     ".set nomicromips\n"
     ".align 2\n"
     "vec2:\n"
     "\tla  $26,ExceptionHandler\n"
     "\tjr  $26\n"
     "endvec2:\n"
     ".set pop\n");

       第十二步:修改port/ os_cpu_c.c文件,将OSInitHookBegin函数的内容清空,如下:
void  OSInitHookBegin (void)
{
}

       第十三步:修改port/ os_cpu_c.c文件,修改OSTaskStkInit函数,将其中的如下代码:
sr_val  |= 0x0000C001; /* Initialize stack to allow for tick interrupt  */
       改为:
sr_val  |= 0x0000C401;  /* Initialize stack to allow for tick interrupt  */
       因为在OpenMIPS中,时钟中断对应的是外部中断2。

       第十四步:修改port/ os_cpu_c.c文件,添加中断处理函数,如下,首先得到CP0中Cause寄存器的值,然后判断是否是时钟中断引起的,也就是判断第10bit的值是否为1,如果是时钟中断,那么调用TickISR,该函数是时钟中断处理函数,最后清除Cause寄存器的时钟中断表示位,也就是第10bit为0。
void  BSP_Interrupt_Handler (void)
{
    INT32U   cause_val;
    INT32U   cause_reg;
    INT32U   cause_ip;
    asm ("mfc0   %0,$13"   : "=r"(cause_val));
    cause_reg  = cause_val;                     /* 得到Exc Code        */
    cause_ip = cause_reg & 0x0000FF00;
    if((cause_ip & 0x00000400) != 0 )
    {
        TickISR(0x0);
        asm ("mfc0   %0,$13"   : "=r"(cause_val));
        cause_val = cause_val & 0xfffffbff;
        asm volatile("mtc0   %0,$13" : : "r"(cause_val));
    }
}

       第十五步:修改port/ os_cpu_c.c文件,添加异常处理函数,如下,首先得到CP0中Cause寄存器的值,然后分别判断是否由syscall指令、自陷指令、无效指令引起的,此处不对这些异常进行处理,只是简单地调用OSIntCtxSw函数,进行Task切换。
void  BSP_Exception_Handler (void)
{
    INT32U   cause_val;
    INT32U   cause_exccode;
    INT32U   EPC;
    asm volatile("mfc0   %0,$13"   : "=r"(cause_val));
    cause_exccode  = (cause_val & 0x0000007C);   /* 得到Exc Code        */
    if(cause_exccode == 0x00000020 )   /* 判断是否是由于syscall指令引起 */
    {
    OSIntCtxSw();                                           
    }
    else if(cause_exccode == 0x00000034) /* 判断是否是由于Txx指令引起 */
    {
    OSIntCtxSw();
    }
    else if(cause_exccode == 0x00000028)  
    /* 判断是否是由于invalid instruction引起 */
    {
    asm volatile("mfc0   %0,$14"   : "=r"(EPC));
    } 
}

       好了,要修改代码就这些,下一步就可以建立Makefile了。
       未完待续!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值