用过51、AVR、Freescale、STM32,但是写程序一直没有用过实时操作系统,一是因为写的项目不大,二是不太想去看手册学东西。现在写的项目也算比较大,因为需要,所以就学一下,这样也不至于每次的程序都裸奔。

用的红牛STM32开发板(很久之前的板子,STM32F103ZET6芯片)

首先下载官方的库,还有uc/OS的源码。建立好工程后,添加UC/OS。如图

注意os_cfg.h 和 app_cfg.h 在源码里是没有的,一般是拷贝Micrium\Software\EvalBoards里面的。

修改 startup_stm32f10x_hd.s

把PendSV_Handler 替换成 OS_CPU_PendSVHandler

把SysTick_Handler 替换成 OS_CPU_SysTickHandler

如果编译器报错说这两个函数没有声明,那在前面再添加 IMPORT 声明下。如下:

        DCD     SVC_Handler               ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD ; Reserved
; DCD PendSV_Handler ; PendSV Handler
IMPORT OS_CPU_PendSVHandler
DCD OS_CPU_PendSVHandler
; DCD SysTick_Handler ; SysTick Handler
IMPORT OS_CPU_SysTickHandler
DCD OS_CPU_SysTickHandler ; External Interrupts
DCD WWDG_IRQHandler ; Window Watchdog
DCD PVD_IRQHandler ; PVD through EXTI Line detect
DCD TAMPER_IRQHandler ; Tamper

修改OS_CFG.H,这里面主要是系统要启用的功能,我的配置如下:

