查看: 2234|回复: 0

我来教你如何将uTenux移植到GD32F207ZE小红板

[复制链接]

该用户从未签到

发表于 2016-3-11 09:56:00 | 显示全部楼层 |阅读模式
分享到:
GD32系列MCU作为较罕见的国产MCU产品表现出了很高的品质,特别是GD32F207ZET6芯片为基于Cortex-M3内核的通用MCU属于一款较高端的产品。
   目前国产的RTOS更是百花齐放,既有trochiliOS,还有RT-Thread、SylixOS、djyos、raw-os、uTenux等等。在这里选择了uTenux移植到小红板。
   uTenux实时操作系统是由大连悠龙软件公司以基于TRON标准的T-Kernel精简版本uT/Kernel为核心开发的,主要针对ARM系列微控制器从ARM7/9至Cortex M系列。在大连悠龙的官网上有关于uTenux的具体介绍,这里不再过多说明。
   接下来,对uTenux的移植进行介绍。
   根据GD32F207ZE小红板自带的软件(GD32-Colibri-F207ZE-DEMO)我们看到其已经对小红板的led、uart、key等给出了BSP(目录board中),因此这对方便我们移植起到了帮助。本次移植要实现led点亮和uart打印输出的功能以帮助测试uTenux。
从悠龙公司官网下载uTenux的源码包,目前最新版的uTenux为V2.0.00r400版,本移植工作就是针对这一版本进行。解压下载的源码包,可以在其中看到有uTenux的内核文件(source)、说明文件(manual)、代码示例(sample)等多个文件夹。其中uTenux与具体芯片无关的内核文件位于目录/source/uTenux/uTOS中,可将其整体复制到准备新建的工程中使用。
      采用Keil MDK 5.16a工具进行移植开发工作。建立的文件目录如图所示,其中

