FreeRTOS基本函数使用

FreeRTOS基本api使用

在嵌入式领域中,嵌入式实时操作系统正得到越来越广泛的应用。采用嵌入式实时操作系统(RTOS)可以更合理、更有效地利用CPU的资源,简化应用软件的设计,缩短系统开发时间,更好地保证系统的实时性和可靠性。

一.常用api

Freertos 函数定义在与task.h,semphr. h 和queue.h中,这里简单介绍下常用api接口。

@任务-----task.h
1.xTaskCreate
函数原型 xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask )

参数定义
pvTaskCode指向任务的入口函数. 每个任务是个死循环
pcName描述任务的名字。主要便于调试。最大长度由configMAX_TASK_NAME_LEN.定义
usStackDepth指定任务堆栈的大小 ,堆栈能保护变量的数目- 不是字节数
pvParameters指针用于作为一个参数传向创建的任务
uxPriority任务运行时的优先级
pvCreatedTask用于传递一个处理——引用创建的任务

返回值: pdPASS 是如果任务成功创建并且添加到就绪列中,另外错误代码在projdefs. H文件定义

2.vTaskDelete
函数原型 void vTaskDelete( xTaskHandle pxTask )
删除任务

3.vTaskDelay
函数原型 void vTaskDelay( portTickType xTicksToDelay )
INCLUDE_vTaskDelay必须设置为1,这个函数才为可用。参考配置获得更多信息。 延时任务为已知时间片。任务被锁住剩余的实际时间由时间片率决定。portTICK_RATE_MS常量用来用来从时间片速率(一片周期代表着分辨率)来计算实际时间。 vTaskDelay()指定一个任务希望的时间段,这个时间之后(调用vTaskDelay() )任务解锁。例如,指定周期段为100时间片,将使任务在调用vTaskDelay()100个时间片后解锁。vTaskDelay()不提供一个控制周期性任务频率的好方法,像通过代码采取的路径,和其他任务和中断一样,在调用vTaskDelay()后响频率,因此任务所需的时间下一次执行。 参考 vTaskDelayUntil() ,这个交替的API函数设计了执行固定的频率。它是指定的一个绝对时(而不是一个相对时间)后,调用任务解锁。
参数:时间数量,调用任务应该锁住的时间片周期

4.uxTaskPriorityGet/vTaskPrioritySet
获取任务优先级 unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask )
设置任务优先级 void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority )

5.vTaskStartScheduler/vTaskEndSchedule
开启调度函数/停止调度函数

@队列-----queue.h
6.xQueueCreate(创建队列)
函数原型:xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize );

参数含义
uxQueueLength队列传输最大个数
uxItemSize队列传输数据的大小

返回值:队列句柄

7.xQueueSend(发送数据)
函数原型:portBASE_TYPE xQueueSend( xQueueHandle xQueue, const void * pvItemToQueue, portTickType xTicksToWait )

参数含义
xQueue哪个队列
pvItemToQueue存放什么数据
xTicksToWait等待时间

返回值:pdTRUE/errQUEUE_FULL
注意:xQueueSendToBack(向队列后添加)与xQueueSend等价/xQueueSendToFront(向队列前添加)

8.xQueueReceive(接收数据)
函数原型:portBASE_TYPE xQueueReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait );

参数含义
pxQueue要从哪个队列取数据
pvBuffer取出来放哪
xTicksToWait取数据等待时间

@信号量—semphr. h
9.xSemaphoreCreateMutex
函数原型:xSemaphoreHandle xSemaphoreCreateMutex( void )
使用已存在的队列结构来创建互斥锁信号量的宏。通过此宏创建的互斥锁可以使用xSemaphoreTake()与 xSemaphoreGive()宏来访问
返回值:信号量句柄

10.xSemaphoreTake
函数原型:xSemaphoreTake( xSemaphoreHandle xSemaphore, portTickType xBlockTime )

参数含义
xSemaphore已经创建的信号量句柄
xBlockTime等待信号量可用的时钟滴答次数,可以使用 portTICK_RATE_MS宏来转换为实际的时间 。当为0时可以用于 对信号量进行轮询(poll the semaphore) 如果INCLUDE_vTaskSuspend置位“1”,则指定xBlockTime为 portMAX_DELAY会导致任务阻塞时间不确定(不会超时)

10.xSemaphoreGive(释放信号量)
函数原型:xSemaphoreGive( xSemaphoreHandle xSemaphore )
参数:信号量句柄
返回值:pdTRUE/pdFALSE

