VSF的MCU移植包括2部分,1是基本構(gòu)架,2是外設(shè)驅(qū)動(dòng)移植。這里先講一下基本構(gòu)架的移植。
VSF的基本構(gòu)架的移植,包括arch移植、編譯器的移植。
1. 編譯器移植
位于vsf/compiler目錄下,可以參考IAR的compiler.h,需要實(shí)現(xiàn)如下宏/函數(shù):
1) packed相關(guān)的宏
#define PACKED_HEAD __packed
#define PACKED_MID
#define PACKED_TAIL
復(fù)制代碼用例:
PACKED_HEAD struct PACKED_MID vsfip_protoport_t
{
uint16_t src;
uint16_t dst;
}; PACKED_TAIL
復(fù)制代碼2) ROOTFUNC
#define ROOTFUNC __root
復(fù)制代碼用例:
ROOTFUNC void UART0_IRQHandler(void)
{
uart_handler(0);
}
復(fù)制代碼3) weak相關(guān)宏
#define WEAKFUNC_HEAD __weak
#define WEAKFUNC_TAIL
復(fù)制代碼用例:
WEAKFUNC_HEAD void HardFault_Handler(void) WEAKFUNC_TAIL
{
while (1);
}
復(fù)制代碼4) 中斷控制相關(guān)
#define vsf_gint_t __istate_t
#define vsf_set_gint(gint) __set_interrupt_state(gint)
#define vsf_get_gint() __get_interrupt_state()
#define vsf_enter_critical() __disable_interrupt()
#define vsf_leave_critical() __enable_interrupt()
復(fù)制代碼5) heap相關(guān)unsigned char * compiler_get_heap(void);
long compiler_get_heap_size(void);
復(fù)制代碼實(shí)現(xiàn):
#pragma segment=“HEAP”
unsigned char * compiler_get_heap(void)
{
return __sfb(“HEAP”);
}
long compiler_get_heap_size(void)
{
return (long)__sfe(“HEAP”) - (long)__sfb(“HEAP”);
}
復(fù)制代碼6) pc/lr相關(guān),實(shí)際沒有用到,做一些實(shí)驗(yàn)的時(shí)候加上的
#define compiler_set_pc(reg) asm(“MOV pc, %0” : :“r”(reg))
#define compiler_get_lr(reg) asm(“MOV %0, lr” : “=r”(reg))
復(fù)制代碼
2. ARCH移植位于vsf/hal/arch/XXXX
多任務(wù)核心根據(jù)需要實(shí)現(xiàn)的優(yōu)先級(jí)數(shù)量,對(duì)MCU的中斷系統(tǒng)會(huì)有不同的要求。
1) 只需要非實(shí)時(shí),系統(tǒng)運(yùn)行類似前后臺(tái)
對(duì)MCU沒要求,大部分MCU都可以使用,這種模式下,vsfmain.c可以非常簡單,如下:
// IMPORTANT: DONOT CHANGE ANYTHING IN THIS FILE
#include “vsf.h”
#include “usrapp.h”
#if defined(APPCFG_NRT_QUEUE_LEN) && (APPCFG_NRT_QUEUE_LEN 》 0)
#define APPCFG_MAINQ_EN // 設(shè)置了NRT隊(duì)列,使能MAIN_QUEUE
#endif
#if defined(APPCFG_VSFTIMER_NUM) && (APPCFG_VSFTIMER_NUM 》 0)
#define APPCFG_VSFTIMER_EN // 設(shè)置了定制器支持
#endif
struct vsfapp_t
{
// 用戶的APP結(jié)構(gòu)指針
struct usrapp_t *usrapp;
// 如果使能了定時(shí)器,根據(jù)是否支持內(nèi)存管理,來選擇定時(shí)器的內(nèi)存池類型(動(dòng)態(tài)池和靜態(tài)池)
#ifdef APPCFG_VSFTIMER_EN
#ifdef APPCFG_BUFMGR_SIZE
struct vsf_dynpool_t vsftimer_pool;
#else
VSFPOOL_DEFINE(vsftimer_pool, struct vsftimer_t, APPCFG_VSFTIMER_NUM);
#endif
#endif
// 設(shè)置MAIN_QUEUE數(shù)據(jù)結(jié)構(gòu)
#if VSFSM_CFG_PREMPT_EN
#ifdef APPCFG_MAINQ_EN
struct vsfsm_evtq_t mainq;
struct vsfsm_evtq_element_t mainq_ele[APPCFG_NRT_QUEUE_LEN];
#endif
#endif
} static app =
{
.usrapp = (struct usrapp_t *)&usrapp,
#if VSFSM_CFG_PREMPT_EN
#ifdef APPCFG_MAINQ_EN
.mainq.size = dimof(app.mainq_ele),
.mainq.queue = app.mainq_ele,
.mainq.activate = NULL,
#endif
#endif
#if defined(APPCFG_VSFTIMER_EN) && defined(APPCFG_BUFMGR_SIZE)
.vsftimer_pool.item_size = sizeof(struct vsftimer_t),
.vsftimer_pool.pool_size = APPCFG_VSFTIMER_NUM,
#endif
};
// 定時(shí)器分配接口
#ifdef APPCFG_VSFTIMER_EN
#ifdef APPCFG_BUFMGR_SIZE
static struct vsftimer_t* vsftimer_memop_alloc(void)
{
return vsf_dynpool_alloc(&app.vsftimer_pool);
}
static void vsftimer_memop_free(struct vsftimer_t *timer)
{
vsf_dynpool_free(&app.vsftimer_pool, timer);
}
#else
static struct vsftimer_t* vsftimer_memop_alloc(void)
{
return VSFPOOL_ALLOC(&app.vsftimer_pool, struct vsftimer_t);
}
static void vsftimer_memop_free(struct vsftimer_t *timer)
{
VSFPOOL_FREE(&app.vsftimer_pool, timer);
}
#endif
const struct vsftimer_mem_op_t vsftimer_memop =
{
.alloc = vsftimer_memop_alloc,
.free = vsftimer_memop_free,
};
// 定時(shí)器回調(diào)
// tickclk interrupt, simply call vsftimer_callback_int
static void app_tickclk_callback_int(void *param)
{
vsftimer_callback_int();
}
#endif
static void vsfapp_init(struct vsfapp_t *app)
{
#if VSFSM_CFG_PREMPT_EN
vsfsm_evtq_set(&app-》mainq);
#endif
// 初始化MCU內(nèi)核、tickclk(系統(tǒng)滴答)
vsfhal_core_init(NULL);
vsfhal_tickclk_init(APPCFG_TICKCLK_PRIORITY);
vsfhal_tickclk_start();
// 初始化定時(shí)器內(nèi)存池
#ifdef APPCFG_VSFTIMER_EN
#ifdef APPCFG_BUFMGR_SIZE
vsf_dynpool_init(&app-》vsftimer_pool);
#else
VSFPOOL_INIT(&app-》vsftimer_pool, struct vsftimer_t, APPCFG_VSFTIMER_NUM);
#endif
vsftimer_init((struct vsftimer_mem_op_t *)&vsftimer_memop);
vsfhal_tickclk_config_cb(app_tickclk_callback_int, NULL);
#endif
// 初始化內(nèi)存管理
#ifdef APPCFG_BUFMGR_SIZE
vsf_bufmgr_init(compiler_get_heap(), APPCFG_BUFMGR_SIZE);
#endif
// 用戶非實(shí)時(shí)部分初始化
#ifdef APPCFG_NRT_QUEUE_LEN
usrapp_nrt_init(app-》usrapp);
#endif
}
int main(void)
{
// 關(guān)中斷
vsf_enter_critical();
#ifdef APPCFG_INITIAL_INIT
usrapp_initial_init(app.usrapp);
#endif
// MAIN_QUEUE初始化
#ifdef APPCFG_MAINQ_EN
vsfsm_evtq_init(&app.mainq);
#endif
// 應(yīng)用初始化
vsfapp_init(&app);
// 開中斷
vsf_leave_critical();
while (1)
{
#if defined(APPCFG_USR_POLL) && !defined(APPCFG_MAINQ_EN)
// 輪詢模式
vsfhal_tickclk_poll();
usrapp_nrt_poll(app.usrapp);
#elif defined(APPCFG_USR_POLL_SLEEP)
// 帶休眠輪詢
usrapp_nrt_poll(app.usrapp);
vsfhal_core_sleep(VSFHAL_SLEEP_WFI);
#elif defined(APPCFG_MAINQ_EN)
// 事件隊(duì)列模式
vsfsm_poll();
#ifdef APPCFG_USR_POLL
usrapp_nrt_poll(app.usrapp);
#endif
vsf_enter_critical();
if (!vsfsm_get_event_pending()
#ifdef APPCFG_USR_CANSLEEP
&& usrapp_cansleep(app.usrapp)
#endif
)
{
vsfhal_core_sleep(VSFHAL_SLEEP_WFI); // will enable interrupt
}
else
vsf_leave_critical();
#else
// 無非實(shí)時(shí)任務(wù)
vsfhal_core_sleep(VSFHAL_SLEEP_WFI);
#endif
}
}
復(fù)制代碼vsfhal中內(nèi)核層需要實(shí)現(xiàn)的基本接口:vsfhal_core_init: MCU內(nèi)核初始化,初始化時(shí)鐘、復(fù)位、調(diào)試口、等等核心功能
tickclk相關(guān): 用于實(shí)現(xiàn)系統(tǒng)滴答,可選
vsfhal_core_sleep: 內(nèi)核休眠,可選
2) 非實(shí)時(shí)+軟實(shí)時(shí)+硬實(shí)時(shí)
在1) 的基礎(chǔ)上,需要MCU支持可控的、可屏蔽的、可設(shè)置優(yōu)先級(jí)的軟件中斷。比如CortexM的PendSV,CortexA的SGI。
評(píng)論
查看更多