uTOS中存放为上述的uTenux与具体芯片无关的内核文件;
Obj中为建立的keil工程文件;
GD32F207ZET6中为小红板的所有硬件相关文件;
App中为用户主程序和任务应用程序;
    实现uTenux在小红板上的移植主要是对tk_config_depend.h、tm_monitor.c和startup_gd32f20x.s三个文件进行修改。
    tk_config_depend.h中定义了所移植芯片的一些参数,以及对uTenux的配置参数,具体设置可以参考文件《uTOS内核移植指南_uTenux_uTOS_Porting_Guide_C》;

  • #ifndef __TK_CONFIG_DEPEND_H__
  • #define __TK_CONFIG_DEPEND_H__

  • #ifdef __cplusplus
  • extern "C" {
  • #endif

  • /*
  • * Vector ROM region definition, must be same as with startup code.
  • */
  • #define TK_ROM_VECTORAREA_TOP   0x08000000UL   /* ROM VCETOR table start     */
  • #define TK_ROM_VECTORAREA_END   0x080001A8UL   /* ROM VCETOR table end   418B */
  • #define TK_ROM_VECTOR_NUMBER         106U   /* ROM VCETOR table size      */

  • /*
  • * Kernel RAM region definition, ram region defined in link script must be same.
  • */
  • #define TK_RAM_TOTALAREA_TOP     0x20000000UL   /* Total Internal RAM start    */
  • #define TK_RAM_VECTORAREA_TOP   0x20000000UL   /* RAM VCETOR table start     */
  • #define TK_RAM_VECTORAREA_END   0x200001A8UL   /* RAM VCETOR table end   0.4K */
  • #define TK_RAM_BSSDATAAREA_TOP    0x200001A8UL   /* Bss and Data area start   */
  • #define TK_RAM_BSSDATAAREA_END    0x20002000UL   /* Bss and Data area end 7.6k */
  • #define TK_RAM_SYSTEMAREA_TOP   0x20002000UL   /* Kernel malloc area start    */
  • #define TK_RAM_SYSTEMAREA_END   0x20012000UL   /* Kernel malloc area end 64k */
  • #define TK_RAM_USERAREA_TOP      0x20012000UL   /* User manual area start     */
  • #define TK_RAM_USERAREA_END      0x20020000UL   /* User manual area end    56k */
  • #define TK_RAM_STACKAREA_TOP     0x20020000UL   /* Stack startup area start    */
  • #define TK_RAM_STACKAREA_END     0x20020000UL   /* Stack startup area end   0k */
  • #define TK_RAM_TOTALAREA_END     0x20020000UL   /* Total Internal RAM end 128k */
  • #define TK_RAM_VECTOR_NUMBER         106U   /* RAM VCETOR table size      */

  • /*
  • * Use Chip Deep Sleep ( Stop and Standby ) function
  • */
  • #define TK_USE_POW_DEEP       0U          /* 0isable 1:Enable */

  • /*
  • * Kernel tick source timer clock function and definition
  • */
  • #define TK_USE_SYSTICK_LESS      0U          /* 0: use systick, 1: use other timer */
  • #define KNL_CFG_TIMER_CLOCK      72U       /* Timer clock input(MHz)¡ê?select MCK */
  • #define KNL_CFG_TIMER_INTLEVEL    0U          /* Timer interrupt level */
  • #define KNL_CFG_TIMER_PERIOD     10U         /* Timer period(ms), between 1 and 50 */

  • /*
  • * System object number config
  • */
  • #define KNL_CFG_MAX_TSKID       8
  • #define KNL_CFG_MAX_SEMID       4
  • #define KNL_CFG_MAX_FLGID       4
  • #define KNL_CFG_MAX_MBXID       2
  • #define KNL_CFG_MAX_MTXID       2
  • #define KNL_CFG_MAX_MBFID       2
  • #define KNL_CFG_MAX_PORID       2
  • #define KNL_CFG_MAX_MPLID       2
  • #define KNL_CFG_MAX_MPFID       2
  • #define KNL_CFG_MAX_CYCID       2
  • #define KNL_CFG_MAX_ALMID       2

  • /*
  • * Task priority config
  • */
  • #define KNL_CFG_MAX_PRI       16U                 /* Large means low priority */

  • /*
  • * Use dynamic memory allocation when kernel init
  • */
  • #define TK_USE_MALLOC          1U

  • /*
  • * Use dynamic exception and high level programming language handler support define
  • */
  • #define TK_USE_INT_DEFHDR       1U          /* Dynamic exception handler support */
  • #define TK_USE_INT_HLLHDR       1U          /* High level program language support*/

  • /*
  • * Use FPU for active FPU function
  • */
  • #define TK_USE_FPU            0U          /* 0isable 1:Enable */

  • /*
  • * Use clean-up sequence when kernel exit
  • */
  • #define KNL_CFG_USE_CLEANUP      1U

  • /*
  • * Debugger support function
  • *   0: Invalid
  • *   1: Valid
  • */
  • #define TK_USE_DBGSPT          0U

  • /*
  • * Use program trace function (in debugger support)
  • */
  • #define TK_USE_HOOK_TRACE       0U

  • /*
  • * Use object name to each control block
  • *   0: Do not use object name
  • *   1: Use object name
  • */
  • #define TK_USE_OBJ_NAME       1U
  • #define TK_OBJ_NAME_LENGTH     8U          /* Object name length (Byte) */

  • /*
  • * Use tm_monitor to output kernel message
  • */
  • #define TK_USE_TM_MONITOR       1U

  • /*
  • * Output (error) messages from Kernel
  • *   0: Do not output message
  • *   1: Output message
  • */
  • #define TK_USE_MESSAGE         1U

  • /*
  • * Predefined boot message
  • */
  • #define KNL_CFG_BOOT_MESSAGE \
  •          "\n" \
  •          "-------------------------------------------------------\n" \
  •          "               micro Tenux               \n" \
  •          "         Supported MCU is GD32F207ZET6         \n" \
  •          "               (build 0400)             \n" \
  •          " Copyright(c) 2008-2014 by Tenux Open Source Society \n" \
  •          "-------------------------------------------------------\n" \
  •          "\n\0"

  • #ifdef __cplusplus
  • }
  • #endif

  • #endif /* __TK_CONFIG_DEPEND_H__ */
