μTenux操作系统内核μT OS v2.0.0 移植指南(STM32F401RE Nucleo开发板,寄存器版) - TenuxOS/uTOS-Puertea GitHub Wiki

μTenux操作系统内核μT/OS v2.0.0 移植指南(STM32F401RE-Nucleo开发板,寄存器版)

一、目的

本移植指南使用ST官方的STM32F4-Discovery开发板上的STM32F407VG作为参考芯片,选择ST官方的STM32F401RE-Nucleo开发板上的STM32F401RE作为移植芯片,同时升级STM32F4xx的CMSIS头文件。

二、适用范围

  • 芯片内核属于Cortex M内核;
  • 在官网发布的μT/OS内核开源代码中存在与移植目标芯片同厂商同内核同系列的参考芯片;
  • 为了能够运行全部实验例子,移植芯片的Flash超过64K,RAM超过8K。

三、技术要求

  1. 需要有以下嵌入式开发技术:
  • 能看懂芯片手册,能通过外设寄存器和CMSIS中的外设结构定义对时钟、GPIO、UART等芯片外设编程;
  • 能使用Keil RealView MDK开发环境;
  • 能独立下载并且按照手册在参考芯片上构造μT/OS内核,以及运行样例代码。
  1. 参考文档
序号 文档名
1 μT/OS V2.0.0 移植指南
2 μT/OS V2.0.0 内核支持开发板列表
3 μT/OS V2.0.0 内核配置指南
4 STM32 Nucleo-64 boards User manual
5 STM32F401xE Datasheet
6 STM32F401xE Reference manual

四、准备工作

按照说明列填写对照表,判断需要移植的技术点(粗体表示需要移植的不同点),其中参考芯片的信息是从《μT/OS V2.0.0 内核支持开发板列表》而来,移植芯片的信息是从《STM32 Nucleo-64 boards User manual》和《STM32F401xE Reference manual》而来。

序号 大类别 小类别 参考芯片 移植芯片 说明
1 开发板 名称 STM32F4-Discovery STM32F401RE-Nucleo 查看开发板手册或者包装
2 芯片 STM32F407VG STM32F401RE 查看开发板手册(同厂商同系列)
3 晶振 8M 16M(内部) 查看开发板手册或者电路原理图
4 芯片 内核/指令集 Cortex M4F Cortex M4F 查看芯片手册(同内核),对于M4确认FPU
5 主频 168M 84M 查看芯片手册,一般是CPU的最快或可能频率,最高84M
6 定时器 Systick Systick 对于CM内核默认使用Systick,低功耗芯片使用外部定时器
7 异常中断 98个 98个 查看芯片手册,包括内核异常和外设中断
8 Flash 1024K 512K 查看芯片手册,一般是芯片的第一块连续区域
9 RAM 112K 96K 查看芯片手册,一般是芯片的第一块连续区域
10 管脚 RX PC11/TX PC10 RX PA3/TX PA2 查看开发板手册或者电路原理图中选定UART使用的管脚
11 串口 USART3 USART2 查看开发板手册或者电路原理图中确定使用的UART
12 软件 CMSIS系列名称 STM32F4xx V1.2.0RC2 STM32F4xx V1.8.0 查看开发板配套驱动软件包,或者从芯片厂商的网站上下载(同系列)
13 EWARM V7.10 - 最好相同版本,因为不支持,-标注
14 MDK V5.10 V5.24a 最好相同版本,如果不支持,-标注
15 μT/Studio V4.00 - 最好相同版本,因为不支持,-标注

五、创建目录和复制文件

按照说明列填写下表,创建和复制目录和文件(粗体表示创建、斜体表示复制)。

