你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

查看: 4312|回复: 5

【STM32F429开发日志】UCOSII简单移植

[复制链接]

2

主题

16

回帖

0

蝴蝶豆

新手上路

最后登录
2018-5-30
发表于 2014-6-23 21:35:12 | 显示全部楼层 |阅读模式
 一直都是用MCU裸奔程序,现在在STM32F429 discovery上试了下移植UCOSII,现在把自己的心得分享一下,有不正确的地方,请指出来!
先直接把程序贴出来,说明放在后面。关于移植前的准备工作以及UCOSII的源码,大家可以网上搜索,很多资料,现只贴出主函数部分,其中用到的其他函数都是很简单就能实现的,方法很多,就不赘述了。
 
#include
#include "delay.h"
#include "key.h"
#include "led.h"
#include "usart.h"
#include "includes.h"
 
//UCOSII任务设置
// 起始任务
#define START_TASK_PRIO  10            //设置任务优先级
#define START_STK_SIZE   64            //设置任务堆栈大小
OS_STK  START_TASK_STK[START_STK_SIZE];//任务堆栈
void START_Task(void *pdata);          //任务函数
 
//LED任务(红灯)
#define RLED_TASK_PRIO    7           
#define RLED_STK_SIZE    64           
OS_STK  RLED_TASK_STK[RLED_STK_SIZE]; 
void RLED_Task(void *pdata);             
 
//主任务
#define MAIN_TASK_PRIO    5          
#define MAIN_STK_SIZE   128         
OS_STK  MAIN_TASK_STK[MAIN_STK_SIZE];  
void MAIN_Task(void *pdata);          
 
//按键任务
#define KEY_TASK_PRIO     4            
#define KEY_STK_SIZE     64          
OS_STK  KEY_TASK_STK[KEY_STK_SIZE];  
void KEY_Task(void *pdata);            
 
OS_EVENT *msg_key;  //邮箱事件块指针(按键用)
OS_TMR *tmr1;       //软件定时器1
 
//软件定时器1的回调函数
void TMR1_Callback(OS_TMR *ptmr,void *p_arg)
{
        static u16 cpuusage = 0;
        static u8 tcnt = 0;
        if(tcnt == 5)
        {
                printf("CPU使用率:%d%%\r\n",cpuusage/5);//每隔一段时间打印出CPU使用率
                cpuusage = 0;
                tcnt = 0;
        }
        cpuusage += OSCPUUsage;
        tcnt++;
}
 
int main(void)
{
        F4_Clock_Init();                 //关于时钟复位,参照官方例程,基本是照抄的
        Delay_Init(150);                 //延时初始化
        MYUSART1_Init(75,115200);        //串口初始化
        LED_Init();                      //LED端口初始化
        KEY_Init();                      //按键端口初始化
       
        OSInit();
        //创建起始任务
        OSTaskCreate(START_Task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO);
        OSStart();
       
}
 
//起始任务
void START_Task(void *pdata)
{
        OS_CPU_SR cpu_sr = 0;
        pdata = pdata;
       
        msg_key  = OSMboxCreate((void *)0);//创建消息邮箱
        OSStatInit();                                //初始化统计任务
       
        OS_ENTER_CRITICAL();//进入临界区,系统不响应中断
        //创建如下任务
        OSTaskCreate(RLED_Task,(void *)0,(OS_STK *)&RLED_TASK_STK[RLED_STK_SIZE-1],RLED_TASK_PRIO);
        OSTaskCreate(MAIN_Task,(void *)0,(OS_STK *)&MAIN_TASK_STK[MAIN_STK_SIZE]-1,MAIN_TASK_PRIO);
        OSTaskCreate(KEY_Task,(void *)0,(OS_STK *)&KEY_TASK_STK[KEY_STK_SIZE-1],KEY_TASK_PRIO );
        OSTaskSuspend(START_TASK_PRIO);//将起始任务挂起
        OS_EXIT_CRITICAL(); //退出临界区,系统正常响应中断
}
 
//LED任务
void RLED_Task(void *pdata)
{
        while(1)
        {
                LED_On(REDLED);
                OSTimeDly(500);
                LED_Off(REDLED);
                OSTimeDly(500);
        }
}
 
//主任务
void MAIN_Task(void *pdata)
{
        u32 key = 0;
        u8 state;
        u8 err;       
        //创建软件定时器1
        tmr1 = OSTmrCreate(10,5,OS_TMR_OPT_PERIODIC,(OS_TMR_CALLBACK)TMR1_Callback,0,"tmr1",&err);
        OSTmrStart(tmr1,&err);//启动软件定时器1
        while(1)
        {
                key = (u32)OSMboxPend(msg_key,10,&err);//获取(请求)按键消息
                switch(key)
                {
                        case 1:
                                LED_Toggle(GREENLED);//翻转LED状态
                                state = LED_State(GREENLED);//获取LED当前状态
                                if(state == 1)
                                        printf("邮箱消息发送成功,绿灯点亮!\r\n");
                                else printf(" 邮箱消息发送成功,绿灯熄灭!\r\n");
                                break;
                        default:
                                break;
                }
                OSTimeDly(10);
        }
}
 