#ifndef OS_CFG_H
#define OS_CFG_H /* ---------------------- MISCELLANEOUS ----------------------- */
#define OS_APP_HOOKS_EN 0 /* Application-defined hooks are called from the uC/OS-II hooks */
#define OS_ARG_CHK_EN 1 /* Enable (1) or Disable (0) argument checking */
#define OS_CPU_HOOKS_EN 1 /* uC/OS-II hooks are found in the processor port files */ #define OS_DEBUG_EN 0 /* Enable(1) debug variables */
#define OS_EVENT_MULTI_EN 0 /* Include code for OSEventPendMulti() */ #define OS_EVENT_NAME_SIZE 16 /* Determine the size of the name of a Sem, Mutex, Mbox or Q */ #define OS_LOWEST_PRIO 31 /* Defines the lowest priority that can be assigned ... */
/* ... MUST NEVER be higher than 254! */ #define OS_MAX_EVENTS 10 /* Max. number of event control blocks in your application */
#define OS_MAX_FLAGS 5 /* Max. number of Event Flag Groups in your application */
#define OS_MAX_MEM_PART 5 /* Max. number of memory partitions */
#define OS_MAX_QS 4 /* Max. number of queue control blocks in your application */
#define OS_MAX_TASKS 16 /* Max. number of tasks in your application, MUST be >= 2 */ #define OS_SCHED_LOCK_EN 0 /* Include code for OSSchedLock() and OSSchedUnlock() */ #define OS_TICK_STEP_EN 0 /* Enable tick stepping feature for uC/OS-View */
#define OS_TICKS_PER_SEC 1000 /* Set the number of ticks in one second */ /* --------------------- TASK STACK SIZE ---------------------- */
#define OS_TASK_TMR_STK_SIZE 128 /* Timer task stack size (# of OS_STK wide entries) */
#define OS_TASK_STAT_STK_SIZE 128 /* Statistics task stack size (# of OS_STK wide entries) */
#define OS_TASK_IDLE_STK_SIZE 128 /* Idle task stack size (# of OS_STK wide entries) */ /* --------------------- TASK MANAGEMENT ---------------------- */
#define OS_TASK_CHANGE_PRIO_EN 0 /* Include code for OSTaskChangePrio() */
#define OS_TASK_CREATE_EN 1 /* Include code for OSTaskCreate() */
#define OS_TASK_CREATE_EXT_EN 1 /* Include code for OSTaskCreateExt() */
#define OS_TASK_DEL_EN 1 /* Include code for OSTaskDel() */
#define OS_TASK_NAME_SIZE 16 /* Determine the size of a task name */
#define OS_TASK_PROFILE_EN 1 /* Include variables in OS_TCB for profiling */
#define OS_TASK_QUERY_EN 0 /* Include code for OSTaskQuery() */
#define OS_TASK_STAT_EN 0 /* Enable (1) or Disable(0) the statistics task */
#define OS_TASK_STAT_STK_CHK_EN 0 /* Check task stacks from statistic task */
#define OS_TASK_SUSPEND_EN 0 /* Include code for OSTaskSuspend() and OSTaskResume() */
#define OS_TASK_SW_HOOK_EN 1 /* Include code for OSTaskSwHook() */ /* ----------------------- EVENT FLAGS ------------------------ */
#define OS_FLAG_EN 0 /* Enable (1) or Disable (0) code generation for EVENT FLAGS */
#define OS_FLAG_ACCEPT_EN 1 /* Include code for OSFlagAccept() */
#define OS_FLAG_DEL_EN 1 /* Include code for OSFlagDel() */
#define OS_FLAG_NAME_SIZE 16 /* Determine the size of the name of an event flag group */
#define OS_FLAGS_NBITS 16 /* Size in #bits of OS_FLAGS data type (8, 16 or 32) */
#define OS_FLAG_QUERY_EN 1 /* Include code for OSFlagQuery() */
#define OS_FLAG_WAIT_CLR_EN 1 /* Include code for Wait on Clear EVENT FLAGS */ /* -------------------- MESSAGE MAILBOXES --------------------- */
#define OS_MBOX_EN 0 /* Enable (1) or Disable (0) code generation for MAILBOXES */
#define OS_MBOX_ACCEPT_EN 1 /* Include code for OSMboxAccept() */
#define OS_MBOX_DEL_EN 1 /* Include code for OSMboxDel() */
#define OS_MBOX_PEND_ABORT_EN 1 /* Include code for OSMboxPendAbort() */
#define OS_MBOX_POST_EN 1 /* Include code for OSMboxPost() */
#define OS_MBOX_POST_OPT_EN 1 /* Include code for OSMboxPostOpt() */
#define OS_MBOX_QUERY_EN 1 /* Include code for OSMboxQuery() */ /* --------------------- MEMORY MANAGEMENT -------------------- */
#define OS_MEM_EN 0 /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */
#define OS_MEM_NAME_SIZE 16 /* Determine the size of a memory partition name */
#define OS_MEM_QUERY_EN 1 /* Include code for OSMemQuery() */ /* ---------------- MUTUAL EXCLUSION SEMAPHORES --------------- */
#define OS_MUTEX_EN 0 /* Enable (1) or Disable (0) code generation for MUTEX */
#define OS_MUTEX_ACCEPT_EN 1 /* Include code for OSMutexAccept() */
#define OS_MUTEX_DEL_EN 1 /* Include code for OSMutexDel() */
#define OS_MUTEX_QUERY_EN 1 /* Include code for OSMutexQuery() */ /* ---------------------- MESSAGE QUEUES ---------------------- */
#define OS_Q_EN 0 /* Enable (1) or Disable (0) code generation for QUEUES */
#define OS_Q_ACCEPT_EN 1 /* Include code for OSQAccept() */
#define OS_Q_DEL_EN 1 /* Include code for OSQDel() */
#define OS_Q_FLUSH_EN 1 /* Include code for OSQFlush() */
#define OS_Q_PEND_ABORT_EN 1 /* Include code for OSQPendAbort() */
#define OS_Q_POST_EN 1 /* Include code for OSQPost() */
#define OS_Q_POST_FRONT_EN 1 /* Include code for OSQPostFront() */
#define OS_Q_POST_OPT_EN 1 /* Include code for OSQPostOpt() */
#define OS_Q_QUERY_EN 1 /* Include code for OSQQuery() */ /* ------------------------ SEMAPHORES ------------------------ */
#define OS_SEM_EN 0 /* Enable (1) or Disable (0) code generation for SEMAPHORES */
#define OS_SEM_ACCEPT_EN 1 /* Include code for OSSemAccept() */
#define OS_SEM_DEL_EN 1 /* Include code for OSSemDel() */
#define OS_SEM_PEND_ABORT_EN 1 /* Include code for OSSemPendAbort() */
#define OS_SEM_QUERY_EN 1 /* Include code for OSSemQuery() */
#define OS_SEM_SET_EN 1 /* Include code for OSSemSet() */ /* --------------------- TIME MANAGEMENT ---------------------- */
#define OS_TIME_DLY_HMSM_EN 1 /* Include code for OSTimeDlyHMSM() */
#define OS_TIME_DLY_RESUME_EN 1 /* Include code for OSTimeDlyResume() */
#define OS_TIME_GET_SET_EN 1 /* Include code for OSTimeGet() and OSTimeSet() */
#define OS_TIME_TICK_HOOK_EN 1 /* Include code for OSTimeTickHook() */ /* --------------------- TIMER MANAGEMENT --------------------- */
#define OS_TMR_EN 0 /* Enable (1) or Disable (0) code generation for TIMERS */
#define OS_TMR_CFG_MAX 16 /* Maximum number of timers */
#define OS_TMR_CFG_NAME_SIZE 16 /* Determine the size of a timer name */
#define OS_TMR_CFG_WHEEL_SIZE 8 /* Size of timer wheel (#Spokes) */
#define OS_TMR_CFG_TICKS_PER_SEC 10 /* Rate at which timer management task runs (Hz) */ #endif

