keil MDK 之RTX信号量的API函数
2015-12-20 23:30
411 查看
一、RTX信号量的API函数总共有4个,如下图
下面我们对这四个函数进行解析
1、os_sem_init函数原型
函数描述:该函数用于信号量的初始化并设置信号量的值
第一个参数为信号量的ID
第二个参数为信号量的初始值
使用举例:
2、os_sem_send函数原型
函数描述:
该函数用于释放信号量,调用后信号量加1
第一个参数是信号量的ID
使用举例:
3、isr_sem_send函数原型
函数描述:
该函数用于释放信号量,只能在中断中使用,调用后信号量加1
第一个参数是信号量的ID
使用举例:
4、os_sem_wait函数原型
函数描述:
该函数用于获取信号量,如果信号量大于1,就减1,否则该任务挂起,等待有信号量
第一个参数是信号量的ID
第二个参数是等待信号的延时时间 范围1 --- 0xFFFF 如果参数是0xFFFF就无线等待
使用举例:
实验目的:
学习RTX的信号量
实验内容:
1、k1按下发送信号量
2、AppTaskRun任务实现LED闪烁
3、AppTaskLED等待信号量 实现LED反转
4、AppTaskUserKey任务实现按键键值的处理
下面是完整的代码
#include "bsp.h" /* 底层硬件驱动 */
#include <RTL.h>
static uint64_t AppTaskLEDStk[256/8];/*任务栈*/
static uint64_t AppTaskStartStk[512/8];/*任务栈*/
static uint64_t AppTaskUserKeyStk[512/8];/*任务栈*/
static uint64_t AppTaskRunStk[512/8];/*任务栈*/
/*任务句柄*/
OS_TID HandleTaskLED = NULL;
OS_TID HandleTaskKey = NULL;
OS_TID HandleTaskRun = NULL;
/*函数声明*/
static void AppTaskCreate(void);
__task void AppTaskLED(void);
__task void AppTaskStart(void);
__task void AppTaskKey(void);
__task void AppTaskRun(void);
/*信号量的ID*/
OS_SEM sem;
/*
*********************************************************************************************************
* 函 数 名: main
* 功能说明: c程序入口
* 形 参:无
* 返 回 值: 错误代码(无需处理)
*********************************************************************************************************
*/
int main(void)
{
/*
ST固件库中的启动文件已经执行了 SystemInit() 函数,该函数在 system_stm32f4xx.c 文件,主要功能是
配置CPU系统的时钟,内部Flash访问时序,配置FSMC用于外部SRAM
*/
bsp_Init();/**/
os_sys_init_user(AppTaskStart, /*任务函数*/
2, /*任务优先级*/
&AppTaskStartStk, /*任务栈*/
sizeof(AppTaskStartStk));/*任务栈大小*/
/* 进入主程序循环体 */
while (1)
{
;
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskLED
* 功能说明: LED闪烁的任务
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
__task void AppTaskLED(void)
{
static uint8_t i = 0;
OS_RESULT Resurt;
while(1)
{
if(i % 2 == 0)
{
GPIO_ResetBits(GPIOI,GPIO_Pin_10);/*点亮LED*/
}
else
{
GPIO_SetBits(GPIOI,GPIO_Pin_10);/*熄灭LED*/
}
i++;
Resurt = os_sem_wait(sem,0xFFFF);
switch(Resurt)
{
case OS_R_SEM:
printf("收到信号量\r\n");
break;
case OS_R_OK:
printf("无需等待,立即获得信号量\r\n");
break;
case OS_R_TMO:
printf("超时\r\n");
break;
default:
break;
}
os_dly_wait(10);/*系统延时函数 因为时钟节拍为1000 所以这里是延时800ms,也就是使AppTaskLED任务挂起800MS*/
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskRun
* 功能说明: LED闪烁的任务
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
__task void AppTaskRun(void)
{
static uint8_t i = 0;
while(1)
{
if(i % 2 == 0)
{
GPIO_ResetBits(GPIOC,GPIO_Pin_2);
}
else
{
GPIO_SetBits(GPIOC,GPIO_Pin_2);
}
i++;
os_dly_wait(200);
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskKey
* 功能说明: 键值处理函数
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
__task void AppTaskKey(void)
{
uint8_t ucKeyCode = 0;
while(1)
{
ucKeyCode = bsp_GetKey();
switch(ucKeyCode)
{
case KEY_DOWN_K1:
printf("发送信号量\r\n");
os_sem_send(sem);
break;
case KEY_DOWN_K2:
break;
case KEY_DOWN_K3:
break;
default:
break;
}
os_dly_wait(20);
}
}
/*
*********************************************************************************************************
* 函 数 名:AppTaskCreate
* 功能说明: 任务创建
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
static void AppTaskCreate(void)
{
HandleTaskLED = os_tsk_create_user(AppTaskLED, /*任务函数*/
1, /*优先级 注意RTX的数字越小,优先级越低*/
&AppTaskLEDStk, /*任务栈起始地址*/
sizeof(AppTaskLEDStk));/*任务栈大小*/
HandleTaskKey = os_tsk_create_user(AppTaskKey, /*任务函数*/
3, /*优先级 注意RTX的数字越小,优先级越低*/
&AppTaskUserKeyStk, /*任务栈起始地址*/
sizeof(AppTaskUserKeyStk));/*任务栈大小*/
HandleTaskRun = os_tsk_create_user(AppTaskRun,
2,
&AppTaskRunStk,
sizeof(AppTaskRunStk));
}
/*
*********************************************************************************************************
* 函 数 名:AppTaskStart
* 功能说明: 开始任务
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
__task void AppTaskStart(void)
{
AppTaskCreate();/*创建AppTaskLED任务*/
os_sem_init(&sem,0);
while(1)
{
os_dly_wait(10);/*系统延时函数*/
bsp_KeyScan();
}
}
实验现象:
按下K1 LED反转,同时串口调试助手可以看到相关信息
下面我们对这四个函数进行解析
1、os_sem_init函数原型
void os_sem_init ( OS_ID semaphore, /* The semaphore object to initialize */ U16 token_count ); /* Initial number of tokens */
函数描述:该函数用于信号量的初始化并设置信号量的值
第一个参数为信号量的ID
第二个参数为信号量的初始值
使用举例:
__task void task1 (void) { .. os_sem_init (&semaphore1, 0); os_sem_send (&semaphore1); .. }
2、os_sem_send函数原型
OS_RESULT os_sem_send ( OS_ID semaphore ); /* The semaphore whose token count is incremented */
函数描述:
该函数用于释放信号量,调用后信号量加1
第一个参数是信号量的ID
使用举例:
__task void task1 (void) { .. os_sem_init (&semaphore1, 0); os_sem_send (&semaphore1); .. }
3、isr_sem_send函数原型
void isr_sem_send ( OS_ID semaphore ); /* The semaphore whose token count is incremented */
函数描述:
该函数用于释放信号量,只能在中断中使用,调用后信号量加1
第一个参数是信号量的ID
使用举例:
void timer1 (void) __irq { .. isr_sem_send (&semaphore1); .. }
4、os_sem_wait函数原型
OS_RESULT os_sem_wait ( OS_ID semaphore, /* The semaphore to get the token from */ U16 timeout ); /* Length of time to wait for the token */
函数描述:
该函数用于获取信号量,如果信号量大于1,就减1,否则该任务挂起,等待有信号量
第一个参数是信号量的ID
第二个参数是等待信号的延时时间 范围1 --- 0xFFFF 如果参数是0xFFFF就无线等待
使用举例:
__task void task1 (void) { .. os_sem_wait (&semaphore1, 0xffff); .. }
实验目的:
学习RTX的信号量
实验内容:
1、k1按下发送信号量
2、AppTaskRun任务实现LED闪烁
3、AppTaskLED等待信号量 实现LED反转
4、AppTaskUserKey任务实现按键键值的处理
下面是完整的代码
#include "bsp.h" /* 底层硬件驱动 */
#include <RTL.h>
static uint64_t AppTaskLEDStk[256/8];/*任务栈*/
static uint64_t AppTaskStartStk[512/8];/*任务栈*/
static uint64_t AppTaskUserKeyStk[512/8];/*任务栈*/
static uint64_t AppTaskRunStk[512/8];/*任务栈*/
/*任务句柄*/
OS_TID HandleTaskLED = NULL;
OS_TID HandleTaskKey = NULL;
OS_TID HandleTaskRun = NULL;
/*函数声明*/
static void AppTaskCreate(void);
__task void AppTaskLED(void);
__task void AppTaskStart(void);
__task void AppTaskKey(void);
__task void AppTaskRun(void);
/*信号量的ID*/
OS_SEM sem;
/*
*********************************************************************************************************
* 函 数 名: main
* 功能说明: c程序入口
* 形 参:无
* 返 回 值: 错误代码(无需处理)
*********************************************************************************************************
*/
int main(void)
{
/*
ST固件库中的启动文件已经执行了 SystemInit() 函数,该函数在 system_stm32f4xx.c 文件,主要功能是
配置CPU系统的时钟,内部Flash访问时序,配置FSMC用于外部SRAM
*/
bsp_Init();/**/
os_sys_init_user(AppTaskStart, /*任务函数*/
2, /*任务优先级*/
&AppTaskStartStk, /*任务栈*/
sizeof(AppTaskStartStk));/*任务栈大小*/
/* 进入主程序循环体 */
while (1)
{
;
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskLED
* 功能说明: LED闪烁的任务
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
__task void AppTaskLED(void)
{
static uint8_t i = 0;
OS_RESULT Resurt;
while(1)
{
if(i % 2 == 0)
{
GPIO_ResetBits(GPIOI,GPIO_Pin_10);/*点亮LED*/
}
else
{
GPIO_SetBits(GPIOI,GPIO_Pin_10);/*熄灭LED*/
}
i++;
Resurt = os_sem_wait(sem,0xFFFF);
switch(Resurt)
{
case OS_R_SEM:
printf("收到信号量\r\n");
break;
case OS_R_OK:
printf("无需等待,立即获得信号量\r\n");
break;
case OS_R_TMO:
printf("超时\r\n");
break;
default:
break;
}
os_dly_wait(10);/*系统延时函数 因为时钟节拍为1000 所以这里是延时800ms,也就是使AppTaskLED任务挂起800MS*/
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskRun
* 功能说明: LED闪烁的任务
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
__task void AppTaskRun(void)
{
static uint8_t i = 0;
while(1)
{
if(i % 2 == 0)
{
GPIO_ResetBits(GPIOC,GPIO_Pin_2);
}
else
{
GPIO_SetBits(GPIOC,GPIO_Pin_2);
}
i++;
os_dly_wait(200);
}
}
/*
*********************************************************************************************************
* 函 数 名: AppTaskKey
* 功能说明: 键值处理函数
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
__task void AppTaskKey(void)
{
uint8_t ucKeyCode = 0;
while(1)
{
ucKeyCode = bsp_GetKey();
switch(ucKeyCode)
{
case KEY_DOWN_K1:
printf("发送信号量\r\n");
os_sem_send(sem);
break;
case KEY_DOWN_K2:
break;
case KEY_DOWN_K3:
break;
default:
break;
}
os_dly_wait(20);
}
}
/*
*********************************************************************************************************
* 函 数 名:AppTaskCreate
* 功能说明: 任务创建
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
static void AppTaskCreate(void)
{
HandleTaskLED = os_tsk_create_user(AppTaskLED, /*任务函数*/
1, /*优先级 注意RTX的数字越小,优先级越低*/
&AppTaskLEDStk, /*任务栈起始地址*/
sizeof(AppTaskLEDStk));/*任务栈大小*/
HandleTaskKey = os_tsk_create_user(AppTaskKey, /*任务函数*/
3, /*优先级 注意RTX的数字越小,优先级越低*/
&AppTaskUserKeyStk, /*任务栈起始地址*/
sizeof(AppTaskUserKeyStk));/*任务栈大小*/
HandleTaskRun = os_tsk_create_user(AppTaskRun,
2,
&AppTaskRunStk,
sizeof(AppTaskRunStk));
}
/*
*********************************************************************************************************
* 函 数 名:AppTaskStart
* 功能说明: 开始任务
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
__task void AppTaskStart(void)
{
AppTaskCreate();/*创建AppTaskLED任务*/
os_sem_init(&sem,0);
while(1)
{
os_dly_wait(10);/*系统延时函数*/
bsp_KeyScan();
}
}
实验现象:
按下K1 LED反转,同时串口调试助手可以看到相关信息
相关文章推荐
- 每天学一点linux(7)
- HTML 排版与标签(三)
- MVC 自定义验证
- linux 搭建zookeeper注册中心(单节点)
- 学习 Mars 老师 Android 开发视频教程笔记之01_06 Android 常用控件
- wpa_supplicant使用笔记
- 关于php中的spl_autoload_register
- (深度优先搜索第一课) 统计三角形 - DFS
- 226. Invert Binary Tree
- C语言局部变量和全局变量
- maven 版本管理
- git reset soft,hard,mixed之区别深解
- test
- 格式化字符串漏洞简介
- phpmail
- SHU1954 Dispsy loves flowers
- PAT乙级题目1002构思的改进和实践
- 从头认识java-13.10 边界的作用
- 分享几种常见WEB服务器配置方案
- MVC 架构设计