http://ju.outofmemory.cn/entry/39028

聚客频道
牧童遥指杏花村,一枝红杏出墙来…

FreeRTOS介绍与移植

andy的linux小屋 2013-07-29 3157 阅读

最近在看一个实时嵌入式操作系统————FreeRTOS, 为什么看它呢?首先它是开源的,其次它的内核最小只需要三个文件 task.clist.cqueue.c,加起来5000多行代码还有很多注释在里面。他的优点网上也有很多介绍的,我也就不多说了,感兴趣的可以去百度google一下。

源代码目录结构

从FreeRTOS的官方网站可以下载到FreeRTOS的全部源代码。下载下来的压缩包的目录结构类似如下:

FreeRTOSV7.4.0/|--FreeRTOS///这里是FreeRTOS的源代码和示例工程||--Demo//示例工程||--License//许可证文件||--Source///内核源代码|||--include //头文件|||--portable //芯片相关的代码||\--readme.txt |\--readme.txt |--FreeRTOS-Plus// 这里是FreeRTOS的一些增强程序 比如文件系统、 网络层等等\--readme.txt

我们主要还是看FreeRTOS目录下的东西,移植FreeRTOS到一个平台上主要要改以下几个文件:

FreeRTOSConfig.h    //主要的配置文件,可以用来裁剪部分不需要的功能portable/<Compiler>/<Platform>/port.c portable/<Compiler>/<Platform>/portmacro.h portable/<Compiler>/<Platform>/portasm.s

上面的Compiler是你使用的编译器名称,Platform是你使用的平台名称,那个汇编文件是可选的,因为有些编译器可以在C语言中嵌入汇编。

开始移植

开始移植之前,你可以先去Demo目录下看看,有没有与你的板子相符合的工程,可以直接拿过来使用,或者是找一个相近的,修改一下就可以使用了。

portmacro.h

先看看portmacro.h文件

/*Type definitions.*/
#define portCHAR        char
#define portFLOAT       float
#define portDOUBLE      double
#define portLONG        long
#define portSHORT       short
#define ortSTACK_TYPE  unsigned portLONG
#define portBASE_TYPE   long
#if( configUSE_16_BIT_TICKS == 1 )typedef unsigned portSHORT portTickType;#define portMAX_DELAY ( portTickType ) 0xffff
#elsetypedef unsigned portLONG portTickType;#define portMAX_DELAY ( portTickType ) 0xffffffff
#endif
/*-----------------------------------------------------------*/
/*Architecture specifics.*/
#define portSTACK_GROWTH            ( -1 )
#define portTICK_RATE_MS            ( ( portTickType ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT          8
/*-----------------------------------------------------------*/
/*Scheduler utilities.*/
extern void vPortYieldFromISR( void);#define portYIELD()                 vPortYieldFromISR()
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()
/*-----------------------------------------------------------*/
/*Critical section management.*/extern void vPortEnterCritical( void);extern void vPortExitCritical( void);extern unsigned long ulPortSetInterruptMask( void);extern void vPortClearInterruptMask( unsigned longulNewMaskValue );#define portSET_INTERRUPT_MASK_FROM_ISR()       ulPortSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)    vPortClearInterruptMask(x)
#define portDISABLE_INTERRUPTS()                ulPortSetInterruptMask()
#define portENABLE_INTERRUPTS()                 vPortClearInterruptMask(0)
#define portENTER_CRITICAL()                    vPortEnterCritical()
#define portEXIT_CRITICAL()                     vPortExitCritical()

首先是将一些数据类型定义为port开头的类型,而不是使用C语言自带的类型名。然后是定义一些硬件相关的宏:

portBYTE_ALIGNMENT //貌似是分配任务堆栈空间用的宏定义
portSTACK_GROWTH   //定义堆栈生长的方向,一般是向下生长的 定义为-1
portTICK_RATE_MS   //这个是在用户程序中能用到的 表示Tick间隔多少ms
portYIELD()        //实现任务切换
portNOP()           //空操作
portENTER_CRITICAL()  //进入临界区
portEXIT_CRITICAL()  //退出临界区
portENABLE_INTERRUPTS() //开中断
portDISABLE_INTERRUPTS() //关中断

port.c

port.c文件里面就是实现了上面的头文件中用的的几个函数:

pxPortInitialiseStack()
xPortStartScheduler()
vPortEndScheduler()
vPortYield()
vPortTickInterrupt()

定义了几个全局变量:

