自制处理器OpenMIPS移植ucos-II过程之4——ucos-II文件目录建立

 经过前面三步的准备,想必大家对OpenMIPS已经有所了解了,甚至有的小朋友可能已经会使用了(如果真是这样……,啥也别说了,感动的想哭),从本文开始就正式进入ucos-II的移植部分了,本文介绍ucos-II文件目录的建立。
       我们的移植思路是:充分借鉴已有的移植经验。
       经过搜索,发现目前比较接近的是将ucos-II移植到MIPS M14K,就这个了。另外还借鉴了ucos-II移植到OR1200的过程,主要是借鉴了其Makefile的组织方式。

       第一步:从http://micrium.com/downloadcenter/download-results/?searchterm=hm-mips&supported=true下载针对MIPS M14K的ucos-II移植代码,版本是v2.90

       第二步:从http://micrium.com/downloadcenter/micrium-source-code/下载ucos-II源代码,版本是v2.91

       第三步:在Ubuntu中新建文件夹ucos,将ucos-II源代码的文件复制到该文件夹下。

       第四步:新建文件夹port,将针对MIPS M14K的ucos-II移植代码(除了cpu.h、os_cpu.h两个头文件)复制到该文件夹下。

       第五步:新建文件夹include,将ucos-II源代码的文件夹下ucos_ii.h、os_cfg_r.h两个头文件,以及针对MIPS M14K的μC/OS-II移植代码中的cpu.h、os_cpu.h两个头文件,一共四个头文件复制到该文件夹下。并将其中的os_cfg_r.h重命名为os_cfg.h,注意:在重命名前需要去掉该文件的只读属性,否则无法重命名。

       第六步:新建一个common文件夹。其中存放测试用的主任务。现在新建一个测试使用的主任务文件,起名为openmips.c,其中包含main函数,将该文件保存在common文件夹下,这个主任务很简单,在main函数中新建了一个Task,名字叫TaskStart,在这个TaskStart中初始化串口、GPIO,然后通过串口输出一个字符串的两个字节(一个汉子对应两个字节),同时GPIO的输出加2,然后等待100ms,再输出这个字符串的下两个字节,直到字符串输出完毕。其主要内容如下:

/*             要输出的字符串,这是一段汉字的编码    */
char Info[103]={0xC9,0xCF,0xB5,0xDB,0xCB,0xB5,0xD2,0xAA,0xD3,0xD0,0xB9,0xE2,0xA3,0xAC,0xD3,0xDA,0xCA,0xC7,0xBE,0xCD,0xD3,0xD0,0xC1,0xCB,0xB9,0xE2,0x0D,0x0A,0xC9,0xCF,0xB5,0xDB,0xCB,0xB5,0xD2,0xAA,0xD3,0xD0,0xCC,0xEC,0xBF,0xD5,0xA3,0xAC,0xD3,0xDA,0xCA,0xC7,0xBE,0xCD,0xD3,0xD0,0xC1,0xCB,0xCC,0xEC,0xBF,0xD5,0x0D,0x0A,0xC9,0xCF,0xB5,0xDB,0xCB,0xB5,0xD2,0xAA,0xD3,0xD0,0xC2,0xBD,0xB5,0xD8,0xBA,0xCD,0xBA,0xA3,0xD1,0xF3,0xA3,0xAC,0xD3,0xDA,0xCA,0xC7,0xBE,0xCD,0xD3,0xD0,0xC1,0xCB,0xC2,0xBD,0xB5,0xD8,0xBA,0xCD,0xBA,0xA3,0xD1,0xF3,0x0D};

/*                 串口初始化函数                   */
void uart_init(void)
{
        INT32U divisor;
        /* 依据希望的波特率,设置分频器的值,我们在上一篇文章中介绍过了 */
  divisor = (INT32U) IN_CLK/(16 * UART_BAUD_RATE);
        REG8(UART_BASE + UART_LC_REG) = 0x80;
        REG8(UART_BASE + UART_DLB1_REG) = divisor & 0x000000ff;
        REG8(UART_BASE + UART_DLB2_REG) = (divisor >> 8) & 0x000000ff;
        REG8(UART_BASE + UART_LC_REG) = 0x00;
        
        /* 禁止串口中断 */
        REG8(UART_BASE + UART_IE_REG) = 0x00;
       
        /* 设置串口信息格式,8bit数据,没有奇偶校验位,1位停止位 */
        REG8(UART_BASE + UART_LC_REG) = UART_LC_WLEN8 | (UART_LC_ONE_STOP | UART_LC_NO_PARITY);
        
        /* 通过串口输出初始化完毕信息 */
        uart_print_str("UART initialize done ! \n");
return;
}

/*                 通过串口输出字节的函数                   */
void uart_putc(char c)
{
        unsigned char lsr;
        WAIT_FOR_THRE;               /* 这是一个宏定义,参考完整的openmips.c */
        REG8(UART_BASE + UART_TH_REG) = c;
        if(c == '\n') {
          WAIT_FOR_THRE;
          REG8(UART_BASE + UART_TH_REG) = '\r';
        }
        WAIT_FOR_XMITR;   /* 这是一个宏定义,参考完整的openmips.c */
}

