资源描述
嵌入式ARM+
μC/OS-II
大连理工大学软件学院嵌入式教研室
2010年11月
1. 题目要求
一、Uc/Os任务间通信机制(信号量——生产者消费者)
实验目的:
采用生产者和消费者之间的关系来练习多任务请求之间的消息传递和同步的工作过程。
实验要求:
试利用uc/os提供的通信机制,设计一个简单的应用程序,实现基本的生产者消费者程序。
二. Uc/Os内存管理——内存块分配
实验目的:
为了了解内存分区变化的情况,编写代码来观察分区头指针和已被使用内存块的个数
实验要求:
试设计一个有3个任务的应用程序,这3个任务分别是MyTask,YouTask和HerTask。在应用程序中创建一个动态内存分区,该分区有8个内存块,每个内存块的长度为6字节。应用程序的任务YouTask和HerTask都在任务运行后请求一个内存块,随后就释放它;任务MyTask也在任务运行后请求一个内存块,但是要在任务MyTask运行6次后,才释放它所申请的内存块。
我们给出了PC环境下的示意代码,要求改造成44B0下,并调试成功。
uCOS-II任务间通信和内存管理实验
任务通信和内存管理工程实践
使用Embest IDE for ARM 开发环境,建立工程名为ucos-ii_test1,并在些工程下建立四个文件夹:ucos_source,ucos_include,ucos_port,44b0_source,
44b0_include,main,misc文件夹。
在ucos_source中添加os_core.c,os_dbg_r.c,os_flag.c,os_mbox.c,os_mem.c,
os_mutex.c,os_q.c,os_sem.c,os_task.c,os_time.cucos_ii.c11个内核源文件;
在ucos_include中添加includes.h,os_cfg.h,os_cpu.h,ucos_ii.h4个头文件;
在ucos_port中添加os_cpu_a.s,os_cpu_c.c两个与硬件相关的文件;
在44b0_source中添加44binit.s,44blib.c,uhal.c三个代码文件
在44b0_include中添加44b.h,44blib.h,def.h,memcfg.a,option.a,option.h,uhal.h七个头文件;
在main中添加irq.s,main.c 2个代码文件
在main中添加命令脚本文件ev40boot.cs的链接脚本文件ram_ice.ld文件
图1-1 建立工程文件夹
在主函数中编写:
/**************************************************************************
* 文件名: main.c 给出的是参考代码,里面需要调试的部分很多,大家需要自己调试纠错出来。
* 功能: 任务通信工程实践主函数
* 说明:Embest S3C2410实验平台,Embest ARM标准/增强型仿真器套件。
**************************************************************************/
#include "\software\ucos-ii\ex1_x86l\bc45\source\includes.h"
#define TASK_STK_SIZE 512 /* Size of each task's stacks (# of WORDs) */
#define N_TASKS 10 /* Number of identical tasks */
OS_EVENT* pCommMbox;
INT16U msg;
INT8U colorFlag;
OS_STK TaskStk[N_TASKS][TASK_STK_SIZE]; /* Tasksstacks */
OS_STK TaskStartStk[TASK_STK_SIZE];
void SendTask();
void AcceptTask();
/*
*********************************************************************************************************
* MAIN
*********************************************************************************************************
*/
void main (void)
{
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); /* Clear the screen */
OSInit(); /* Initialize uC/OS-II */
PC_DOSSaveReturn(); /* Save environment to return to DOS */
PC_VectSet(uCOS, OSCtxSw);
/* Install uC/OS-II's context switch vector */
colorFlag = 0;
pCommMbox = OSMboxCreate((void*)0);
OSTaskCreate(SendTask, (void *)0, &TaskStk[1][TASK_STK_SIZE - 1], 1 );
OSStart();
}
/*
*********************************************************************************************************
* STARTUP TASK
*********************************************************************************************************
*/
void SendTask()
{
#if OS_CRITICAL_METHOD == 2 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT8U err;
OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR); /* Install uC/OS-II's clock tick ISR */
PC_SetTickRate(OS_TICKS_PER_SEC); /* Reprogram tick rate */
OS_EXIT_CRITICAL();
OSStatInit(); /* Initialize uC/OS-II's statistics */
OSTaskCreate(AcceptTask, (void *)0, &TaskStk[2][TASK_STK_SIZE - 1], 2 );
PC_DispStr(1, 1, "SendTask has been Started!", DISP_FGND_YELLOW + DISP_BGND_RED);
for (;;)
{
if (PC_GetKey(&msg) == TRUE)
{
colorFlag++;
if(colorFlag % 2 == 0)
{
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);
PC_DispStr(1, 1, "SendTask has been Started!", DISP_FGND_YELLOW + DISP_BGND_RED);
PC_DispStr(1, 3, "AcceptTask has been Started!", DISP_FGND_YELLOW + DISP_BGND_RED);
err = OSMboxPost(pCommMbox, (void *)&msg);
PC_DispStr(1, 5, "SendTask send a message to AcceptTask!", DISP_FGND_YELLOW + DISP_BGND_RED);
}
else
{
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);
PC_DispStr(1, 1, "SendTask has been Started!", DISP_FGND_RED + DISP_BGND_BLACK);
PC_DispStr(1, 3, "AcceptTask has been Started!", DISP_FGND_RED + DISP_BGND_BLACK);
err = OSMboxPost(pCommMbox, (void *)&msg);
PC_DispStr(1, 5, "SendTask send a message to AcceptTask!", DISP_FGND_RED + DISP_BGND_BLACK);
}
if (msg == 0x1B)
{
OSTimeDly(1000);
PC_DOSReturn();
}
}
OSCtxSwCtr = 0;
OSTimeDlyHMSM(0, 0, 1, 0);
}
}
/*
*********************************************************************************************************
* TASKS
*********************************************************************************************************
*/
void AcceptTask()
{
INT8U err;
void *message;
PC_DispStr(1, 3, "AcceptTask has been Started!", DISP_FGND_YELLOW + DISP_BGND_RED);
for(;;)
{
message = OSMboxPend(pCommMbox, 0, &err);
if(err == OS_NO_ERR)
{
if((*(INT16U *)message) == 0x1B)
{
if(colorFlag % 2 == 0)
{
PC_DispStr(1, 7, "the message AcceptTask had accepted is: quit", DISP_FGND_YELLOW + DISP_BGND_RED);
PC_DispStr(1, 8, "AcceptTask quit!", DISP_FGND_YELLOW + DISP_BGND_RED);
}
else
{
PC_DispStr(1, 7, "the message AcceptTask had accepted is: quit", DISP_FGND_RED + DISP_BGND_BLACK);
PC_DispStr(1, 8, "AcceptTask quit!", DISP_FGND_RED + DISP_BGND_BLACK);
}
break;
}
else if((*(INT16U *)message) == 13)
{
if(colorFlag % 2 == 0)
{
PC_DispStr(1, 7, "the message AcceptTask had accepted is: execute", DISP_FGND_YELLOW + DISP_BGND_RED);
PC_DispStr(1, 8, "execute: the AcceptTask is running!", DISP_FGND_YELLOW + DISP_BGND_RED);
}
else
{
PC_DispStr(1, 7, "the message AcceptTask had accepted is: execute", DISP_FGND_RED + DISP_BGND_BLACK);
PC_DispStr(1, 8, "execute: the AcceptTask is running!", DISP_FGND_RED + DISP_BGND_BLACK);
}
}
}
OSTimeDly(500);
}
}
/**************************************************************************
* 名称: target_init()
* 功能: 初始化ARM目标板
* 入口参数: 无
* 返回值: 无
* 说明:
**************************************************************************/
void target_init(void)
{
int i;
sys_init(); // Initial 44B0X's Interrupt,Port and UART
uart_printf("\n*==================================*\n");
uart_printf("*==================================*\n");
uart_printf("*= 大连理工大学软件学院 =*\n");
uart_printf("*==================================*\n");
uart_printf("*========== R&D CENTER ==========*\n");
uart_printf("*======= ucos ========*\n");
uart_printf("*===== wuguowei ======*\n");
uart_printf("*=== OS Version:%d ===*\n",OSVersion());
uart_printf("*==================================*\n");
uart_printf(" uCOS-II Running... \n") ;
uhal_init_interrupts();
uhal_init_timers();
} /* targetInit */
/**************************************************************************
* 名称: target_start()
* 功能: 启动ARM目标板
* 入口参数: 无
* 返回值: 无
* 说明:
**************************************************************************/
void target_start(void)
{
uhal_register_irq(HandlerTIMER0, (void *)TickHandler);
uhal_enable_int(BIT_TIMER0);
}
void Timer0Interrupt()
{
rI_ISPC = BIT_TIMER0;
OSTimeTick();
}
设置工程:
连接实验平台,打开超级终端,设置波特率115200,运行以上代码。
内存部分的参考代码(PC环境下的,要求改造为44B0的)
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <setjmp.h>
#include "\software\ucos-ii\ix86l\bc45\os_cpu.h"
#include "\software\ucos-ii\ex1_x86l\bc45\source\os_cfg.h"
#include "\software\ucos-ii\source\ucos_ii.h"
#include "\software\blocks\pc\bc45\pc.h"
/*
*********************************************************************************************************
* CONSTANTS
*********************************************************************************************************
*/
#define TASK_STK_SIZE 512 /* Size of each task's stacks (# of WORDs) */
#define N_TASKS 10 /* Number of identical tasks */
/*
*********************************************************************************************************
* VARIABLES
*********************************************************************************************************
*/
OS_STK TaskStk[N_TASKS][TASK_STK_SIZE]; /* Tasks stacks */
OS_STK TaskStartStk[TASK_STK_SIZE];
OS_MEM *CommMem,*pmem;
INT32U CommBuf[4][128];
void *CommMsg;
OS_MEM_DATA *pdata;
INT32U str1[80];
INT32U str2[80];
INT32U str3[80];
INT32U str4[80];
volatile INT8U i; /* Parameters to pass to each task */
volatile INT8U j;
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
void Task1(void *data);
void Task2(void *data);/* Function prototypes of tasks */
void Task3(void *data);
void TaskStart(void *data); /* Function prototypes of Startup task */
static void TaskStartCreateTasks(void);
static void TaskStartDispInit(void);
static void TaskStartDisp(void);
/*$PAGE*/
/*
*********************************************************************************************************
* MAIN
*********************************************************************************************************
*/
void main (void)
{
INT8U *err;
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); /* Clear the screen */
OSInit(); /* Initialize uC/OS-II */
CommMem = OSMemCreate(CommBuf, 4, 128, &err);
//CommMem 是指向内存控制块的指针
PC_DOSSaveReturn(); /* Save environment to return to DOS */
PC_VectSet(uCOS, OSCtxSw); /* Install uC/OS-II's context switch vector */
OSTaskCreate(TaskStart, (void *)0, &TaskStartStk[TASK_STK_SIZE - 1], 0);
OSStart(); /* Start multitasking */
}
/*
*********************************************************************************************************
* STARTUP TASK
*********************************************************************************************************
*/
void TaskStart (void *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
char s[100];
INT16S key;
pdata = pdata; /* Prevent compiler warning */
TaskStartDispInit(); /* Initialize the display */
OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR); /* Install uC/OS-II's clock tick ISR */
PC_SetTickRate(OS_TICKS_PER_SEC); /* Reprogram tick rate */
OS_EXIT_CRITICAL();
OSStatInit(); /* Initialize uC/OS-II's statistics */
TaskStartCreateTasks(); /* Create all the application tasks */
for (;;) {
TaskStartDisp(); /* Update the display */
if (PC_GetKey(&key) == TRUE) { /* See if key has been pressed */
if (key == 0x1B)
{ /* Yes, see if it's the ESCAPE key */
PC_DOSReturn(); /* Return to DOS */
}
}
OSCtxSwCtr = 0; /* Clear context switch counter */
OSTimeDlyHMSM(0, 0, 1, 0); /* Wait one second */
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* INITIALIZE THE DISPLAY
*********************************************************************************************************
*/
static void TaskStartDispInit (void)
{
PC_DispStr( 0, 0, " <-PRESS 'ESC' TO QUIT-> ", DISP_FGND_BLACK + DISP_BGND_LIGHT_GRAY + DISP_BLINK);
PC_DispStr( 20, 10, "Task1", DISP_FGND_LIGHT_GRAY+DISP_BGND_BLACK);
PC_DispStr( 50, 10, "Task2", DISP_FGND_LIGHT_GRAY+DISP_BGND_BLACK);
PC_DispStr( 35, 28, "Task3", DISP_FGND_LIGHT_GRAY+DISP_BGND_BLACK);
PC_DispStr(19, 30, "free memory blocks: ", DISP_FGND_YELLOW + DISP_BGND_BLUE);
PC_DispStr(19, 31, "used memory blocks: ", DISP_FGND_YELLOW + DISP_BGND_BLUE);
PC_DispStr(19, 32, "memory block size: ", DISP_FGND_YELLOW + DISP_BGND_BLUE);
PC_DispStr(19, 33, "total memory blocks: ", DISP_FGND_YELLOW + DISP_BGND_BLUE);
}
/*
*********************************************************************************************************
* UPDATE THE DISPLAY
*********************************
展开阅读全文