/*The priority used by the kernel is assigned to a variable to make access
from inline assembler easier.*/
const unsigned long ulKernelPriority =configKERNEL_INTERRUPT_PRIORITY;/*Each task maintains its own interrupt status in the critical nesting
variable.*/
static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;

FreeRTOSConfig.h

接下来就是FreeRTOS的全局配置文件了。先来看一个示例的FreeRTOSConfig.h:

#ifndef FREERTOS_CONFIG_H#define FREERTOS_CONFIG_H
/*是否采用抢占式调度器*/
#define configUSE_PREEMPTION            1
/*是否使用空闲任务*/
#define configUSE_IDLE_HOOK                0
/*是否使用心跳钩子函数*/
#define configUSE_TICK_HOOK                0
/*定义MCU内核工作频率*/
#define configCPU_CLOCK_HZ                ( 100000000UL )
/*时钟Tick的频率*/
#define configTICK_RATE_HZ                ( ( portTickType ) 1000 )
/*程序中可以使用的最大优先级*/
#define configMAX_PRIORITIES            ( ( unsigned portBASE_TYPE ) 5 )
/*任务堆栈的最小大小*/
#define configMINIMAL_STACK_SIZE        ( ( unsigned short ) 90 )
/*设置堆空间的大小,只有当程序中采用FreeRTOS提供的内存分配算法才用到*/
#define configTOTAL_HEAP_SIZE            ( ( size_t ) ( 8 * 1024 ) )
/*任务名称最大长度,包括末尾的NULL结束字节*/
#define configMAX_TASK_NAME_LEN            ( 10 )
/*如果要使用TRACE功能*/
#define configUSE_TRACE_FACILITY        0
/*设为1 portTickType将定义为无符号16整型,否则为无符号32位整型*/
#define configUSE_16_BIT_TICKS            0
/*这个参数控制那些优先级与idle 任务相同的任务的行为,并且只有当内核被配置为抢占式任务调度时才有实际作用。* 内核对具有同样优先级的任务会采用时间片轮转调度算法。当任务的优先级高于idle任务时,各个任务分到的时间片是同样大小的。* 但当任务的优先级与idle任务相同时情况就有些不同了。当configIDLE_SHOULD_YIELD 被配置为1时,当任何优先级与idle 任务相同的任务处于就绪态时,idle任务会立刻要求调度器进行任务切换。这会使idle任务占用最少的CPU时间,但同时会使得优先级与idle 任务相同的任务获得的时间片不是同样大小的。因为idle任务会占用某个任务的部分时间片*/
#define configIDLE_SHOULD_YIELD            0
/*程序中是否包含mutex相关代码*/
#define configUSE_MUTEXES                1
/*队列注册表有两个作用,但是这两个作用都依赖于调试器的支持:* 1.        给队列一个名字,方便调试时辨认是哪个队列。* 2.        包含调试器需要的特定信息用来定位队列和信号量。* 如果你的调试器没有上述功能,哪个这个注册表就毫无用处,还占用的宝贵的RAM空间*/
#define configQUEUE_REGISTRY_SIZE        8
/*是否检测堆栈溢出*/
#define configCHECK_FOR_STACK_OVERFLOW    2
/*是否包含recursive mutex代码*/
#define configUSE_RECURSIVE_MUTEXES        1
#define configUSE_MALLOC_FAILED_HOOK    0
#define configUSE_APPLICATION_TASK_TAG    0
#define configUSE_COUNTING_SEMAPHORES    1
/*Co-routine definitions.*/
/*是否使用协程*/
#define configUSE_CO_ROUTINES         0
/*协程可以使用的优先级数量*/
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/*Software timer definitions.*/
/*是否包含软件定时器*/
#define configUSE_TIMERS                1
/*软件定时器任务优先级*/
#define configTIMER_TASK_PRIORITY        ( 2 )
/*设置软件定时器任务中用到的命令队列长度*/
#define configTIMER_QUEUE_LENGTH        10
/*设置软件定时器任务所需任务堆栈大小*/
#define configTIMER_TASK_STACK_DEPTH    ( configMINIMAL_STACK_SIZE * 2 )
/*Set the following definitions to 1 to include the API function, or zero
to exclude the API function.*/
#define INCLUDE_vTaskPrioritySet        1
#define INCLUDE_uxTaskPriorityGet        1
#define INCLUDE_vTaskDelete                1
#define INCLUDE_vTaskCleanUpResources    1
#define INCLUDE_vTaskSuspend            1
#define INCLUDE_vTaskDelayUntil            1
#define INCLUDE_vTaskDelay                1
/*Run time stats gathering definitions.*/#ifdef __ICCARM__/*The #ifdef just prevents this C specific syntax from being included inassembly files.*/void vMainConfigureTimerForRunTimeStats( void);unsignedlong ulMainGetRunTimeCounterValue( void);#endif
#define configGENERATE_RUN_TIME_STATS    1
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vMainConfigureTimerForRunTimeStats()
#define portGET_RUN_TIME_COUNTER_VALUE() ulMainGetRunTimeCounterValue()
/*Cortex-M specific definitions.*/#ifdef __NVIC_PRIO_BITS/*__BVIC_PRIO_BITS will be specified when CMSIS is being used.*/#define configPRIO_BITS               __NVIC_PRIO_BITS
#else#define configPRIO_BITS               4        /* 15 priority levels */
#endif
/*The lowest interrupt priority that can be used in a call to a "set priority"
function.*/
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY            0xf
/*The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values.*/
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5
/*Interrupt priorities used by the kernel port layer itself.  These are generic
to all Cortex-M ports, and do not rely on any particular library functions.*/
/*决定内核使用的优先级*/
#define configKERNEL_INTERRUPT_PRIORITY         ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/*!!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
Seehttp://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
/*决定了可以调用API函数的中断的最高优先级。高于这个值的中断处理函数不能调用任何API 函数。*/
#define configMAX_SYSCALL_INTERRUPT_PRIORITY     ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/*Normal assert() semantics without relying on the provision of an assert.h
header file.*/
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
/*Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names.*/
#define vPortSVCHandler         SVC_Handler
#define xPortPendSVHandler      PendSV_Handler
#define xPortSysTickHandler     SysTick_Handler
#endif /* FREERTOS_CONFIG_H */