然后在 os_cpu_c.c 中添加一个获取时钟频率的函数:

INT32U OS_CPU_SysTickClkFreq(void)
{
RCC_ClocksTypeDef rcc_clocks;
RCC_GetClocksFreq(&rcc_clocks);
return ((INT32U)rcc_clocks.HCLK_Frequency); }

到此为止移植的差不多了。

主函数:

#include "common.h"

extern const unsigned char gImage_image[];
static OS_STK startup_task_stk[STARTUP_TASK_STK_SIZE]; void HW_Init(void)
{
SystemInit();
TFT_Init();
RB_LED_GPIO_Init();
ili9320_Clear(Green);
RB_Comm_GPIOOUT_Init();
RB_Time2_Mode_Config();
RB_Time2_NVIC_Configuration(); }
void HW_Set_Init(void)
{
ili9320_DrawPicture(,,,,(u16*)gImage_image);
} int main()
{
HW_Init();
SysTick_Config(SystemCoreClock/OS_TICKS_PER_SEC);
OSInit();
OSTaskCreate(RB_Task_LED,(void *),&startup_task_stk[STARTUP_TASK_STK_SIZE-], STARTUP_TASK_PRIO);
OSStart();
return ;
}

OS的APP函数:

#include "ucos_app.h"

static OS_STK task_led1_stk[TASK_LED1_STK_SIZE];
static OS_STK task_led2_stk[TASK_LED2_STK_SIZE]; void RB_Task_LED(void *p_arg)
{
(void)p_arg;
OSTaskCreate(RB_Task_led1,(void *),&task_led1_stk[TASK_LED1_STK_SIZE-], TASK_LED1_PRIO);
OSTaskCreate(RB_Task_led2,(void *),&task_led2_stk[TASK_LED2_STK_SIZE-], TASK_LED2_PRIO);
while()
{
RB_LED_ReadWrite(,);
OSTimeDlyHMSM(, ,,);
RB_LED_ReadWrite(,);
OSTimeDlyHMSM(, ,,);
}
}
void RB_Task_led1(void *p_arg)
{
(void)p_arg;
while()
{
RB_LED_ReadWrite(,);
OSTimeDlyHMSM(, ,,);
RB_LED_ReadWrite(,);
OSTimeDlyHMSM(, ,,);
}
} void RB_Task_led2(void *p_arg)
{
(void)p_arg;
while()
{
RB_LED_ReadWrite(,);
OSTimeDlyHMSM(, ,,);
RB_LED_ReadWrite(,);
OSTimeDlyHMSM(, ,,);
}
}

APP_CFG.H

#ifndef __APP_CFG_H__
#define __APP_CFG_H__ #define STARTUP_TASK_PRIO 4 //任务优先级
#define TASK_LED1_PRIO 5
#define TASK_LED2_PRIO 6 #define STARTUP_TASK_STK_SIZE 80 //设置栈大小
#define TASK_LED1_STK_SIZE 80
#define TASK_LED2_STK_SIZE 80 #endif

编译通过后,下载到板子既可以发现三个LED以不同频率闪烁了

