Ostaskstkinit (): Initialization of the task stack structure

Source: Internet
Author: User

Ostaskstkinit (): Initialization of the task stack structure

Ostaskcreate () and Ostaskcreateext () initialize the stack structure of the task by calling Ostaskstkinit (). Therefore, the stack looks like a break just happened, and all registers are stored on the stack. The schematic Code of Ostaskstkinit () is shown below.

Schematic code of Ostaskstkinit () L:

Os_stk *ostaskstkinit (void (*task) (void *pd), void *pdata, Os_stk *ptos, int16u opt)

{

Simulates a function call with parameters (pdata); (1)

Analog ISR vector; (2)

Initializes the stack structure according to the pre-designed register value; (3)

Returns the stack top pointer to the function that called the function; (4)

}

The following figure shows what form the task stack should initialize when Ostaskstkinit () is set up for a task.

Note: Here it is assumed that the stack is descending from the top down. The following discussion also applies to stack structures that increment from bottom to top in the opposite direction.

The following list of programs gives the function prototypes for Ostaskcreate (), Ostaskcreateext (), and Ostaskstkinit (), where the parameters Task,pdata,ptos and opt are called ostaskstkinit () The function must pass past arguments. Because only the ostaskcreate () function does not support additional opt options, when ostaskcreate () calls Ostaskstkinit (), the OPT is set to 0x0000.

List of programs:

int8u ostaskcreate (void (*task) (VOID*PD), void *pdata, Os_stk *ptos, int8u prio);

int8u ostaskcreateext (void (*task) (VOID*PD), void *pdata, Os_stk *ptos, int8u prio, int16u ID, Os_stk*pbos, int32u stk_siz E, void *pext, int16u opt);

Os_stk *ostaskstkinit (void (*task) (VOID*PD), void *pdata, Os_stk *ptos, int16u opt);

Recall that a task can be an infinite loop, or it can be deleted after a single execution. It is important to note that the task code is not actually deleted, but that the task code is no longer uc/os-ii, so it will not run again. The task looks like any C function, has a return type and a parameter, except that it never returns. The return type of the task must be defined as void type.

In other words, in uc/os-ii, the task is an infinite loop, and the rest of it looks no different than the other C functions.

When Uc/os-ii lets the task start executing, the task receives a parameter, as if it were called by another task, as listed in the following code.

Task code:

void MyTask (void *pdata)

{

for (;;) {

}

}

If you call MyTask () from another function, the C compiler will first save the return address of the calling MyTask () function to the stack, and then save the parameter to the stack. Ostaskstkinit () needs to mimic this action of the compiler. In fact, some compilers pass the pdata parameter in one or more registers, which are discussed later.

F (1)

L (1) Assuming that pdata will be saved to the stack by the compiler, Ostaskstkinit () will mimic this behavior of the compiler, saving pdata to the stack.

F (2)

L (1) Unlike a call to a C function, the return address of the caller is unknown because the function is not called at all, just to create a stack structure for a task, as if the task code had been called. The Ostaskstkinit () function only knows the starting address of the task (which is passed as a parameter). In other words, you do not need to know the return address because the task is no longer returned.

F (3)

L (2) At this point, ostaskstkinit () is required to save the processor's register to the stack. When the processor recognizes and begins to execute the interrupt, it automatically completes the process. Some processors push all registers into the stack, while others push only some of the registers onto the stack. In general, the processor needs at least the value of the program counter (the interrupt return address) and the processor's status word to be stored on the stack. Obviously, the processor pushes registers into the stack in a certain order, and the user must follow this order when they push the registers into the stack.

F (4)

L (3) Ostaskstkinit () need to save the remaining processor registers to the stack. The order of the stacks depends on whether the processor is allowed to operate in a different order. Some processors can save all registers at once with one instruction, while others have several instructions. This process must be done strictly in the order in which the processor requires it to be in the stack. For example, Intel80x86 has a pusha instruction that pushes 8 registers onto the stack, and for MOTOROLA68HC11 processors, all registers are automatically saved to the stack in a certain order during interrupt response. Therefore, you must also conform to this order when you initialize the stack.

F (5)

L (4) After initializing the stack, Ostaskstkinit () should return the address pointed to by the stack pointer. Ostaskcreate () or Ostaskcreateext () obtains this address and is saved in the task control block. The documentation for the processor should tell the user whether the stack pointer refers to the next available stack space or to the data that was last entered. For example, 80x86 is pointing to the last stored data, while Motorola's 68HC11 processor refers to the down-to-use stack space.

Now is the time to discuss this: what to do if the user's C compiler passes the pdata parameter with the register instead of using the stack pass parameter. Take a look at the picture below.

F (1)

L (1) in the same case, Ostaskstkinit () mimics the invocation of the application's task code and saves the task start address on the stack.

F (2)

L (2) Similarly, Ostaskstkinit () saves the register to the stack. Automatically pushes registers into the stack when the processor recognizes and starts to perform interrupts. Some processors push all registers into the stack, while others push only some of the registers onto the stack. In general, the processor needs at least the value of the program counter (the interrupt return address) and the processor's status word to be stored on the stack. It is clear that the processor pushes registers into the stack in a certain order, and the user must strictly follow the same sequence when pushing registers into the stack.