上面的文件,我已经做了部分注释了。 一般改好这三个文件,就算成功的将FreeRTOS移植到了你的芯片平台上了,至于怎么使用FreeRTOS, 你可以去官网查看帮助文档,官方有写一个使用手册《Using_the_FreeRTOS_Real_Time_Kernel-A_Practical_Guide_opened》,这本手册本来是要收费的,不过网上也是可以找的到下载的,网上也有一个网友翻译的中文版,你也可以去网上找来,看一看。

作者:andy的linux小屋

原文地址:FreeRTOS介绍与移植, 感谢原作者分享。

→FreeRTOS系列[一] 什么是操作系统?←结束了,我的飞思卡尔

http://blog.csdn.net/liyuanbhu/article/details/7912170/

配置FreeRTOS

FreeRTOS 是高度可配置的。所有的可配置项都在FreeRTOSConfig.h 文件中。每一个Demo 程序中都包含了一个配置好的FreeRTOSConfig.h 文件,可以以Demo程序中的FreeRTOSConfig.h 文件作为模板,在其基础上加以修改。

下面先给出一个典型的FreeRTOSConfig.h 文件,然后再逐项加以说明。

#ifndef FREERTOS_CONFIG_H#define FREERTOS_CONFIG_H/*Here is a good place to include header files that are required across
your application.*/#include"something.h"#define configUSE_PREEMPTION                1
#define configUSE_IDLE_HOOK                 0
#define configUSE_TICK_HOOK                 0
#define configCPU_CLOCK_HZ                  58982400
#define configTICK_RATE_HZ                  250
#define configMAX_PRIORITIES                5
#define configMINIMAL_STACK_SIZE            128
#define configTOTAL_HEAP_SIZE               10240
#define configMAX_TASK_NAME_LEN             16
#define configUSE_TRACE_FACILITY            0
#define configUSE_16_BIT_TICKS              0
#define configIDLE_SHOULD_YIELD             1
#define configUSE_MUTEXES                   0
#define configUSE_RECURSIVE_MUTEXES         0
#define configUSE_COUNTING_SEMAPHORES       0
#define configUSE_ALTERNATIVE_API           0
#define configCHECK_FOR_STACK_OVERFLOW      0
#define configQUEUE_REGISTRY_SIZE           10
#define configGENERATE_RUN_TIME_STATS       0#define configUSE_CO_ROUTINES               0
#define configMAX_CO_ROUTINE_PRIORITIES     1#define configUSE_TIMERS                    1
#define configTIMER_TASK_PRIORITY           3
#define configTIMER_QUEUE_LENGTH            10
#define configTIMER_TASK_STACK_DEPTH        configMINIMAL_STACK_SIZE#define configKERNEL_INTERRUPT_PRIORITY            [dependent of processor]
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    [dependent on processor and application]#define configASSERT( ( x ) )               if( ( x ) == 0 ) vCallAssert( __FILE__, __LINE__ )#define INCLUDE_vTaskPrioritySet                1
#define INCLUDE_uxTaskPriorityGet               1
#define INCLUDE_vTaskDelete                     1
#define INCLUDE_vTaskSuspend                    1
#define INCLUDE_xResumeFromISR                  1
#define INCLUDE_vTaskDelayUntil                 1
#define INCLUDE_vTaskDelay                      1
#define INCLUDE_xTaskGetSchedulerState          1
#define INCLUDE_xTaskGetCurrentTaskHandle       1
#define INCLUDE_uxTaskGetStackHighWaterMark     0
#define INCLUDE_xTaskGetIdleTaskHandle          0
#define INCLUDE_xTimerGetTimerDaemonTaskHandle  0
#define INCLUDE_pcTaskGetTaskName               0#endif /* FREERTOS_CONFIG_H */