移植主要参考的是 野火的教程 :《从0开始移植UCOS II到野火M3开发板教程(V2.0》

接下来就是学习UC/OS的具体用法和功能了。

2015-5-13

uC/OS-II 移植笔记的更多相关文章

  1. 【小梅哥SOPC学习笔记】NIOS II处理器运行UC/OS II

    SOPC开发流程之NIOS II 处理器运行 UC/OS II 这里以在芯航线FPGA学习套件的核心板上搭建 NIOS II 软核并运行 UCOS II操作系统为例介绍SOPC的开发流程. 第一步:建 ...

  2. uC/OS II原理分析及源码阅读(一)

    uC/OS II(Micro Control Operation System Two)是一个可以基于ROM运行的.可裁减的.抢占式.实时多任务内核,具有高度可移植性,特别适合于微处理器和控制器,是和 ...

  3. uc/os iii移植到STM32F4---IAR开发环境

    也许是先入为主的原因,时钟用不惯Keil环境,大多数的教程都是拿keil写的,尝试将官方的uc/os iii 移植到IAR环境. 1.首先尝试从官网上下载的官方移植的代码,编译通过,但是执行会报堆栈溢 ...

  4. 【原创】uC/OS II 任务切换原理

    今天学习了uC/OS II的任务切换,知道要实现任务的切换,要将原先任务的寄存器压入任务堆栈,再将新任务中任务堆栈的寄存器内容弹出到CPU的寄存器,其中的CS.IP寄存器没有出栈和入栈指令,所以只能引 ...

  5. uC/OS - III 移植 IAR平台

    关于移植uC/OS-III 网上已经有很多教程了此处只是做个记录 首先下载源码然后解压得到下面的文件: 然后在模版工程里新建各种文件夹: 最后全部都添加进工程: OK了,编译一下,惊呆了,竟然 0错误 ...

  6. uC/OS II 函数说明 之–OSTaskCreate()与OSTaskCreateExt()

    1. OSTaskCreate()    OSTaskCreate()建立一个新任务,能够在多任务环境启动之前,或者执行任务中建立任务.注意,ISR中禁止建立任务,一个任务必须为无限循环结构.    ...

  7. 在STM32F401上移植uC/OS的一个小问题 [原创]

    STM32F401xx是意法半导体新推出的Cortex-M4内核的MCU,相较于已经非常流行的STM32F407xx和STM32F427xx等相同内核的MCU而言,其特点是功耗仅为128uA/MHz, ...

  8. 关于uC/OS的简单学习(转)

    1.微内核 与Linux的首要区别是,它是一个微内核,内核所实现的功能非常简单,主要包括: 一些通用函数,如TaskCreate(),OSMutexPend(),OSQPost()等. 中断处理函数, ...

  9. STemWin5.22移植笔记【转】

    来自:http://www.openedv.com/posts/list/27697.htm STemWin5.22移植笔记 网上关于emwin的资料很少,我在移植的时候查了很多资料,对我一个感觉是好 ...

随机推荐

  1. JS操作Radio与Select

    //radio的chang事件,以及获取选中的radio的值 $("input[name=radioName]").on("change", function( ...

  2. Project Euler 95:Amicable chains 亲和数链

    Amicable chains The proper divisors of a number are all the divisors excluding the number itself. Fo ...

  3. *[hackerrank]Jim Beam

    https://www.hackerrank.com/contests/infinitum-aug14/challenges/jim-beam 学习了线段相交的判断法.首先是叉乘,叉乘的几何意义是有向 ...

  4. Linux中断(interrupt)子系统

    Linux中断(interrupt)子系统之一:中断系统基本原理 Linux中断(interrupt)子系统之二:arch相关的硬件封装层 Linux中断(interrupt)子系统之三:中断流控处理 ...

  5. NPOI技术,

    using(FileStream stream=new FileStream("C:\Users\XXXXXX\Desktop\1.xls",FileMode.Open))     ...

  6. C#实现的ReplaceFirst和ReplaceLast

    原文:C#实现的ReplaceFirst和ReplaceLast ReplaceFirst: public static string ReplaceFirst(string input, strin ...

  7. 转:linux下Xampp安装与配置

    --转载时请保留下面,以供大家加我MSN,增强交流,共同学习.--姜庭华  msn: jaimejth@live.cn--博客:http://blog.csdn.net/jaimejth 软件下载在以 ...

  8. HDU 2836 Traversal 简单DP + 树状数组

    题意:给你一个序列,问相邻两数高度差绝对值小于等于H的子序列有多少个. dp[i]表示以i为结尾的子序列有多少,易知状态转移方程为:dp[i] = sum( dp[j] ) + 1;( abs( he ...

  9. Could not write to output file 'c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\xx'

    1.清了C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files 2.给上述文件夹EveryOne和IIS_Use ...

  10. [HDOJ1811]Rank of Tetris(并查集、拓扑排序)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1811 求一堆数据的拓扑序. 处理:x>y就是x到y一条边,x<y就是y到x一条边.关键问题 ...