首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

STM32之FreeRTOS

STM32之FreeRTOS

学习操作系统,我并没有一开始就学习UCOS,而是选择了FreeRTOS。FreeRTOS可以方便地搭建在各个平台上,因为汇编相关,都已经由官方完成,我们要做的仅是添加自己的代码,可省去很多工作量。      问题1:在使用多任务时,我想利用USART输出信息,但是如果直接放在任务中输出,往往会造成字符收发顺序不一致的情况,这是仿真时遇到的实际问题。为解决这个问题,可以在USART输出信息时挂起其它任务,利用vTaskSuspendAll函数挂起,再利用xTaskResumeAll重启内核调度。这样可以保证USART正确发送信息。但是,我觉得还不如为USART建立一个任务,这样子,USART就不会发生发送字符顺序错乱的问题了!而完成任务间的通信,就可以考虑使用队列!
       在此,队列的功能相当于任务与任务之间进行通信的通道。USART的任务可通过查询队列是否为空来决定是否输出。
队列的使用:
       定义队列:
      xQueueHandle USART_Q;
       建立队列:
       xQueueCreate( uxQueueLength, uxItemSize );
       第一个参数为队列中元素个数;第二个参数为队列中元素大小,单位为字节。
       也可以使用
       xQueueGenericCreate( uxQueueLength, uxItemSize, queueQUEUE_TYPE_BASE )创建队列,接下来的三个函数都有两种使用方法。


       发送消息:
      xQueueSend( xQueue, pvItemToQueue, xTicksToWait );
      第一个参数为队列句柄,第二个参数为队列元素,第三个参数为阻塞超时时间,如果在发送时队列已满,这个时间即是任务处于阻塞态等待队列空间有效的最长等待时间。


      接收消息:
      xQueueReceive( xQueue, pvBuffer, xTicksToWait )
      一般用法如:while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS );
以上为队列用法,因为学习粗浅,不能进行深入分析……
注意,经查看代码,发送元素到队列的过程中,是将元素复制进队列中的,而并不是指针引用。


演示代码:

xQueueHandle  USART1_MSGQ;   //To receive the usart characters's queue
volatile unsigned long mainDELAY_LOOP_COUNT=0xffff;
void vTask1( void *pvParameters )
{
    volatile unsigned long ul;
    for( ;; )
   {
        xQueueSend( USART1_MSGQ, "This is task 1 !\n",portMAX_DELAY);
        for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ );
   }
}
void vTask2( void *pvParameters )
{
   volatile unsigned long ul;
   for( ;; )
   {
       xQueueSend( USART1_MSGQ, "This is task 2 !\n",portMAX_DELAY);
       for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ );
    }
}
void vTask3( void *pvParameters )
{
    char str[100];
    volatile unsigned long ul;
    for( ;; )
   {
       while( xQueueReceive( USART1_MSGQ, str, portMAX_DELAY ) != pdPASS );
       printf(str);
    }
}

在main函数中添加:
USART1_MSGQ = xQueueCreate(10,(sizeof(char))*100);
xTaskCreate( vTask1, "Task 1", 1000, NULL, 1, NULL );
xTaskCreate( vTask2, "Task 2", 1000, NULL, 1, NULL );
xTaskCreate( vTask3, "Task 3", 1000, NULL, 2, NULL );
vTaskStartScheduler();
while(1);
注意,printf函数已定位到USART1串口上,使用Keil调试的时候,可以通过串口窗口看到输出内容。
继承事业,薪火相传
返回列表