RT-Thread信号量的基本操作
抽象的来讲,信号量的特性如下:信号量是一个非负整数(车位数),所有通过它的线程/进程(车辆)都会将该整数减一(通过它当然是为了使用资源),当该整数值为 0 时,所有试图通过它的线程都将处于等待状态。在信号量上我们定义两种操作: take ( 获取) 和Release(释放)。当一个线程调用 take 操作时,它要么得到资源然后将信号量减一,要么
一直等下去(指放入阻塞队列),直到信号量大于等于一时。 Release(释放)实际上是在信号量上执行加操作, take(获取)实际上是在信号量上执行减操作。RT-Thread 中的信号量有静态和动态之分(同静态线程、动态线程), 和信号量有关的操作如下:
初始化—rt_sem_init()( 对应静态信号量) ;
建立—rt_sem_create()( 对应动态信号量);
获取—rt_sem_take();
释放—rt_sem_release();
脱离—rt_sem_detach()( 对应静态信号量) ;
删除—rt_sem_delete()( 对应动态信号量) ;
/**********************************************************************************************************
*
* 模块名称 : 功能演示
* 文件名称 : test.c
* 版 本 : V1.0
* 说 明 :
* 修改记录 :
* 版本号 日期 作者 说明
*
* v1.0 2013-4-20 jiezhi320(UP MCU 工作室) 演示信号量的基本操作 源码来自官方教程文件
*
* Copyright (C), 2012-2013,
* 淘宝店: http://shop73275611.taobao.com
* QQ交流群: 258043068
*
**********************************************************************************************************/
#include <rtthread.h>
#include <stm32f10x.h>
#include "test.h" rt_uint32_t g_tmp;/* 定义一个全局变量*/ /* 变量分配4字节对齐 */
ALIGN(RT_ALIGN_SIZE) /* 静态线程的 线程堆栈*/
static rt_uint8_t thread1_stack[]; /* 静态线程的 线程控制块 */
static struct rt_thread thread_test1; static void test1_thread_entry(void* parameter); /* 信号量控制块 */
static struct rt_semaphore static_sem;
/* 指向信号量的指针 */
static rt_sem_t dynamic_sem = RT_NULL; rt_err_t demo_thread_creat(void)
{
rt_err_t result; /* 初始化静态信号量,初始值是0 */
result = rt_sem_init(&static_sem, "ssem", , RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
rt_kprintf("init static semaphore failed.\n");
return -;
} /* 创建一个动态信号量,初始值是0 */
dynamic_sem = rt_sem_create("dsem", , RT_IPC_FLAG_FIFO);
if (dynamic_sem == RT_NULL)
{
rt_kprintf("create dynamic semaphore failed.\n");
return -;
} /* 创建静态线程 : 优先级 16 ,时间片 5个系统滴答 */
result = rt_thread_init(&thread_test1,
"test1",
test1_thread_entry, RT_NULL,
(rt_uint8_t*)&thread1_stack[], sizeof(thread1_stack), , ); if (result == RT_EOK)
{
rt_thread_startup(&thread_test1);
}
return ;
} void test1_thread_entry(void* parameter)
{
rt_err_t result;
rt_tick_t tick; /* 1. staic semaphore demo */
/* 获得当前的OS Tick */
tick = rt_tick_get(); /* 试图持有信号量,最大等待10个OS Tick后返回 */
result = rt_sem_take(&static_sem, ); //获取
if (result == -RT_ETIMEOUT)
{
/* 超时后判断是否刚好是10个OS Tick */
if (rt_tick_get() - tick != )
{
rt_sem_detach(&static_sem); //脱离—rt_sem_detach()( 对应静态信号量) ;
return ;
}
rt_kprintf("take semaphore timeout\n"); //////////////////////////////////////
}
else
{
/* 因为没有其他地方释放信号量,所以不应该成功持有信号量,否则测试失败 */
rt_kprintf("take a static semaphore, failed.\n");
rt_sem_detach(&static_sem); //脱离—rt_sem_detach()( 对应静态信号量) ;
return ;
} /* 释放一次信号量 */
rt_sem_release(&static_sem); //释放—rt_sem_release(); /* 永久等待方式持有信号量 */
result = rt_sem_take(&static_sem, RT_WAITING_FOREVER);//获取—rt_sem_take();
if (result != RT_EOK)
{
/* 不成功则测试失败 */
rt_kprintf("take a static semaphore, failed.\n");
rt_sem_detach(&static_sem);//脱离—rt_sem_detach()( 对应静态信号量) ;
return ;
} rt_kprintf("take a staic semaphore, done.\n");//////////////////////////////////////// /* 脱离信号量对象 */
rt_sem_detach(&static_sem);//脱离—rt_sem_detach()( 对应静态信号量) ; /* 2. dynamic semaphore test */ tick = rt_tick_get(); /* 试图持有信号量,最大等待10个OS Tick后返回 */
result = rt_sem_take(dynamic_sem, );
if (result == -RT_ETIMEOUT)
{
/* 超时后判断是否刚好是10个OS Tick */
if (rt_tick_get() - tick != )
{
rt_sem_delete(dynamic_sem);
return ;
}
rt_kprintf("take semaphore timeout\n");/////////////////////////////////////////////////////
}
else
{
/* 因为没有其他地方释放信号量,所以不应该成功持有信号量,否则测试失败 */
rt_kprintf("take a dynamic semaphore, failed.\n");
rt_sem_delete(dynamic_sem);
return ;
} /* 释放一次信号量 */
rt_sem_release(dynamic_sem); /* 永久等待方式持有信号量 */
result = rt_sem_take(dynamic_sem, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
/* 不成功则测试失败 */
rt_kprintf("take a dynamic semaphore, failed.\n");
rt_sem_delete(dynamic_sem);
return ;
} rt_kprintf("take a dynamic semaphore, done.\n");///////////////////////////////////////////
/* 删除信号量对象 */
rt_sem_delete(dynamic_sem);
}
演示了静态、动态信号量的各种操作。例程的运行输出如下:
RT-Thread信号量的基本操作的更多相关文章
- RT Thread 通过ENV来配置SFUD,操作SPI Flash
本实验基于正点原子stm32f4探索者板子 请移步我的RT Thread论坛帖子. https://www.rt-thread.org/qa/forum.php?mod=viewthread& ...
- STM32 + RT Thread OS 学习笔记[二]
串口通讯例程 通过上面的练习,对STM32项目开发有了一个直观印象,接下来尝试对串口RS232进行操作. 1. 目标需求: 开机打开串口1,侦听上位机(使用电脑串口测试软件)发送的信息,然后原样输 ...
- STM32 + RT Thread OS 串口通讯
1. 创建项目 a) 禁用Finsh和console b) 默认情况下,项目文件包含了finsh,它使用COM1来通讯,另外,console输出(rt_kprintf)也使用了COM1.因 ...
- STM32 + RT Thread OS 学习笔记[三]
RTGUI 据说RTGUI是多线程的,因此与RT-Thread OS的耦合度较高,有可能要访问RT-Thread的线程控制块.如果要移植到其它OS,估计难度较大.目前还处于Alpha状态,最终将会包含 ...
- STM32 + RT Thread OS 学习笔记[四]
1. 补注 a) 硬件,打通通讯通道 若学习者购买了学习板,通常可以在学习板提供的示例代码中找到LCD的相关驱动代码,基本上,这里的驱动的所有代码都可以从里面找到. 从上面的示意图可见,M ...
- RT thread 设备驱动组件之USART设备
本文以stm32f4xx平台介绍串口驱动,主要目的是:1.RTT中如何编写中断处理程序:2.如何编写RTT设备驱动接口代码:3.了解串行设备的常见处理机制.所涉及的主要源码文件有:驱动框架文件(usa ...
- RT Thread的SPI设备驱动框架的使用以及内部机制分析
注释:这是19年初的博客,写得很一般,理解不到位也不全面.19年末得空时又重新看了RTThread的SPI和GPIO,这次理解得比较深刻.有时间时再整理上传. -------------------- ...
- RT Thread SPI设备 使用
后记: 之前,我把SPI的片选在Cubemx中配置成了SPI_NSS.现在我给它改为了GPIO_OUTPUT. 同时参考了别人的类似的一个操作无线模块(采用SPI设备驱动)的例子程序(清楚了RTT的 ...
- 优先级反转实验,使用信号量实现【RT-Thread学习笔记 5】
RTOS中很经典的问题.就是在使用共享资源的时候,优先级低的进程在优先级高的进程之前执行的问题.这里模拟这种情况. 下面的实验模拟了优先级反转的情况: 先定义三个线程: //优先级反转实验 rt_se ...
随机推荐
- Zookeeper笔记(四)Zookeeper在Dubbo中的应用
Zookeeper在Dubbo中的应用 Dubbo的架构 节点角色说明: Provider: 暴露服务的服务提供方.Consumer: 调用远程服务的服务消费方.Registry: 服务注册与发现的注 ...
- ***mysql中经度纬度字段用什么存储(关于mysql的float和decimal区别)
float,decimal精确度比较 float,double容易产生误差,对精确度要求比较高时,建议使用decimal来存,decimal在mysql内存是以字符串存储的, 用于定义货币要求精确 ...
- ajax该什么时候用
第一.请求的提交是为了页面数据的显示,这时候用户一般不希望看到页面的刷新,是使用AJAX的一个最佳时候. 第二.如果请求提交后,用户能从页面感觉到提交结果,这时候,也最好不要有页面刷新,推荐使用AJA ...
- HDU 4974 Dracula and Ethan 优先队列
Dracula and Ethan Time Limit: 1 Sec Memory Limit: 256 MB Description Dragon is watching competition ...
- jQuery检查某个元素在网页上是否存在
jQuery选择器有比较完善的处理机制,用jQuery获取网页中不存在的元素也不会报错,值得注意的是,利用$('#tt')获取的永远是对象,即使网页上没有此元素.当使用jQuery检查某个元素在网页上 ...
- React-Native 之控件布局
Nodejs 一度将前端JS 推到了服务器端,而15年FB的React-Native RN再一次将JS 推到了移动端的开发浪潮中.RN的优势这里不再重复,它是我们这些习惯了服务端.web端开发,而又不 ...
- BZOJ1099 : [POI2007]树Drz
首先1与i交换,n与i交换,i与i+1交换的可以$O(n)$算出. 然后只需要考虑i与x交换(1<i,x<n且|i-x|>1). 设 a[i]=h[i-1] b[i]=h[i+1] ...
- BZOJ3073 : [Pa2011]Journeys
用线段树套链表维护所有边,用set维护未访问过的点 然后BFS,每次在线段树上找边,然后在set中查询点 一条边使用之后就没有用了,所以在链表中将它删去 时间复杂度$O((n+m)\log n+m\l ...
- 20130617 hbase regionserver 老挂掉
hbase regionserver 老挂掉: 添加如下: <property><name>hbase.regionserver.restart.on.zk.expire< ...
- 密码等级:至少包含字母、大小写数字、字符中的两种 JS实现方案
前言 密码,如果设置的太简单,很容易就被攻破,所以很多网站将密码设置的要求设置的挺严格,一般是字母.数字.字符3选2,区分大小写.对于设置得太简单的密码,予以错误提示.或者予以密码等级(低中高)显示, ...