复制代码
   tm_monitor.c中主要是用于uTenux输出信息的一些函数,需要对其与小红板BSP进行适配修改,这里只需小的修改就可和小红板自带DEMO中colibri_bsp_uart.c文件中的函数进行替换;

  • #include "colibri_bsp_uart.h"
  • #include "gd32f20x.h"
  • #include <tm_monitor.h>


  • #if TK_USE_TM_MONITOR

  • /* Definition of normal control char */
  • #define TM_CHAR_NUL        0x00U           /* null character */
  • #define TM_CHAR_ETX        0x03U           /* end of text character */
  • #define TM_CHAR_CR       0x0DU           /* carriage return character */
  • #define TM_CHAR_LF       0x0AU           /* line feed character */

  • /*
  • *    Function Name : tm_getchar
  • *    Create Date   : 2013/2/18-2014/4/1
  • *    Author     : wangshb
  • *    Description   : disable interrupt,then receive char from console,util success
  • *             supported only on wait != 0 (polling not supported)
  • *    Param       : int32_t wait: no used
  • *    Return Code   : int32_t c: char to receive
  • */
  • int32_t tm_getchar( int32_t wait )
  • {
  •     uint8_t c;
  •     uint32_t imask;
  •         char character;

  •     /* Disable interrupt */
  •     imask = __get_PRIMASK();
  •     __set_PRIMASK( 0x1u );

  •     //c = tm_recvuart();
  •         EvbUart1ReadByte(&character);
  •         c = (uint8_t)character;

  •     /* Enable interrupt */
  •     __set_PRIMASK( imask );

  •     return (int32_t)c;
  • }

  • /*
  • *    Function Name : tm_getline
  • *    Create Date   : 2013/2/18-2014/4/1
  • *    Author     : wangshb
  • *    Description   : disable interrupt,then receive a line from console,util success
  • *             special key is not supported
  • *    Param       : uint8_t *buff: buffer to save one line chars
  • *    Return Code   : int32_t len: line length to receive
  • */
  • int32_t tm_getline( uint8_t *buff )
  • {
  •     int32_t len = 0;
  •     uint32_t imask;

  •     /* Disable interrupt */
  •     imask = __get_PRIMASK();
  •     __set_PRIMASK( 0x1u );

  •     for (;;) {
  •      //*buff = tm_recvuart();
  •                  EvbUart1ReadByte(buff);
  •      //tm_senduart(*buff);                /* echo back */
  •                  EvbUart1WriteByte(*buff);
  •      if ( *buff == TM_CHAR_CR ) {
  •          //tm_senduart(TM_CHAR_LF);
  •                              EvbUart1WriteByte(TM_CHAR_LF);
  •          *buff = TM_CHAR_NUL;
  •      } else if ( *buff == TM_CHAR_ETX ) {
  •          *buff = TM_CHAR_NUL;
  •          len = -1;
  •      }
  •      if ( *buff == TM_CHAR_NUL ) {
  •          break;
  •      }
  •      len++;
  •      buff++;
  •     }

  •     /* Enable interrupt */
  •     __set_PRIMASK( imask );

  •     return len;
  • }
  • #endif /* TK_USE_TM_MONITOR */

  • /*
  • *    Function Name : tm_monitor
  • *    Create Date   : 2013/2/18-2013/4/26
  • *    Author     : wangshb
  • *    Description   : Empty loop
  • *    Param       : none
  • *    Return Code   : none
  • */
  • void tm_monitor( void )
  • {
  •     for(;;) {
  •      ;
  •     }
  • }

  • #if TK_USE_TM_MONITOR
  • /*
  • *    Function Name : tm_putchar
  • *    Create Date   : 2013/2/18-2014/4/1
  • *    Author     : wangshb
  • *    Description   : send a char to console util success
  • *             Ctrl-C is not supported
  • *    Param       : int32_t c: char to send
  • *    Return Code   : int32_t len: not used
  • */
  • int32_t tm_putchar( int32_t c )
  • {
  •     uint8_t buf = (uint8_t)c;
  •     uint32_t imask;

  •     /* Disable interrupt */
  •     imask = __get_PRIMASK();
  •     __set_PRIMASK( 0x1u );

  •     if (buf == TM_CHAR_LF) {
  •      //tm_senduart(TM_CHAR_CR);
  •                  EvbUart1WriteByte(TM_CHAR_CR);
  •     }
  •     //tm_senduart(buf);
  •             EvbUart1WriteByte(buf);

  •     /* Enable interrupt */
  •     __set_PRIMASK( imask );

  •     return 0;
  • }

  • /*
  • *    Function Name : tm_putstring
  • *    Create Date   : 2013/2/18-2014/4/1
  • *    Author     : wangshb
  • *    Description   : send a string to console util success
  • *             Ctrl-C is not supported
  • *    Param       : const uint8_t *buff: string to send
  • *    Return Code   : int32_t len: not used
  • */
  • int32_t tm_putstring( const uint8_t *buff )
  • {
  •     uint32_t imask;

  •     /* Disable interrupt */
  •     imask = __get_PRIMASK();
  •     __set_PRIMASK( 0x1u );

  •     while ( *buff != TM_CHAR_NUL ) {
  •      if (*buff == TM_CHAR_LF) {
  •          //tm_senduart(TM_CHAR_CR);
  •                              EvbUart1WriteByte(TM_CHAR_CR);
  •      }
  •      //tm_senduart(*buff);
  •                      EvbUart1WriteByte(*buff);
  •      buff++;
  •     }

  •     /* Enable interrupt */
  •     __set_PRIMASK( imask );

  •     return 0;
  • }
  • #endif /* TK_USE_TM_MONITOR */
