VSF MCU移植说明 -- 基本构架移植

[复制链接]
1302|1
 楼主| vsfopen 发表于 2018-10-5 21:45 | 显示全部楼层 |阅读模式
本帖最后由 vsfopen 于 2018-10-5 22:23 编辑

VSF的MCU移植包括2部分,1是基本构架,2是外设驱动移植。这里先讲一下基本构架的移植。

VSF的基本构架的移植,包括arch移植、编译器的移植。

1. 编译器移植
位于vsf/compiler目录下,可以参考IAR的compiler.h,需要实现如下宏/函数:
1) packed相关的宏
  1. #define PACKED_HEAD                __packed
  2. #define PACKED_MID               
  3. #define PACKED_TAIL               
用例:
  1. PACKED_HEAD struct PACKED_MID vsfip_protoport_t
  2. {
  3.         uint16_t src;
  4.         uint16_t dst;
  5. }; PACKED_TAIL
2) ROOTFUNC
  1. #define ROOTFUNC                __root
用例:
  1. ROOTFUNC void UART0_IRQHandler(void)
  2. {
  3.         uart_handler(0);
  4. }
3) weak相关宏
  1. #define WEAKFUNC_HEAD        __weak
  2. #define WEAKFUNC_TAIL        
用例:
  1. WEAKFUNC_HEAD void HardFault_Handler(void) WEAKFUNC_TAIL
  2. {
  3.         while (1);
  4. }
4) 中断控制相关
  1. #define vsf_gint_t                                                __istate_t
  2. #define vsf_set_gint(gint)                                __set_interrupt_state(gint)
  3. #define vsf_get_gint()                                        __get_interrupt_state()
  4. #define vsf_enter_critical()                        __disable_interrupt()
  5. #define vsf_leave_critical()                        __enable_interrupt()
5) heap相关
  1. unsigned char * compiler_get_heap(void);
  2. long compiler_get_heap_size(void);
实现:
  1. #pragma segment="HEAP"
  2. unsigned char * compiler_get_heap(void)
  3. {
  4.         return __sfb("HEAP");
  5. }

  6. long compiler_get_heap_size(void)
  7. {
  8.         return (long)__sfe("HEAP") - (long)__sfb("HEAP");
  9. }
6) pc/lr相关,实际没有用到,做一些实验的时候加上的
  1. #define compiler_set_pc(reg)                        asm("MOV pc, %0" : :"r"(reg))
  2. #define compiler_get_lr(reg)                        asm("MOV %0, lr" : "=r"(reg))

