FreeRTOS移植 V10.4.3
1、 FreeRTOS时钟节拍采用SYSTICK,所以需要将SYSTICK功能初始化,详情请参考正点原子移植的STM32F103历程。
2、 SYSTICK例程
u32 reload; SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//选择外部时钟 HCLK
reload=SystemCoreClock/1000000; //每秒钟的计数次数 单位为M
reload*=1000000/configTICK_RATE_HZ; //根据configTICK_RATE_HZ设定溢出时间
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断
SysTick->LOAD = reload; //每1/configTICK_RATE_HZ秒中断一次
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
//reload为24位寄存器,最大值:16777216,在72M下,约合0.233s左右
3、 系统中断配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
4、 在FreeRTOSConfig.h文件中增加如下代码:
文件末尾:
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define INCLUDE_xTaskGetSchedulerState 1
5、 由于FreeRTOS已经编写好了SysTick_Handler函数名字xPortSysTickHandler,所以我们需要在外部文件实现SysTick_Handler接口,则需要增加如下代码。
extern void xPortSysTickHandler(void);
//systick中断服务函数,使用ucos时用到
void SysTick_Handler(void)
{
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
{
xPortSysTickHandler();
}
}
互斥信号
1、 创建互斥锁。xSemaphoreCreateMutex()
2、 获得互斥锁。xQueueSemaphoreTake()
3、 释放互斥锁。xSemaphoreGive()
4、 要实现任务之前互斥,必须要在任务里增加vTaskDelay(500),不要就不能实现任务互斥执行。
5、 例程如下:
//任务句柄
TaskHandle_t StartTask_Handler;
SemaphoreHandle_t xSemaphore;
static void LED1_Task(void *pvParameters)
{
while(1)
{
if(xQueueSemaphoreTake(xSemaphore,portMAX_DELAY ) == pdTRUE)
{
GPIO_ResetBits(GPIOC,GPIO_Pin_0);
vTaskDelay(1000);
GPIO_SetBits(GPIOC,GPIO_Pin_0);
vTaskDelay(1000);
xSemaphoreGive(xSemaphore);
vTaskDelay(500); //延时500ms,也就是500个时钟节拍
}
}
}
static void LED2_Task(void *pvParameters)
{
while(1)
{
if(xQueueSemaphoreTake(xSemaphore,portMAX_DELAY ) == pdTRUE)
{
GPIO_ResetBits(GPIOC,GPIO_Pin_1);
vTaskDelay(1000);
GPIO_SetBits(GPIOC,GPIO_Pin_1);
vTaskDelay(1000);
xSemaphoreGive(xSemaphore);
vTaskDelay(500); //延时500ms,也就是500个时钟节拍
}
}
}
int main(void)
{
u32 reload;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//选择外部时钟 HCLK
reload=SystemCoreClock/1000000; //每秒钟的计数次数 单位为M
reload*=1000000/configTICK_RATE_HZ; //根据configTICK_RATE_HZ设定溢出时间
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断
SysTick->LOAD = reload; //每1/configTICK_RATE_HZ秒中断一次
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
//reload为24位寄存器,最大值:16777216,在72M下,约合0.233s左右
LED_Init(); // LED 初始化
xSemaphore = xSemaphoreCreateMutex(); //创建互斥锁
if(xSemaphore != NULL)
{
xTaskCreate( (TaskFunction_t) LED1_Task,
(const char *) "LED1_Task",
(uint16_t)128,
(void *) NULL,
(UBaseType_t) 5,
(TaskHandle_t* )&StartTask_Handler);
xTaskCreate( (TaskFunction_t) LED2_Task,
(const char *) "LED2_Task",
(uint16_t)128,
(void *) NULL,
(UBaseType_t) 3,
(TaskHandle_t* )&StartTask_Handler);
vTaskStartScheduler();
}
}