/*                 通过串口输出字符串的函数                   */
void uart_print_str(char* str)
{
       INT32U i=0;
       OS_CPU_SR cpu_sr;
       OS_ENTER_CRITICAL()
       
       while(str[i]!=0)
       {
        uart_putc(str[i]);
        i++;
       }
        
       OS_EXIT_CRITICAL()
        
}

/*                 GPIO初始化的函数                   */
void gpio_init()
{
REG32(GPIO_BASE + GPIO_OE_REG) = 0xffffffff;
REG32(GPIO_BASE + GPIO_INTE_REG) = 0x00000000;
gpio_out(0x0f0f0f0f);
uart_print_str("GPIO initialize done ! \n");
}

/*                 设置GPIO输出的函数                   */
void gpio_out(INT32U number)
{
OS_CPU_SR cpu_sr;
     OS_ENTER_CRITICAL()
REG32(GPIO_BASE + GPIO_OUT_REG) = number;
OS_EXIT_CRITICAL()
}

/*                 读取GPIO输入的函数                   */
INT32U gpio_in()
{
INT32U temp = 0;
OS_CPU_SR cpu_sr;
OS_ENTER_CRITICAL()
temp = REG32(GPIO_BASE + GPIO_IN_REG);
 
OS_EXIT_CRITICAL()
return temp;
}

/*             设置compare寄存器,以使能时钟中断            */
void OSInitTick(void)
{
    INT32U compare = (INT32U)(IN_CLK / OS_TICKS_PER_SEC);
    
    asm volatile("mtc0   %0,$11"   : :"r"(compare));  
    asm volatile("mtc0   %0,$12"   : :"r"(0x10000401));
    uart_print_str("OSInitTick Done!!!\n");
    
    return; 
}

/*                   主任务TaskStart                  */
void  TaskStart (void *pdata)
{
    INT32U count = 0;
    pdata = pdata;            /* Prevent compiler warning                 */
    OSInitTick();      /* don't put this function in main()        */       
    for (;;) {
       if(count <= 102)
    {
         uart_putc(Info[count]);
         uart_putc(Info[count+1]);
        }
        gpio_out(count);
        count=count+2;
        OSTimeDly(10);  /* Wait 100ms                   */
    }
}

/*                         main函数                        */
void main()
{
  OSInit();
  uart_init();
  gpio_init();
  OSTaskCreate(TaskStart, 
      (void *)0, 
      &TaskStartStk[TASK_STK_SIZE - 1], 
      0);
  
  OSStart();  
}

       第七步:在include文件夹下添加openmips.h文件,其中定义了openmips.c中使用到的一些宏定义,如下:

#define REG8(add) *((volatile INT8U *)(add))
#define REG16(add) *((volatile INT16U *)(add))
#define REG32(add) *((volatile INT32U *)(add))

#define IN_CLK 27000000             /* 输入时钟是27MHz */

/*                        串口相关参数、函数               */ 

#define UART_BAUD_RATE  9600          /* 串口速率是9600bps */
#define UART_BASE      0x10000000
#define UART_LC_REG    0x00000003    /* Line Control Register */
#define UART_IE_REG     0x00000001    /* Interrupt Enable Register */
#define UART_TH_REG    0x00000000    /* Transmitter Holding Register */
#define UART_LS_REG     0x00000005    /* Line Status Register */
#define UART_DLB1_REG   0x00000000    /* Divisor Latch Byte 1(LSB) */
#define UART_DLB2_REG   0x00000001    /* Divisor Latch Byte 2(MSB) */

/* Line Status Register的标志位 */
#define UART_LS_TEMT 0x40 /* Transmitter empty */
#define UART_LS_THRE 0x20 /* Transmit-hold-register empty */

/* Line Control Register的标志位 */
#define UART_LC_NO_PARITY 0x00 /* Parity Disable */
#define UART_LC_ONE_STOP 0x00 /* Stop bits: 0x00表示one stop bit */
#define UART_LC_WLEN8  0x03 /* Wordlength: 8 bits */

extern void uart_init(void);
extern void uart_putc(char);
extern void uart_print_str(char*);
extern void uart_print_int(unsigned int);

/*                     GPIO相关参数、函数                         */     
#define GPIO_BASE 0x20000000
#define GPIO_IN_REG  0x00000000
#define GPIO_OUT_REG  0x00000004
#define GPIO_OE_REG  0x00000008
#define GPIO_INTE_REG 0x0000000c

extern void gpio_init(void);
extern void gpio_out(INT32U);
extern INT32U gpio_in(void);
extern void main(void);

       第八步:在include目录下新建文件include.h,内容如下:

#include
#include
#include

#include "ucos_ii.h"
#include "openmips.h"

       第九步:下载OR1200的源文件,可以在OpenCores上下载,找到trunk\rtos\ucos-ii\2.91\common目录下的app_cfg.h文件,将其复制到我们在上面建立的include目录下。

       如此,我们的文件目录就建立好了,最终的效果如下:

自制处理器OpenMIPS移植ucos-II过程之4——ucos-II文件目录建立_第1张图片


       http://bbs.eetop.cn/forum-257-1.html中提供了最终的移植版本,所以小伙伴们先不要着急下载上面提到的所需文件,先读完文章,接着在论坛中找到移植后的版本就可以了。

你可能感兴趣的:(自己动手写CPU)