精华内容
下载资源
问答
  • STM32CubeMX Freertos 外部中断处理例程 使用STM32CubeMX 生成Freertos 外部中断处理例程
  • STM32CubeMX FreeRTOSѧϰ[1] 任务的创建(Lu)详细讲解cubeMX配置freertos步骤,适合对freertos的初学者。一共分为7章,此为第一章节
  • 前提:默认已经装好 MDK V5 和 STM32CubeMX,并安装了 STM32F1xx 系列的支持包。 硬件平台:STM32F1xx 系列。 目的:学习消息队列的使用。
  • 前提:默认已经装好 MDK V5 和 STM32CubeMX,并安装了 STM32F1xx 系列的支持包。 硬件平台:STM32F1xx 系列。 目的:学习计数信号量的使用
  • 前提:默认已经装好 MDK V5 和 STM32CubeMX,并安装了 STM32F1xx 系列的支持包。 硬件平台:STM32F1xx 系列。 目的:学习使用二值信号量进行任务同步。
  • 前提:默认已经装好 MDK V5和STM32CubeMX,并安装了STM32F1xx 系列的支持包。 硬件平台:STM32F1xx系列。 目的:学习软定时器的使用。
  • 笔记的主要内容就是学习 FreeRTOS的各种通讯机制。 笔记的结构非常简单,就是通过简单的实例,演示 FreeRTOS 的 跟随本笔记学习完,能够做到以下几点即可: 1.了解 FreeRTOS 程序的基本架构; 2.能够理解和应用信号...
  • 详细介绍了怎么基于arm新的开发工具CUbeMX建立代码架构,并实现FreeRTOS实时操作系统的移植和开发。
  • HAL库+CubeMX freeRTOS闪烁LED1、概述2、cubeMXfreeRTOS的配置3、cubeMX中创建任务4、程序中创建任务4.1、osThreadDef4.2、osThreadCreate函数5、程序流程图Copy From 大疆学习文档 1、概述 操作系统 (Operating ...


    1、概述

    操作系统 (Operating System) 的本质是一个帮助用户进行功能管理的软件。操作系统运行在硬件之上,为其他工作的软件执行资源分配等管理工作。

    一般称呼不使用操作系统的单片机开发方式为“裸机开发”,当进行裸机开发时,需要自己设计循环,中断,定时等功能来控制各个任务的执行顺序。而使用操作系统进行开发时,只需要创建任务,操作系统会自动按照一些特定的机制自动进行任务的运行和切换。

    除了任务管理之外,操作系统还可以提供许多功能,比如各个任务之间的通信,同步,任务的堆栈管理,控制任务对重要资源的互斥访问等。

    由于单片机的资源比较少,显然无法运行如Windows,MacOS等计算机操作系统,一般在单片机上运行的是经过专门设计的嵌入式实时操作系统 (RTOS)。

    freeRTOS就是其中一种,其他比较常见的嵌入式实时操作系统还有uCOSⅡ,RTThread等。freeRTOS操作系统是完全免费的操作系统,具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行,并且有着庞大的社区和生态。

    2、cubeMX中freeRTOS的配置

    1. 首先打开Middleware标签,选中其中的FREERTOS选项,进入FREERTOS的配置页面。
      在这里插入图片描述
    2. 在Mode页面下,选择Interface的版本,这里选择CMSIS_V1。CMSIS是由Keil提供的一套特殊的函数接口,他对freeRTOS的功能函数进行了封装,使其变得更加易用,在使用freeRTOS时,不需要再去直接调用freeRTOS的函数,只需要调用CMSIS为我们提供的函数即可,目前CMSIS有V1和V2两个版本。
    3. 通过以上方式就可以完成freeRTOS的开启,在生成代码之后,freeRTOS会自动被移植到工程中。接着在Configuration页面下进行freeRTOS的配置
      在页面中,可以配置freeRTOS的一些重要的属性,包括是否支持抢占机制,freeRTOS的系统时钟速率,最大优先级数量,最小任务栈尺寸,最大任务名称长度等。针对一些比较重要的配置列表如下:
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    3、cubeMX中创建任务

    首先在freeRTOS的配置页面中的Configuration下,选中Tasks and Queues标签页,存在一个已经创建的默认任务为“defaultTask”,点击进入配置选项修改为如下图所示。
    在这里插入图片描述
    如果需要增加一个新任务,点击Add,就可以创建一个新的任务。
    在这里插入图片描述
    在弹出的页面中,可以配置任务名称,优先级,栈大小,入口函数等。各个参数的具体功能见下表:
    在这里插入图片描述
    设置完毕之后点击OK,就可以看到列表中多出了自己创建的任务。
    在这里插入图片描述
    在freertos.c中也可以找到修改的默认任务函数。

    __weak void red_led_task(void const * argument) { 
    	/* USER CODE BEGIN red_led_task */ 
    	/* Infinite loop */ 
    		for(;;) { 
    		osDelay(1); 
    	} 
    	/* USER CODE END red_led_task */ 
    }
    

    由于选择了通过__weak修饰符创建一个弱函数,可以再在别处实现该任务函数。程序执行时会自动寻找到这个另外实现的任务函数。

    void red_led_task(void const * argument) { 
    	while(1) { 
    		HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET);
    		osDelay(500); 
    		HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_RESET); 
    		osDelay(500); 
    		HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_RESET); 
    		osDelay(500); 
    	} 
    }
    

    由于新建了任务“LED_GREEN”,并且设置为As external,故而需要再在别处实现任务函数。程序执行时会自动寻找到实现的任务函数。

    void green_led_task(void const * argument){ 
    	while(1) { 
    		HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_RESET);
    		osDelay(500); 
    		HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_SET); 
    		osDelay(500); 
    		HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_RESET); 
    		osDelay(500); 
    	} 
    }
    

    4、程序中创建任务

    打开freertos.c文件,在MX_FREERTOS_Init中,找到创建两个进程的代码,分别是LED_RED和LED_GREEN。可以看到要创建任务时,只需要调用osThreadDef和osThreadCreate即可,创建“LED_BLUE”任务。

    /* Create the thread(s) */ 
    /* definition and creation of LED_RED */ 
    osThreadDef(LED_RED, red_led_task, osPriorityNormal, 0, 128); 
    LED_REDHandle = osThreadCreate(osThread(LED_RED), NULL); 
    
    /* definition and creation of LED_GREEN */ 
    osThreadDef(LED_GREEN, green_led_task, osPriorityHigh, 0, 128); 
    LED_GREENHandle = osThreadCreate(osThread(LED_GREEN), NULL); 
    
    /* USER CODE BEGIN RTOS_THREADS */ 
    /* add threads, ... */ 
    osThreadDef(LED_BLUE, blue_led_task, osPriorityHigh, 0, 128); 
    led_blue_handle = osThreadCreate(osThread(LED_BLUE), NULL);
    /* USER CODE END RTOS_THREADS */
    
    

    4.1、osThreadDef

    首先介绍osThreadDef,实际上这不是一个函数,而是一个由CMSIS提供的宏定义,用于对要创建的任务进行设置

    #define osThreadDef(name, thread, priority, instances, stacksz) \ 
    extern const osThreadDef_t os_thread_def_##name
    

    在这里插入图片描述

    4.2、osThreadCreate函数

    接着通过CMSIS提供的osThreadCreate函数来创建任务

    osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument);
    

    在这里插入图片描述
    通过以上两步,一个任务就成功创建了,创建一个名称和osThreadDef中的thread参数一致的函数,操作系统会自动找到该函数并将其作为一个进程来执行。比如声明thread为blue_led_task,则还需要执行函数void blue_led_task(void const * argument),while(1)循环中的内容为用户自己的代码。

    5、程序流程图

    在这里插入图片描述

    Copy From 大疆学习文档

    展开全文
  • CubeMX FreeRtos

    2019-12-20 20:17:29
  • 任务应用函数是一组辅助类函数,一般用于调试信息输出、获取任务句柄、获取任务状态、操作任务标签值等等。 1.获取任务系统状态 1.1函数描述 UBaseType_t uxTaskGetSystemState( TaskStatus_t * ...

    任务应用函数是一组辅助类函数,一般用于调试信息输出、获取任务句柄、获取任务状态、操作任务标签值等等。

    1.获取任务系统状态

    1.1函数描述

             UBaseType_t uxTaskGetSystemState(
                           TaskStatus_t * constpxTaskStatusArray,
                           const UBaseType_tuxArraySize,
                           unsigned long * constpulTotalRunTime );

          该函数向TaskStatus_t结构体填充相关信息,系统中每一个任务的信息都可以填充到TaskStatus_t结构体数组中,数组大小由uxArraySize指定。结构体TaskStatus_t定义如下:

    typedef struct xTASK_STATUS
    {
       /* 任务句柄*/
       TaskHandle_t xHandle;
     
       /* 指针,指向任务名*/
       const signed char *pcTaskName;
     
       /*任务ID,是一个独一无二的数字*/
       UBaseType_t xTaskNumber;
     
       /*填充结构体时,任务当前的状态(运行、就绪、挂起等等)*/
       eTaskState eCurrentState;
     
       /*填充结构体时,任务运行(或继承)的优先级。*/
       UBaseType_t uxCurrentPriority;
     
       /* 当任务因继承而改变优先级时,该变量保存任务最初的优先级。仅当configUSE_MUTEXES定义为1有效。*/
       UBaseType_t uxBasePriority;
     
       /* 分配给任务的总运行时间。仅当宏configGENERATE_RUN_TIME_STATS为1时有效。*/
       unsigned long ulRunTimeCounter;
     
       /* 从任务创建起,堆栈剩余的最小数量,这个值越接近0,堆栈溢出的可能越大。 */
       unsigned short usStackHighWaterMark;
    }TaskStatus_t;

         注意,这个函数仅用来调试用,调用此函数会挂起所有任务,直到函数最后才恢复挂起的任务,因此任务可能被挂起很长时间。在文件FreeRTOSConfig.h中,宏configUSE_TRACE_FACILITY必须设置为1,此函数才有效。

    1.2参数描述

     

    • pxTaskStatusArray:指向TaskStatus_t类型的结构体数组。这个数组至少要包含1个元素。RTOS控制的任务数量可以使用API函数uxTaskGetNumberOfTasks()获取。
    • uxArraySize:参数pxTaskStatusArray指向的数组大小,也就是该数组的索引数目。
    • pulTotalRunTime:如果在文件FreeRTOSConfig.h中设置宏configGENERATE_RUN_TIME_STATS为1,则该函数将总运行时间写入*pulTotalRunTime中。pulTotalRunTime可以设置为NULL,表示忽略总运行时间。

     

    1.3返回值

             被填充的TaskStatus_t结构体数量。这个值应该等于通过调用API函数uxTaskGetNumberOfTasks()返回的值,但如果传递给uxArraySize参数的值太小,则返回0。

    1.4用法举例

    /*本例演示如是使用uxTaskGetSystemState()函数来获取运行时间信息,并将其转化为程序员更易识别的字符格式,这些转化后的字符保存到pcWriteBuffer中。*/
    void vTaskGetRunTimeStats(signed char *pcWriteBuffer )
    {
       TaskStatus_t*pxTaskStatusArray;
       volatileUBaseType_t uxArraySize, x;
       unsignedlong ulTotalRunTime, ulStatsAsPercentage;
     
       /* 防御性代码,确保字符串有合理的结束*/
      *pcWriteBuffer = 0x00;
     
       /* 获取任务总数目*/
      uxArraySize = uxTaskGetNumberOfTasks ();
     
       /*为每个任务的TaskStatus_t结构体分配内存,也可以静态的分配一个足够大的数组 */
      pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ));
     
       if(pxTaskStatusArray != NULL )
       {
          /*获取每个任务的状态信息 */
         uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize,&ulTotalRunTime );
     
          /* 百分比计算 */
         ulTotalRunTime /= 100UL;
     
          /* 避免除零错误 */
          if(ulTotalRunTime > 0 )
          {
             /* 将获得的每一个任务状态信息部分的转化为程序员容易识别的字符串格式*/
            for( x = 0; x < uxArraySize; x++ )
             {
               /* 计算任务运行时间与总运行时间的百分比。*/
               ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter /ulTotalRunTime;
     
               if( ulStatsAsPercentage > 0UL )
               {
                  sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n",
                                    pxTaskStatusArray[ x ].pcTaskName,
                                    pxTaskStatusArray[ x ].ulRunTimeCounter,
                                    ulStatsAsPercentage );
               }
               else
               {
                  /* 任务运行时间不足总运行时间的1%*/
                  sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n",
                                    pxTaskStatusArray[ x ].pcTaskName,
                                     pxTaskStatusArray[x ].ulRunTimeCounter );
               }
     
               pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
             }
          }
     
          /* 释放之前申请的内存*/
         vPortFree( pxTaskStatusArray );
       }
    }

    2.获取当前任务句柄

    2.1函数描述

          TaskHandle_t xTaskGetCurrentTaskHandle(void );

          在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetCurrentTaskHandle必须设置为1,此函数才有效。

    2.2返回值

          返回当前任务(调用该函数的任务)的句柄。

    3.获取空闲任务句柄

    3.1函数描述

          TaskHandle_t xTaskGetIdleTaskHandle(void );

          在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetIdleTaskHandle必须设置为1,此函数才有效。

    3.2返回值

          返回空闲任务句柄。空闲任务在RTOS调度器启动时自动创建。

    4.获取任务堆栈最大使用深度

    4.1函数描述

          UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );

          任务的堆栈空间会随着任务执行以及中断处理而增长或缩小。该函数可以返回任务启动后的最小剩余堆栈空间。换句话说,可以间接估算出一个任务最多需要多少堆栈空间。在文件FreeRTOSConfig.h中,宏INCLUDE_uxTaskGetStackHighWaterMark 必须设置成1,此函数才有效。

    4.2参数描述

    • xTask:任务句柄。NULL表示查看当前任务的堆栈使用情况。

    4.3返回值

          返回最小剩余堆栈空间,以字为单位。比如一个32为架构处理器,返回值为1表示有4字节堆栈空间没有使用过。如果返回值为0,则任务很可能已经发生了堆栈溢出。

    4.4用法举例

         void vTask1( void * pvParameters )
         {
             UBaseType_tuxHighWaterMark;
     
             /* 入口处检测一次 */
             uxHighWaterMark =uxTaskGetStackHighWaterMark( NULL );
     
             for( ;; )
             {
                 /* 正常调用函数 */
                 vTaskDelay( 1000 );
     
                 /* 测量堆栈使用情况 */
                 uxHighWaterMark =uxTaskGetStackHighWaterMark( NULL );
             }
        }

    5.获取任务状态

    5.1函数描述

          eTaskState eTaskGetState( TaskHandle_txTask );

          返回一个枚举类型的任务状态值。在文件FreeRTOSConfig.h中,宏INCLUDE_eTaskGetState必须设置为1,此函数才有效。

    5.2参数描述

     

    • xTask:任务句柄

     

    5.3返回值

             下表列出返回值和对应的任务状态。

    6.获取任务描述内容

    6.1函数描述

          char * pcTaskGetTaskName( TaskHandle_txTaskToQuery );

          获取任务的描述内容,在文件FreeRTOSConfig.h中,宏INCLUDE_pcTaskGetTaskName必须设置成1,此函数才有效。

    6.2参数描述

     

    • xTaskToQuery:任务的句柄。NULL表示获取当前任务的描述内容指针。

     

    6.3返回值

          一个指针,指向任务描述字符串。

    7.获取系统节拍次数

    7.1函数描述

          volatile TickType_t xTaskGetTickCount(void );

          这个函数不能在ISR中调用。在ISR中用xTaskGetTickCountFromISR(),原型为volatileTickType_t xTaskGetTickCountFromISR( void )。

    7.2返回值

          返回从vTaskStartScheduler函数调用后的系统时钟节拍次数。

    8.获取调度器状态

    8.1函数描述

          BaseType_t xTaskGetSchedulerState( void);

          获取调度器当前状态。在文件FreeRTOSConfig.h中,宏INCLUDE_xTaskGetSchedulerState或configUSE_TIMERS必须定义为1,此函数才有效。

    8.2返回值

          返回值是以下常量之一(定义在task.h):taskSCHEDULER_NOT_STARTED(未启动)、taskSCHEDULER_RUNNING(正常运行)、taskSCHEDULER_SUSPENDED(挂起)。

    9.获取任务总数

    9.1函数描述

          UBaseType_t uxTaskGetNumberOfTasks(void );

          获取RTOS内核当前管理的任务总数。包含所有就绪、阻塞和挂起状态的任务。对于一个删除的任务,如果它的堆栈空间还没有被空闲任务释放掉,则这个被删除的任务也含在计数值中。

    9.2返回值

          返回RTOS内核当前管理的任务总数。

    10.获取所有任务详情

    10.1函数描述

          void vTaskList( char *pcWriteBuffer );

          将每个任务的状态、堆栈使用情况等以字符的形式保存到参数pcWriteBuffer指向的区域。vTaskList()函数调用usTaskGetSystemState()函数,然后将得到的信息格式化为程序员易读的字符形式。输出的内容例子如下图所示,图中State一栏中,B表示阻塞、R表示就绪、D表示删除(等待清除内存)、S表示挂起或阻塞。

          注意,调用这个函数会挂起所有任务,这一过程可能持续较长时间,因此本函数仅在调试时使用。在文件FreeRTOSConfig.h中,宏configUSE_TRACE_FACILITY和configUSE_STATS_FORMATTING_FUNCTIONS必须定义为1,此函数才有效。

    10.2参数描述

    • pcWriteBuffer:任务的信息会写入这个缓冲区,为ASCII表单形式。这个缓冲区要足够大,以容纳生成的报告,每个任务大约需要40个字节。

    11.获取任务运行时间

    11.1函数描述

          void vTaskGetRunTimeStats( char*pcWriteBuffer );

          这个函数用于统计每个任务的运行时间。要使用这个函数必须满足一些条件,那就是必须有一个用于时间统计的定时器或计数器,这个定时器或计数器的精度要至少大于10倍的系统节拍周期。这个定时器或计数器的配置以及获取定时时间是由两个宏定义实现的,这两个宏一般在文件FreeRTOSConfig.h中定义。配置定时器或计数器的宏为portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(),获取定时时间的宏为portGET_RUN_TIME_COUNTER_VALUE。实现了这两个宏定义后,还必须在文件FreeRTOSConfig.h中将宏configGENERATE_RUN_TIME_STATS和configUSE_STATS_FORMATTING_FUNCTIONS设置为1,此API函数才有效。

          这个API函数调用usTaskGetSystemState()函数获取每个任务的状态信息,并把其中的运行时间格式化为程序员易读的字符形式,并将这些信息保存到参数pcWriteBuffer指向的区域。

          注意,调用这个函数会挂起所有任务,这一过程可能持续较长时间,因此本函数仅在调试时使用。

    11.2参数描述

    • pcWriteBuffer:任务的运行时间信息会写入这个缓冲区,为ASCII表单形式。这个缓冲区要足够大,以容纳生成的报告,每个任务大约需要40个字节。

    11.3用法举例

          以lpc17xx系列为控制为例,我们使用定时器0来作为统计基准时钟。

    11.3.1使能函数宏

          在文件FreeRTOSConfig.h中,设置宏configGENERATE_RUN_TIME_STATS和configUSE_STATS_FORMATTING_FUNCTIONS为1,

    11.3.2定时初始化定时器代码

    void vConfigureTimerForRunTimeStats( void )
    {
        /* 使能定时器0的外设电源,配置外设时钟 */
        PCONP |= 0x02UL;
        PCLKSEL0 = (PCLKSEL0& (~(0x3<<2))) | (0x01 << 2);
     
        /* 复位定时器 0 */
        T0TCR = 0x02;
     
        /* 作为计数器 */
        T0CTCR = 0x00;
     
        /* 预分频,设置合适的分辨率即可 */
        T0PR =  ( configCPU_CLOCK_HZ / 10000UL ) - 1UL;
     
        /* 启动计数器 */
        T0TCR = 0x01;
    }

    11.3.3定义配置定时器和获取定时时间宏

          在文件FreeRTOSConfig.h中,定义下列代码:

    extern void vConfigureTimerForRunTimeStats( void );
    #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
    #defineportGET_RUN_TIME_COUNTER_VALUE() T0TC

    12.设置任务标签值

    12.1函数描述

           voidvTaskSetApplicationTaskTag( TaskHandle_t xTask,
                            TaskHookFunction_tpxTagValue );

          可以给每个任务分配一个标签值。这个值一般用于应用程序,RTOS内核不会使用。在文件FreeRTOSConfig.h中,宏configUSE_APPLICATION_TASK_TAG必须设置为1,此函数才有效。

    12.2参数描述

    • xTask:任务句柄。NULL表示当前任务。
    • pxTagValue:要分配给任务的标签值。这是一个TaskHookFunction_t类型的函数指针,但也可以给任务标签分配任意的值。

          注:TaskHookFunction_t原型定义:typedef BaseType_t (*TaskHookFunction_t)(void * )

    12.3用法举例

    /* 在这个例子中,给任务设置一个整形标签值。例子中使用了RTOS跟踪钩子宏。*/
    void vATask( void *pvParameters )
    {
      /* 为自己的标签分配一个整形值 */
     vTaskSetApplicationTaskTag( NULL, ( void * ) 1 );
     
      for( ;; )
      {
        /* 任务主体代码 */
      }
    }
    /*****************************************************************************/
     
    /*在这个任务中,给任务设置一个函数标签值。首先定义一个回调函数,这个函数必须声明为TaskHookFunction_t类型。 */
    static BaseType_t prvExampleTaskHook( void * pvParameter )
    {
      /* 这里为用户定义代码 –可能是记录数据、更新任务状态值等。*/
     
      return 0;
    }
     
    /* 将回调函数设置为任务的标签值。 */
    void vAnotherTask( void *pvParameters )
    {
      /* 注册回调函数*/
     vTaskSetApplicationTaskTag( NULL, prvExampleTaskHook );
     
      for( ;; )
      {
         /* 任务主体代码 */
      }
    }
     
    /* 每当任务切换时,会调用xTaskCallApplicationTaskHook 函数(见14.)。 */
    #define traceTASK_SWITCHED_OUT() xTaskCallApplicationTaskHook(pxCurrentTCB,0 )

     

    13.获取任务标签值

    13.1函数描述

          TaskHookFunction_txTaskGetApplicationTaskTag( TaskHandle_t xTask );

          返回分配给任务的标签值。程序员定义标签值,RTOS内核通常不会访问标签值。

          函数仅对高级用户使用。在文件FreeRTOSConfig.h中,宏configUSE_APPLICATION_TASK_TAG必须设置为1,此函数才有效。

    13.2参数描述

    • xTask:任务句柄。NULL表示当前任务。

    13.3返回值

          返回指定任务的标签值。

    14.执行任务的应用钩子函数

    14.1函数描述

             BaseType_txTaskCallApplicationTaskHook(
                                       TaskHandle_txTask,
                                       void*pvParameter );

          可以为每个任务分配一个标签值,当这个值是一个TaskHookFunction_t类型函数指针时,相当于应用程序向任务注册了一个回调函数,而API函数xTaskCallApplicationTaskHook用来调用这个回调函数。

          一般这个函数配合RTOS跟踪钩子宏使用,见12.设置任务标签值一节的用法举例。

    14.2参数描述

    • xTask:任务句柄。NULL表示当前任务。
    • pvParameter:作为参数传递给应用钩子函数

    15.设置线程本地存储指针

    15.1函数描述

           void vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet,
                                           BaseType_t xIndex,
                                            void*pvValue )

     

     

          此函数仅用于高级用户。

          线程本地存储允许应用程序在任务的控制块中存储一些值,每个任务都有自己独立的储存空间。

          比如,许多库函数都包含一个叫做errno的全局变量。某些库函数使用errno返回库函数错误信息,应用程序检查这个全局变量来确定发生了那些错误。在单线程程序中,将errno定义成全局变量是可以的,但是在多线程应用中,每个线程(任务)必须具有自己独有的errno值,否则,一个任务可能会读取到另一个任务的errno值。

          FreeRTOS提供了一个灵活的机制,使得应用程序可以使用线程本地存储指针来读写线程本地存储。在文件FreeRTOSConfig.h中,宏configNUM_THREAD_LOCAL_STORAGE_POINTERS指定每个任务线程本地存储指针数组的大小。API函数vTaskSetThreadLocalStoragePointer()用于向指针数组中写入值,API函数pvTaskGetThreadLocalStoragePointer()用于从指针数组中读取值。

    15.2参数描述

    • xTaskToSet:任务句柄。NULL表示当前任务。
    • xIndex:写入到线程本地存储数组的索引号,线程本笃存储数组的大小由宏configNUM_THREAD_LOCAL_STORAGE_POINTERS设定,该宏在文件FreeRTOSConfig.h中。
    • pvValue:写入到指定索引地址的数据值

    15.3用法举例

         参见16.获取线程本地存储指针一节。

    16.读取线程本地存储指针

    16.1函数描述

             void*pvTaskGetThreadLocalStoragePointer(
                                     TaskHandle_txTaskToQuery,
                                     BaseType_txIndex );

          此函数仅用于高级用户。从线程本地存储指针数组中读取值。更详细描述见15.设置线程本地存储指针一节。

    16.2参数描写

    • xTaskToQuery:任务句柄。NULL表示当前任务。
    • xIndex:写入到线程本地存储数组的索引号,线程本笃存储数组的大小由宏configNUM_THREAD_LOCAL_STORAGE_POINTERS设定,该宏在文件FreeRTOSConfig.h中。

    16.3返回值

          返回一个指针,这个指针存储在线程本地存储指针数组中,数组索引由参数xIndex指定。

    16.4用法举例

    16.4.1存储一个整形数

    uint32_tulVariable;
     
    /* 向当前任务的线程本地存储数组下标为1的位置写入一个指向32位常量值的指针。*/
    vTaskSetThreadLocalStoragePointer(NULL, 1, ( void * ) 0x12345678 );
     
    /*向当前任务的线程本地存储数组下标为0的位置写入一个指向32整形值的指针*/
    ulVariable= ERROR_CODE;
    vTaskSetThreadLocalStoragePointer(NULL, 0, ( void * ) ulVariable );
     
    /*从当前任务的线程本地存储数组下标为5的位置读取出一个指针并赋值给32位整形变量。*/
    ulVariable= ( uint32_t ) pvTaskGetThreadLocalStoragePointer( NULL, 5 );

    16.4.2存储结构提

    typedefstruct
    {
        uint32_t ulValue1;
        uint32_t ulValue2;
    }xExampleStruct;
     
    xExampleStruct*pxStruct;
     
    /*为结构体分配内存*/
    pxStruct= pvPortMalloc( sizeof( xExampleStruct ) );
     
    /*为结构体成员赋值*/
    pxStruct->ulValue1= 0;
    pxStruct->ulValue2= 1;
     
    /*向当前任务的线程本地存储数组下标为0的位置写入一个指向结构体变量的指针*/
    vTaskSetThreadLocalStoragePointer(NULL, 0, ( void * ) pxStruct );
     
    /*从当前任务的线程本地存储数组下标为0的位置读取出一个结构体指针*/
    pxStruct= ( xExampleStruct * ) pvTaskGetThreadLocalStoragePointer( NULL, 0 );

    17.设置超时状态

    17.1函数描述

          void vTaskSetTimeOutState( TimeOut_t *const pxTimeOut );

          此函数仅用于高级用户,通常与API函数xTaskCheckForTimeOut()共同使用。

          任务因为等待某事件而进入阻塞状态,通常情况下任务会设置一个等待超时周期。如果在等待事件超时,任务会退出阻塞状态。想象一个这样的应用,某任务等待一个事件而进入阻塞状态,但是事件迟迟不发生,超时后任务退出阻塞状态继续执行任务。假如任务等待的事件仍然没有发生,则任务又会阻塞在该事件下。只要任务等待的事件一直不发生,这个任务进入阻塞然后超时退出阻塞,再进入阻塞的循环就会一直存在。是不是可以设定一个总超时时间,只要总阻塞时间大于这个总超时时间,则可以结束这个任务或进行相应记录?freeRTOS提供了两个API函数来完成这个功能,这就是vTaskSetTimeOutState()和xTaskCheckForTimeOut()。

          vTaskSetTimeOutState()函数用于设置初始条件,之后调用xTaskCheckForTimeOut()函数检查任务总阻塞时间是否超过总超时时间,如果没有超过,则调整剩余的超时时间计数器。

    17.2参数描述

    • pxTimeOut:指向一个结构体的指针,该结构体用来保存确定超时是否发生的必要信息。vTaskSetTimeOutState()函数会设置结构体的成员。

    17.3用法举例

          参见18.超时检测

    18.超时检测

    18.1函数描述

             BaseType_t xTaskCheckForTimeOut(TimeOut_t * const pxTimeOut,
                                     TickType_t* const pxTicksToWait );

          此函数仅用于高级用户,通常与API函数vTaskSetTimeOutState共同使用。

          详细描述见17.设置超时状态

    18.2参数描述

    • pxTimeOut:指向一个结构体的指针。该结构体保存确定超时是否发生的必要信息。使用API函数vTaskSetTimeOutState初始化该结构体。
    • pxTicksToWait:TickType_t指针,指向的变量保存总超时时间。

    18.3返回值

    • pdTRUE:总超时发生
    • pdFALSE:总超时未发生

    18.4用法举例

    /* 函数用于从RX缓冲区中接收uxWantedBytes字节数据,RX缓冲区由UART中断填充。如果RX缓冲区没有足够的数据,则任务进入阻塞状态,直到RX缓冲区有足够数据或者发生超时。如果超时后仍然没有足够的数据,则任务会再次进入阻塞状态,xTaskCheckForTimeOut()函数用于重新计算总超时时间以确保总阻塞状态时间不超过MAX_TIME_TO_WAIT。如果总阻塞状态时间大于了总超时时间,则不管RX缓冲区是否有充足数据,都将这些数据读出来。
     */
    size_txUART_Receive( uint8_t *pucBuffer, size_t uxWantedBytes )
    {
        size_t uxReceived = 0;
        TickType_t xTicksToWait = MAX_TIME_TO_WAIT;
        TimeOut_t xTimeOut;
     
       /* 初始化结构体变量xTimeOut。*/
       vTaskSetTimeOutState( &xTimeOut );
     
       /* 无限循环,直到缓冲区包含足够的数据或者阻塞超时发生。*/
       while( UART_bytes_in_rx_buffer(pxUARTInstance ) < uxWantedBytes )
       {
          /* RX缓冲区没有足够多的数据,表示任务已经进入过一次阻塞状态。调用API函数xTaskCheckForTimeOut检查总阻塞时间是否超过总超时时间,如果没有,则调整剩余的总超时时间。*/
          if( xTaskCheckForTimeOut( &xTimeOut,&xTicksToWait ) != pdFALSE )
          {
             /* 如果总阻塞时间大于总超时时间,则退出这个循环 */
             break;
          }
     
          /* 在等待了xTicksToWait个系统节拍周期后,向接收中断发出通知,需要更多数据。
    */
          ulTaskNotifyTake( pdTRUE, xTicksToWait );
       }
     
        /*从RX缓冲区读取uxWantedBytes个字节并放到pucBuffer缓冲区。*/
        uxReceived = UART_read_from_receive_buffer(pxUARTInstance,  pucBuffer,  uxWantedBytes );
     
        return uxReceived;
    }

     

    展开全文
  • (本文记录了使用cubemx创建一个队列的实验,没有详细的原理) 由于是先写到onenote上再截图下来发表,所以图片之间会有些不连贯,请读者见谅

    (本文记录了使用cubemx创建一个队列的实验)
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    展开全文
  • enable backward compatibility 为enable启用向后兼容,头文件FreeRTOS.h包含一系列#define宏定义,用来映射版本V8.0.0和V8.0.0之前版本的数据类型名字。这些宏可以确保RTOS内核升级到V8.0.0或以上版本时,之前的...
  • STM32CubeMx配置FreeRTOS+LWIP,MCU:STM32F407IG,PHY:LAN8720A,实现多任务,LED灯,按键操作等任务处理,LWIP TCP Sever接收数据然后通过串口接收发送测试
  • 之前裸机emWin成功了,接下来尝试CubeMx FreeRTOS emWin,又遇到三个坑。 先说第一个坑: 我直接再之前裸机的工程上增加FreeRTOS,结果生成程序后,编译报一大堆错误,分析了一下错误实在是无从下手,因此怀疑...
  • 配置STM32CubeMX如下 生成的Keil代码的创建启动定时器如下 /* Create the timer(s) */ /* definition and creation of myTimer01 */ osTimerDef(myTimer01, Callback01); myTimer01Handle = ...
  • CubeMx Freertos 添加任务查看 1、通过CubeMx 打开FreeRtos相应宏定义 在CubeMx中,选择freertos->Config Parameters->Run time and task stats gathering related definitions ->GENERATE_RUN_TIME_STATS ...
  • STM32CubeMX+FreeRTOS学习[5]-邮箱队列(Lu) 精品文档 精品文档 收集于网络如有侵权请联系管理员删除 收集于网络如有侵权请联系管理员删除 精品文档 收集于网络如有侵权请联系管理员删除 FreeRTOS学习之五邮箱队列 ...
  • STM32CubeMX FreeRTOS软件定时器实验

    千次阅读 2018-02-05 22:51:10
    2、STM32CubeMX 关于这两个软件在linux的安装教程请看我另一篇博文 Linux/Windows配置stm32免费开发环境详细流程 sw4stm32比较难下载,在此提供百度网盘链接: 链接:https://pan.baidu.com/s/1nxgh1VF ...
  • stm32f429 cubemx freertos lwip 服务器进行通信
  • CubeMX生成FreeRTOS工程以后,因为兼容多个RTOS的缘故,对很多函数的API做了封装,刚开始接触,不是很清楚这些API的资料在哪找,在此列出。 实际使用时,对照下面的官方的API介绍,会发现这个CMSIS RTOS的API太少...
  • STM32CubeMX FreeRTOS二值信号量实验

    千次阅读 2018-02-06 11:57:46
    系统:linux mint xfce 64bit 软件: 1、SW4STM32 ...本次实验二值信号量的作用是中断与任务间同步,使用STM32CubeMX配置的freertos其API进行了封装,是CMSIS格式的API,关于二值信号量的操作函数如
  • stm32cubemx 版本5.6.0 keil版本5.29.0 freertos.c中代码 /* Includes ------------------------------------------------------------------*/ #include "FreeRTOS.h" #include "task.h" #include "main.h" #...
  • 内核控制函数 osStatus osKernelInitialize (void); //内核初始化 osStatus osKernelStart (void); //内核开始运行 int32_t osKernelRunning(void); //返
  • STM32 CubeMX FreeRTOS中Inclued parameters各参数的作用 vTaskPrioritySet 说明:当该参数设置为(Enable)时,系统Inclued vTaskPrioritySet( ) API函数; void vTaskPrioritySet( TaskHandle_t ...
  • FreeRTOS 学习之七软定时器 前提默认已经装好MDK V5 和STM32CubeMX 并安装了STM32F1xx 系列的支持包 硬件平台STM32F1xx 系列 目的学习软定时器的使用 有时候我们需要定时进行一些例行处理FreeRTOS 提供了软定时器来...
  • 野火STM32F429开发板,通过CUBEMX搭建最新资源所有中间件测试OK。不包括网络USB。触摸屏支持软件I2C和硬件I2C切换,FATFS为最新版本。
  • 使用STM32CubeMX创建基于FreeRTOS的lwIP工程 博文地址:https://blog.csdn.net/yy123xiang/article/details/83062764
  • STM32CubeMX开发FreeRTOS stm32f103rbt6例程,PA3,PA4同时输出PWM。UAR1同时调用发送串口打印信息。详细说明见https://mp.csdn.net/postlist
  • 相关函数官方解释: 资料来源,参照 ...int32_t osSignalSet (osThreadId thread_id, int32_t signals) //Set the specified Signal Flags of an active thread. 给一个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,565
精华内容 626
关键字:

cubemxfreertos