F (3)

L (3) Ostaskstkinit () Saves the remaining processor registers to the stack. The order of the stacks depends on whether the processor is allowed to operate in a different order. Some processors can use one instruction to push many registers onto the stack, while others require several instructions. At this point, these instructions should be simulated. Because the compiler uses the register to pass parameters (at least some of the parameters are passed through the register), it should be clear from the corresponding document which register the pdata is passing through and push the register into the stack.

F (4)

L (4) After initializing the stack, the Ostaskstkinit () function should return the address pointed to by the stack pointer. Ostaskcreate () or Ostaskcreateext () gets this address and is saved in the task control block. Again, it should be clear whether the stack pointer refers to an empty stack space down, or to the value that was last pushed onto the stack.

Summary: the Ostaskstkinit () function is called by ostaskcreate () or Ostaskcreateext (), the parameter to be passed is the start address of the task code, the parameter pointer (pdata), the address at the top of the task stack, and the additional opt option. The stack that is used to initialize the task, and the initial state of the stack simulates the stacking structure after an outage. After the stack initialization work is complete, ostaskstkinit () returns a new stack top pointer, ostaskcreate () or Ostaskcreateext () to save the pointer in the OS_TCB of the task. That is, calling Ostaskstkinit () makes an initial task context stack for the task.

Transplantation of Uc/os-ii on 80x86 (Ostaskstkinit () part)

The following figure illustrates the stack content after initialization of Ostaskstkinit (). Note that the stack structure in the diagram is not after the Ostaskstkinit () task is called, but after the newly created task.

The following is a list of ostaskstkinit () programs:

Program List L Ostaskstkinit ()

void *ostaskstkinit (void (*task) (VOID*PD), void *pdata, void *ptos, int16u opt)

{

INT16U*STK;

opt= opt;

stk= (int16u *) PTOs;

*stk--= (int16u) fp_seg (pdata);

*stk--= (int16u) Fp_off (pdata);

*stk--= (int16u) fp_seg (Task);

*stk--= (int16u) Fp_off (Task);

*stk--= (int16u) 0x0202;

*stk--= (int16u) fp_seg (Task);

*stk--= (int16u) Fp_off (Task);

*stk--= (int16u) 0xAAAA;

*stk--= (int16u) 0xCCCC;

*stk--= (int16u) 0xDDDD;

*stk--= (int16u) 0xBBBB;

*stk--= (int16u) 0x0000;

*stk--= (int16u) 0x1111;

*stk--= (int16u) 0x2222;

*stk--= (int16u) 0x3333;

*stk--= (int16u) 0x4444;

*stk= _ds;

Return ((OS_STK *) STK);

}

L (1)

Because the 80x86 stack is 16-bit wide (in words), ostaskstkinit () creates a pointer to a region of memory in words, and requires the stack pointer to point to the top of the empty stack.

L (2)

Because the borlandc/c++ compiler used by the author is configured to pass the parameter pdata with a stack instead of a register, the segment address and offset of the parameter pdata are saved on the stack.

L (3)

The stack is followed by the start address of the task function, which in theory should be the return address of the task, but in Uc/os-ii, the task function must be an infinite loop structure and cannot have a return point.

L (4)

The return address is the status word (SW), and the status word is set to simulate the stack structure after the break occurs. The SW in the stack is initialized to 0x0202, which allows the interrupt to occur after the task is started, and, if set to 0x0002, disables the interrupt after the task starts. It is important to note that if the Select task starts to allow interrupts to occur, then all of the tasks are allowed to break during the run and, similarly, if the selection task is started and the interrupt is disabled, all tasks are prevented from being interrupted and not selected.

If you do need to break through the above limitations, you can pass the parameter pdata to the task to deliver the interrupt state you want to implement. If a task chooses to disable interrupts after it has been started, other tasks need to be reopened when they are running. Also modify the Os_taskidle () and Os_taskstat () functions to enable interrupts at run time. If there is a problem with any of these links, the system will crash. So I recommend setting SW to 0x0202, which interrupts when the task starts.

L (5)

There is also room for each register in the stack, note that the position of the register in the stack is the same as the order in which the run instruction Pusha,push es and PUSHDS are pressed into the stack. The above instruction is called every time the Interrupt service program is entered.

The order of Ax,bx,cx,dx,sp,bp,si and Di is the same as the order of the Pusha of the instruction. If you use a 80x86 processor that does not have a Pusha directive, you use multiple push instructions to press into the registers, in the same order as Pusha. Each register in the program manifest is initialized to a different value, which is convenient for debugging.

L (6)

The Borland compiler supports pseudo-register variable operations, which can be used to obtain the value of the Cpuds register using the _ds keyword, where the tag in the program list is copied directly to the stack using the _ds DS register.

After the stack initialization work is complete, ostaskstkinit () returns a new stack top pointer, ostaskcreate () or Ostaskcreateext () to save the pointer in the OS_TCB of the task.

Also note: Osstarthighrdy () will never return to Osstart () because Osstarthighrdy () is called by Osstart () and the associated context is not saved.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.