可配置的参数

configUSE_PREEMPTION

设为 1则采用抢占式调度器, 设为 0则采用协作式调度器。

configUSE_IDLE_HOOK

设为1则使能 idle hook,设为0则禁止idle hook。

configUSE_TICK_HOOK

设为1则使能 tick hook,设为0则禁止tick hook。

configCPU_CLOCK_HZ

设置为 MCU 内核的工作频率,以Hz为单位。配置FreeRTOS的时钟Tick时会用到。对不同的移植代码也可能不使用这个参数。如果确定移植代码中不用它就可以注释掉这行。

configTICK_RATE_HZ

FreeRTOS的时钟Tick的频率,也就是FreeRTOS用到的定时中断的产生频率。这个频率越高则定时的精度越高,但是由此带来的开销也越大。FreeRTOS 自带的Demo 程序中将TickRate 设为了1000Hz只是用来测试内核的性能的。实际的应用程序应该根据需要改为较小的数值。

当多个任务共用一个优先级时,内核调度器回来每次时钟中断到来后轮转切换任务(round robin),因此,更高的Tick Rate 会导致任务的时间片“time slice”变短。

configMAX_PRIORITIES

程序中可以使用的最大优先级。FreeRTOS 会为每个优先级建立一个链表,因此没多一个优先级都会增加些RAM 的开销。所以,要根据程序中需要多少种不同的优先级来设置这个参数。

configMINIMAL_STACK_SIZE

任务堆栈的最小大小,FreeRTOS根据这个参数来给idle task 分配堆栈空间。这个值如果设置的比实际需要的空间小,会导致程序挂掉。因此,最好不要减小Demo 程序中给出的大小。

configTOTAL_HEAP_SIZE

设置堆空间(Heap)的大小。只有当程序中采用FreeRTOS 提供的内存分配算法时才会用到。

configMAX_TASK_NAME_LEN

任务名称最大的长度,这个长度是以字节为单位的,并且包括最后的 NULL 结束字节。

configUSE_TRACE_FACILITY

如果程序中需要用到TRACE功能,则需将这个宏设为1。否则设为0。开启TRACE功能后,RAM占用量会增大许多,因此在设为1之前请三思。

configUSE_16_BIT_TICKS

将 configUSE_16_BIT_TICKS设为 1后portTickType 将被定义为无符号的16位整形类型,configUSE_16_BIT_TICKS 设为0 后portTickType 则被定义为无符号的32位整型。

configIDLE_SHOULD_YIELD

这个参数控制那些优先级与idle 任务相同的任务的行为,并且只有当内核被配置为抢占式任务调度时才有实际作用。

内核对具有同样优先级的任务会采用时间片轮转调度算法。当任务的优先级高于idle任务时,各个任务分到的时间片是同样大小的。

但当任务的优先级与idle任务相同时情况就有些不同了。当configIDLE_SHOULD_YIELD 被配置为1时,当任何优先级与idle 任务相同的任务处于就绪态时,idle任务会立刻要求调度器进行任务切换。这会使idle任务占用最少的CPU时间,但同时会使得优先级与idle 任务相同的任务获得的时间片不是同样大小的。因为idle任务会占用某个任务的部分时间片。

configUSE_MUTEXES

设为 1 则程序中会包含mutex 相关的代码,设为 0 则忽略相关的代码。

configUSE_RECURSIVE_MUTEXES

设为 1 则程序中会包含recursive mutex 相关的代码,设为 0 则忽略相关的代码。