2. ARCH移植位于vsf/hal/arch/XXXX
多任务核心根据需要实现的优先级数量,对MCU的中断系统会有不同的要求。
1) 只需要非实时,系统运行类似前后台
对MCU没要求,大部分MCU都可以使用,这种模式下,vsfmain.c可以非常简单,如下:
  1. // IMPORTANT: DONOT CHANGE ANYTHING IN THIS FILE
  2. #include "vsf.h"
  3. #include "usrapp.h"

  4. #if defined(APPCFG_NRT_QUEUE_LEN) && (APPCFG_NRT_QUEUE_LEN > 0)
  5. #define APPCFG_MAINQ_EN     // 设置了NRT队列,使能MAIN_QUEUE
  6. #endif
  7. #if defined(APPCFG_VSFTIMER_NUM) && (APPCFG_VSFTIMER_NUM > 0)
  8. #define APPCFG_VSFTIMER_EN  // 设置了定制器支持
  9. #endif

  10. struct vsfapp_t
  11. {
  12.         // 用户的APP结构指针
  13.         struct usrapp_t *usrapp;

  14.         // 如果使能了定时器,根据是否支持内存管理,来选择定时器的内存池类型(动态池和静态池)
  15. #ifdef APPCFG_VSFTIMER_EN
  16. #ifdef APPCFG_BUFMGR_SIZE
  17.         struct vsf_dynpool_t vsftimer_pool;
  18. #else
  19.         VSFPOOL_DEFINE(vsftimer_pool, struct vsftimer_t, APPCFG_VSFTIMER_NUM);
  20. #endif
  21. #endif

  22.         // 设置MAIN_QUEUE数据结构
  23. #if VSFSM_CFG_PREMPT_EN
  24. #ifdef APPCFG_MAINQ_EN
  25.         struct vsfsm_evtq_t mainq;
  26.         struct vsfsm_evtq_element_t mainq_ele[APPCFG_NRT_QUEUE_LEN];
  27. #endif
  28. #endif
  29. } static app =
  30. {
  31.         .usrapp = (struct usrapp_t *)&usrapp,
  32. #if VSFSM_CFG_PREMPT_EN
  33. #ifdef APPCFG_MAINQ_EN
  34.         .mainq.size = dimof(app.mainq_ele),
  35.         .mainq.queue = app.mainq_ele,
  36.         .mainq.activate = NULL,
  37. #endif
  38. #endif

  39. #if defined(APPCFG_VSFTIMER_EN) && defined(APPCFG_BUFMGR_SIZE)
  40.         .vsftimer_pool.item_size = sizeof(struct vsftimer_t),
  41.         .vsftimer_pool.pool_size = APPCFG_VSFTIMER_NUM,
  42. #endif
  43. };

  44. // 定时器分配接口
  45. #ifdef APPCFG_VSFTIMER_EN
  46. #ifdef APPCFG_BUFMGR_SIZE
  47. static struct vsftimer_t* vsftimer_memop_alloc(void)
  48. {
  49.         return vsf_dynpool_alloc(&app.vsftimer_pool);
  50. }

  51. static void vsftimer_memop_free(struct vsftimer_t *timer)
  52. {
  53.         vsf_dynpool_free(&app.vsftimer_pool, timer);
  54. }
  55. #else
  56. static struct vsftimer_t* vsftimer_memop_alloc(void)
  57. {
  58.         return VSFPOOL_ALLOC(&app.vsftimer_pool, struct vsftimer_t);
  59. }

  60. static void vsftimer_memop_free(struct vsftimer_t *timer)
  61. {
  62.         VSFPOOL_FREE(&app.vsftimer_pool, timer);
  63. }
  64. #endif

  65. const struct vsftimer_mem_op_t vsftimer_memop =
  66. {
  67.         .alloc                        = vsftimer_memop_alloc,
  68.         .free                        = vsftimer_memop_free,
  69. };

  70. // 定时器回调
  71. // tickclk interrupt, simply call vsftimer_callback_int
  72. static void app_tickclk_callback_int(void *param)
  73. {
  74.         vsftimer_callback_int();
  75. }
  76. #endif

  77. static void vsfapp_init(struct vsfapp_t *app)
  78. {
  79. #if VSFSM_CFG_PREMPT_EN
  80.         vsfsm_evtq_set(&app->mainq);
  81. #endif

  82.         // 初始化MCU内核、tickclk(系统滴答)
  83.         vsfhal_core_init(NULL);
  84.         vsfhal_tickclk_init(APPCFG_TICKCLK_PRIORITY);
  85.         vsfhal_tickclk_start();

  86.         // 初始化定时器内存池
  87. #ifdef APPCFG_VSFTIMER_EN
  88. #ifdef APPCFG_BUFMGR_SIZE
  89.         vsf_dynpool_init(&app->vsftimer_pool);
  90. #else
  91.         VSFPOOL_INIT(&app->vsftimer_pool, struct vsftimer_t, APPCFG_VSFTIMER_NUM);
  92. #endif
  93.         vsftimer_init((struct vsftimer_mem_op_t *)&vsftimer_memop);
  94.         vsfhal_tickclk_config_cb(app_tickclk_callback_int, NULL);
  95. #endif

  96.         // 初始化内存管理
  97. #ifdef APPCFG_BUFMGR_SIZE
  98.         vsf_bufmgr_init(compiler_get_heap(), APPCFG_BUFMGR_SIZE);
  99. #endif

  100.         // 用户非实时部分初始化
  101. #ifdef APPCFG_NRT_QUEUE_LEN
  102.         usrapp_nrt_init(app->usrapp);
  103. #endif
  104. }

  105. int main(void)
  106. {
  107.         // 关中断
  108.         vsf_enter_critical();

  109. #ifdef APPCFG_INITIAL_INIT
  110.         usrapp_initial_init(app.usrapp);
  111. #endif

  112.         // MAIN_QUEUE初始化
  113. #ifdef APPCFG_MAINQ_EN
  114.         vsfsm_evtq_init(&app.mainq);
  115. #endif

  116.         // 应用初始化
  117.         vsfapp_init(&app);
  118.         // 开中断
  119.         vsf_leave_critical();

  120.         while (1)
  121.         {
  122. #if defined(APPCFG_USR_POLL) && !defined(APPCFG_MAINQ_EN)
  123.                 // 轮询模式
  124.                 vsfhal_tickclk_poll();
  125.                 usrapp_nrt_poll(app.usrapp);
  126. #elif defined(APPCFG_USR_POLL_SLEEP)
  127.                 // 带休眠轮询
  128.                 usrapp_nrt_poll(app.usrapp);
  129.                 vsfhal_core_sleep(VSFHAL_SLEEP_WFI);
  130. #elif defined(APPCFG_MAINQ_EN)
  131.                 // 事件队列模式
  132.                 vsfsm_poll();
  133. #ifdef APPCFG_USR_POLL
  134.                 usrapp_nrt_poll(app.usrapp);
  135. #endif
  136.                 vsf_enter_critical();
  137.                 if (!vsfsm_get_event_pending()
  138. #ifdef APPCFG_USR_CANSLEEP
  139.                         && usrapp_cansleep(app.usrapp)
  140. #endif
  141.                         )
  142.                 {
  143.                         vsfhal_core_sleep(VSFHAL_SLEEP_WFI);        // will enable interrupt
  144.                 }
  145.                 else
  146.                         vsf_leave_critical();
  147. #else
  148.                 // 无非实时任务
  149.                 vsfhal_core_sleep(VSFHAL_SLEEP_WFI);
  150. #endif
  151.         }
  152. }
vsfhal中内核层需要实现的基本接口:vsfhal_core_init: MCU内核初始化,初始化时钟、复位、调试口、等等核心功能
tickclk相关: 用于实现系统滴答,可选
vsfhal_core_sleep: 内核休眠,可选

2) 非实时+软实时+硬实时
在1) 的基础上,需要MCU支持可控的、可屏蔽的、可设置优先级的软件中断。比如CortexM的PendSV,CortexA的SGI。



aEs3sgeKl 发表于 2020-2-22 19:56 | 显示全部楼层
怎么就没人拜我为偶像那??

90

主题

325

帖子

8

粉丝
快速回复 在线客服 返回列表 返回顶部