复制代码
   startup_gd32f20x.s中为小红板的启动文件,是汇编语言写的。这里需要将sysTick和PendSV所对应的中断处理函数替换为uTenux所提供的函数;

  • Stack_Size        EQU   0x400

  •              AREA    STACK, NOINIT, READWRITE, ALIGN = 3
  • Stack_Mem       SPACE   Stack_Size
  • __initial_sp

  • ;// <h> Heap Configuration
  • ;//   <o> Heap Size (in Bytes) <0-4096:8>
  • ;// </h>
  • Heap_Size       EQU   0x200

  •              AREA    HEAP, NOINIT, READWRITE, ALIGN = 3
  • __heap_base
  • Heap_Mem         SPACE   Heap_Size
  • __heap_limit

  •              IMPORT knl_dsp_entry                [WEAK]
  •                             IMPORT knl_int_tckhdr               [WEAK]

  •              PRESERVE8
  •              THUMB

  • ; Vector table entries with the exceptions ISR address
  •              AREA    RESET, DATA, READONLY
  •              EXPORT __Vectors
  •              EXPORT __Vectors_End
  •              EXPORT __Vectors_Size

  • __Vectors       DCD   __initial_sp                ; Top of Stack
  •              DCD   Reset_Handler               ; Vector Number 1,Reset Handler
  •              DCD   NMI_Handler               ; Vector Number 2,NMI Handler
  •              DCD   HardFault_Handler           ; Vector Number 3,Hard Fault Handler
  •              DCD   MemManage_Handler           ; Vector Number 4,MPU Fault Handler
  •              DCD   BusFault_Handler             ; Vector Number 5,Bus Fault Handler
  •              DCD   UsageFault_Handler            ; Vector Number 6,Usage Fault Handler
  •              DCD   0                       ; Reserved
  •              DCD   0                       ; Reserved
  •              DCD   0                       ; Reserved
  •              DCD   0                       ; Reserved
  •              DCD   SVC_Handler               ; Vector Number 11,SVCall Handler
  •              DCD   DebugMon_Handler             ; Vector Number 12,Debug Monitor Handler
  •              DCD   0                       ; Reserved
  •              ;DCD   PendSV_Handler             ; Vector Number 14,PendSV Handler
  •                             ;DCD   SysTick_Handler              ; Vector Number 15,SysTick Handler
  •              DCD   knl_dsp_entry               ; Vector Number 14,knl_dsp_entry
  •                             DCD   knl_int_tckhdr             ; Vector Number 15,knl_int_tckhdr
复制代码
   uTenux启动任务的过程为:
main()->initctsk()->usermain()->App_TaskCreate()->App_TaskStart()
   这里建立三个用户任务:tsk_id_LED_R;tsk_id_LED_G;tsk_id_LED_Y分别点亮三个LED并通过uart输出相应的信息。
   以上就是对在小红板上移植uTenux的阶段总结。目前移植工作还未完成,存在任务启动后没有输出信息的问题,正在进一步解决中,所以就先不上传代码了。还是先把作业交了占个位置吧。
   TRON标 准是国际上嵌入式领域OS开发的一个标准,因此这里对uTenux进行了研究和移植。当然对于RTOS还是要根据开发工作的需要进行选择。对于学习而言更 推荐参考资料全面的trochiliOS,它有和小红板配套的教材《嵌入式实时操作系统原理与最佳实践》。毕竟RTOS的原理基本是类似的,一通百通吗。
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /5 下一条

手机版|小黑屋|与非网

GMT+8, 2024-12-19 22:58 , Processed in 0.114759 second(s), 17 queries , MemCache On.

ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

苏公网安备 32059002001037号

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.