@定时器—timers.h
11.xTimerCreate(创建定时器)
函数原型:imerHandle_t xTimerCreate ( const char * const pcTimerName, const TickType_t xTimerPeriod,const UBaseType_t uxAutoReload, void * const pvTimerID,TimerCallbackFunction_t pxCallbackFunction )

参数含义
pcTimerName定时器名字
xTimerPeriod定时时间,函数多久执行一次
uxAutoReload定时器类型pdTRUE/pdTRUE,是否连续执行定时器函数
pvTimerID定时器id
pxCallbackFunction定时器函数

返回值:定时器句柄

12.xTimerStart(开启定时器)
函数原型:BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xBlockTime )

参数含义
xTimer要开启的定时器句柄
xBlockTime成功启动定时器前的最大等待时间设置

返回值:pdFAIL/pdPASS
注意:定时器使用注意FreeRTOSConfig.h文件中使能宏#define configUSE_TIMERS
另外多个定时器可以使用pvTimerGetTimerID获取定时器id

二.应用

下面代码在mt7686芯片上跑的一个简单应用

//freertos init
QueueHandle_t queue_test = NULL;
SemaphoreHandle_t semaphore_test = NULL;
TimerHandle_t timer_test = NULL;

//任务间通信结构体定义
typedef struct
{
	int msgid;
	char msgdate[20];
} queue_msg_type;
int count_js = 0;

queue_msg_type datemsg;

void timer_test_fun(void)
{
	count_js ++;
	if(count_js%5 == 0)
	{
	//释放信号量
		xSemaphoreGive((SemaphoreHandle_t)semaphore_test);		
	}

}

void Vtask1(void)
{
	queue_msg_type sendate;
	int i = 1;
	printf("##enter into client######\n");
	while(1)
	{
		
		sendate.msgid = i++;
		sprintf(sendate.msgdate,"%d hello world",i);
		//sendate.msgid = 10;
		//strcpy(sendate.msgdate,"hello world");
		printf("send msg\n");
		if (xQueueSend(queue_test, &sendate, portMAX_DELAY) != pdPASS)
		{
			printf("[%s]xQueueSend err!!!\r\n",__func__);
			return 0;
		}
		vTaskDelay(1000/portTICK_RATE_MS);
	}
}

void Vtask2(void)
{
	queue_msg_type recdate;
	printf("##enter into service######\n");
	while(1)
	{
		//printf("rec msg\n");
		if (xQueueReceive(queue_test, (void *)&recdate, portMAX_DELAY))
		{
			printf("######recid:%d,recdate:%s#####\n",recdate.msgid,recdate.msgdate);
		}
		vTaskDelay(1000/portTICK_RATE_MS);
	}
}

void Vtask3(void)
{
	while(1)
	{
	//信号量阻塞,需要释放
		xSemaphoreTake((SemaphoreHandle_t)semaphore_test, portMAX_DELAY);
		printf("##enter into semaphore##\n");
		vTaskDelay(1000/portTICK_RATE_MS);
	}
}
int main(void)
{
	AUCODEC_STATUS_e codec_status;
	//系统初始化
    system_init();
	//wdt_init();
	//i2c_init();
	bsp_init();
	//串口初始化
	bsp_io_def_uart_init();

	//创建消息队列,任务间通信
	queue_test = xQueueCreate(150, sizeof(datemsg));

	//创建信号量
	semaphore_test = xSemaphoreCreateMutex();

	//创建定时器
	timer_test = xTimerCreate("Timer_test", /* Just a text name, not used by the kernel. */
					(1* 1000 / portTICK_PERIOD_MS), /* The timer period in ticks. */
					pdTRUE, /* The timers will auto-reload themselves when they expire. */
					NULL, /* Assign each timer a unique id equal to its array index. */
					timer_test_fun /* Each timer calls the same callback when it expires. */
					);
	//启动定时器
	xTimerStart(timer_test, 0);
	
	//创建任务
	xTaskCreate(Vtask1, "CLIENT", 1024*8 / sizeof(portSTACK_TYPE), NULL, 5, NULL);
	xTaskCreate(Vtask2, "SERVICE", 1024*8 / sizeof(portSTACK_TYPE), NULL, 5, NULL);
	xTaskCreate(Vtask3, "SEMAPHORE", 1024*8 / sizeof(portSTACK_TYPE), NULL, 5, NULL);

	//启动任务调度器
    vTaskStartScheduler();

	for (;;);
}

编译工程,将可执行文件烧写,启动,串口log如下图
在这里插入图片描述
本文为freertos基本api使用的简单介绍,更深层次的了解和掌握相关内容,请自行查找每个api的用法等。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值