嵌入式实时操作系统的设计与开发(信号量学习)

这篇具有很好参考价值的文章主要介绍了嵌入式实时操作系统的设计与开发(信号量学习)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

信号量

除了临界点机制、互斥量机制可实现临界资源的互斥访问外,信号量(Semaphore)是另一选择。

信号量与互斥量的区别

  • 对于互斥量来说,主要应用于临界资源的互斥访问,并且能够有效地避免优先级反转问题。
  • 对于信号量而言,它虽然也能用于临界资源的互斥访问,但是不能处理优先级反转问题。

也正因为信号量没有考虑优先级反转问题,所以相对于互斥量来说是一种轻量级的实现方式,比互斥量耗费更少的CPU资源。
此外,信号量除了用于互斥,还可以用于处理不同线程之间的同步问题,而互斥量却不行。

针对上述情况,有三种类型的信号量,按照功能来分,可以分为线程对临界资源互斥访问的互斥信号量、用于线程间同步的信号量、控制系统中临界资源的多个实例使用的计数信号量。

用于同步的信号量其初始值在创建信号量时设置为0,表示同步事件尚未发生。
临界资源互斥的信号量初始值为1,表明当前没有任务获取该信号量。
用于控制系统中临界资源的多个实例使用的计数信号量其初始值为n,表明需要管理的实例个数最大数为n,这样的信号量也称为计数信号量。

以下例子,通过一个计数信号量和互斥信号量实现对一个有界缓冲使用的控制,这就是“生产者与消费者”问题。

  • 计数信号量FULL表示已经被填充了的数据项目。
  • 计数信号量EMPTY表示空闲数据项数目。
    以上的取值范围均为(0,n-1),其初始值分别为0,n-1。
    由于有界缓冲区是共享资源,还需要一个互斥信号量MUTEX控制生产者线程与消费者线程对它的互斥访问,其初始值为1。

创建信号量

acoral_evt_t *acoral_sem_create(unsigned int semNum)
{
	acoral_evt_t *evt;
	evt = acoral_alloc_evt();
	if (NULL == evt)
	{
		return NULL;
	}
	semNum = 1 - semNum;
	evt->count = semNum;
	evt->type = ACORAL_EVENT_SEM;
	evt->data = NULL;
	acoral_evt_init(evt);
	return evt;
}

初始化信号量。当静态定义信号量而不是采用指针形式定义时,内存空间已经在定义时分配,此时应当调用初始化函数acoral_sem_init()对定义过的信号量进行初始化。

aCoralSemRetValEnum acoral_sem_init(acoral_evt_t *evt,unsigned int semNum)
{
	if(NULL == evt)
	{
		return SEM_ERR_NULL;
	}
	semNum = 1 - semNum;
	evt->count = semNum;
	evt->type = ACORAL_EVENT_SEM;
	evt->data = NULL;
	acoral_evt_init(evt);
	return SEM_SUCCED;
}

与互斥量初始化类似,就是为acoral_evt_t各个成员赋值。
这里需要提及的是count初始化,从传入的参数semNum可知,该变量用来表示当前信号量所控制的临界资源的实例的数量,但在具体实现时,并不是和大家想象的数字一样,如1代表有1个资源,2代表有2个资源…
在实现时,实例数量是用“1-semNum”来表示的,此时0代表有1个资源,-1代表有两个资源,1代表已经没有资源,且有1个线程在等待该资源实例。

申请信号量。申请信号量时需要传入两个参数:先前创建的信号量的地址,超时处理的时间。

acoralSemRetValEnum acoral_sem_pend(acoral_evt_t *evt, unsigned int timeout)
{
	acoral_thread_t *cur = acoral_cur_thread;
	if(acoral_intr_nesting)
	{
		return SEM_ERR_INTR;
	}
	if(NULL == evt)
	{
		return SEM_ERR_NULL;
	}
	if(ACORAL_EVENT_SEM != evt->type)
	{
		return SEM_ERR_TYPE;
	}

	//计算信号量处理
	acoral_enter_critical();
	/*判断是否还有可用资源,从前面的介绍可知,这里的SEM_RES_AVAI其实就是0,如果count数目小于等于0,代表有资源实例。如果count大于0,代表在等待的有多少个线程。如果有可用的资源实例,让count的数目加一后退出,表示成功申请信号量。*/
	if((char)evt->count <= SEM_RES_AVAI)
	{
		evt->count++;
		acoral_exit_critical();
		return SEM_SUCCED;
	}
	//如果无可用的资源实例,让count的数目加一后,再将自身挂起,重新调度线程
	evt->count++;
	acoral_unrdy_thread(cur);
	if(timeout > 0)
	{
		cur->delay = TIME_TO_TICKS(timeout);
		timeout_queue_add(cur);
	}
	acoral_evt_queue_add(evt, cur);
	acoral_exit_critical();
	acoral_sched();
	acoral_enter_critical();

	//如果某个线程等待某个资源实例而又无法获取,它将被挂起,而若它希望被挂起的时间小于一个设定值timeout,还需将TCB的成员更新为timeout,并挂载到延迟队列中,如果延迟时间到,将进行相应处理
	if(timeout > 0 && cur->Delay <= 0)
	{
		evt->count--;
		acoral_evt_queue_Del(cur);
		acoral_exit_critical();
		return SEM_ERR_TIMEOUT;
	}
	timeout_queue_del(cur);
	acoral_exit_critical();
	return SEM_SUCCED;
}

释放信号量

