⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tk_386.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
字号:
/*  tk_386.c

   Copyright 2000 by InterNiche Technologies Inc. All rights reserved.

   Machine dependant portions of tasking package.

   This code does Microsoft C++ v6.0, Intel 386 "protected" mode, small model.
*/

#include "ipport.h"
#ifndef SUPERLOOP

#include "task.h"
static int task_sem = 0;  /* semaphore to keep task switch single-threaded */


/* void tk_frame(task * newtk, int (*proc)(int), int parm);

       Prepare a new task to run (low level). newtk->tk_stack and 
newtk->tk_size should be set before this is called. This fills in the
task frame as though the task had called tk_block(). When the round
robin scheduler gets to it, it should look like any other task ready
to resume.

Stack on C++ v6.0 compiled tk_switch() at instant of 
wake is:

sp    -> EBP (done by our inline asm)
sp+4  -> pushed EDI (C frame )
sp+8  -> pushed ESI
sp+12 -> pushed EBX
sp+16 -> pushed ECX
sp+20 -> pushed EBP (done by C frame ) <- EBP points here
sp+24 -> ret value (tk_entry)
sp+28 -> parameter

   Returns a pointer for insertion as the stack pointer (SP)
in the new task.
*/

stack_t *
tk_frame(task * newtk, int (*proc)(int), unsigned parm)
{
stack_t * fp;
int      stacksize = newtk->tk_size;
stack_t* stackbase = newtk->tk_stack;

   _asm { mov  ecx, parm };      /* get initial parameter for task */
   _asm { mov  ebx, stackbase };
   _asm { add  ebx, stacksize }; /* ebx -> top of task stack */
   _asm { sub  ebx, 32 };        /* adjust frame pointer */
   _asm { mov  [ebx]+28, ecx };  /* load param into stack so as to "pass" it */
   _asm { mov  eax, proc };      /* get pointer to initial task routine */
   _asm { mov  [ebx]+24, eax };  /* load it on stack as "ret" address */
   _asm { mov  eax, ebx };       /* copy stack frame ptr */
   _asm { add  eax, 20 };        /* make into EBP value */
   _asm { mov  [ebx]+20, eax };  /* load tasks EBP value */
   _asm { mov  [ebx], eax };     /* ...in two places */
   _asm { mov  fp, ebx };        /* load frame pointer for return */

   return fp;
}


/* tk_switch() - yield CPU, swap in next runnable task */

void
tk_switch(struct task * newtk)
{
   stack_t * tmp_fp;

   if (task_sem != 0)         /* Keep tasks out of this */
      return;
   task_sem++;
   /* _asm { cli };               Keep tasks out of this */
   _asm { push ebp };         /* Intel weirdness */
   _asm { mov  tmp_fp, esp }; /* get current stack pointer */

   tk_cur->tk_fp = tmp_fp; /* save current SP in task */
   tk_cur = newtk;         /* swap in the new task */
   tmp_fp = newtk->tk_fp;  /* get new tasks SP */

   _asm { mov  esp, tmp_fp };    /* Install new tasks stack */
   _asm { pop  ebp };

   task_sem--;                /* Reset semaphore */
   /* _asm { sti }; */
}
   
stack_t *
tk_getsp() /* for small model 32 bit just return ESP reg. */
{
   stack_t * retval;
   _asm { mov retval, esp }
   return retval;
}

#endif /* ifndef SUPERLOOP */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -