经过前面三步的准备,想必大家对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_TEMT0x40/* Transmitter empty */
#define UART_LS_THRE0x20/* Transmit-hold-register empty */
/* Line Control Register的标志位 */
#define UART_LC_NO_PARITY0x00/* Parity Disable */
#define UART_LC_ONE_STOP0x00/* 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目录下。
如此,我们的文件目录就建立好了,最终的效果如下:
论坛中提供了最终的移植版本,所以小伙伴们先不要着急下载上面提到的所需文件,先读完文章,然后点击页面下方的鲜花,接着在论坛中找到移植后的版本就可以了。