您的位置:首页 > 其它

freeRTOS 在 BlackFin533 平台上的移植 (1)

2017-05-31 19:41 405 查看
这块板子在手上有好几年了,还是在上家公司的时候,vender送给我。

吃灰吃了这么多年,最近花了二十天的时间把freeRTOS给移植到上面去了。

总共运行了四个task,后面会把关键的代码给贴出来。

1. 这段汇编代码是主要是做入栈和出栈处理的。

#define CPU_SAVE_CONTEXT()\
[ --sp ] = rets;\
[ --sp ] = fp;\
[ --sp ] = astat;\
[--sp] = (r7:0, p5:0);\
[--sp] = lc0;\
[--sp] = lc1;\
[--sp] = lt0;\
[--sp] = lt1;\
[--sp] = lb0;\
[--sp] = lb1;\
[--sp] = a0.W;\
[--sp] = a0.X;\
[--sp] = a1.W;\
[--sp] = a1.X;\
[--sp] = i0;\
[--sp] = i1;\
[--sp] = i2;\
[--sp] = i3;\
[--sp] = b0;\
[--sp] = b1;\
[--sp] = b2;\
[--sp] = b3;\
[--sp] = l0;\
[--sp] = l1;\
[--sp] = l2;\
[--sp] = l3;\
[--sp] = m0;\
[--sp] = m1;\
[--sp] = m2;\
[--sp] = m3;

#define CPU_RESTORE_CONTEXT() \
m3 = [sp++];\
m2 = [sp++];\
m1 = [sp++];\
m0 = [sp++];\
l3 = [sp++];\
l2 = [sp++];\
l1 = [sp++];\
l0 = [sp++];\
b3 = [sp++];\
b2 = [sp++];\
b1 = [sp++];\
b0 = [sp++];\
i3 = [sp++];\
i2 = [sp++];\
i1 = [sp++];\
i0 = [sp++];\
a1.X = [sp++];\
a1.W = [sp++];\
a0.X = [sp++];\
a0.W = [sp++];\
lb1 = [sp++];\
lb0 = [sp++];\
lt1 = [sp++];\
lt0 = [sp++];\
lc1 = [sp++];\
lc0 = [sp++];\
(r7:0, p5:0) = [sp++];\
astat = [ sp++ ];\
fp = [ sp++ ];\
rets = [ sp++ ];

2. 下面这段代码是OS在create几个task后,需要启动第一个task要调用的汇编函数。

    a)每个task在create的时候,都会调用prvInitialiseNewTask()函数,在该函数内部会调用pxPortInitialiseStack()函数进行stack的初始化。

    b)在每个task的stack初始化完成后,该stack会在后续的以下汇编函数中进行使用。

    c)函数pxPortInitialiseStack()进行stack的初始化的顺序比如和上面代码1中入栈宏的操作顺序一致。

//==========================================================================================
// Function:
// this function OSStartHighRdy() will be called only one time.
// the OS will select a highest priority task to start for the first time.
//==========================================================================================
.global _OSStartHighRdy;

_OSStartHighRdy:

// need to save RETS since _OSStartHighRdy never returns

// Get the SP for the highest ready task
p1.L = _pxCurrentTCB;
p1.H = _pxCurrentTCB;
p2 = [ p1 ];
sp = [ p2 + 0 ];
nop; nop; nop;

sp += 4;

// Restore CPU context
CPU_RESTORE_CONTEXT()

// Return to high ready task
rts;

_OSStartHighRdy.end:

3. 下面的函数是进行任务切换的核心函数,主要操作如下:
    a) 先进行当前任务的context信息的保存

    b) 调用vTaskSwitchContext() 函数,找到highest priority的任务

    c) 将找到的任务的context信息切入。

    d) 函数返回到新切入的任务,同时,rti汇编会打开中断。

    e) 为了代码简便,该函数没有处理当找到的高优先级任务就是当前任务时的处理方式。

//==========================================================================================
// Function:
// This function is called to switch the context of the current running task
// This function is registered as the IVG14 handler and will be called to handle both
// interrupt and task level context switches.
//==========================================================================================

.global _OSCtxSw;

_OSCtxSw:

// Save context, interrupts disabled by IPEND[4] bit
CPU_SAVE_CONTEXT()

// The task Program Counter is in RETI,
// IPEND[4] is not cleared when it is stored
// on the stack via an intermediate register like r1
// so interrupts remain disabled
r1 = reti;
[ --sp ] = r1;

//p1 -> pxCurrentTCB
p1.L = _pxCurrentTCB;
p1.H = _pxCurrentTCB;
p2 = [p1]; //p2 -> pxCurrentTCB->pxTopOfStack
[p2] = sp; //store the switched out task's stack

// to get the higher priority task to switch in
call _vTaskSwitchContext;

// Sometime the highest priority task is current task,
// i still proceed here without skipping below code.
// Get a highest ready task priority
p3.L = _pxCurrentTCB;
p3.H = _pxCurrentTCB;
p2 = [ p3 ];

sp = [ p2 + 0 ];
nop; nop; nop;

// Recover the start address of the task
reti = [ sp++ ];

// Restoring CPU context
CPU_RESTORE_CONTEXT()

// Reenable interrupts via IPEND[4] bit and return to task
rti;

_OSCtxSw.end:
今天的代码就更新到此。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: