抽象的来讲,信号量的特性如下:信号量是一个非负整数(车位数),所有通过它的线程/进程(车辆)都会将该整数减一(通过它当然是为了使用资源),当该整数值为 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信号量的基本操作的更多相关文章

  1. RT Thread 通过ENV来配置SFUD,操作SPI Flash

    本实验基于正点原子stm32f4探索者板子 请移步我的RT Thread论坛帖子. https://www.rt-thread.org/qa/forum.php?mod=viewthread& ...

  2. STM32 + RT Thread OS 学习笔记[二]

    串口通讯例程 通过上面的练习,对STM32项目开发有了一个直观印象,接下来尝试对串口RS232进行操作. 1.   目标需求: 开机打开串口1,侦听上位机(使用电脑串口测试软件)发送的信息,然后原样输 ...

  3. STM32 + RT Thread OS 串口通讯

    1.   创建项目 a)   禁用Finsh和console b)   默认情况下,项目文件包含了finsh,它使用COM1来通讯,另外,console输出(rt_kprintf)也使用了COM1.因 ...

  4. STM32 + RT Thread OS 学习笔记[三]

    RTGUI 据说RTGUI是多线程的,因此与RT-Thread OS的耦合度较高,有可能要访问RT-Thread的线程控制块.如果要移植到其它OS,估计难度较大.目前还处于Alpha状态,最终将会包含 ...

  5. STM32 + RT Thread OS 学习笔记[四]

    1.  补注 a)      硬件,打通通讯通道 若学习者购买了学习板,通常可以在学习板提供的示例代码中找到LCD的相关驱动代码,基本上,这里的驱动的所有代码都可以从里面找到. 从上面的示意图可见,M ...

  6. RT thread 设备驱动组件之USART设备

    本文以stm32f4xx平台介绍串口驱动,主要目的是:1.RTT中如何编写中断处理程序:2.如何编写RTT设备驱动接口代码:3.了解串行设备的常见处理机制.所涉及的主要源码文件有:驱动框架文件(usa ...

  7. RT Thread的SPI设备驱动框架的使用以及内部机制分析

    注释:这是19年初的博客,写得很一般,理解不到位也不全面.19年末得空时又重新看了RTThread的SPI和GPIO,这次理解得比较深刻.有时间时再整理上传. -------------------- ...

  8. RT Thread SPI设备 使用

    后记: 之前,我把SPI的片选在Cubemx中配置成了SPI_NSS.现在我给它改为了GPIO_OUTPUT.  同时参考了别人的类似的一个操作无线模块(采用SPI设备驱动)的例子程序(清楚了RTT的 ...

  9. 优先级反转实验,使用信号量实现【RT-Thread学习笔记 5】

    RTOS中很经典的问题.就是在使用共享资源的时候,优先级低的进程在优先级高的进程之前执行的问题.这里模拟这种情况. 下面的实验模拟了优先级反转的情况: 先定义三个线程: //优先级反转实验 rt_se ...

随机推荐

  1. Asp.net MVC 利用自定义RouteHandler来防止图片盗链

    你曾经注意过在你服务器请求日志中多了很多对图片资源的请求吗?这可能是有人在他们的网站中盗链了你的图片所致,这会占用你的服务器带宽.下面这种方法可以告诉你如何在ASP.NET MVC中实现一个自定义Ro ...

  2. 蓝桥杯 入门训练 Fibonacci数列(水题,斐波那契数列)

    入门训练 Fibonacci数列 时间限制:1.0s   内存限制:256.0MB 问题描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. 当n比较大时,Fn也非 ...

  3. hdu 3466 排序01背包

    也是好题,带限制的01背包,先排序,再背包 这题因为涉及到q,所以不能直接就01背包了.因为如果一个物品是5 9,一个物品是5 6,对第一个进行背包的时候只有dp[9],dp[10],…,dp[m], ...

  4. 解决Inno Setup制作安装包无法创建桌面快捷方式的问题

    转自:http://yedward.net/?id=104 昨天想把个java程序做成exe安装软件,然后就去下载了Inno Setup这个软件安装包制作软件,Inno Setup这个软件确实非常好用 ...

  5. visible,invisible,gone区别

    在Android开发中,大部分控件都有visibility这个属性,其属性有3个分别为“visible ”.“invisible”.“gone”.主要用来设置控制控件的显示和隐藏.有些人可能会疑惑In ...

  6. 了解Json

    Json(JavaScript Object Notation) 是一种轻量级的数据交换格式,它是基于JavaScript的一个子集. 数据格式简单, 易于读写, 占用带宽小. {'age':'12' ...

  7. BZOJ2819 Nim(DFS序)

    题目:单点修改.树链查询. 可以直接用树链剖分做.. 修改是O(QlogN),查询是O(QlogNlogN),Q=N=500000: 听说会超时.. 这题也可以用DFS序来做. 先不看修改,单单查询: ...

  8. java.lang.RuntimeException: Invalid action class configuration that references an unknown class named [xxxAction]。

    java.lang.RuntimeException: Invalid action class configuration that references an unknown class name ...

  9. gprof参数说明及常见错误

    参数说明 l -b 不再输出统计图表中每个字段的详细描述. l -p 只输出函数的调用图(Call graph的那部分信息). l -q 只输出函数的时间消耗列表. l -e Name 不再输出函数N ...

  10. TYVJ P1068 STR Label:KMP匹配 不懂

    描述 给你两个串A,B,可以得到从A的任意位开始的子串和B匹配的长度.给定K个询问,对于每个询问给定一个x,求出匹配长度恰为x的位置有多少个.N,M,K<=200000 输入格式 第一行三个数  ...