//按键扫描任务
void KEY_Task(void *pdata)
{
        u8 key;
        while(1)
        {
                key = KEY_Scan(0);
                if(key)
                {
                        printf("key=%d,准备发送消息邮箱...\r\n",key);
                        OSMboxPost(msg_key,(void *)key);//发送消息
                }
                OSTimeDly(10);
        }
}
 
说明:
1,以上代码仅包含几个基础的简单功能:1)创建任务,设置任务的优先级,堆栈和任务函数,达到多任务运行的效果。2)通过消息邮箱,达到任务间通信的目的。3)使用软件定时器,打印出CPU的使用率。
2,在官方源码中,最重要的也是需要我们经常修改的是os_cfg.h这个文件。当然其他地方也会有修改的,限于本人水平还请大家多百度。关于os_cfg.h中几个重要的参数(仅讲本代码中用到的功能)如下:
OS_MAX_TASKS        允许的任务的最大数量,最新版的UCOSII最大任务支持255个。一般调试使用10个基本够了。
OS_TICKS_PER_SEC      时间节拍,这个是很重要的参数,该参数决定整个UCOSII系统的时间基准,就是一秒钟的节拍数量,如果设置为10,那么时间基准就是1000/10=100ms,依次类推,一般设置为1~100ms。在cortex-m4内核有SYSTICK定时器,一般以此定时器在硬件上产生时间节拍。关于延时函数,最终都是要调用UCOSII的自带的延时函数OSTimeDly。
OS_TMR_EN          定时器使能,取1时使能,不然会出现无法使用数据类型OS_TMR等问题
OS_TMR_CFG_TICKS_PER_SEC      定时器的节拍,意义等同于STM32的定时器设置产生中断的时间,具体要看在软件定时器的相关函数中的用法,大家可以自己多研究下。
下一句是自己添加的,设置优先级。
#define OS_TASK_TMR_PRIO           0u  //设置软件定时器1的优先级为最高
3,一些基础知识普及,比较简单基础:
1)UCOSII的任何任务都是通过任务控制块来控制,任务控制块包括:
任务函数指针,任务堆栈指针,任务优先级。
任务函数指针用于找到函数入口,去执行具体的操作;
任务堆栈指针,用于该任务释放了CPU使用权时,用于保护现场,即保存该任务的相关参数到堆栈中,等待下次改任务获取了CPU使用权了,再从堆栈中加载参数,继续执行函数;
优先级是识别每个任务的唯一标示,且优先级不能有相同的。
2)每个任务就是一个死循环,在循环中至少要有一个延时语句,这样才能在该延时语句处释放该任务的CPU使用权,转而去响应中断或者执行优先级更高的任务,且延时长短视具体程序而定,一般延时10ms。
3)关于创建任务的语句,其中一个参数与具体处理器的堆栈增长方式有关,向上增长和向下增长是不同的参数。
4)中断响应时间是体现系统实时性好不好的重要参数之一。
备注:很多代码参照了正点原子的战舰STM32F103开发板的资料,有什么不明白的,大家可以多看看相关资料,还有任哲和邵贝贝的关于UCOSII的讲解,非常详细和经典。
 
 
 
 
 
 
<
回复

使用道具 举报

2

主题

51

回帖

0

蝴蝶豆

初级会员

最后登录
2020-12-1
发表于 2014-6-25 00:14:38 | 显示全部楼层

RE:【STM32F429开发日志】UCOSII简单移植

谢谢楼主分享经验,不过讲的略简
回复 支持 反对

使用道具 举报

0

主题

11

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
发表于 2014-6-25 01:01:09 | 显示全部楼层

RE:【STM32F429开发日志】UCOSII简单移植

可否把代码打个包贴上来呢,那样就更好了!
回复 支持 反对

使用道具 举报

2

主题

16

回帖

0

蝴蝶豆

新手上路

最后登录
2018-5-30
 楼主| 发表于 2014-6-26 00:00:19 | 显示全部楼层

回复:【STM32F429开发日志】UCOSII简单移植

回复第 3 楼 于2014-06-25 01:01:09发表:
可否把代码打个包贴上来呢,那样就更好了!
http://www.openedv.com/posts/list/13912.htm这里有详细的资料,呵呵,本人的代码从上面借鉴不少,很多值得学习的地方.
 
回复 支持 反对

使用道具 举报

100

主题

3617

回帖

1

蝴蝶豆

论坛元老

最后登录
2020-12-8
发表于 2015-4-8 10:43:49 | 显示全部楼层
学习一下。。。
回复 支持 反对

使用道具 举报

100

主题

3617

回帖

1

蝴蝶豆

论坛元老

最后登录
2020-12-8
发表于 2015-4-12 16:26:46 | 显示全部楼层
学习一下。。。。
回复 支持 反对

使用道具 举报

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版