configUSE_COUNTING_SEMAPHORES

设为 1 则程序中会包含semaphore 相关的代码,设为 0 则忽略相关的代码。

configUSE_ALTERNATIVE_API

设为 1 则程序中会包含一些关于队列操作的额外API函数,设为 0 则忽略相关的代码。这些额外提供的API运行速度更快,但是临界区(关中断)的长度也更长。有利也有弊,是否要采用需要用户自己考虑了。

configCHECK_FOR_STACK_OVERFLOW

控制是否检测堆栈溢出。

configQUEUE_REGISTRY_SIZE

队列注册表有两个作用,但是这两个作用都依赖于调试器的支持:

1.        给队列一个名字,方便调试时辨认是哪个队列。

2.        包含调试器需要的特定信息用来定位队列和信号量。

如果你的调试器没有上述功能,哪个这个注册表就毫无用处,还占用的宝贵的RAM空间。

configGENERATE_RUN_TIME_STATS

设置是否产生运行时的统计信息,这些信息只对调试有用,会保存在RAM 中,占用RAM空间。因此,最终程序建议配置成不产生运行时统计信息。

configUSE_CO_ROUTINES

设置为1则包含co-routines 功能,如果包含了co-routines功能,则编译时需包含croutine.c 文件

configMAX_CO_ROUTINE_PRIORITIES

co-routines 可以使用的优先级的数量。

configUSE_TIMERS

设置为1则包含软件定时器功能。

configTIMER_TASK_PRIORITY

设置软件定时器任务的优先级。

configTIMER_QUEUE_LENGTH

设置软件定时器任务中用到的命令队列的长度。

configTIMER_TASK_STACK_DEPTH

设置软件定时器任务需要的任务堆栈大小。

configKERNEL_INTERRUPT_PRIORITY 和 configMAX_SYSCALL_INTERRUPT_PRIORITY

Cortex-M3, PIC24, dsPIC, PIC32, SuperH 和 RX600 的移植代码中会使用到 configKERNEL_INTERRUPT_PRIORITY.

PIC32, RX600 和 Cortex-M系列 会使用到 configMAX_SYSCALL_INTERRUPT_PRIORITY

configKERNEL_INTERRUPT_PRIORITY应该被设为最低优先级。

对那些只定义了 configKERNEL_INTERRUPT_PRIORITY 的系统:

configKERNEL_INTERRUPT_PRIORITY决定了FreeRTOS内核使用的优先级。

所有调用API函数的中断的优先级都应设为这个值,不调用API函数的中断可以设为更高的优先级。

对那些定义了configKERNEL_INTERRUPT_PRIORITY 和configMAX_SYSCALL_INTERRUPT_PRIORITY的系统:

configKERNEL_INTERRUPT_PRIORITY决定了FreeRTOS内核使用的优先级。

configMAX_SYSCALL_INTERRUPT_PRIORITY决定了可以调用API函数的中断的最高优先级。高于这个值的中断处理函数不能调用任何API 函数。

configASSERT

宏configASSERT()的作用类似C语言标准库中的宏assert(),configASSERT() 可以帮助调试,但是定义了configASSERT()后会增加程序代码,也会使程序变慢。

以INCLUDE 开头参数

以 'INCLUDE' 开头的宏允许我们将部分不需要的API 函数排除在编译生成的代码之外。这可以使内核代码占用更少的ROM 和RAM。

比如,如果代码中需要用到 vTaskDelete 函数则这样写:

#defineINCLUDE_vTaskDelete    1

如果不需要,则这样写:

#defineINCLUDE_vTaskDelete    0

转载于:https://www.cnblogs.com/tfanalysis/articles/4497271.html

