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 ...
随机推荐
- jquery学习笔记---插件开发模式和结构
JQuery插件开发http://www.cnblogs.com/damonlan/archive/2012/04/06/2434460.html github教程:https://github.co ...
- 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))
解决办法:在项目属性里设置“生成”=>“目标平台”为x86而不是默认的ANY CPU.
- MQ的通讯模式
1) 点对点通讯:点对点方式是最为传统和常见的通讯方式,它支持一对一.一对多.多对多.多对一等多种配置方式,支持树状.网状等多种拓扑结构. 2) 多点广播:MQ适用于不同类型的应用.其中重要的,也是正 ...
- js 下拉列表 省 市
js 下拉列表 省 市 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:/ ...
- CC2540开发板学习笔记(四)——定时器
一.实验内容 分别使用定时器T1和T3使得LED周期性闪烁 二.实验过程 1.定时器T1(查询IRCON来控制) (1)需要调配的寄存器 T1CTL(0XE4) Timer1控制寄存器 BIT3, ...
- SqlServer2005或2008数据库字典--表结构.sql
SELECT TOP 100 PERCENT --a.id, CASE WHEN a.colorder = 1 THEN d.name ELSE '' END AS 表名, C ...
- WinForm下窗体标题栏上有“帮助”按钮
将FormBorderStyle设置为Sizable. 最大化和最小化设置为false helpbutton 设置为true
- kali 安装火狐
转自:http://www.kali.org.cn/thread-21271-1-1.html 安装火狐浏览器 打开终端 第一步:apt-get remove iceweasel 第二步: echo ...
- Hark的数据结构与算法练习之煎饼排序
算法说明 假设煎锅里边有N个煎饼摞在了一起,它们大小不一并且顺序不一致,我们需要通过拿铲子将它们不停的翻个,进行排序,最终得到一个底下是大的煎饼,上边是小的煎饼的序列.这个排序的过程就是煎饼排序. 这 ...
- swift1.2语言函数和闭包函数介绍
swift1.2语言函数和闭包函数介绍 在编程中,随着处理问题的越来越复杂,代码量飞速增加.其中,大量的代码往往相互重复或者近似重复.如果不采有效方式加以解决,代码将很难维护. swift1.2语言函 ...