RT-Thread信号量使用方法说明及代码示例

信号量的作用

信号量主要用作线程间的同步及互斥,信号量的获取不能在ISR中调用,会导致中断挂起,系统不能有效的进行线程切换及运行。信号量分为动态创建信号量和静态创建信号量,当创建信号量时系统会初始化IPC以及与semaphone相关的部分。在创建信号量指定的参数过程中,flag参数定义FIFO时,信号量采取先入先出的方式,定义为IPRO时,信号量采取优先级的方式,优先级高的线程将先获得等待的信号量。
静态创建信号量
rt_err_t rt_sem_init (rt_sem_t sem, const char* name, rt_uint32_t value, rt_uint8_t flag);/在内存编译时间就编译出来,放在数据段或ZI段上,初始化成功将返回RT_OK/

动态创建信号量
rt_sem_t rt_sem_create (const char* name, rt_uint32_t value, rt_uint8_t flag);/初始化成功将返回创建的信号量控制块指针,否则返回RT_NULL/

删除信号量
rt_err_t rt_sem_delete (rt_sem_t sem);/调用这个函数时,系统将去删除信号量,当有线程任务在等待该信号量时,系统将优先调用等待的线程,赋给等待线程的返回值为-RT_ERROR,注意sem参数必须是create创建的信号量/

脱离信号量
rt_err_t rt_sem_detach (rt_sem_t sem);/调用这个函数用于让信号从内核对象管理器中移除掉,当有信号量正在等待获取时,系统首先去让等待的函数返回-RT_ERROR,注意sem参数是init创建信号量的信号量句柄/

获取信号量
rt_err_t rt_sem_take (rt_sem_t sem, rt_int32_t time);/等待获取信号量,time定义了获取信号量的等待时间,未解决问题,当定义time时间为0时,线程会直接返回,是退出线程吗?/
rt_err_t rt_sem_trytake(rt_sem_t sem);/无等待获取信号量,和rt_sem_take(sem,0)效果相同/
释放信号量
rt_err_t rt_sem_release(rt_sem_t sem);/执行代码内容去释放信号量/

下列是动态创建信号量并让LED灯闪烁的示例代码

#define  LED0		82

#define THREAD_PRIORITY 25
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 20


static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;
static rt_sem_t semaphone1= RT_NULL;
static rt_sem_t semaphone2= RT_NULL;

static void entry_critical1()
{

	while(1)
	{
		rt_sem_take(semaphone2,RT_WAITING_FOREVER);
		{
			rt_pin_write(LED0,1);
			rt_thread_mdelay(500);
			rt_sem_release(semaphone1);
		}
	}
}
static void entry_critical2()
{

	while(1)
	{
		rt_sem_take(semaphone1,RT_WAITING_FOREVER);
		{
			rt_pin_write(LED0,0);
			rt_thread_mdelay(500);
		}
		rt_sem_release(semaphone2);
	}
}

int main(void)
{
	
	rt_int32_t sem1 = 0;
	rt_int32_t sem2 = 1;
	
	rt_pin_mode(LED0, PIN_MODE_OUTPUT);
	dma_check_task_init();
	user_uart_init(USER_UART_2);
	user_node_init();
	semaphone1 = rt_sem_create("sem1",sem1,RT_IPC_FLAG_FIFO);//创建动态信号量
	semaphone2 = rt_sem_create("sem2",sem2,RT_IPC_FLAG_FIFO);//创建动态信号量
	tid1 = rt_thread_create("t1",entry_critical1, RT_NULL,THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
	if (tid1 != RT_NULL)
		rt_thread_startup(tid1);
	else
		return -1;
	tid2 = rt_thread_create("t2",entry_critical2,RT_NULL,THREAD_STACK_SIZE,THREAD_PRIORITY,THREAD_TIMESLICE-2);
	if(tid1 != RT_NULL)
		rt_thread_startup(tid2);
	else
		return -1;

}

猜你喜欢

转载自blog.csdn.net/weixin_42560250/article/details/105577636
今日推荐