FreeRTOS介绍与移植相关推荐

  1. linux模块移植到freertos,FATFS在嵌入式操作系统FreeRTOS中的移植与应用

    摘 要: FreeRTOS作为一款免费的实时操作系统,系统内核小.裁剪方便.移植性好,广泛应用于对成本敏感的小型嵌入式系统中,但是FreeRTOS本身不带文件管理功能,不便于很多需要经常进行文件存储与 ...

  2. keil工程 freertos AC5编译器移植到AC6编译器

    keil工程 freertos AC5编译器移植到AC6编译器 本文基于正点原子的rtos工程进行移植. 打开工程,将其更换为AC6编译器,然后点击编译 编译完成之后,我们可以看到有很多的错误,这里要 ...

  3. rt-thread的at组件在freeRTOS上的移植与应用

    目录 一.AT命令 二.rtthread at组件简介 三.移植到freeRTOS 3.1.数据结构 3.2.API 3.3.at client 流程 3.4.串口数据接收处理 3.5.数据缓存 -- ...

  4. STM32F407霸天虎FreeRTOS学习笔记——移植FreeRTOS到开发板上

    STM32F407霸天虎FreeRTOS学习笔记--移植FreeRTOS到开发板上 FreeRTOS源码获取 移植第一步:创建文件夹 Keil main.c 实验效果 FreeRTOS源码获取 在移植 ...

  5. The FreeRTOS Distribution(介绍、移植、类型定义)

    1 Understand the FreeRTOS Distribution 1.1 Definition :FreeRTOS Port FreeRTOS目前可以在20种不同的编译器构建,并且可以在3 ...

  6. FreeRTOS学习及移植笔记之一:开始FreeRTOS之旅

     1.必要的准备工作 工欲善其事,必先利其器,在开始学习和移植之前,相应的准备工作必不可少.所以在开始我们写要准备如下: 测试环境:我准备在STM32F103平台上移植和测试FreeRTOS系统 ...

  7. freertos zynq 移植_Zynq-7000 FreeRTOS(一)系统移植配置

    软件版本:VIvado HLx 2018.2 从FreeRTOS的官网中下载源代码: https://www.freertos.org/a00104.html 图:FreeRTOS的官网 上图中,点击 ...

  8. FreeRTOS介绍

    1.为什么学习RTOS? 作为基于ARM7.Cortex-M3硬件开发的嵌入式工程师,我一直反对使用RTOS.不仅因为不恰当的使用RTOS会给项目带来额外的稳定性风险,更重要的是我认为绝大多数基于AR ...

  9. FreeRTOS学习及移植笔记之二:在IAR和STM32F103VET上移植FreeRTOS

     上一次,我们简单的测试了FreeRTOS的基于IAR EWARMv6.4和STM32F103VET6平台的Demo,对其有了一个基本认识.接下来我们开始自己移植FreeRTOS的过程. 1.创建 ...

  10. 亲测有效的UCOSIII嵌入STM32F103C8T6实验,介绍常见移植问题,付实测代码!!!

    花了两天时间,作为一名UCOSIII系统小白终于成功地将该系统移植到了C8T6中,当LED闪烁时,成就感与喜悦感不亚于第一次用51或者STM32点亮LED.我认为类似我这样的第一次接触UCOSIII并 ...

最新文章

  1. 从零开始单排学设计模式「UML类图」定级赛
  2. java和c语言的区别_单片机为什么一直用C语言,不用其他编程语言?只有学过的知道...
  3. 缓存-分布式锁-Redisson-lock锁测试
  4. mysql query sql_sql:query 标签
  5. 西门子精智和精简面板区别_西门子S7-1200的功能与特点,应用范围介绍
  6. mobilenet V1
  7. mysql卡住如何定位_MySQL 5.7中如何定位DDL被阻塞的问题
  8. sql server 跨服务器查询数据
  9. 集群介绍 keepalived介绍 用keepalived配置高可用集群
  10. ios音乐播放器使用综述
  11. IplImage中的widthStep大小计算及原理
  12. matlab boxplot显示平均值,r – Boxplot显示平均值
  13. 获取android手机步数,获取手机健康应用中的步数和距离
  14. java手机连点脚本_自动连点器app下载 自动连点器(屏幕点击器) for Android v1.0 安卓版 下载-脚本之家...
  15. mac Android studio 使用 阿里 maven 报错
  16. redis设计秒杀活动图解
  17. 输入法规则(V模式输入)
  18. 用c++设计 公司职工的信息管理程序 求大神!!
  19. 台式计算机硬盘英寸,台式电脑硬盘和笔记本电脑硬盘有区别吗?台式机硬盘报价一般是多少?...
  20. ORB-SLAM3相对于ORB-SLAM2有哪些优势?

热门文章

  1. EF-DbUpdateException--实体类和数据库列不对应的解决方案
  2. Sql Server之旅——第二站 理解万恶的表扫描
  3. wamp2.2c集成环境搭建网站问题总结
  4. eclipse插件:OpenExplorer快速打开文件目录
  5. asp.net分页方法
  6. 新增SDK 错误解决办法
  7. 怎么把我的文档C盘的路径改到E盘啊
  8. 在PS中读取敏感数据
  9. layDate——初步使用
  10. ArcMAp10.2生成栅格数据时报错