序号 目录 说明
1 Maker 所有厂商以及具体芯片移植相关文件的目录
2 └ST └意法芯片移植相关文件的目录
3 └─Libraries └─相关系列CMSIS标准头文件、外设库文件
4 └──CMSIS └──CMSIS约定目录
5 └───Device └───本目录以下目录是CMSIS规范要求的
6 └────ST └────芯片厂商名称和第2级目录相同
7 └─────STM32F4xx └─────参考芯片的CMSIS系列文件目录(同系列
8 └──────Include └──────芯片定义头文件目录以及两个头文件 直接从芯片厂商
9 └───────stm32f4xx.h └───────提供的芯片CMSIS驱动软件包中复制过来(新版),替换。
10 └───────system_stm32f4xx.h └───────同上
11 └─STM32F4-Discovery └─参考芯片的开发板移植文件目录
12 └─STM32F401RE-Nucleo └─移植芯片的开发板移植文件目录
13 └──App └──应用程序的文件目录
14 └───usermain.c └───应用入口程序文件
15 └──Config └──芯片级内核配置文件以及芯片BSP文件目录
16 └───tk_config_depend.h └───芯片内核配置文件
17 └───tm_bsp.c/.h └───芯片BSP文件
18 └───tm_monitor.c/.h └───芯片内核控制台输入输出文件
19 └──MDK └──REALVIEW MDK工程相关文件目录
20 └───startup.S └───芯片启动代码文件
21 └───uTenux.uvmpw └───工程的工作平台文件
22 └───uTenux.uvoptx └───工程的项目文件,MDK打开后,会把 uTenux.uvopt升级为 uTenux.uvoptx
23 └───uTenux.uvprojx └───工程的项目文件,MDK打开后,会把 uTenux.uvproj升级为 uTenux.uvprojx
24 └───uTenux-flash.sct └───芯片链接脚本文件
25 uTOS μT/OS实时内核和具体芯片移植无关文件的目录

六、修改代码

按照说明列填写下表,修改代码(粗体表示修改)
1、tk_config_depend.h:

序号 内存区域配置宏定义 功能 参考芯片值 移植芯片值 说明
1 TK_ROM_VECTORAREA_TOP Flash向量表起始地址 0x08000000UL 0x08000000UL 查看芯片手册
2 TK_ROM_VECTORAREA_END Flash向量表结束地址 0x08000188UL 0x08000188UL 1项+向量数量*4字节
3 TK_ROM_VECTOR_NUMBER Flash向量数量 98U 98U 包括异常和外设中断
4 TK_RAM_TOTALAREA_TOP 内存开始地址 0x20000000UL 0x20000000UL CM统一内存起始地址
5 TK_RAM_VECTORAREA_TOP 内存向量表起始地址 0x20000000UL 0x20000000UL 同上
6 TK_RAM_VECTORAREA_END 内存向量表结束地址 0x20000188UL 0x20000188UL 上项+向量数量*4字节
7 TK_RAM_BSSDATAAREA_TOP BSS和DATA段起始地址 0x20000188UL 0x20000188UL 和上项相同,内存衔接
8 TK_RAM_BSSDATAAREA_END BSS和DATA段结束地址 0x20002000UL 0x20002000UL 根据链接信息调整
9 TK_RAM_SYSTEMAREA_TOP 系统管理区域起始地址 0x20002000UL 0x20002000UL 和上项相同,内存衔接
10 TK_RAM_SYSTEMAREA_END 系统管理区域结束地址 0x2001b000UL 0x20017000UL 尽量大,系统动态分配
11 TK_RAM_USERAREA_TOP 用户管理区域起始地址 0x2001b000UL 0x20017000UL 和上项相同,内存衔接
12 TK_RAM_USERAREA_END 用户管理区域结束地址 0x2001c000UL 0x20018000UL 根据用户用途调整
13 TK_RAM_STACKAREA_TOP 启动代码所用栈底地址 0x2001c000UL 0x20018000UL 芯片内存最高端
14 TK_RAM_STACKAREA_END 启动代码所用栈顶地址 0x2001c000UL 0x20018000UL 芯片内存最高端
15 TK_RAM_TOTALAREA_END 内存结束地址 0x2001c000UL 0x20018000UL 芯片内存最高端
16 TK_RAM_VECTOR_NUMBER 内存向量数量 98U 98U 同3项
序号 系统时钟配置宏定义 功能 参考芯片值 移植芯片值 说明
1 TK_USE_SYSTICK_LESS 内核定时器的来源 0U 0U 内部定时器设置为0
2 KNL_CFG_TIMER_CLOCK 内核定时器的时钟频率 168U 84U 定时器输入时钟频率
序号 内核对象配置宏定义 功能 参考芯片值 移植芯片值 说明
1 KNL_CFN_MAX_TSKID 任务最大数量 10 10
2 KNL_CFN_MAX_SEMID 信号量最大数量 4 4
3 KNL_CFN_MAX_FLGID 事件标志最大数量 4 4
4 KNL_CFN_MAX_MBXID 邮箱最大数量 2 2
5 KNL_CFN_MAX_MTXID 互斥体最大数量 2 2
6 KNL_CFN_MAX_MBFID 消息缓冲区最大数量 2 2
7 KNL_CFN_MAX_PORID 集合点端口最大数量 2 2
8 KNL_CFN_MAX_MPLID 可变尺寸内存池最大数量 2 2
9 KNL_CFN_MAX_MPFID 固定尺寸内存池最大数量 2 2
10 KNL_CFN_MAX_CYCID 周期性处理最大数量 2 2
11 KNL_CFN_MAX_ALMID 警报处理最大数量 2 2
  • 如果上表中BSS和DATA段区域内存<=4K,尽量压缩系统对象种类和数量,在运行成功地基础上再根据需要扩大对象的数量和种类;
  • 如果上表中BSS和DATA段区域内存> 4K,不修改或者根据需要扩大数量。
序号 内核信息配置宏定义 功能 参考芯片值 移植芯片值 说明
1 KNL_CFN_BOOT_MESSAGE 启动时在串口输出的提示信息 STM32F407VG STM32F401RE 修改MCU型号信息

2、tm_bsp.h:如果有需要在芯片CMSIS头文件使用的宏,比如晶振频率等,在包含之前先进行定义

序号 芯片CMSIS头文件包含语句 功能 参考芯片值 移植芯片值 说明
1 #include <头文件> 需要使用芯片外设的结构以及常量宏定义 stm32f4xx.h stm32f4xx.h 包含第四节表中的第11行
2 #define HSx_VALUE 定义外部晶振频率 8000000U 16000000U 包含第四节表中的第3行,X=E表示外部,X=I表示内部

3、tm_bsp.c:

序号 外设初始化函数定义 功能 说明
1 void tm_initrcc(void) 时钟初始化 如果第四节表中的晶振和主频变化,修改实现代码
2 void tm_initflash(void) Flash控制器初始化 一般不修改,除非主频变化太大,导致执行出现错误
3 void tm_initwdg(void) 看门狗初始化 不修改
4 void tm_inituart(void) UART初始化 如果第四节表中主频、管脚、串口变化,修改代码
5 void tm_initbsp ( void ) BSP初始化 不修改
6 void tm_senduart(uint8_t c) UART发送字符 如果第四节表中的串口变化,修改实现代码
7 uint8_t tm_recvuart(void) UART接收字符 如果第四节表中的串口变化,修改实现代码
参考芯片代码(USART3(PC10\PC11)、外部8M晶振、168MHz主频)
126行:
void tm_initrcc(void)
{
    uint32_t data;

    /* Enable HSE */
    RCC->CR |=  RCC_CR_HSEON;

    /* Test if HSE is ready */
    while( (RCC->CR & RCC_CR_HSERDY) == 0u ){
        ;
    }

    /* Set HCLK=SYSCLK,PCLK2=HCLK/2,PCLK1=HCLK/4 */
    RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_HPRE)) | RCC_CFGR_HPRE_DIV1;
    RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_PPRE2)) | RCC_CFGR_PPRE2_DIV2;
    RCC->CFGR = (RCC->CFGR & ~(RCC_CFGR_PPRE1)) | RCC_CFGR_PPRE1_DIV4;


    /* Set HSE as PLL source,and Enable PLL, P=2,M=8/25,N=336 */
    RCC->PLLCFGR &= ( (~RCC_PLLCFGR_PLLSRC) & (~RCC_PLLCFGR_PLLP) & \
              (~RCC_PLLCFGR_PLLN)&(~RCC_PLLCFGR_PLLM) );
    RCC->PLLCFGR |= ( RCC_PLLCFGR_PLLSRC_HSE | \
            RCC_PLLCFGR_PLLN_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_8 | \
            (HSE_VALUE/1000000u) );

    RCC->CR |= RCC_CR_PLLON;

    /* Test if PLL is ready */
    while( (RCC->CR & RCC_CR_PLLRDY) == 0u ){
        ;
    }

    /* Switch pll as system clock */
    data = ( RCC->CFGR & (~RCC_CFGR_SW )) | RCC_CFGR_SW_PLL;
    RCC->CFGR = data;

    /* Test if pll switch successfully */
    while( (RCC->CFGR & RCC_CFGR_SWS_PLL) == 0u ){
        ;
    }

    return;
}