acoralSemRetValEnum acoral_sem_post(acoral_evt_t *evt)
{
	acoral_thread_t *thread;

	/* 参数检测*/
	if (NULL == evt)
	{
		return SEM_ERR_NULL; /* error*/
	}
	if (ACORAL_EVENT_SEM != evt->type)
	{
		return SEM_ERR_TYPE;
	}

	acoral_enter_critical();
	if((char)evt->count <= SEM_RES_NOVAI)
	{
		evt->count--;
		acoral_exit_critical();
		return SEM_SUCCED;
	}
	evt->count--;
	thread = acoral_evt_high_thread(evt);
	if(thread == NULL)
	{
		acoral_print("Err Sem post\n");
		acoral_Exit_critical();
		return SEM_ERR_UNDEF;
	}
	timeout_queue_del(thread);
	acoral_evt_queue_del(thread);
	acoral_rdy_thread(thread);
	acoral_exit_critical();
	acoral_sched();
	return SEM_SUCCED;
}

同步机制

信号量机制不仅可以实现临界资源互斥访问,控制系统中临界资源多个实例的使用,还可以用于维护线程之间、线程和中断之间的同步。

当信号量用来实现同步时,其初始值为0,如一个线程正等待某个I/O操作,当该I/O操作完成后,中断服务程序发出信号量,该线程得到信号量后才能继续往下执行。
某个线程将一直处于等待状态,除非获取了其它线程发给它的信号量。

用于互斥的信号量初始值在创建时设置为1,此时1-semNum=0,是小于等于0的,表明当前没有线程获取该信号量。
而用于同步的信号量初始值在信号量创建时设置为0,此时1-semNum=1,是大于1的,表明同步尚未发生。

同步信号量的实现和互斥信号量是一样的,只是创建时传入的参数决定了是用于同步还是用于互斥。文章来源地址https://www.toymoban.com/news/detail-719887.html

到了这里,关于嵌入式实时操作系统的设计与开发(信号量学习)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【小黑嵌入式系统第十课】μC/OS-III概况——实时操作系统的特点、基本概念(内核&任务&中断)、与硬件的关系&实现

    上一课: 【小黑嵌入式系统第九课】PSoC 5LP第一个实验——LED、字符型LCD显示实验 下一课: 【小黑嵌入式系统第十一课】μC/OS-III程序设计基础(一)——任务设计、任务管理(创建基本状态内部任务)、任务调度、系统函数 一. 凡从事嵌入式系统开发工作的人,必须对嵌入

    2024年02月05日
    浏览(55)
  • 嵌入式操作系统(嵌入式学习)

    嵌入式操作系统是一种专门设计和优化用于嵌入式系统的操作系统。它是在资源受限的嵌入式设备上运行的操作系统,如微控制器、嵌入式处理器和系统芯片等。 嵌入式操作系统的主要目标是提供对硬件资源的有效管理和对应用程序的调度,以实现系统的可靠性、实时性和效

    2024年02月10日
    浏览(60)
  • 嵌入式操作系统--篮球记分计时系统

    题目:篮球记分计时系统 一   实训任务 利用Qt-Creator编程设计一个篮球记分计时界面开发系统,实现24秒一节次的倒计时篮球记 分牌。 二   实训要求 1 、基本要求 (1)按照题目要求使用Qt编程,独立设计系统所需界面,实现24秒倒计时的篮球记分计 时界面开发系统。 (2)

    2024年02月09日
    浏览(56)
  • ToBeWritten之嵌入式操作系统

    也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬请移步知识星球 感谢大家一直以来对我CSDN博客的关注和支持,但

    2023年04月08日
    浏览(40)
  • 主流嵌入式操作系统有哪些

    嵌入式操作系统EOS(Embedded OperatingSystem)是一种用途广泛的系统软件,过去它主要应用于工业控制和国防系统领域。常见的嵌入式操作系统有wince、PALM OS、linux、Android、FreeRTOS。 WINDOWS CE是微软开发的一个开放的、可升级的32位嵌入式操作系统,是基于掌上型电脑类的电子设备操

    2024年02月06日
    浏览(63)
  • 【小黑嵌入式系统第二课】嵌入式系统的概述(二)——外围设备、处理器、ARM、操作系统

    上一课: 【小黑嵌入式系统第一课】嵌入式系统的概述(一)——概念、特点、发展、应用 下一课: 【小黑嵌入式系统第三课】嵌入式系统硬件平台(一)——概述、总线、存储设备(RAMROMFLASH) 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享

    2024年02月08日
    浏览(48)
  • 【嵌入式操作系统】实验2:GPIO编程及应用

    熟悉STM32 模块的GPIO硬件连接; 掌握GPIO初始化配置; 掌握GPIO控制板上LED灯编程; 熟练KEIL 工程的配置,编译,调试,下载。 操作系统:WINDOWS 10 开发工具:Keil 4,UartAssists 实验设备:125K RFID读写器模块、JLink在线调试器、电源、PC   运行程序后,LED灯D7、D8按照全熄灭、亮

    2024年02月09日
    浏览(40)
  • C语言嵌入式系统编程注意事项之内存操作

    在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C++以外的其它编程语言基本没有直接访问绝对地址的能力 数据指针 在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C++以外的其它编程语言

    2024年02月09日
    浏览(67)
  • 从何着手OpenHarmony?从这里开始认识嵌入式开源鸿蒙操作系统

    首先,我们需要知道HarmonyOS与OpenHarmony是不同的概念,我们需要知道它们的区别:         HarmonyOS是华为独家开发的,但华为在2020、2021年分两次 将HarmonyOS的基础能力全部捐献给了开放原子开源基金会,形成了OpenHarmony开源项目 ,华为对开源鸿蒙没有控制权,当然华为仍将

    2024年02月04日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包