版本 587050de6c58dba4bc9e79cc8ee33cddc9f7b5e3
Changes from 587050de6c58dba4bc9e79cc8ee33cddc9f7b5e3 to d9ddca975da51c2d29fa19bdec2964eb9feba4ce
---
title: rtenv-plus
categories: embedded, arm, stm32, stm32f429
toc: no
...
`HackPad 共筆<https://embedded2014.hackpad.com/Rtenv-plus-0VHEYKBpr3D>`_
組員
----
* 楊震 / <`Omar002<https://github.com/Omar002/rtenv-plus/>`_>
* 丁士宸 / <`Stanley Ding<https://github.com/StanleyDing/rtenv>`_>
* 程政罡 / <`marktwtn<https://github.com/marktwtn/rtenv-plus>`_>
* 李昆憶 / <`LanKuDot<https://github.com/LanKuDot/rtenv-plus>`_>
* 鄭聖文 / <`Shengwen<https://github.com/shengwen1997/>`_>
楊震 / <`Omar002<https://github.com/Omar002/rtenv-plus/>`_>
丁士宸 / <`Stanley Ding<https://github.com/StanleyDing/rtenv>`_>
程政罡 / <`marktwtn<https://github.com/marktwtn/rtenv-plus>`_>
李昆憶 / <`LanKuDot<https://github.com/LanKuDot/rtenv-plus>`_>
鄭聖文 / <`Shengwen<https://github.com/shengwen1997/>`_>
作業系統架構
-----------------------
Context Switch
===============
**activate**
- 功能: 將 kernel state push 到 Main stack 中,再將目前正在執行的 process state pop 到 register 中。
- 功能:將 kernel state push 到 Main stack 中,再將目前正在執行的 process state pop 到 register 中。
.. code-block:: c
activate:
41 /* save kernel state */
42 mrs ip, psr
43 push {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}
44
45 /* switch to process stack pointer */
46 msr psp, r0
47 mov r0, #3
48 msr control, r0
49
50 /* load user state */
51 pop {r4, r5, r6, r7, r8, r9, r10, r11, lr}
52 pop {r7}
53
54 bx lr
- 指令介紹:``mrs Rd, PSR`` 及 ``msr PSR, Rd``[1]_:Rd 為 general-purpose registers,PSR 可以為 psr、cpsr、apsr、msp、psp 等。
``mrs Rd, PSR`` 可以將 PSR 的值寫到 Rd,而 ``msr PSR, Rd`` 則是將 Rd 值寫到 PSR 裡。
- 運作:
- L42,43:將 ``psr``(program status register) 的值保存到 ``ip`` (r12) 裡,然後一同 push 到 main stack 裡。
- L46:將 ``r0`` 所帶的值寫入到 ``psp`` (process stack pointer),注意呼叫 activate 所放的參數就是該 task 之 task_control_block 中 stack 的 address。
- L47,48:將 ``control`` register 的值設為 3,藉此可以將 stack pointer 轉為指向 process stack (使 sp 值為 psp)。所以藉由 ``sp`` 可以存取其 stack 的內容。
- L51:將 ``user_thread_stack`` 的 register 依序 pop 到 r4~r11 及lr,也是為何 ``user_thread_stack`` 的前9個 register 設計為 r4~r10、fp、_lr。
- L52:再將 ``user_thread_stack`` 的 ``_r7`` pop 到 ``r7``,達成傳遞 syscall 的功能。
- 所以除了 r0~r3 及 ip、sp、pc、cpsr 之外,都被換成 user-mode 的 register 了。
init_task
==========
- 功能:將系統初始函式 ``first()`` 的位址放置到 process stack 的 lr 位置。藉由 ``activate`` 置換 process state 上來,可讓程式執行 ``first()``。
- 運作:
.. code-block:: c
/* 傳入的參數為:欲執行 first() 的 task 的 stack位址 以及 first() 的位址 */
unsigned int *init_task(unsigned int *stack, void (*start)())
{
/* 由於 stack 的設計為 full descendent stack,
* 所以 stack pointer 一開始必須指向最高位址。
* 觀察 user_thread_stack 的設計:r4 是最低位址,處在 stack 的底部
* 而預期將 first() 的位址存到 _lr 中,所以必須 push 9個 word
*/
stack += STACK_SIZE - 9;
/* 利用 pointer arithmetic,可以將 first() 的位址存到 _lr 中:
* user_thread_stack -> |r4 |r5 |r6 |r7 |r8 |r9 |r10|fp |_lr|...
* stack -> |[0]|[1]|[2]|[3]|[4]|[5]|[6]|[7]|[8]|...
*/
stack[8] = (unsigned int)start;
/* 回傳新的 sp 給該 task */
return stack;
}
硬體驅動原理
=============
* `USB OTG</embedded/OTG>`_
效能表現
========
參考資料
-----------
.. [1] `mrs指令<http://infocenter.arm.com/help/topic/com.arm.doc.dui0489i/Cihjcedb.html>`_ 、 `msr指令<http://infocenter.arm.com/help/topic/com.arm.doc.dui0489i/Cihibbbh.html>`_