192行:
static void tm_inituart(void)
{
    uint32_t data;

    /* GPIOC clock enable */
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;

    /* USART3 clock enable */
    RCC->APB1ENR |= RCC_APB1ENR_USART3EN;

    /* set PC10/PC11 to Alternate function for USART3 transmit/receive */
    data = GPIOC->MODER;
    data &= (~GPIO_MODER_MODER10);
    data |= ( GPIO_MODER_MODER10_1 );
    GPIOC->MODER = data;

    data = GPIOC->OTYPER;
    data &= ( ~(GPIO_OTYPER_OT_10) );
    GPIOC->OTYPER = data;

    data = GPIOC->PUPDR;
    data &= ( ~(GPIO_PUPDR_PUPDR10) );
    data |= (GPIO_PUPDR_PUPDR10_0 );
    GPIOC->PUPDR = data;

    data = GPIOC->OSPEEDR;
    data &= ( ~(GPIO_OSPEEDER_OSPEEDR10) );
    data |= ( GPIO_OSPEEDER_OSPEEDR10_1 );
    GPIOC->OSPEEDR = data;

    data = GPIOC->AFR[1];
    data &= ( ~( GPIO_AFR_MASK<
    data |= ( GPIO_AFR_AF7<
    GPIOC->AFR[1] = data;

    data = GPIOC->MODER;
    data &= (~GPIO_MODER_MODER11);
    data |= ( GPIO_MODER_MODER11_1 );
    GPIOC->MODER = data;

    data = GPIOC->PUPDR;
    data &= ( ~(GPIO_PUPDR_PUPDR11) );
    data |= (GPIO_PUPDR_PUPDR11_0 );
    GPIOC->PUPDR = data;

    data = GPIOC->OSPEEDR;
    data &= ( ~(GPIO_OSPEEDER_OSPEEDR11) );
    data |= ( GPIO_OSPEEDER_OSPEEDR11_1 );
    GPIOC->OSPEEDR = data;

    data = GPIOC->AFR[1];
    data &= ( ~( GPIO_AFR_MASK<
    data |= ( GPIO_AFR_AF7<
    GPIOC->AFR[1] = data;

    /* Disable USART and TX and RX */
    USART3->CR1 &= 0xdff3u;

    /* Clear STOP bit,CLKEN,CPOL,CPHA */
    USART3->CR2 &= 0x8060u;

    /* Set 8bit,non parity,no interupt */
    USART3->CR1 &= 0xe80Fu;

    /* Disable CTS and DMA */
    USART3->CR3 &= 0xf800u;

    /* Set baud=115200bps */
    USART3->BRR = 0x016cu;

    /* Enable receiver and transmitter and USART */
    USART3->CR1 |= 0x200cu;

    return;
}

295行:
void tm_senduart(uint8_t c)
{
    /* Wait for the transmitter to be ready while */
    while( (USART3->SR & USART_SR_TXE) == 0u){
        ;
    }

    /* Send character */
    USART3->DR = c;

    /* Wait for the transmitter to be ready while */
    while( (USART3->SR & USART_SR_TXE) == 0u){
            ;
    }

    return;
}

321行:
uint8_t tm_recvuart(void)
{
    uint8_t c;

    /* Wait for the receiver to be ready while */
    while( ((USART3->SR) & USART_SR_RXNE) == 0u){
         ;
    }

    c = (uint8_t)USART3->DR;

    return c;
}
移植芯片代码(USART2(PA2\PA3)、内部16M晶振、84MHz主频)
126行:                                                        /* 说明:HSE更改为HSI,M从8更改为16,N从336更改为168,同时修改了一些代码的风格 */
void tm_initrcc(void)
{
    /* Enable HSI */
    RCC->CR |=  RCC_CR_HSION;

    /* Test if HSI is ready */
    while( (RCC->CR & RCC_CR_HSIRDY) == 0u ){
        ;
    }

    /* Set HCLK=SYSCLK,PCLK2=HCLK,PCLK1=HCLK/2 */
    RCC->CFGR &= (~RCC_CFGR_HPRE);
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;

    RCC->CFGR &= (~RCC_CFGR_PPRE2);
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;

    RCC->CFGR &= (~RCC_CFGR_PPRE1);
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;

    /* Set HSI as PLL source,and Enable PLL, P=2,M=16,N=168 */
    RCC->PLLCFGR &= ( (~RCC_PLLCFGR_PLLSRC) & 
                      (~RCC_PLLCFGR_PLLP) & \
                      (~RCC_PLLCFGR_PLLN) & \
                      (~RCC_PLLCFGR_PLLM) );
    RCC->PLLCFGR |= ( RCC_PLLCFGR_PLLSRC_HSI | \
                      RCC_PLLCFGR_PLLN_3 | \
                      RCC_PLLCFGR_PLLN_5 | \
                      RCC_PLLCFGR_PLLN_7 | \
                     (HSI_VALUE/1000000u) );

    RCC->CR |= RCC_CR_PLLON;

    /* Test if PLL is ready */
    while( (RCC->CR & RCC_CR_PLLRDY) == 0u ){
        ;
    }

    /* Switch pll as system clock */
    RCC->CFGR &= (~RCC_CFGR_SW);
    RCC->CFGR |= RCC_CFGR_SW_PLL;

    /* Test if pll switch successfully */
    while( (RCC->CFGR & RCC_CFGR_SWS_PLL) == 0u ){
        ;
    }

    return;
}

192行:                                                        /* 说明:USART3更改为USART2,USART2和3都在APB1总线上,而且总线频率都是42MHz */  
static void tm_inituart(void)
{
    uint32_t data;

    /* GPIOA clock enable */
    RCC->AHBENR |= RCC_AHBENR_GPIOAEN;

    /* USART2 clock enable */
    RCC->APB1ENR |= RCC_APB1ENR_USART2EN;

    /* set PA2/PA3 to Alternate function for USART2 transmit/receive */
    data = GPIOA->MODER;
    data &= (~GPIO_MODER_MODER2);
    data |= ( GPIO_MODER_MODER2_1 );
    GPIOA->MODER = data;

    data = GPIOA->OTYPER;
    data &= ( ~(GPIO_OTYPER_OT_2) );
    GPIOA->OTYPER = (uint16_t)data;

    data = GPIOA->PUPDR;
    data &= ( ~(GPIO_PUPDR_PUPDR2) );
    data |= (GPIO_PUPDR_PUPDR2_0 );
    GPIOA->PUPDR = data;

    data = GPIOA->OSPEEDR;
    data &= ( ~(GPIO_OSPEEDER_OSPEEDR2) );
    data |= ( GPIO_OSPEEDER_OSPEEDR2 );
    GPIOA->OSPEEDR = data;

    data = GPIOA->AFR[0];
    data &= ( ~( GPIO_AFR_MASK << GPIO_AFRL_SHIFT(2u) ) );
    data |= ( GPIO_AFR_AF1 << GPIO_AFRL_SHIFT(2u) );
    GPIOA->AFR[0] = data;

    data = GPIOA->MODER;
    data &= (~GPIO_MODER_MODER3);
    data |= ( GPIO_MODER_MODER3_1 );
    GPIOA->MODER = data;

    data = GPIOA->PUPDR;
    data &= ( ~(GPIO_PUPDR_PUPDR3) );
    data |= (GPIO_PUPDR_PUPDR3_0 );
    GPIOA->PUPDR = data;

    data = GPIOA->OSPEEDR;
    data &= ( ~(GPIO_OSPEEDER_OSPEEDR3) );
    data |= ( GPIO_OSPEEDER_OSPEEDR3 );
    GPIOA->OSPEEDR = data;

    data = GPIOA->AFR[0];
    data &= ( ~( GPIO_AFR_MASK << GPIO_AFRL_SHIFT(3u) ) );
    data |= ( GPIO_AFR_AF1 << GPIO_AFRL_SHIFT(3u) );
    GPIOA->AFR[0] = data;

    /* Disable USART and TX and RX */
    USART2->CR1 &= 0xdff3u;

    /* Clear STOP bit,CLKEN,CPOL,CPHA */
    USART2->CR2 &= 0x8060u;

    /* Set 8bit,non parity,no interupt */
    USART2->CR1 &= 0xe80fu;

    /* Disable CTS and DMA */
    USART2->CR3 &= 0xf800u;

    /* Set baud=115200bps */
    USART2->BRR = 0x016cu;

    /* Enable receiver and transmitter and USART */
    USART2->CR1 |= USART_CR1_MME | USART_CR1_RE | USART_CR1_TE | USART_CR1_UE;

    return;
}

295行:                                                        /* 说明:USART3更改为USART2 */   
void tm_senduart(uint8_t c)
{
    /* Wait for the transmitter to be ready while */
    while( (USART2->SR & USART_SR_TXE) == 0u){
        ;
    }

    /* Send character */
    USART2->DR = c;

    /* Wait for the transmitter to be ready while */
    while( (USART2->SR & USART_SR_TXE) == 0u){
            ;
    }

    return;
}

321行:                                                        /* 说明:USART3更改为USART2 */ 
uint8_t tm_recvuart(void)
{
    uint8_t c;

    /* Wait for the receiver to be ready while */
    while( ((USART2->SR) & USART_SR_RXNE) == 0u){
         ;
    }

    c = (uint8_t)USART2->DR;

    return c;
}
 

七、设置KEIL MDK开发环境

按照说明列填写下表,修改环境选项(粗体表示修改)
1、Target名称:

序号 窗口 功能 参考芯片值 移植芯片值 说明
1 Project窗口 显示构成Project的Target以及下属的Group和文件 参考芯片Target设置 移植芯片Target设置 使用移植芯片开发板名称

2、编译选项:

序号 Tab 条目 参考芯片值 移植芯片值 说明
1 Device Device STM32F407VG STM32F401RE 选择移植芯片型号
2 C/C++ Preprocessor Symbols STM32F40XX STM32F401xx 设置芯片子系列宏定义
3 Include paths STM32F4xx STM32F4xx 参考第三节表中CMSIS系列名称修改包含头文件路径
4 Asm Include paths STM32F4xx STM32F4xx

3、uTenux-flash.sct:

序号 条目 地址 参考芯片值 移植芯片值 说明
1 LOAD_INTERFLASHROM EXEC_INTERROM 起始地址 0x08000000 0x08000000 参考第六节表中第1行修改
2 容量 0x00100000 0x00080000 参考第四节表中Flash大小修改
3 EXEC_VECTORRAM 起始地址 0x20000000 0x20000000 参考第六节表第5、6行修改
4 容量 0x00000188 0x00000188
5 EXEC_BSSDATARAM 起始地址 0x20000188 0x20000188 参考第六节表中第7、8行修改
6 容量 0x00001e78 0x00001e78
7 EXEC_SYSTEMRAM 起始地址 0x20002000 0x20002000 参考第六节表中第9、10行修改
8 容量 0x00019000 0x00015000
9 EXEC_USERRAM 起始地址 0x2001b000 0x20017000 参考第六节表中第11、12行修改
10 容量 0x00001000 0x00001000
11 EXEC_STACKRAM 起始地址 0x2001c000 0x20018000 参考第六节表中第13、14行修改
12 容量 0x00000000 0x00000000

4、调试:编译链接通过后,下载到开发板上,确认输出了内核的启动信息,并且按任意键系统关闭

八、进行测试

  1. 对于芯片内存>=8K的移植芯片,按照实验手册运行所有的例子,确认正常;(本移植芯片有效
  2. 对于芯片内存<8K的移植芯片,按照第六节调整内核对象配置数量,可以运行实验手册个别例子,确认正常。(本移植芯片无效

九、总结规模和效率

序号 类别 条目 参考芯片值 移植芯片值 说明
1 规模 代码行数 194 140 所有文件只计算修改的代码行,不包括文件头注释和函数头注释
2 效率 开发人时 - 5 统计第四节到第七节的累计时间
3 测试人时 1 1 统计第八节的累计时间

十、感谢篇

感谢您使用μTenux®嵌入式操作系统系列产品,有何意见与建议,非常欢迎您与我们联系。

社 区:Tenux开源社区

电 话:+86-13387892890

主 页:www.tenux.org、www.tenux.cn

微 博:Tenux开源社区@新浪微博

微 信:Tenux-RTOS

十一、移植历史

序号 状态 版本 修改内容 修改位置 修改人 日期
1 C 0.50 支持Keil MDK开发环境,第1次移植 全文 王绍斌 2017/08/28
2 M 0.60 格式改为MD 全文 王绍斌 2017/09/15
3 M 0.61 修正在华为云上MD表格乱码,加目录 全文 王绍斌 2017/09/16
4 M 0.70 修正开发板名称,重排版对齐 全文 王绍斌 2017/10/21

状态:C—创建文档,A—增加内容,M—修改内容,D—删除内容

⚠️ **GitHub.com Fallback** ⚠️