uCOS III 生产者消费者模型实现

Introduction

本文介绍了我实时系统课程的一个小作业,在ucos 上实现一个生产者消费者模型样例。基于ucos iii,因为ucos ii能直接跑的源码不好找。。

ucos 信号量

官方文档

主要有这么几个函数:


OSSemCreate()
OSSemDel()
OSSemPend()
OSSemPendAbort()
OSSemPost()
OSSemSet()

OSSemCreate


void  OSSemCreate (OS_SEM      *p_sem,
                   CPU_CHAR    *p_name,
                   OS_SEM_CTR   cnt,
                   OS_ERR      *p_err)

p_sem:信号量指针p_name:给这个信号量取的名字

cnt:这个信号量的初始值,如果这个信号量用于

p_err:如果有错误,将通过它返回错误

OSSemPend


OS_SEM_CTR  OSSemPend (OS_SEM   *p_sem,
                       OS_TICK   timeout,
                       OS_OPT    opt,
                       CPU_TS   *p_ts,
                       OS_ERR   *p_err)

p_sem:信号量指针

tmeout:如果超过这个时间,任务将继续执行下去,设置为0,则永远等待这个信号量

opt:OS_OPT_PEND_BLOCKING(caller不能继续执行,直到信号量有效或者触发超时) or OS_OPT_PEND_NON_BLOCKING(不阻塞caller执行)

p_ts:在时间戳不需要的时候,默认NULL即可

p_err:如果有错误,将通过它返回错误

OSSemPendAbort


OS_OBJ_QTY  OSSemPendAbort (OS_SEM  *p_sem,
                            OS_OPT   opt,
                            OS_ERR  *p_err)

opt:

OS_OPT_PEND_ABORT_1 仅等待队列里优先级最高的

OS_OPT_PEND_ABORT_ALL 所有等待的任务

OS_OPT_POST_NO_SCHED 调用后是否调度


OS_SEM_CTR  OSSemPost (OS_SEM  				*p_sem,
                       OS_OPT   opt,
                       OS_ERR  *p_err)

p_sem:信号量指针

opt:OS_OPT_POST_1,只把等待信号量的最高优先级的任务置为ready OS_OPT_POST_ALL,把所有等待信号量的任务都ready(此时不适用于资源共享的情况)OS_OPT_POST_NO_SCHED,最好在多个post或者用户想等都完成以后再reschedule

p_err:如果有错误,将通过它返回错误

OSSemDel和OSSemSet


OS_OBJ_QTY  OSSemDel (OS_SEM  *p_sem,
                      OS_OPT   opt,
                      OS_ERR  *p_err)
void  OSSemSet (OS_SEM      *p_sem,
                OS_SEM_CTR   cnt,
                OS_ERR      *p_err)

p_sem:信号量指针

opt:OS_OPT_DEL_NO_PEND如果没有任务在等待他,才删除OS_OPT_DEL_ALWAYS 不管有没有等着他的任务,都删除。告诉等着他的任务,ready,并返回合适的错误码

p_err:如果有错误,将通过它返回错误

cnt:要设置的数值

↑翻译自官方文档。

生产者消费者

代码参考了 麻省大学罗威尔分校University of Massachusetts Lowell大学的嵌入式实时系统课程实验使用ucos iii的实现生产者消费者模型:

http://faculty.uml.edu/george_cheney/Teaching/Courses/Spring2017/16572/index.htm

February 14 (Meeting 5)的part 3 部分是视频讲解。

他们的代码百度网盘下载

实现说明

生产者将生产的物品放到仓库里,消费者从中取出,如果仓库满了,则生产者等待仓区有空间,不再继续生产。如果仓库空,则消费者等待生产者生产物品。

生产者代码


void producer (void *p_arg)
{
    OS_ERR  err;
    CPU_TS  ts;
    while (DEF_ON) {
        OSSemPend(&sem_empty, 0,OS_OPT_PEND_BLOCKING,&ts,&err);
        OSSemPost(&sem_full,  OS_OPT_POST_1 ,&err);
        printf("生产者:食物数量:%d\t", sem_full.Ctr);
        OSTimeDlyHMSM(0u, 0u, 1u, 0u,
                             OS_OPT_TIME_HMSM_STRICT,
                             &err);
        /* Check ’err” */
    }
}

消费者代码


void consumer (void *p_arg)
{
    OS_ERR  err;
    CPU_TS  ts;

    while (DEF_ON) {
    	OSSemPend(&sem_full, 0,OS_OPT_PEND_BLOCKING,&ts,&err);
		OSSemPost(&sem_empty,  OS_OPT_POST_1 ,&err);
		printf("消费者:食物数量:%d\t", sem_full.Ctr);
		 OSTimeDlyHMSM(0u, 0u, 2u, 0u,
		                      OS_OPT_TIME_HMSM_STRICT,
		                      &err);
		/* Check ’err” */
	}
}

代码说明

这里使用了sem_emptysem_full两个信号量,初始化sem_empty为10,表示一开始仓库有10的空间来放物品,生产者pend empty生产一个物品,同时也post full。而消费者一开始在等待sem_full > 0,实际上,sem_full = 10 - sem_empty,所以用一个信号量来做更好。

在github上我代码里,OSSemPendOSSemPost的代码我做了几句注释,来解释原理。

文章版权归 FindHao 所有丨本站默认采用CC-BY-NC-SA 4.0协议进行授权|
转载必须包含本声明,并以超链接形式注明作者 FindHao 和本文原始地址:
https://www.findhao.net/easycoding/1993

你可能喜欢:(相似内容推荐和广告都使用了谷歌的推荐系统,需要对本站取消广告屏蔽才能显示。感谢点击↓广告支持博主~)

Find

新浪微博(FindSpace博客)QQ群:不安分的Coder(375670127) 不安分的Coder

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*